innodb_ruby 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
File without changes
data/bin/innodb_space ADDED
@@ -0,0 +1,306 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "getoptlong"
4
+ require "ostruct"
5
+ require "pp"
6
+ require "innodb"
7
+
8
+ def space_summary(space)
9
+ puts "%-12s%-20s%-12s%-12s%-20s" % [
10
+ "page",
11
+ "type",
12
+ "prev",
13
+ "next",
14
+ "lsn",
15
+ ]
16
+
17
+ space.each_page do |page_number, page|
18
+ puts "%-12i%-20s%-12i%-12i%-20i" % [
19
+ page_number,
20
+ page.type,
21
+ page.prev,
22
+ page.next,
23
+ page.lsn,
24
+ ]
25
+ end
26
+ end
27
+
28
+ def space_index_pages_summary(space)
29
+ puts "%-12s%-8s%-8s%-8s%-8s%-8s" % [
30
+ "page",
31
+ "index",
32
+ "level",
33
+ "data",
34
+ "free",
35
+ "records",
36
+ ]
37
+
38
+ space.each_page do |page_number, page|
39
+ case page.type
40
+ when :INDEX
41
+ puts "%-12i%-8i%-8i%-8i%-8i%-8i" % [
42
+ page_number,
43
+ page.ph[:index_id],
44
+ page.ph[:level],
45
+ page.record_space,
46
+ page.free_space,
47
+ page.ph[:n_recs],
48
+ ]
49
+ when :ALLOCATED
50
+ puts "%-12i%-8i%-8i%-8i%-8i%-8i" % [ page_number, 0, 0, 0, page.size, 0 ]
51
+ end
52
+ end
53
+ end
54
+
55
+ def index_recurse(index)
56
+ index.recurse(
57
+ lambda do |page, depth|
58
+ puts "%s%s %i: %i records, %i bytes" % [
59
+ " " * depth,
60
+ page.level == 0 ? "LEAF" : "NODE",
61
+ page.offset,
62
+ page.page_header[:n_recs],
63
+ page.record_space,
64
+ ]
65
+ if page.level == 0
66
+ page.each_record do |record|
67
+ puts "%sRECORD: (%s) -> (%s)" % [
68
+ " " * (depth+1),
69
+ record[:key].join(", "),
70
+ record[:row].join(", "),
71
+ ]
72
+ end
73
+ end
74
+ end,
75
+ lambda do |parent_page, child_page, child_min_key, depth|
76
+ puts "%sLINK %i -> %i: %s records >= (%s)" % [
77
+ " " * depth,
78
+ parent_page.offset,
79
+ child_page.offset,
80
+ child_page.page_header[:n_recs],
81
+ child_min_key.join(", "),
82
+ ]
83
+ end
84
+ )
85
+ end
86
+
87
+ def index_digraph(index)
88
+ puts "digraph btree {"
89
+ puts " rankdir = LR;"
90
+ puts " ranksep = 2.0;"
91
+ index.recurse(
92
+ lambda do |page, depth|
93
+ label = "<page>Page %i|(%i records)" % [
94
+ page.offset,
95
+ page.page_header[:n_recs],
96
+ ]
97
+ page.each_child_page do |child_page_number, child_key|
98
+ label += "|<dir_%i>(%s)" % [
99
+ child_page_number,
100
+ child_key.join(", "),
101
+ ]
102
+ end
103
+ puts " %spage_%i [ shape = \"record\"; label = \"%s\"; ];" % [
104
+ " " * depth,
105
+ page.offset,
106
+ label,
107
+ ]
108
+ end,
109
+ lambda do |parent_page, child_page, child_key, depth|
110
+ puts " %spage_%i:dir_%i -> page_%i:page:nw;" % [
111
+ " " * depth,
112
+ parent_page.offset,
113
+ child_page.offset,
114
+ child_page.offset,
115
+ ]
116
+ end
117
+ )
118
+ puts "}"
119
+ end
120
+
121
+ def index_level_summary(index, levels)
122
+ puts "%-8s%-8s%-8s%-8s%-8s%-8s%-8s" % [
123
+ "page",
124
+ "index",
125
+ "level",
126
+ "data",
127
+ "free",
128
+ "records",
129
+ "min_key",
130
+ ]
131
+
132
+ levels.each do |level|
133
+ index.each_page_at_level(level) do |page|
134
+ puts "%-8i%-8i%-8i%-8i%-8i%-8i%s" % [
135
+ page.offset,
136
+ page.ph[:index_id],
137
+ page.ph[:level],
138
+ page.record_space,
139
+ page.free_space,
140
+ page.ph[:n_recs],
141
+ page.first_record[:key].join("|"),
142
+ ]
143
+ end
144
+ end
145
+ end
146
+
147
+ def usage(exit_code, message = nil)
148
+ print "Error: #{message}\n" unless message.nil?
149
+
150
+ print <<'END_OF_USAGE'
151
+
152
+ Usage: innodb_space -f <file> [-p <page>] [-l <level>] <mode> [<mode>, ...]
153
+
154
+ --help, -?
155
+ Print this usage text.
156
+
157
+ --file, -f <file>
158
+ Load the tablespace file <file>.
159
+
160
+ --page, -p <page>
161
+ Operate on the page <page>; may be specified more than once.
162
+
163
+ --level, -l <level>
164
+ Operate on the level <level>; may be specified more than once.
165
+
166
+ --require, -r <file>
167
+ Use Ruby's "require" to load the file <file>. This is useful for loading
168
+ classes with record describers.
169
+
170
+ --describer, -d <describer>
171
+ Use the named record describer to parse records in index pages.
172
+
173
+ The following modes are supported:
174
+
175
+ page-dump
176
+ Dump the contents of the page, using the Ruby pp ("pretty-print") module.
177
+
178
+ space-summary
179
+ Summarize all pages within a tablespace.
180
+
181
+ space-index-pages-summary
182
+ Summarize all "INDEX" pages within a tablespace. This is useful to analyze
183
+ page fill rates and record counts per page. In addition to "INDEX" pages,
184
+ "ALLOCATED" pages are also printed and assumed to be completely empty.
185
+
186
+ index-recurse
187
+ Recurse an index, starting at the root (which must be provided in the first
188
+ --page/-p argument), printing the node pages, node pointers (links), leaf
189
+ pages. A record describer must be provided with the --describer/-d argument
190
+ to recurse indexes (in order to parse node pages).
191
+
192
+ index-digraph
193
+ Recurse an index as index-recurse does, but print a dot-compatible digraph
194
+ instead of a human-readable summary.
195
+
196
+ index-level-summary
197
+ Print a summary of all pages at a given level (provided with the --level/-l
198
+ argument) in an index.
199
+
200
+ END_OF_USAGE
201
+
202
+ exit exit_code
203
+ end
204
+
205
+ @options = OpenStruct.new
206
+ @options.file = nil
207
+ @options.pages = []
208
+ @options.levels = []
209
+ @options.describer = nil
210
+
211
+ getopt_options = [
212
+ [ "--help", "-?", GetoptLong::NO_ARGUMENT ],
213
+ [ "--file", "-f", GetoptLong::REQUIRED_ARGUMENT ],
214
+ [ "--page", "-p", GetoptLong::REQUIRED_ARGUMENT ],
215
+ [ "--level", "-l", GetoptLong::REQUIRED_ARGUMENT ],
216
+ [ "--require", "-r", GetoptLong::REQUIRED_ARGUMENT ],
217
+ [ "--describer", "-d", GetoptLong::REQUIRED_ARGUMENT ],
218
+ ]
219
+
220
+ getopt = GetoptLong.new(*getopt_options)
221
+
222
+ getopt.each do |opt, arg|
223
+ case opt
224
+ when "--help"
225
+ usage 0
226
+ when "--mode"
227
+ @options.mode = arg
228
+ when "--file"
229
+ @options.file = arg
230
+ when "--page"
231
+ @options.pages << arg.to_i
232
+ when "--level"
233
+ @options.levels << arg.to_i
234
+ when "--require"
235
+ require arg
236
+ when "--describer"
237
+ @options.describer = arg
238
+ end
239
+ end
240
+
241
+ unless @options.file
242
+ usage 1, "File must be provided with -f argument"
243
+ end
244
+
245
+ space = Innodb::Space.new(@options.file)
246
+
247
+ if @options.describer
248
+ space.record_describer = Innodb::RecordDescriber.const_get(@options.describer)
249
+ end
250
+
251
+ if ARGV.empty?
252
+ usage 1, "At least one mode should be provided"
253
+ end
254
+
255
+ ARGV.each do |mode|
256
+ case mode
257
+ when "page-dump"
258
+ if @options.pages.empty?
259
+ usage 1, "Page numbers to dump must be provided"
260
+ end
261
+
262
+ @options.pages.each do |page|
263
+ space.page(page).dump
264
+ end
265
+ when "space-summary"
266
+ space_summary(space)
267
+ when "space-index-pages-summary"
268
+ space_index_pages_summary(space)
269
+ when "index-recurse"
270
+ unless space.record_describer
271
+ usage 1, "Record describer necessary for index recursion"
272
+ end
273
+
274
+ if @options.pages.empty?
275
+ usage 1, "Page number of index root must be provided"
276
+ end
277
+
278
+ @options.pages.each do |page|
279
+ index_recurse(space.index(page))
280
+ end
281
+ when "index-digraph"
282
+ unless space.record_describer
283
+ usage 1, "Record describer necessary for index recursion"
284
+ end
285
+
286
+ if @options.pages.empty?
287
+ usage 1, "Page number of index root must be provided"
288
+ end
289
+
290
+ @options.pages.each do |page|
291
+ index_digraph(space.index(page))
292
+ end
293
+ when "index-level-summary"
294
+ unless space.record_describer
295
+ usage 1, "Record describer necessary for index recursion"
296
+ end
297
+
298
+ if @options.pages.empty?
299
+ usage 1, "Page number of index root must be provided"
300
+ end
301
+
302
+ index_level_summary(space.index(@options.pages.first), @options.levels)
303
+ else
304
+ usage 1, "Unknown mode: #{mode}"
305
+ end
306
+ end
data/lib/innodb.rb CHANGED
@@ -6,6 +6,7 @@ require "innodb/page"
6
6
  require "innodb/page/fsp_hdr_xdes"
7
7
  require "innodb/page/inode"
8
8
  require "innodb/page/index"
9
+ require "innodb/record_describer"
9
10
  require "innodb/space"
10
11
  require "innodb/index"
11
12
  require "innodb/log_block"
data/lib/innodb/index.rb CHANGED
@@ -32,7 +32,7 @@ class Innodb::Index
32
32
 
33
33
  parent_page.each_child_page do |child_page_number, child_min_key|
34
34
  child_page = @space.page(child_page_number)
35
- child_page.record_formatter = @space.record_formatter
35
+ child_page.record_describer = @space.record_describer
36
36
  if child_page.type == :INDEX
37
37
  if link_proc
38
38
  link_proc.call(parent_page, child_page, child_min_key, depth+1)
@@ -76,7 +76,7 @@ class Innodb::Index
76
76
 
77
77
  # Iterate through all records on all leaf pages in ascending order.
78
78
  def each_record
79
- each_leaf_page do |page|
79
+ each_page_at_level(0) do |page|
80
80
  page.each_record do |record|
81
81
  yield record
82
82
  end
data/lib/innodb/log.rb CHANGED
@@ -16,10 +16,14 @@ class Innodb::Log
16
16
 
17
17
  # Open a log file.
18
18
  def initialize(file)
19
- @file = File.open(file)
20
- @size = @file.stat.size
21
- @blocks = ((@size - DATA_START) / Innodb::LogBlock::BLOCK_SIZE)
19
+ @name = file
20
+ File.open(@name) do |log|
21
+ @size = log.stat.size
22
+ @blocks = ((@size - DATA_START) / Innodb::LogBlock::BLOCK_SIZE)
23
+ end
22
24
  end
25
+
26
+ attr_reader :blocks
23
27
 
24
28
  # Return a log block with a given block number as an InnoDB::LogBlock object.
25
29
  # Blocks are numbered after the log file header, starting from 0.
@@ -27,9 +31,11 @@ class Innodb::Log
27
31
  offset = DATA_START + (block_number.to_i * Innodb::LogBlock::BLOCK_SIZE)
28
32
  return nil unless offset < @size
29
33
  return nil unless (offset + Innodb::LogBlock::BLOCK_SIZE) <= @size
30
- @file.seek(offset)
31
- block_data = @file.read(Innodb::LogBlock::BLOCK_SIZE)
32
- Innodb::LogBlock.new(block_data)
34
+ File.open(@name) do |log|
35
+ log.seek(offset)
36
+ block_data = log.read(Innodb::LogBlock::BLOCK_SIZE)
37
+ Innodb::LogBlock.new(block_data)
38
+ end
33
39
  end
34
40
 
35
41
  # Iterate through all log blocks, returning the block number and an
@@ -57,7 +57,7 @@ class Innodb::LogBlock
57
57
  @header ||= begin
58
58
  c = cursor(HEADER_START)
59
59
  {
60
- :block => c.get_uint32,
60
+ :block => c.get_uint32 & (2**31-1),
61
61
  :data_length => c.get_uint16,
62
62
  :first_rec_group => c.get_uint16,
63
63
  :checkpoint_no => c.get_uint32,
@@ -143,7 +143,7 @@ class Innodb::LogBlock
143
143
  end
144
144
 
145
145
  SINGLE_RECORD_MASK = 0x80
146
- RECORD_TYPE_MASK = 0x7f
146
+ RECORD_TYPE_MASK = 0x7f
147
147
 
148
148
  # Return the log record. (This is mostly unimplemented.)
149
149
  def record
@@ -153,7 +153,7 @@ class Innodb::LogBlock
153
153
  type_and_flag = c.get_uint8
154
154
  type = type_and_flag & RECORD_TYPE_MASK
155
155
  type = RECORD_TYPES[type] || type
156
- single_record = (type_and_flag & SINGLE_RECORD_MASK) == SINGLE_RECORD_MASK
156
+ single_record = (type_and_flag & SINGLE_RECORD_MASK) > 0
157
157
  {
158
158
  :type => type,
159
159
  :single_record => single_record,
data/lib/innodb/page.rb CHANGED
@@ -126,13 +126,18 @@ class Innodb::Page
126
126
  fil_header[:next]
127
127
  end
128
128
 
129
+ # A helper function to return the LSN, for easier access.
130
+ def lsn
131
+ fil_header[:lsn]
132
+ end
133
+
129
134
  # Dump the contents of a page for debugging purposes.
130
135
  def dump
131
- puts
132
136
  puts "#{self}:"
133
-
134
137
  puts
138
+
135
139
  puts "fil header:"
136
140
  pp fil_header
141
+ puts
137
142
  end
138
143
  end
@@ -62,15 +62,15 @@ class Innodb::Page::FspHdrXdes < Innodb::Page
62
62
  def dump
63
63
  super
64
64
 
65
- puts
66
65
  puts "fsp header:"
67
66
  pp fsp_header
68
-
69
67
  puts
68
+
70
69
  puts "xdes entries:"
71
70
  each_xdes do |xdes|
72
71
  pp xdes
73
72
  end
73
+ puts
74
74
  end
75
75
  end
76
76
 
@@ -1,5 +1,5 @@
1
1
  class Innodb::Page::Index < Innodb::Page
2
- attr_accessor :record_formatter
2
+ attr_accessor :record_describer
3
3
 
4
4
  # Return the byte offset of the start of the "index" page header, which
5
5
  # immediately follows the "fil" header.
@@ -229,8 +229,8 @@ class Innodb::Page::Index < Innodb::Page
229
229
 
230
230
  # Return (and cache) the record format provided by an external class.
231
231
  def record_format
232
- if record_formatter
233
- @record_format ||= record_formatter.format(self)
232
+ if record_describer
233
+ @record_format ||= record_describer.cursor_sendable_description(self)
234
234
  end
235
235
  end
236
236
 
@@ -318,11 +318,10 @@ class Innodb::Page::Index < Innodb::Page
318
318
  def dump
319
319
  super
320
320
 
321
- puts
322
321
  puts "page header:"
323
322
  pp page_header
324
-
325
323
  puts
324
+
326
325
  puts "sizes:"
327
326
  puts " %-15s%5i" % [ "header", header_space ]
328
327
  puts " %-15s%5i" % [ "trailer", trailer_space ]
@@ -334,17 +333,18 @@ class Innodb::Page::Index < Innodb::Page
334
333
  "per record",
335
334
  (page_header[:n_recs] > 0) ? (record_space / page_header[:n_recs]) : 0
336
335
  ]
337
-
338
336
  puts
337
+
339
338
  puts "system records:"
340
339
  pp infimum
341
340
  pp supremum
342
-
343
341
  puts
342
+
344
343
  puts "records:"
345
344
  each_record do |rec|
346
345
  pp rec
347
346
  end
347
+ puts
348
348
  end
349
349
  end
350
350
 
@@ -35,9 +35,9 @@ class Innodb::Page::Inode < Innodb::Page
35
35
  def dump
36
36
  super
37
37
 
38
- puts
39
38
  puts "inode header:"
40
39
  pp inode_header
40
+ puts
41
41
  end
42
42
  end
43
43
 
@@ -0,0 +1 @@
1
+ class Innodb::RecordDescriber; end
data/lib/innodb/space.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # An InnoDB tablespace file, which can be either a multi-table ibdataN file
2
2
  # or a single-table "innodb_file_per_table" .ibd file.
3
3
  class Innodb::Space
4
- attr_accessor :record_formatter
4
+ attr_accessor :record_describer
5
5
 
6
6
  # Currently only 16kB InnoDB pages are supported.
7
7
  PAGE_SIZE = 16384
@@ -11,7 +11,7 @@ class Innodb::Space
11
11
  @file = File.open(file)
12
12
  @size = @file.stat.size
13
13
  @pages = (@size / PAGE_SIZE)
14
- @record_formatter = nil
14
+ @record_describer = nil
15
15
  end
16
16
 
17
17
  # Get an Innodb::Page object for a specific page by page number.
@@ -24,12 +24,17 @@ class Innodb::Space
24
24
  this_page = Innodb::Page.parse(page_data)
25
25
 
26
26
  if this_page.type == :INDEX
27
- this_page.record_formatter = @record_formatter
27
+ this_page.record_describer = @record_describer
28
28
  end
29
29
 
30
30
  this_page
31
31
  end
32
32
 
33
+ # Get an Innodb::Index object for a specific index by root page number.
34
+ def index(root_page_number)
35
+ Innodb::Index.new(self, root_page_number)
36
+ end
37
+
33
38
  # Iterate through all pages in a tablespace, returning the page number
34
39
  # and an Innodb::Page object for each one.
35
40
  def each_page
@@ -1,3 +1,3 @@
1
1
  module Innodb
2
- VERSION = "0.5.1"
2
+ VERSION = "0.6.0"
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: 9
4
+ hash: 7
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 5
9
- - 1
10
- version: 0.5.1
8
+ - 6
9
+ - 0
10
+ version: 0.6.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jeremy Cole
@@ -15,14 +15,14 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-11-29 00:00:00 Z
18
+ date: 2012-12-01 00:00:00 Z
19
19
  dependencies: []
20
20
 
21
21
  description: Library for parsing InnoDB data files in Ruby
22
22
  email: jeremy@jcole.us
23
23
  executables:
24
- - innodb_dump_log
25
- - innodb_dump_space
24
+ - innodb_log
25
+ - innodb_space
26
26
  extensions: []
27
27
 
28
28
  extra_rdoc_files: []
@@ -38,10 +38,11 @@ files:
38
38
  - lib/innodb/page/fsp_hdr_xdes.rb
39
39
  - lib/innodb/page/index.rb
40
40
  - lib/innodb/page/inode.rb
41
+ - lib/innodb/record_describer.rb
41
42
  - lib/innodb/space.rb
42
43
  - lib/innodb/version.rb
43
- - bin/innodb_dump_log
44
- - bin/innodb_dump_space
44
+ - bin/innodb_log
45
+ - bin/innodb_space
45
46
  homepage: http://jcole.us/
46
47
  licenses: []
47
48
 
@@ -1,189 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "pp"
4
- require "innodb"
5
-
6
- class EdgesRecordFormatter
7
- def format(page)
8
- bytes_per_record = (page.record_space / page.page_header[:n_recs])
9
- case
10
- when [48, 26].include?(bytes_per_record) # Clustered Key
11
- {
12
- # PRIMARY KEY (source_id, state, position)
13
- :type => :clustered,
14
- :key => [
15
- [:get_uint64], # source_id
16
- [:get_i_sint8], # state
17
- [:get_i_sint64], # position
18
- ],
19
- :row => [
20
- [:get_uint32], # updated_at
21
- [:get_uint64], # destination_id
22
- [:get_uint8], # count
23
- ],
24
- }
25
- when [30, 34].include?(bytes_per_record) # Secondary Key
26
- {
27
- # INDEX (source_id, destination_id)
28
- :type => :secondary,
29
- :key => [
30
- [:get_uint64], # source_id
31
- [:get_uint64], # destination_id
32
- ],
33
- # PKV ([source_id], state, position)
34
- :row => [
35
- [:get_i_sint8], # state
36
- [:get_i_sint64], # position
37
- ],
38
- }
39
- end
40
- end
41
- end
42
-
43
- class PageSplitTestFormatter
44
- def format(page)
45
- {
46
- # PRIMARY KEY (id)
47
- :type => :clustered,
48
- :key => [
49
- [:get_uint64], # id
50
- ],
51
- :row => [],
52
- }
53
- end
54
- end
55
-
56
- def digraph_index(index)
57
- puts "digraph btree {"
58
- puts " rankdir = LR;"
59
- puts " ranksep = 2.0;"
60
- index.recurse(
61
- lambda do |page, depth|
62
- if true #page.level != 0
63
- label = "<page>Page %i|(%i records)" % [
64
- page.offset,
65
- page.page_header[:n_recs],
66
- ]
67
- page.each_child_page do |child_page_number, child_key|
68
- label += "|<dir_%i>(%s)" % [
69
- child_page_number,
70
- child_key.join(", "),
71
- ]
72
- end
73
- puts " %spage_%i [ shape = \"record\"; label = \"%s\"; ];" % [
74
- " " * depth,
75
- page.offset,
76
- label,
77
- ]
78
- end
79
- end,
80
- lambda do |parent_page, child_page, child_key, depth|
81
- if true #child_page.level > 0
82
- puts " %spage_%i:dir_%i -> page_%i:page:nw;" % [
83
- " " * depth,
84
- parent_page.offset,
85
- child_page.offset,
86
- child_page.offset,
87
- ]
88
- end
89
- end
90
- )
91
- puts "}"
92
- end
93
-
94
- def recurse_index(index)
95
- index.recurse(
96
- lambda do |page, depth|
97
- puts "%s%s %i: %i records, %i bytes" % [
98
- " " * depth,
99
- page.level == 0 ? "LEAF" : "NODE",
100
- page.offset,
101
- page.page_header[:n_recs],
102
- page.record_space,
103
- ]
104
- if page.level == 0
105
- page.each_record do |record|
106
- puts "%sRECORD: (%s) -> (%s)" % [
107
- " " * (depth+1),
108
- record[:key].join(", "),
109
- record[:row].join(", "),
110
- ]
111
- end
112
- end
113
- end,
114
- lambda do |parent_page, child_page, child_min_key, depth|
115
- puts "%sLINK %i -> %i: %s records >= (%s)" % [
116
- " " * depth,
117
- parent_page.offset,
118
- child_page.offset,
119
- child_page.page_header[:n_recs],
120
- child_min_key.join(", "),
121
- ]
122
- end
123
- )
124
- end
125
-
126
- def dump_space(space)
127
- puts "%-8s%-8s%-8s%-8s%-8s%-8s" % [
128
- "page",
129
- "index",
130
- "level",
131
- "data",
132
- "free",
133
- "records",
134
- ]
135
-
136
- space.each_page do |page_number, page|
137
- case page.type
138
- when :INDEX
139
- puts "%-8i%-8i%-8i%-8i%-8i%-8i" % [
140
- page_number,
141
- page.ph[:index_id],
142
- page.ph[:level],
143
- page.record_space,
144
- page.free_space,
145
- page.ph[:n_recs],
146
- ]
147
- when :ALLOCATED
148
- puts "%-8i%-8i%-8i%-8i%-8i%-8i" % [ page_number, 0, 0, 0, Innodb::Space::PAGE_SIZE, 0 ]
149
- end
150
- end
151
- end
152
-
153
- def dump_index_level(index, level)
154
- puts "%-8s%-8s%-8s%-8s%-8s%-8s%-8s" % [
155
- "page",
156
- "index",
157
- "level",
158
- "data",
159
- "free",
160
- "records",
161
- "min_key",
162
- ]
163
-
164
- index.each_page_at_level(level) do |page|
165
- puts "%-8i%-8i%-8i%-8i%-8i%-8i%s" % [
166
- page.offset,
167
- page.ph[:index_id],
168
- page.ph[:level],
169
- page.record_space,
170
- page.free_space,
171
- page.ph[:n_recs],
172
- page.first_record[:key].join("|"),
173
- ]
174
- end
175
- end
176
-
177
- file, page_number = ARGV.shift(2)
178
-
179
- formatter = EdgesRecordFormatter.new
180
- #formatter = PageSplitTestFormatter.new
181
- space = Innodb::Space.new(file)
182
- space.record_formatter = formatter
183
- space.page(page_number).dump
184
- #space.each_page { |page_number, page| puts "%6i%20s" % [page_number, page.type] }
185
- #dump_space(space)
186
- #dump_index_level(Innodb::Index.new(space, page_number), 1)
187
- #recurse_index(Innodb::Index.new(space, page_number))
188
- #digraph_index(Innodb::Index.new(space, page_number))
189
- #Innodb::Index.new(space, page_number).each_record { |record| puts "(#{record[:key].join(", ")}) -> (#{record[:row].join(", ")})" }