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.
- data/bin/innodb_space +86 -9
- data/lib/innodb/data_type.rb +1 -1
- data/lib/innodb/page/index.rb +11 -0
- data/lib/innodb/record.rb +75 -0
- data/lib/innodb/undo_log.rb +2 -2
- data/lib/innodb/version.rb +1 -1
- metadata +2 -2
data/bin/innodb_space
CHANGED
@@ -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(
|
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
|
-
|
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
|
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
|
-
|
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(
|
1454
|
+
page_directory_summary(space, page)
|
1455
|
+
when "page-records"
|
1456
|
+
page_records(space, page)
|
1384
1457
|
when "page-illustrate"
|
1385
|
-
page_illustrate(
|
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
|
data/lib/innodb/data_type.rb
CHANGED
data/lib/innodb/page/index.rb
CHANGED
@@ -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)
|
data/lib/innodb/record.rb
CHANGED
@@ -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
|
data/lib/innodb/undo_log.rb
CHANGED
@@ -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.
|
24
|
-
:trx_no => c.name("trx_no") { c.
|
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) },
|
data/lib/innodb/version.rb
CHANGED
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.
|
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-
|
13
|
+
date: 2014-09-26 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bindata
|