innodb_ruby 0.9.9 → 0.9.10

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.
@@ -756,8 +756,7 @@ def page_account(innodb_system, space, page_number)
756
756
  end
757
757
  end
758
758
 
759
- def page_directory_summary(page_number)
760
- page = space.page(page_number)
759
+ def page_directory_summary(space, page)
761
760
  if page.type != :INDEX
762
761
  usage 1, "Page must be an index page"
763
762
  end
@@ -785,6 +784,16 @@ def page_directory_summary(page_number)
785
784
  end
786
785
  end
787
786
 
787
+ def page_records(space, page)
788
+ page.each_record do |record|
789
+ puts "Record %i: %s" % [
790
+ record.offset,
791
+ record.string,
792
+ ]
793
+ puts if record.header[:type] == :conventional
794
+ end
795
+ end
796
+
788
797
  def page_illustrate(page)
789
798
  width = 64
790
799
  blocks = Array.new(page.size, " ")
@@ -859,6 +868,38 @@ def page_illustrate(page)
859
868
  puts
860
869
  end
861
870
 
871
+ def record_dump(page, record_offset)
872
+ unless record = page.record(record_offset)
873
+ raise "Record at offset #{record_offset} not found"
874
+ end
875
+
876
+ record.dump
877
+ end
878
+
879
+ def record_history(page, record_offset)
880
+ unless page.leaf?
881
+ raise "Record is not located on a leaf page; no history available"
882
+ end
883
+
884
+ unless record = page.record(record_offset)
885
+ raise "Record at offset #{record_offset} not found"
886
+ end
887
+
888
+ puts "%-14s%-20s%s" % [
889
+ "Transaction",
890
+ "Type",
891
+ "Undo record",
892
+ ]
893
+
894
+ record.each_undo_record do |undo|
895
+ puts "%-14s%-20s%s" % [
896
+ undo.trx_id || "(n/a)",
897
+ undo.header[:type],
898
+ undo.string,
899
+ ]
900
+ end
901
+ end
902
+
862
903
  def index_fseg_lists(index, fseg_name)
863
904
  unless index.fseg(fseg_name)
864
905
  raise "File segment '#{fseg_name}' doesn't exist"
@@ -1170,9 +1211,20 @@ The following modes are supported:
1170
1211
  Summarize the record contents of the page directory in a page. If a record
1171
1212
  describer is available, the key of each record will be printed.
1172
1213
 
1214
+ page-records
1215
+ Summarize all records within a page.
1216
+
1173
1217
  page-illustrate
1174
1218
  Produce an illustration of the contents of a page.
1175
1219
 
1220
+ record-dump
1221
+ Dump a detailed description of a record and the data it contains. A record
1222
+ offset must be provided with -R/--record.
1223
+
1224
+ record-history
1225
+ Summarize the history (undo logs) for a record. A record offset must be
1226
+ provided with -R/--record.
1227
+
1176
1228
  END_OF_USAGE
1177
1229
 
1178
1230
  exit exit_code
@@ -1188,6 +1240,7 @@ Signal.trap("PIPE") { exit }
1188
1240
  @options.table_name = nil
1189
1241
  @options.index_name = nil
1190
1242
  @options.page = nil
1243
+ @options.record = nil
1191
1244
  @options.level = nil
1192
1245
  @options.list = nil
1193
1246
  @options.describer = nil
@@ -1200,6 +1253,7 @@ getopt_options = [
1200
1253
  [ "--table-name", "-T", GetoptLong::REQUIRED_ARGUMENT ],
1201
1254
  [ "--index-name", "-I", GetoptLong::REQUIRED_ARGUMENT ],
1202
1255
  [ "--page", "-p", GetoptLong::REQUIRED_ARGUMENT ],
1256
+ [ "--record", "-R", GetoptLong::REQUIRED_ARGUMENT ],
1203
1257
  [ "--level", "-l", GetoptLong::REQUIRED_ARGUMENT ],
1204
1258
  [ "--list", "-L", GetoptLong::REQUIRED_ARGUMENT ],
1205
1259
  [ "--require", "-r", GetoptLong::REQUIRED_ARGUMENT ],
@@ -1224,6 +1278,8 @@ getopt.each do |opt, arg|
1224
1278
  @options.index_name = arg
1225
1279
  when "--page"
1226
1280
  @options.page = arg.to_i
1281
+ when "--record"
1282
+ @options.record = arg.to_i
1227
1283
  when "--level"
1228
1284
  @options.level = arg.to_i
1229
1285
  when "--list"
@@ -1247,16 +1303,23 @@ if @options.trace > 1
1247
1303
  BufferCursor.trace!
1248
1304
  end
1249
1305
 
1306
+ # A few globals that we'll try to populate from the command-line arguments.
1250
1307
  innodb_system = nil
1308
+ space = nil
1309
+ index = nil
1310
+ page = nil
1311
+
1251
1312
  if @options.system_space_file
1252
1313
  innodb_system = Innodb::System.new(@options.system_space_file)
1253
1314
  end
1254
1315
 
1255
- space = innodb_system ? innodb_system.system_space : nil
1256
1316
  if innodb_system and @options.table_name
1257
- space = innodb_system.space_by_table_name(@options.table_name)
1317
+ table_tablespace = innodb_system.space_by_table_name(@options.table_name)
1318
+ space = table_tablespace || innodb_system.system_space
1258
1319
  elsif @options.space_file
1259
1320
  space = Innodb::Space.new(@options.space_file)
1321
+ else
1322
+ space = innodb_system.system_space
1260
1323
  end
1261
1324
 
1262
1325
  if @options.describer
@@ -1267,9 +1330,13 @@ if @options.describer
1267
1330
  space.record_describer = describer.new
1268
1331
  end
1269
1332
 
1270
- index = nil
1271
1333
  if innodb_system and @options.table_name and @options.index_name
1272
1334
  index = innodb_system.index_by_name(@options.table_name, @options.index_name)
1335
+ if @options.page
1336
+ page = space.page(@options.page)
1337
+ else
1338
+ page = index.root
1339
+ end
1273
1340
  elsif @options.page
1274
1341
  if page = space.page(@options.page) and page.type == :INDEX and page.root?
1275
1342
  index = space.index(@options.page)
@@ -1296,10 +1363,14 @@ if /^index-/.match(mode) and !index
1296
1363
  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"
1297
1364
  end
1298
1365
 
1299
- if /^page-/.match(mode) and !@options.page
1366
+ if /^page-/.match(mode) and !page
1300
1367
  usage 1, "Page number must be specified using -p/--page"
1301
1368
  end
1302
1369
 
1370
+ if /^record-/.match(mode) and !@options.record
1371
+ usage 1, "Record offset must be specified using -R/--record"
1372
+ end
1373
+
1303
1374
  if /-list-iterate$/.match(mode) and !@options.list
1304
1375
  usage 1, "List name must be specified using -L/--list"
1305
1376
  end
@@ -1376,13 +1447,19 @@ when "index-fseg-leaf-frag-pages"
1376
1447
  when "index-fseg-internal-frag-pages"
1377
1448
  index_fseg_frag_pages(index, :internal)
1378
1449
  when "page-dump"
1379
- space.page(@options.page).dump
1450
+ page.dump
1380
1451
  when "page-account"
1381
1452
  page_account(innodb_system, space, @options.page)
1382
1453
  when "page-directory-summary"
1383
- page_directory_summary(@options.page)
1454
+ page_directory_summary(space, page)
1455
+ when "page-records"
1456
+ page_records(space, page)
1384
1457
  when "page-illustrate"
1385
- page_illustrate(space.page(@options.page))
1458
+ page_illustrate(page)
1459
+ when "record-dump"
1460
+ record_dump(page, @options.record)
1461
+ when "record-history"
1462
+ record_history(page, @options.record)
1386
1463
  else
1387
1464
  usage 1, "Unknown mode: #{mode}"
1388
1465
  end
@@ -331,7 +331,7 @@ class Innodb::DataType
331
331
  end
332
332
 
333
333
  def read(c)
334
- c.name("transaction_id") { c.get_hex(6) }
334
+ c.name("transaction_id") { c.get_uint48 }
335
335
  end
336
336
  end
337
337
 
@@ -253,6 +253,11 @@ class Innodb::Page::Index < Innodb::Page
253
253
  self.prev.nil? && self.next.nil?
254
254
  end
255
255
 
256
+ # A helper function to identify leaf index pages.
257
+ def leaf?
258
+ level == 0
259
+ end
260
+
256
261
  # A helper function to return the offset to the first free record.
257
262
  def garbage_offset
258
263
  page_header && page_header[:garbage_offset]
@@ -730,6 +735,12 @@ class Innodb::Page::Index < Innodb::Page
730
735
  RecordCursor.new(self, offset, direction)
731
736
  end
732
737
 
738
+ def record_if_exists(offset)
739
+ each_record do |rec|
740
+ return rec if rec.offset == offset
741
+ end
742
+ end
743
+
733
744
  # Return the minimum record on this page.
734
745
  def min_record
735
746
  min = record(infimum.next)
@@ -13,6 +13,30 @@ class Innodb::Record
13
13
  record[:header]
14
14
  end
15
15
 
16
+ def next
17
+ header[:next]
18
+ end
19
+
20
+ def type
21
+ header[:type]
22
+ end
23
+
24
+ def heap_number
25
+ header[:heap_number]
26
+ end
27
+
28
+ def n_owned
29
+ header[:n_owned]
30
+ end
31
+
32
+ def deleted?
33
+ header[:deleted]
34
+ end
35
+
36
+ def min_rec?
37
+ header[:min_rec]
38
+ end
39
+
16
40
  def offset
17
41
  record[:offset]
18
42
  end
@@ -50,6 +74,8 @@ class Innodb::Record
50
74
  end
51
75
 
52
76
  def undo
77
+ return nil unless roll_pointer
78
+
53
79
  if innodb_system = @page.space.innodb_system
54
80
  undo_space = innodb_system.system_space
55
81
  if undo_page = undo_space.page(roll_pointer[:undo_log][:page])
@@ -122,4 +148,53 @@ class Innodb::Record
122
148
 
123
149
  return 0
124
150
  end
151
+
152
+ def dump
153
+ puts "Record at offset %i" % offset
154
+ puts
155
+
156
+ puts "Header:"
157
+ puts " %-20s: %i" % ["Next record offset", header[:next]]
158
+ puts " %-20s: %i" % ["Heap number", header[:heap_number]]
159
+ puts " %-20s: %s" % ["Type", header[:type]]
160
+ puts " %-20s: %s" % ["Deleted", header[:deleted]]
161
+ puts " %-20s: %s" % ["Length", header[:length]]
162
+ puts
163
+
164
+ if page.leaf?
165
+ puts "System fields:"
166
+ puts " Transaction ID: %s" % transaction_id
167
+ puts " Roll Pointer:"
168
+ puts " Undo Log: page %i, offset %i" % [
169
+ roll_pointer[:undo_log][:page],
170
+ roll_pointer[:undo_log][:offset],
171
+ ]
172
+ puts " Rollback Segment ID: %i" % roll_pointer[:rseg_id]
173
+ puts " Insert: %s" % roll_pointer[:is_insert]
174
+ puts
175
+ end
176
+
177
+ puts "Key fields:"
178
+ key.each do |field|
179
+ puts " %s: %s" % [
180
+ field[:name],
181
+ field[:value].inspect,
182
+ ]
183
+ end
184
+ puts
185
+
186
+ if page.leaf?
187
+ puts "Non-key fields:"
188
+ row.each do |field|
189
+ puts " %s: %s" % [
190
+ field[:name],
191
+ field[:value].inspect,
192
+ ]
193
+ end
194
+ puts
195
+ else
196
+ puts "Child page number: %i" % child_page_number
197
+ puts
198
+ end
199
+ end
125
200
  end
@@ -20,8 +20,8 @@ class Innodb::UndoLog
20
20
  @header ||= page.cursor(@position).name("header") do |c|
21
21
  xid_flag = nil
22
22
  {
23
- :trx_id => c.name("trx_id") { c.get_hex(8) },
24
- :trx_no => c.name("trx_no") { c.get_hex(8) },
23
+ :trx_id => c.name("trx_id") { c.get_uint64 },
24
+ :trx_no => c.name("trx_no") { c.get_uint64 },
25
25
  :delete_mark_flag => c.name("delete_mark_flag") { (c.get_uint16 != 0) },
26
26
  :log_start_offset => c.name("log_start_offset") { c.get_uint16 },
27
27
  :xid_flag => c.name("xid_flag") { xid_flag = (c.get_uint8 != 0) },
@@ -1,5 +1,5 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
 
3
3
  module Innodb
4
- VERSION = "0.9.9"
4
+ VERSION = "0.9.10"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: innodb_ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.9
4
+ version: 0.9.10
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2014-09-25 00:00:00.000000000 Z
13
+ date: 2014-09-26 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bindata