innodb_ruby 0.9.9 → 0.9.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -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