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 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 |block_number, block|
16
- if block.record
17
- space_id = block.record[:space]
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
- block_number,
21
- block.record[:type],
22
+ block_index,
23
+ record[:type],
22
24
  space_id,
23
- block.record[:page_number],
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
- space.data_dictionary.each_index do |table_name, index_name, index|
362
- index.each_fseg do |fseg_name, fseg|
363
- if page_inode == fseg
364
- puts " Index is #{table_name}.#{index_name} of data dictionary."
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(page)
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
- if record.key
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) -> (%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 >= (%s) -> #%i" % [
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 -> page_%i:page:nw;" % [
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, levels)
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
- levels.each do |level|
528
- index.each_page_at_level(level) do |page|
529
- puts "%-8i%-8i%-8i%-8i%-8i%-8i%s" % [
530
- page.offset,
531
- page.page_header[:index_id],
532
- page.level,
533
- page.record_space,
534
- page.free_space,
535
- page.records,
536
- page.first_record.key_string,
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
- print "Error: #{message}\n" unless message.nil?
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 -f <file> [-p <page>] [-l <level>] <mode> [<mode>, ...]
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, -f <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
- --page-size, -P <size>
556
- Provide the page size, overriding auto-detection (in KiB): 16, 8, 4, 2, 1.
557
- Page sizes other than 16 may not work well, or at all.
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>; may be specified more than once.
715
+ Operate on the page <page>.
561
716
 
562
717
  --level, -l <level>
563
- Operate on the level <level>; may be specified more than once.
718
+ Operate on the level <level>.
564
719
 
565
720
  --list, -L <list>
566
- Operate on the list <list>; may be specified more than once.
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.pages = []
681
- @options.levels = []
682
- @options.lists = []
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.pages << arg.to_i
894
+ @options.page = arg.to_i
721
895
  when "--level"
722
- @options.levels << arg.to_i
896
+ @options.level = arg.to_i
723
897
  when "--list"
724
- @options.lists << arg.to_sym
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
- system_space = nil
738
- if @options.system_space_file
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
- unless @options.space_file
743
- usage 1, "Space file must be provided with -f argument"
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 = Innodb::Space.new(@options.space_file, @options.page_size)
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
- if ARGV.empty?
757
- usage 1, "At least one mode should be provided"
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
- ARGV.each do |mode|
761
- case mode
762
- when "page-dump"
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
- if @options.pages.empty?
860
- usage 1, "Page number of index root must be provided with --page/-p"
861
- end
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
- index_fseg_lists(space.index(@options.pages.first), :internal)
876
- when "index-fseg-leaf-list-iterate"
877
- if @options.pages.empty?
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
- if @options.lists.empty?
882
- usage 1, "A list name must be provided with --list/-L"
883
- end
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
- @options.lists.each do |list|
886
- index_fseg_list_iterate(space.index(@options.pages.first), :leaf, list)
887
- end
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
- if @options.lists.empty?
894
- usage 1, "A list name must be provided with --list/-L"
895
- end
968
+ if /^page-/.match(mode) and !@options.page
969
+ usage 1, "Page number must be specified using -p/--page"
970
+ end
896
971
 
897
- @options.lists.each do |list|
898
- index_fseg_list_iterate(space.index(@options.pages.first), :internal, list)
899
- end
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
- index_fseg_frag_pages(space.index(@options.pages.first), :leaf)
906
- when "index-fseg-internal-frag-pages"
907
- if @options.pages.empty?
908
- usage 1, "Page number of index root must be provided with --page/-p"
909
- end
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
- index_fseg_frag_pages(space.index(@options.pages.first), :internal)
912
- else
913
- usage 1, "Unknown mode: #{mode}"
914
- end
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