innodb_ruby 0.8.8 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +6 -1
- data/bin/innodb_log +8 -6
- data/bin/innodb_space +344 -212
- data/lib/innodb.rb +12 -1
- data/lib/innodb/cursor.rb +2 -2
- data/lib/innodb/data_dictionary.rb +591 -0
- data/lib/innodb/index.rb +149 -178
- data/lib/innodb/log.rb +96 -33
- data/lib/innodb/log_block.rb +34 -68
- data/lib/innodb/page.rb +1 -7
- data/lib/innodb/page/index.rb +303 -39
- data/lib/innodb/page/index_compressed.rb +4 -0
- data/lib/innodb/page/sys_data_dictionary_header.rb +1 -43
- data/lib/innodb/record.rb +34 -3
- data/lib/innodb/record_describer.rb +2 -0
- data/lib/innodb/space.rb +37 -22
- data/lib/innodb/stats.rb +46 -0
- data/lib/innodb/system.rb +122 -42
- data/lib/innodb/version.rb +1 -1
- metadata +3 -2
data/README.md
CHANGED
@@ -9,4 +9,9 @@ It is intended as for a few purposes:
|
|
9
9
|
* *As an investigative tool.* InnoDB unfortunately doesn't provide enough information about what it is doing or has done with its on-disk storage. How full are pages? Exactly how many records per page? How is the B+tree structured for a particular table? All of these questions can be answered easily with `innodb_ruby`.
|
10
10
|
* *As a debugging tool.* While making changes to the structures or behaviors of InnoDB, it is necessary to have tools to expose the results both of the original behavior and the new one, in order to validate that the changes have the desired effect.
|
11
11
|
|
12
|
-
Various parts of this library and the tools included may have wildly differing maturity levels, as it is worked on primarily based on immediate needs of the authors.
|
12
|
+
Various parts of this library and the tools included may have wildly differing maturity levels, as it is worked on primarily based on immediate needs of the authors.
|
13
|
+
|
14
|
+
# Resources #
|
15
|
+
|
16
|
+
* Visit the [innodb_ruby mailing list on Google Groups](https://groups.google.com/d/forum/innodb_ruby) or email [innodb_ruby@googlegroups.com](mailto:innodb_ruby@googlegroups.com) — If you have questions about `innodb_ruby` or its usage.
|
17
|
+
* See the [RubyGems page for innodb_ruby](http://rubygems.org/gems/innodb_ruby) — Gem packaged releases are published regularly to RubyGems.org, which also provides online documentation.
|
data/bin/innodb_log
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# -*- encoding : utf-8 -*-
|
2
3
|
|
3
4
|
require "getoptlong"
|
4
5
|
require "ostruct"
|
@@ -12,15 +13,16 @@ def log_summary(log, space_ids)
|
|
12
13
|
"space",
|
13
14
|
"page",
|
14
15
|
]
|
15
|
-
log.each_block do |
|
16
|
-
|
17
|
-
|
16
|
+
log.each_block do |block_index, block|
|
17
|
+
record = block.first_record_preamble
|
18
|
+
if record
|
19
|
+
space_id = record[:space]
|
18
20
|
if @options.space_ids.empty? or @options.space_ids.include?(space_id)
|
19
21
|
puts "%-10i%-30s%-10i%-10i" % [
|
20
|
-
|
21
|
-
|
22
|
+
block_index,
|
23
|
+
record[:type],
|
22
24
|
space_id,
|
23
|
-
|
25
|
+
record[:page_number],
|
24
26
|
]
|
25
27
|
if @options.dump
|
26
28
|
block.dump
|
data/bin/innodb_space
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# -*- encoding : utf-8 -*-
|
2
3
|
|
3
4
|
require "getoptlong"
|
4
5
|
require "ostruct"
|
5
|
-
require "pp"
|
6
6
|
require "innodb"
|
7
7
|
|
8
|
+
# Print metadata about each list in an array of InnoDB::List objects.
|
8
9
|
def print_lists(lists)
|
9
10
|
puts "%-20s%-12s%-12s%-12s%-12s%-12s" % [
|
10
11
|
"name",
|
@@ -27,6 +28,8 @@ def print_lists(lists)
|
|
27
28
|
end
|
28
29
|
end
|
29
30
|
|
31
|
+
# Print a page usage bitmap for each extent descriptor in an array of
|
32
|
+
# Innodb::XdesEntry objects.
|
30
33
|
def print_xdes_list(list)
|
31
34
|
puts "%-12s%-64s" % [
|
32
35
|
"start_page",
|
@@ -44,6 +47,7 @@ def print_xdes_list(list)
|
|
44
47
|
end
|
45
48
|
end
|
46
49
|
|
50
|
+
# Print a summary of page usage for all pages in an index.
|
47
51
|
def print_index_page_summary(pages)
|
48
52
|
puts "%-12s%-8s%-8s%-8s%-8s%-8s" % [
|
49
53
|
"page",
|
@@ -71,6 +75,125 @@ def print_index_page_summary(pages)
|
|
71
75
|
end
|
72
76
|
end
|
73
77
|
|
78
|
+
# Print a summary of all spaces in the InnoDB system.
|
79
|
+
def system_spaces(innodb_system)
|
80
|
+
puts "%-32s%-12s%-12s" % [
|
81
|
+
"name",
|
82
|
+
"pages",
|
83
|
+
"indexes",
|
84
|
+
]
|
85
|
+
|
86
|
+
print_space_information = lambda do |name, space|
|
87
|
+
puts "%-32s%-12i%-12i" % [
|
88
|
+
name,
|
89
|
+
space.pages,
|
90
|
+
space.each_index.to_a.size,
|
91
|
+
]
|
92
|
+
end
|
93
|
+
|
94
|
+
print_space_information.call("(system)", innodb_system.system_space)
|
95
|
+
|
96
|
+
innodb_system.each_table_name do |table_name|
|
97
|
+
space = innodb_system.space_by_table_name(table_name)
|
98
|
+
next unless space
|
99
|
+
print_space_information.call(table_name, space)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Print the contents of the SYS_TABLES data dictionary table.
|
104
|
+
def data_dictionary_tables(innodb_system)
|
105
|
+
puts "%-32s%-12s%-12s%-12s%-12s%-12s%-15s%-12s" % [
|
106
|
+
"name",
|
107
|
+
"id",
|
108
|
+
"n_cols",
|
109
|
+
"type",
|
110
|
+
"mix_id",
|
111
|
+
"mix_len",
|
112
|
+
"cluster_name",
|
113
|
+
"space",
|
114
|
+
]
|
115
|
+
|
116
|
+
innodb_system.data_dictionary.each_table do |record|
|
117
|
+
puts "%-32s%-12i%-12i%-12i%-12i%-12i%-15s%-12i" % [
|
118
|
+
record["NAME"],
|
119
|
+
record["ID"],
|
120
|
+
record["N_COLS"],
|
121
|
+
record["TYPE"],
|
122
|
+
record["MIX_ID"],
|
123
|
+
record["MIX_LEN"],
|
124
|
+
record["CLUSTER_NAME"],
|
125
|
+
record["SPACE"],
|
126
|
+
]
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# Print the contents of the SYS_COLUMNS data dictionary table.
|
131
|
+
def data_dictionary_columns(innodb_system)
|
132
|
+
puts "%-12s%-6s%-32s%-12s%-12s%-6s%-6s" % [
|
133
|
+
"table_id",
|
134
|
+
"pos",
|
135
|
+
"name",
|
136
|
+
"mtype",
|
137
|
+
"prtype",
|
138
|
+
"len",
|
139
|
+
"prec",
|
140
|
+
]
|
141
|
+
|
142
|
+
innodb_system.data_dictionary.each_column do |record|
|
143
|
+
puts "%-12i%-6i%-32s%-12i%-12i%-6i%-6i" % [
|
144
|
+
record["TABLE_ID"],
|
145
|
+
record["POS"],
|
146
|
+
record["NAME"],
|
147
|
+
record["MTYPE"],
|
148
|
+
record["PRTYPE"],
|
149
|
+
record["LEN"],
|
150
|
+
record["PREC"],
|
151
|
+
]
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
# Print the contents of the SYS_INDEXES data dictionary table.
|
156
|
+
def data_dictionary_indexes(innodb_system)
|
157
|
+
puts "%-12s%-12s%-32s%-10s%-6s%-12s%-12s" % [
|
158
|
+
"table_id",
|
159
|
+
"id",
|
160
|
+
"name",
|
161
|
+
"n_fields",
|
162
|
+
"type",
|
163
|
+
"space",
|
164
|
+
"page_no",
|
165
|
+
]
|
166
|
+
|
167
|
+
innodb_system.data_dictionary.each_index do |record|
|
168
|
+
puts "%-12i%-12i%-32s%-10i%-6i%-12i%-12i" % [
|
169
|
+
record["TABLE_ID"],
|
170
|
+
record["ID"],
|
171
|
+
record["NAME"],
|
172
|
+
record["N_FIELDS"],
|
173
|
+
record["TYPE"],
|
174
|
+
record["SPACE"],
|
175
|
+
record["PAGE_NO"],
|
176
|
+
]
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
# Print the contents of the SYS_FIELDS data dictionary table.
|
181
|
+
def data_dictionary_fields(innodb_system)
|
182
|
+
puts "%-12s%-12s%-32s" % [
|
183
|
+
"index_id",
|
184
|
+
"pos",
|
185
|
+
"col_name",
|
186
|
+
]
|
187
|
+
|
188
|
+
innodb_system.data_dictionary.each_field do |record|
|
189
|
+
puts "%-12i%-12i%-32s" % [
|
190
|
+
record["INDEX_ID"],
|
191
|
+
record["POS"],
|
192
|
+
record["COL_NAME"],
|
193
|
+
]
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
74
197
|
def space_summary(space, start_page)
|
75
198
|
puts "%-12s%-20s%-12s%-12s%-20s" % [
|
76
199
|
"page",
|
@@ -168,9 +291,10 @@ def space_list_iterate(space, list_name)
|
|
168
291
|
end
|
169
292
|
end
|
170
293
|
|
171
|
-
def space_indexes(space)
|
172
|
-
puts "%-12s%-12s%-12s%-12s%-12s%-12s" % [
|
294
|
+
def space_indexes(innodb_system, space)
|
295
|
+
puts "%-12s%-32s%-12s%-12s%-12s%-12s%-12s" % [
|
173
296
|
"id",
|
297
|
+
"name",
|
174
298
|
"root",
|
175
299
|
"fseg",
|
176
300
|
"used",
|
@@ -180,8 +304,9 @@ def space_indexes(space)
|
|
180
304
|
|
181
305
|
space.each_index do |index|
|
182
306
|
index.each_fseg do |fseg_name, fseg|
|
183
|
-
puts "%-12i%-12i%-12s%-12i%-12i%-12s" % [
|
307
|
+
puts "%-12i%-32s%-12i%-12s%-12i%-12i%-12s" % [
|
184
308
|
index.id,
|
309
|
+
innodb_system ? innodb_system.index_name_by_id(index.id) : "",
|
185
310
|
index.root.offset,
|
186
311
|
fseg_name,
|
187
312
|
fseg.used_pages,
|
@@ -282,7 +407,7 @@ def space_inodes_detail(space)
|
|
282
407
|
end
|
283
408
|
end
|
284
409
|
|
285
|
-
def page_account(space, page_number)
|
410
|
+
def page_account(innodb_system, space, page_number)
|
286
411
|
puts "Accounting for page #{page_number}:"
|
287
412
|
|
288
413
|
if page_number > space.pages
|
@@ -345,6 +470,12 @@ def page_account(space, page_number)
|
|
345
470
|
if page_inode == fseg
|
346
471
|
puts " Fseg is in #{fseg_name} fseg of index #{index.id}."
|
347
472
|
puts " Index root is page #{index.root.offset}."
|
473
|
+
if innodb_system
|
474
|
+
table_name, index_name = innodb_system.table_and_index_name_by_id(index.id)
|
475
|
+
if table_name and index_name
|
476
|
+
puts " Index is #{table_name}.#{index_name}."
|
477
|
+
end
|
478
|
+
end
|
348
479
|
end
|
349
480
|
end
|
350
481
|
end
|
@@ -358,10 +489,12 @@ def page_account(space, page_number)
|
|
358
489
|
puts " Fseg is doublewrite buffer."
|
359
490
|
end
|
360
491
|
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
492
|
+
if innodb_system
|
493
|
+
innodb_system.data_dictionary.each_data_dictionary_index do |table_name, index_name, index|
|
494
|
+
index.each_fseg do |fseg_name, fseg|
|
495
|
+
if page_inode == fseg
|
496
|
+
puts " Index is #{table_name}.#{index_name} of data dictionary."
|
497
|
+
end
|
365
498
|
end
|
366
499
|
end
|
367
500
|
end
|
@@ -375,7 +508,12 @@ def page_account(space, page_number)
|
|
375
508
|
end
|
376
509
|
end
|
377
510
|
|
378
|
-
def page_directory_summary(
|
511
|
+
def page_directory_summary(page_number)
|
512
|
+
page = space.page(page_number)
|
513
|
+
if page.type != :INDEX
|
514
|
+
usage 1, "Page must be an index page"
|
515
|
+
end
|
516
|
+
|
379
517
|
puts "%-8s%-8s%-14s%-8s%s" % [
|
380
518
|
"slot",
|
381
519
|
"offset",
|
@@ -387,9 +525,7 @@ def page_directory_summary(page)
|
|
387
525
|
page.directory.each_with_index do |offset, slot|
|
388
526
|
record = page.record(offset)
|
389
527
|
key = if [:conventional, :node_pointer].include? record.header[:type]
|
390
|
-
|
391
|
-
"(%s)" % record.key_string,
|
392
|
-
end
|
528
|
+
"(%s)" % record.key_string
|
393
529
|
end
|
394
530
|
puts "%-8i%-8i%-14s%-8i%s" % [
|
395
531
|
slot,
|
@@ -441,7 +577,7 @@ def index_recurse(index)
|
|
441
577
|
]
|
442
578
|
if page.level == 0
|
443
579
|
page.each_record do |record|
|
444
|
-
puts "%sRECORD: (%s)
|
580
|
+
puts "%sRECORD: (%s) → (%s)" % [
|
445
581
|
" " * (depth+1),
|
446
582
|
record.key_string,
|
447
583
|
record.row_string,
|
@@ -450,9 +586,9 @@ def index_recurse(index)
|
|
450
586
|
end
|
451
587
|
end,
|
452
588
|
lambda do |parent_page, child_page, child_min_key, depth|
|
453
|
-
puts "%sNODE POINTER RECORD
|
589
|
+
puts "%sNODE POINTER RECORD ≥ (%s) → #%i" % [
|
454
590
|
" " * depth,
|
455
|
-
child_min_key.map { |r| "%s=%s" % [r[:name], r[:value]] }.join(", "),
|
591
|
+
child_min_key.map { |r| "%s=%s" % [r[:name], r[:value].inspect] }.join(", "),
|
456
592
|
child_page.offset,
|
457
593
|
]
|
458
594
|
end
|
@@ -502,7 +638,7 @@ def index_digraph(index)
|
|
502
638
|
]
|
503
639
|
end,
|
504
640
|
lambda do |parent_page, child_page, child_key, depth|
|
505
|
-
puts " %spage_%i:dir_%i
|
641
|
+
puts " %spage_%i:dir_%i → page_%i:page:nw;" % [
|
506
642
|
" " * depth,
|
507
643
|
parent_page.offset,
|
508
644
|
child_page.offset,
|
@@ -513,7 +649,7 @@ def index_digraph(index)
|
|
513
649
|
puts "}"
|
514
650
|
end
|
515
651
|
|
516
|
-
def index_level_summary(index,
|
652
|
+
def index_level_summary(index, level)
|
517
653
|
puts "%-8s%-8s%-8s%-8s%-8s%-8s%-8s" % [
|
518
654
|
"page",
|
519
655
|
"index",
|
@@ -524,46 +660,65 @@ def index_level_summary(index, levels)
|
|
524
660
|
"min_key",
|
525
661
|
]
|
526
662
|
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
]
|
538
|
-
end
|
663
|
+
index.each_page_at_level(level) do |page|
|
664
|
+
puts "%-8i%-8i%-8i%-8i%-8i%-8i%s" % [
|
665
|
+
page.offset,
|
666
|
+
page.page_header[:index_id],
|
667
|
+
page.level,
|
668
|
+
page.record_space,
|
669
|
+
page.free_space,
|
670
|
+
page.records,
|
671
|
+
page.first_record.key_string,
|
672
|
+
]
|
539
673
|
end
|
540
674
|
end
|
541
675
|
|
542
676
|
def usage(exit_code, message = nil)
|
543
|
-
|
677
|
+
if message
|
678
|
+
puts "Error: #{message}; see --help for usage information\n\n"
|
679
|
+
exit exit_code
|
680
|
+
end
|
544
681
|
|
545
682
|
print <<'END_OF_USAGE'
|
546
683
|
|
547
|
-
Usage: innodb_space
|
684
|
+
Usage: innodb_space <options> <mode>
|
685
|
+
|
686
|
+
Invocation examples:
|
687
|
+
|
688
|
+
innodb_space -s ibdata1 [-T tname [-I iname]] [options] <mode>
|
689
|
+
Use ibdata1 as the system tablespace and load the tname table (and the
|
690
|
+
iname index for modes that require it) from data located in the system
|
691
|
+
tablespace data dictionary. This will automatically generate a record
|
692
|
+
describer for any indexes.
|
693
|
+
|
694
|
+
innodb_space -f tname.ibd [-r ./desc.rb -d DescClass] [options] <mode>
|
695
|
+
Use the tname.ibd table (and the DescClass describer where required).
|
696
|
+
|
697
|
+
The following options are supported:
|
548
698
|
|
549
699
|
--help, -?
|
550
700
|
Print this usage text.
|
551
701
|
|
552
|
-
--file, -
|
553
|
-
Load the tablespace file <file
|
702
|
+
--system-space-file, -s <file>
|
703
|
+
Load the system tablespace file <file> (normally ibdata1).
|
554
704
|
|
555
|
-
--
|
556
|
-
|
557
|
-
|
705
|
+
--table-name, -T <name>
|
706
|
+
Use the table name <name>.
|
707
|
+
|
708
|
+
--index-name, -I <name>
|
709
|
+
Use the index name <name>.
|
710
|
+
|
711
|
+
--space-file, -f <file>
|
712
|
+
Load the tablespace file <file>.
|
558
713
|
|
559
714
|
--page, -p <page>
|
560
|
-
Operate on the page <page
|
715
|
+
Operate on the page <page>.
|
561
716
|
|
562
717
|
--level, -l <level>
|
563
|
-
Operate on the level <level
|
718
|
+
Operate on the level <level>.
|
564
719
|
|
565
720
|
--list, -L <list>
|
566
|
-
Operate on the list <list
|
721
|
+
Operate on the list <list>.
|
567
722
|
|
568
723
|
--require, -r <file>
|
569
724
|
Use Ruby's "require" to load the file <file>. This is useful for loading
|
@@ -572,8 +727,27 @@ Usage: innodb_space -f <file> [-p <page>] [-l <level>] <mode> [<mode>, ...]
|
|
572
727
|
--describer, -d <describer>
|
573
728
|
Use the named record describer to parse records in index pages.
|
574
729
|
|
730
|
+
--page-size, -P <size>
|
731
|
+
Provide the page size, overriding auto-detection (in KiB): 16, 8, 4, 2, 1.
|
732
|
+
Page sizes other than 16 may not work well, or at all.
|
733
|
+
|
575
734
|
The following modes are supported:
|
576
735
|
|
736
|
+
system-spaces
|
737
|
+
Print a summary of all spaces in the system.
|
738
|
+
|
739
|
+
data-dictionary-tables
|
740
|
+
Print all records in the SYS_TABLES data dictionary table.
|
741
|
+
|
742
|
+
data-dictionary-columns
|
743
|
+
Print all records in the SYS_COLUMNS data dictionary table.
|
744
|
+
|
745
|
+
data-dictionary-indexes
|
746
|
+
Print all records in the SYS_INDEXES data dictionary table.
|
747
|
+
|
748
|
+
data-dictionary-fields
|
749
|
+
Print all records in the SYS_FIELDS data dictionary table.
|
750
|
+
|
577
751
|
space-summary
|
578
752
|
Summarize all pages within a tablespace. A starting page number can be
|
579
753
|
provided with the --page/-p argument.
|
@@ -619,16 +793,6 @@ The following modes are supported:
|
|
619
793
|
space-inodes-detail
|
620
794
|
Iterate through all inodes, printing a detailed report of each FSEG.
|
621
795
|
|
622
|
-
page-dump
|
623
|
-
Dump the contents of a page, using the Ruby pp ("pretty-print") module.
|
624
|
-
|
625
|
-
page-account
|
626
|
-
Account for a page's usage in FSEGs.
|
627
|
-
|
628
|
-
page-directory-summary
|
629
|
-
Summarize the record contents of the page directory in a page. If a record
|
630
|
-
describer is available, the key of each record will be printed.
|
631
|
-
|
632
796
|
index-recurse
|
633
797
|
Recurse an index, starting at the root (which must be provided in the first
|
634
798
|
--page/-p argument), printing the node pages, node pointers (links), leaf
|
@@ -664,6 +828,16 @@ The following modes are supported:
|
|
664
828
|
Print a summary of all fragment pages in an index file segment. Index root
|
665
829
|
page must be provided with --page/-p.
|
666
830
|
|
831
|
+
page-dump
|
832
|
+
Dump the contents of a page, using the Ruby pp ("pretty-print") module.
|
833
|
+
|
834
|
+
page-account
|
835
|
+
Account for a page's usage in FSEGs.
|
836
|
+
|
837
|
+
page-directory-summary
|
838
|
+
Summarize the record contents of the page directory in a page. If a record
|
839
|
+
describer is available, the key of each record will be printed.
|
840
|
+
|
667
841
|
END_OF_USAGE
|
668
842
|
|
669
843
|
exit exit_code
|
@@ -677,9 +851,9 @@ Signal.trap("PIPE") { exit }
|
|
677
851
|
@options.space_file = nil
|
678
852
|
@options.table_name = nil
|
679
853
|
@options.index_name = nil
|
680
|
-
@options.
|
681
|
-
@options.
|
682
|
-
@options.
|
854
|
+
@options.page = nil
|
855
|
+
@options.level = nil
|
856
|
+
@options.list = nil
|
683
857
|
@options.page_size = nil
|
684
858
|
@options.describer = nil
|
685
859
|
|
@@ -687,9 +861,9 @@ getopt_options = [
|
|
687
861
|
[ "--help", "-?", GetoptLong::NO_ARGUMENT ],
|
688
862
|
[ "--trace", "-t", GetoptLong::NO_ARGUMENT ],
|
689
863
|
[ "--system-space-file", "-s", GetoptLong::REQUIRED_ARGUMENT ],
|
690
|
-
[ "--space-file", "-f", GetoptLong::REQUIRED_ARGUMENT ],
|
691
864
|
[ "--table-name", "-T", GetoptLong::REQUIRED_ARGUMENT ],
|
692
865
|
[ "--index-name", "-I", GetoptLong::REQUIRED_ARGUMENT ],
|
866
|
+
[ "--space-file", "-f", GetoptLong::REQUIRED_ARGUMENT ],
|
693
867
|
[ "--page", "-p", GetoptLong::REQUIRED_ARGUMENT ],
|
694
868
|
[ "--level", "-l", GetoptLong::REQUIRED_ARGUMENT ],
|
695
869
|
[ "--list", "-L", GetoptLong::REQUIRED_ARGUMENT ],
|
@@ -717,11 +891,11 @@ getopt.each do |opt, arg|
|
|
717
891
|
when "--index-name"
|
718
892
|
@options.index_name = arg
|
719
893
|
when "--page"
|
720
|
-
@options.
|
894
|
+
@options.page = arg.to_i
|
721
895
|
when "--level"
|
722
|
-
@options.
|
896
|
+
@options.level = arg.to_i
|
723
897
|
when "--list"
|
724
|
-
@options.
|
898
|
+
@options.list = arg.to_sym
|
725
899
|
when "--require"
|
726
900
|
require File.expand_path(arg)
|
727
901
|
when "--page-size"
|
@@ -734,16 +908,25 @@ getopt.each do |opt, arg|
|
|
734
908
|
end
|
735
909
|
end
|
736
910
|
|
737
|
-
|
738
|
-
|
739
|
-
system_space = Innodb::Space.new(@options.system_space_file)
|
911
|
+
unless @options.system_space_file or @options.space_file
|
912
|
+
usage 1, "System space file (-s) or space file (-f) must be specified"
|
740
913
|
end
|
741
914
|
|
742
|
-
|
743
|
-
usage 1, "
|
915
|
+
if @options.system_space_file and @options.space_file
|
916
|
+
usage 1, "Only one of system space or space file may be specified"
|
917
|
+
end
|
918
|
+
|
919
|
+
innodb_system = nil
|
920
|
+
if @options.system_space_file
|
921
|
+
innodb_system = Innodb::System.new(@options.system_space_file)
|
744
922
|
end
|
745
923
|
|
746
|
-
space =
|
924
|
+
space = innodb_system ? innodb_system.system_space : nil
|
925
|
+
if innodb_system and @options.table_name
|
926
|
+
space = innodb_system.space_by_table_name(@options.table_name)
|
927
|
+
elsif @options.space_file
|
928
|
+
space = Innodb::Space.new(@options.space_file, @options.page_size)
|
929
|
+
end
|
747
930
|
|
748
931
|
if @options.describer
|
749
932
|
describer = eval(@options.describer)
|
@@ -753,163 +936,112 @@ if @options.describer
|
|
753
936
|
space.record_describer = describer.new
|
754
937
|
end
|
755
938
|
|
756
|
-
|
757
|
-
|
939
|
+
index = nil
|
940
|
+
if innodb_system and @options.table_name and @options.index_name
|
941
|
+
index = innodb_system.index_by_name(@options.table_name, @options.index_name)
|
942
|
+
elsif @options.page
|
943
|
+
if page = space.page(@options.page) and page.type == :INDEX and page.root?
|
944
|
+
index = space.index(@options.page)
|
945
|
+
end
|
758
946
|
end
|
759
947
|
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
if @options.pages.empty?
|
764
|
-
usage 1, "Page numbers to dump must be provided with --page/-p"
|
765
|
-
end
|
766
|
-
|
767
|
-
@options.pages.each do |page_number|
|
768
|
-
space.page(page_number).dump
|
769
|
-
end
|
770
|
-
when "page-account"
|
771
|
-
if @options.pages.empty?
|
772
|
-
usage 1, "Page numbers to dump must be provided with --page/-p"
|
773
|
-
end
|
774
|
-
|
775
|
-
@options.pages.each do |page_number|
|
776
|
-
page_account(space, page_number)
|
777
|
-
end
|
778
|
-
when "page-directory-summary"
|
779
|
-
if @options.pages.empty?
|
780
|
-
usage 1, "Page numbers to dump must be provided with --page/-p"
|
781
|
-
end
|
782
|
-
|
783
|
-
page = space.page(@options.pages.first)
|
784
|
-
if page.type != :INDEX
|
785
|
-
usage 1, "Page must be an index page"
|
786
|
-
end
|
787
|
-
|
788
|
-
page_directory_summary(page)
|
789
|
-
when "space-summary"
|
790
|
-
space_summary(space, @options.pages.first || 0)
|
791
|
-
when "space-index-pages-summary"
|
792
|
-
space_index_pages_summary(space, @options.pages.first || 0)
|
793
|
-
when "space-index-pages-free-plot"
|
794
|
-
name = File.basename(@options.space_file).sub(".ibd", "")
|
795
|
-
space_index_pages_free_plot(space, name, @options.pages.first || 0)
|
796
|
-
when "space-page-type-regions"
|
797
|
-
space_page_type_regions(space, @options.pages.first || 0)
|
798
|
-
when "space-page-type-summary"
|
799
|
-
space_page_type_summary(space, @options.pages.first || 0)
|
800
|
-
when "space-lists"
|
801
|
-
space_lists(space)
|
802
|
-
when "space-list-iterate"
|
803
|
-
if @options.lists.empty?
|
804
|
-
usage 1, "A list name must be provided with --list/-L"
|
805
|
-
end
|
806
|
-
|
807
|
-
@options.lists.each do |list|
|
808
|
-
space_list_iterate(space, list)
|
809
|
-
end
|
810
|
-
when "space-indexes"
|
811
|
-
space_indexes(space)
|
812
|
-
when "space-extents"
|
813
|
-
space_extents(space)
|
814
|
-
when "space-inodes-summary"
|
815
|
-
space_inodes_summary(space)
|
816
|
-
when "space-inodes-detail"
|
817
|
-
space_inodes_detail(space)
|
818
|
-
when "index-recurse"
|
819
|
-
unless space.record_describer
|
820
|
-
usage 1, "Record describer necessary for index recursion"
|
821
|
-
end
|
822
|
-
|
823
|
-
if @options.pages.empty?
|
824
|
-
usage 1, "Page number of index root must be provided with --page/-p"
|
825
|
-
end
|
826
|
-
|
827
|
-
@options.pages.each do |page|
|
828
|
-
index_recurse(space.index(page))
|
829
|
-
end
|
830
|
-
when "index-record-offsets"
|
831
|
-
unless space.record_describer
|
832
|
-
usage 1, "Record describer necessary for index recursion"
|
833
|
-
end
|
834
|
-
|
835
|
-
if @options.pages.empty?
|
836
|
-
usage 1, "Page number of index root must be provided with --page/-p"
|
837
|
-
end
|
838
|
-
|
839
|
-
@options.pages.each do |page|
|
840
|
-
index_record_offsets(space.index(page))
|
841
|
-
end
|
842
|
-
when "index-digraph"
|
843
|
-
unless space.record_describer
|
844
|
-
usage 1, "Record describer necessary for index recursion"
|
845
|
-
end
|
846
|
-
|
847
|
-
if @options.pages.empty?
|
848
|
-
usage 1, "Page number of index root must be provided with --page/-p"
|
849
|
-
end
|
850
|
-
|
851
|
-
@options.pages.each do |page|
|
852
|
-
index_digraph(space.index(page))
|
853
|
-
end
|
854
|
-
when "index-level-summary"
|
855
|
-
unless space.record_describer
|
856
|
-
usage 1, "Record describer necessary for index recursion"
|
857
|
-
end
|
948
|
+
# The non-option argument on the command line is the mode (usually the last,
|
949
|
+
# but not required).
|
950
|
+
mode = ARGV.shift
|
858
951
|
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
index_level_summary(space.index(@options.pages.first), @options.levels)
|
864
|
-
when "index-fseg-leaf-lists"
|
865
|
-
if @options.pages.empty?
|
866
|
-
usage 1, "Page number of index root must be provided with --page/-p"
|
867
|
-
end
|
868
|
-
|
869
|
-
index_fseg_lists(space.index(@options.pages.first), :leaf)
|
870
|
-
when "index-fseg-internal-lists"
|
871
|
-
if @options.pages.empty?
|
872
|
-
usage 1, "Page number of index root must be provided with --page/-p"
|
873
|
-
end
|
952
|
+
unless mode
|
953
|
+
usage 1, "At least one mode must be provided"
|
954
|
+
end
|
874
955
|
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
usage 1, "Page number of index root must be provided with --page/-p"
|
879
|
-
end
|
956
|
+
if /^(system-|data-dictionary-)/.match(mode) and !innodb_system
|
957
|
+
usage 1, "System tablespace must be specified using -s/--system-space-file"
|
958
|
+
end
|
880
959
|
|
881
|
-
|
882
|
-
|
883
|
-
|
960
|
+
if /^space-/.match(mode) and !space
|
961
|
+
usage 1, "Tablespace must be specified using either -f/--space-file or a combination of -s/--system-space-file and -T/--table"
|
962
|
+
end
|
884
963
|
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
when "index-fseg-internal-list-iterate"
|
889
|
-
if @options.pages.empty?
|
890
|
-
usage 1, "Page number of index root must be provided with --page/-p"
|
891
|
-
end
|
964
|
+
if /^index-/.match(mode) and !index
|
965
|
+
usage 1, "Index must be specified using a combination of either -f/--space-file and -p/--page or -s/--system-space-file, -T/--table-name, and -I/--index-name"
|
966
|
+
end
|
892
967
|
|
893
|
-
|
894
|
-
|
895
|
-
|
968
|
+
if /^page-/.match(mode) and !@options.page
|
969
|
+
usage 1, "Page number must be specified using -p/--page"
|
970
|
+
end
|
896
971
|
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
when "index-fseg-leaf-frag-pages"
|
901
|
-
if @options.pages.empty?
|
902
|
-
usage 1, "Page number of index root must be provided with --page/-p"
|
903
|
-
end
|
972
|
+
if /-list-iterate$/.match(mode) and !@options.list
|
973
|
+
usage 1, "List name must be specified using -L/--list"
|
974
|
+
end
|
904
975
|
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
976
|
+
if [
|
977
|
+
"index-recurse",
|
978
|
+
"index-record-offsets",
|
979
|
+
"index-digraph",
|
980
|
+
"index-level-summary",
|
981
|
+
].include?(mode) and !index.record_describer
|
982
|
+
usage 1, "Record describer must be specified using -d/--describer"
|
983
|
+
end
|
910
984
|
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
985
|
+
case mode
|
986
|
+
when "system-spaces"
|
987
|
+
system_spaces(innodb_system)
|
988
|
+
when "data-dictionary-tables"
|
989
|
+
data_dictionary_tables(innodb_system)
|
990
|
+
when "data-dictionary-columns"
|
991
|
+
data_dictionary_columns(innodb_system)
|
992
|
+
when "data-dictionary-indexes"
|
993
|
+
data_dictionary_indexes(innodb_system)
|
994
|
+
when "data-dictionary-fields"
|
995
|
+
data_dictionary_fields(innodb_system)
|
996
|
+
when "space-summary"
|
997
|
+
space_summary(space, @options.page || 0)
|
998
|
+
when "space-index-pages-summary"
|
999
|
+
space_index_pages_summary(space, @options.page || 0)
|
1000
|
+
when "space-index-pages-free-plot"
|
1001
|
+
name = File.basename(@options.space_file).sub(".ibd", "")
|
1002
|
+
space_index_pages_free_plot(space, name, @options.page || 0)
|
1003
|
+
when "space-page-type-regions"
|
1004
|
+
space_page_type_regions(space, @options.page || 0)
|
1005
|
+
when "space-page-type-summary"
|
1006
|
+
space_page_type_summary(space, @options.page || 0)
|
1007
|
+
when "space-lists"
|
1008
|
+
space_lists(space)
|
1009
|
+
when "space-list-iterate"
|
1010
|
+
space_list_iterate(space, @options.list)
|
1011
|
+
when "space-indexes"
|
1012
|
+
space_indexes(innodb_system, space)
|
1013
|
+
when "space-extents"
|
1014
|
+
space_extents(space)
|
1015
|
+
when "space-inodes-summary"
|
1016
|
+
space_inodes_summary(space)
|
1017
|
+
when "space-inodes-detail"
|
1018
|
+
space_inodes_detail(space)
|
1019
|
+
when "index-recurse"
|
1020
|
+
index_recurse(index)
|
1021
|
+
when "index-record-offsets"
|
1022
|
+
index_record_offsets(index)
|
1023
|
+
when "index-digraph"
|
1024
|
+
index_digraph(index)
|
1025
|
+
when "index-level-summary"
|
1026
|
+
index_level_summary(index, @options.level)
|
1027
|
+
when "index-fseg-leaf-lists"
|
1028
|
+
index_fseg_lists(index, :leaf)
|
1029
|
+
when "index-fseg-internal-lists"
|
1030
|
+
index_fseg_lists(index, :internal)
|
1031
|
+
when "index-fseg-leaf-list-iterate"
|
1032
|
+
index_fseg_list_iterate(index, :leaf, @options.list)
|
1033
|
+
when "index-fseg-internal-list-iterate"
|
1034
|
+
index_fseg_list_iterate(index, :internal, @options.list)
|
1035
|
+
when "index-fseg-leaf-frag-pages"
|
1036
|
+
index_fseg_frag_pages(index, :leaf)
|
1037
|
+
when "index-fseg-internal-frag-pages"
|
1038
|
+
index_fseg_frag_pages(index, :internal)
|
1039
|
+
when "page-dump"
|
1040
|
+
space.page(@options.page).dump
|
1041
|
+
when "page-account"
|
1042
|
+
page_account(innodb_system, space, @options.page)
|
1043
|
+
when "page-directory-summary"
|
1044
|
+
page_directory_summary(@options.page)
|
1045
|
+
else
|
1046
|
+
usage 1, "Unknown mode: #{mode}"
|
915
1047
|
end
|