innodb_ruby 0.6.2 → 0.6.3

Sign up to get free protection for your applications and to get access to all the features.
data/bin/innodb_space CHANGED
@@ -70,6 +70,52 @@ def space_page_type_regions(space)
70
70
  end
71
71
  end
72
72
 
73
+ def space_index_pages_free_plot(space, image)
74
+ unless require "gnuplot"
75
+ raise "Couldn't load gnuplot. Is it installed?"
76
+ end
77
+
78
+ index_data = {0 => {:x => [], :y => []}}
79
+
80
+ space.each_page do |page_number, page|
81
+ case page.type
82
+ when :INDEX
83
+ data = (index_data[page.page_header[:index_id]] ||= {:x => [], :y => []})
84
+ data[:x] << page_number
85
+ data[:y] << page.free_space
86
+ when :ALLOCATED
87
+ index_data[0][:x] << page_number
88
+ index_data[0][:y] << page.size
89
+ end
90
+ end
91
+
92
+ image_file = image + "_free.png"
93
+ # Aim for one horizontal pixel per extent, but min 1k and max 10k width.
94
+ image_width = [10000, [1000, space.pages / 64].max].min
95
+
96
+ Gnuplot.open do |gp|
97
+ Gnuplot::Plot.new(gp) do |plot|
98
+ plot.terminal "png size #{image_width}, 800"
99
+ plot.output image_file
100
+ plot.title image
101
+ plot.key "reverse left top box horizontal Left textcolor variable"
102
+ plot.ylabel "free space per page"
103
+ plot.xlabel "page number"
104
+ plot.yrange "[-100:18000]"
105
+ plot.xtics "border"
106
+
107
+ index_data.each do |id, data|
108
+ plot.data << Gnuplot::DataSet.new([data[:x], data[:y]]) do |ds|
109
+ ds.with = "dots"
110
+ ds.title = id == 0 ? "Unallocated" : "Index #{id}"
111
+ end
112
+ end
113
+
114
+ puts "Wrote #{image_file}"
115
+ end
116
+ end
117
+ end
118
+
73
119
  def index_recurse(index)
74
120
  index.recurse(
75
121
  lambda do |page, depth|
@@ -201,6 +247,12 @@ The following modes are supported:
201
247
  page fill rates and record counts per page. In addition to "INDEX" pages,
202
248
  "ALLOCATED" pages are also printed and assumed to be completely empty.
203
249
 
250
+ space-index-pages-free-plot
251
+ Use Ruby's gnuplot module to produce a scatterplot of page free space for
252
+ all "INDEX" and "ALLOCATED" pages in a tablespace. More aesthetically
253
+ pleasing plots can be produced with space-index-pages-summary output,
254
+ but this is a quick and easy way to produce a passable plot.
255
+
204
256
  space-page-type-regions
205
257
  Summarize all contiguous regions of the same page type. This is useful to
206
258
  provide an overall view of the space and allocations within it.
@@ -288,6 +340,9 @@ ARGV.each do |mode|
288
340
  space_summary(space)
289
341
  when "space-index-pages-summary"
290
342
  space_index_pages_summary(space)
343
+ when "space-index-pages-free-plot"
344
+ name = File.basename(@options.file).sub(".ibd", "")
345
+ space_index_pages_free_plot(space, name)
291
346
  when "space-page-type-regions"
292
347
  space_page_type_regions(space)
293
348
  when "index-recurse"
@@ -112,8 +112,6 @@ class Innodb::Page::Index < Innodb::Page
112
112
 
113
113
  # Return the "index" header.
114
114
  def page_header
115
- return nil unless type == :INDEX
116
-
117
115
  c = cursor(pos_index_header)
118
116
  @page_header ||= {
119
117
  :n_dir_slots => c.get_uint16,
@@ -145,6 +143,24 @@ class Innodb::Page::Index < Innodb::Page
145
143
  self.prev.nil? && self.next.nil?
146
144
  end
147
145
 
146
+ # Parse an "fseg" header entry.
147
+ def fseg_entry(cursor)
148
+ {
149
+ :space_id => cursor.get_uint32,
150
+ :page_number => cursor.get_uint32,
151
+ :offset => cursor.get_uint16,
152
+ }
153
+ end
154
+
155
+ # Return the "fseg" header.
156
+ def fseg_header
157
+ c = cursor(pos_fseg_header)
158
+ @fseg_header ||= {
159
+ :free_list => fseg_entry(c),
160
+ :btree_segment => fseg_entry(c),
161
+ }
162
+ end
163
+
148
164
  RECORD_BITS_SIZE = 3
149
165
  RECORD_NEXT_SIZE = 2
150
166
 
@@ -328,6 +344,10 @@ class Innodb::Page::Index < Innodb::Page
328
344
  pp page_header
329
345
  puts
330
346
 
347
+ puts "fseg header:"
348
+ pp fseg_header
349
+ puts
350
+
331
351
  puts "sizes:"
332
352
  puts " %-15s%5i" % [ "header", header_space ]
333
353
  puts " %-15s%5i" % [ "trailer", trailer_space ]
data/lib/innodb/space.rb CHANGED
@@ -2,6 +2,7 @@
2
2
  # or a single-table "innodb_file_per_table" .ibd file.
3
3
  class Innodb::Space
4
4
  attr_accessor :record_describer
5
+ attr_reader :pages
5
6
 
6
7
  # Currently only 16kB InnoDB pages are supported.
7
8
  PAGE_SIZE = 16384
@@ -1,3 +1,3 @@
1
1
  module Innodb
2
- VERSION = "0.6.2"
2
+ VERSION = "0.6.3"
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: innodb_ruby
3
3
  version: !ruby/object:Gem::Version
4
- hash: 3
4
+ hash: 1
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 6
9
- - 2
10
- version: 0.6.2
9
+ - 3
10
+ version: 0.6.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jeremy Cole