innodb_ruby 0.9.14 → 0.9.15
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.
- data/bin/innodb_space +174 -35
- data/lib/innodb/page/index.rb +20 -0
- data/lib/innodb/version.rb +1 -1
- metadata +1 -1
data/bin/innodb_space
CHANGED
@@ -1015,41 +1015,6 @@ def page_account(innodb_system, space, page_number)
|
|
1015
1015
|
page_type[:usage],
|
1016
1016
|
]
|
1017
1017
|
|
1018
|
-
if page.corrupt?
|
1019
|
-
puts " Page appears to be corrupt."
|
1020
|
-
puts " Stored checksum is %d, type %s." % [
|
1021
|
-
page.checksum,
|
1022
|
-
page.checksum_type ? page.checksum_type : "unknown",
|
1023
|
-
]
|
1024
|
-
puts " Calculated checksums:"
|
1025
|
-
puts " crc32 %d" % [page.checksum_crc32]
|
1026
|
-
puts " innodb %d" % [page.checksum_innodb]
|
1027
|
-
end
|
1028
|
-
|
1029
|
-
if page.torn?
|
1030
|
-
puts " Page appears to be torn."
|
1031
|
-
puts " Full LSN from header is %d." % [page.lsn]
|
1032
|
-
puts " Low 32 bits of LSN from header is %d, trailer is %d." % [
|
1033
|
-
page.lsn_low32_header,
|
1034
|
-
page.lsn_low32_trailer,
|
1035
|
-
]
|
1036
|
-
end
|
1037
|
-
|
1038
|
-
if page.misplaced?
|
1039
|
-
puts " Page appears to be misplaced."
|
1040
|
-
if page.misplaced_offset?
|
1041
|
-
puts " Requested page %d but offset stored in page is %d." % [
|
1042
|
-
page_number,
|
1043
|
-
page.offset,
|
1044
|
-
]
|
1045
|
-
end
|
1046
|
-
if page.misplaced_space?
|
1047
|
-
puts " Space's ID %d does not match page's stored space ID %d." % [
|
1048
|
-
page.space.space_id,
|
1049
|
-
page.space_id,
|
1050
|
-
]
|
1051
|
-
end
|
1052
|
-
end
|
1053
1018
|
|
1054
1019
|
xdes = space.xdes_for_page(page_number)
|
1055
1020
|
puts " Extent descriptor for pages %d-%d is at page %d, offset %d." % [
|
@@ -1136,6 +1101,175 @@ def page_account(innodb_system, space, page_number)
|
|
1136
1101
|
end
|
1137
1102
|
end
|
1138
1103
|
|
1104
|
+
def page_validate_index(page)
|
1105
|
+
page_is_valid = true
|
1106
|
+
|
1107
|
+
print "Parsing all records in page... "
|
1108
|
+
records = page.each_record.to_a
|
1109
|
+
puts "done."
|
1110
|
+
|
1111
|
+
directory_offsets = page.each_directory_offset.to_a
|
1112
|
+
record_offsets = records.map { |rec| rec.offset }
|
1113
|
+
|
1114
|
+
invalid_directory_entries =
|
1115
|
+
directory_offsets.select { |n| ! record_offsets.include?(n) }
|
1116
|
+
|
1117
|
+
unless invalid_directory_entries.empty?
|
1118
|
+
page_is_valid = false
|
1119
|
+
puts "Invalid page directory entries (offsets not to valid records):"
|
1120
|
+
invalid_directory_entries.each do |offset|
|
1121
|
+
puts " slot %d, offset %d" % [
|
1122
|
+
page.offset_is_directory_slot?(offset),
|
1123
|
+
offset,
|
1124
|
+
]
|
1125
|
+
end
|
1126
|
+
end
|
1127
|
+
|
1128
|
+
# Read all records corresponding to valid directory entries.
|
1129
|
+
directory_records = directory_offsets.
|
1130
|
+
select { |o| !invalid_directory_entries.include?(o) }.
|
1131
|
+
map { |o| page.record(o) }
|
1132
|
+
|
1133
|
+
misordered_directory_entries = []
|
1134
|
+
prev = nil
|
1135
|
+
directory_records.each do |rec|
|
1136
|
+
unless prev
|
1137
|
+
prev = rec
|
1138
|
+
next
|
1139
|
+
end
|
1140
|
+
if rec.compare_key(prev.key.map { |v| v[:value]}) == 1
|
1141
|
+
page_is_valid = false
|
1142
|
+
misordered_directory_entries << {
|
1143
|
+
:slot => page.offset_is_directory_slot?(rec.offset),
|
1144
|
+
:offset => rec.offset,
|
1145
|
+
:key => rec.key_string,
|
1146
|
+
:prev_key => prev.key_string,
|
1147
|
+
}
|
1148
|
+
end
|
1149
|
+
prev = rec
|
1150
|
+
end
|
1151
|
+
unless misordered_directory_entries.empty?
|
1152
|
+
puts "Misordered page directory entries (key < prev key):"
|
1153
|
+
misordered_directory_entries.each do |entry|
|
1154
|
+
puts " slot %d, offset %d, key %s, prev key %s" % [
|
1155
|
+
entry[:slot],
|
1156
|
+
entry[:offset],
|
1157
|
+
entry[:key],
|
1158
|
+
entry[:prev_key],
|
1159
|
+
]
|
1160
|
+
end
|
1161
|
+
end
|
1162
|
+
|
1163
|
+
misordered_records = []
|
1164
|
+
prev = nil
|
1165
|
+
page.each_record do |rec|
|
1166
|
+
unless prev
|
1167
|
+
prev = rec
|
1168
|
+
next
|
1169
|
+
end
|
1170
|
+
if rec.compare_key(prev.key.map { |v| v[:value]}) == 1
|
1171
|
+
page_is_valid = false
|
1172
|
+
misordered_records << {
|
1173
|
+
:offset => rec.offset,
|
1174
|
+
:key => rec.key_string,
|
1175
|
+
:prev_key => prev.key_string,
|
1176
|
+
}
|
1177
|
+
end
|
1178
|
+
prev = rec
|
1179
|
+
end
|
1180
|
+
unless misordered_records.empty?
|
1181
|
+
puts "Misordered records in record list (key < prev key):"
|
1182
|
+
misordered_records.each do |entry|
|
1183
|
+
puts " offset %d, key %s, prev key %s" % [
|
1184
|
+
entry[:offset],
|
1185
|
+
entry[:key],
|
1186
|
+
entry[:prev_key],
|
1187
|
+
]
|
1188
|
+
end
|
1189
|
+
end
|
1190
|
+
|
1191
|
+
page_is_valid
|
1192
|
+
end
|
1193
|
+
|
1194
|
+
|
1195
|
+
def page_validate(innodb_system, space, page_number)
|
1196
|
+
page_is_valid = true
|
1197
|
+
puts "Validating page %d..." % [page_number]
|
1198
|
+
|
1199
|
+
print "Parsing page... "
|
1200
|
+
page = space.page(page_number)
|
1201
|
+
puts "done."
|
1202
|
+
|
1203
|
+
if page.corrupt?
|
1204
|
+
page_is_valid = false
|
1205
|
+
puts "Page appears to be corrupt:"
|
1206
|
+
puts " Stored checksums:"
|
1207
|
+
puts " header %10d (0x%08x), type %s" % [
|
1208
|
+
page.checksum,
|
1209
|
+
page.checksum,
|
1210
|
+
page.checksum_type ? page.checksum_type : "unknown",
|
1211
|
+
]
|
1212
|
+
puts " trailer %10d (0x%08x)" % [
|
1213
|
+
page.checksum_trailer,
|
1214
|
+
page.checksum_trailer,
|
1215
|
+
]
|
1216
|
+
puts " Calculated checksums:"
|
1217
|
+
puts " crc32 %10d (0x%08x)" % [
|
1218
|
+
page.checksum_crc32,
|
1219
|
+
page.checksum_crc32,
|
1220
|
+
]
|
1221
|
+
puts " innodb %10d (0x%08x)" % [
|
1222
|
+
page.checksum_innodb,
|
1223
|
+
page.checksum_innodb,
|
1224
|
+
]
|
1225
|
+
end
|
1226
|
+
|
1227
|
+
if page.torn?
|
1228
|
+
page_is_valid = false
|
1229
|
+
puts "Page appears to be torn:"
|
1230
|
+
puts " Full LSN:"
|
1231
|
+
puts " header %d (0x%016x)" % [
|
1232
|
+
page.lsn,
|
1233
|
+
page.lsn,
|
1234
|
+
]
|
1235
|
+
puts " Low 32 bits of LSN:"
|
1236
|
+
puts " header %10d (0x%08x)" % [
|
1237
|
+
page.lsn_low32_header,
|
1238
|
+
page.lsn_low32_header,
|
1239
|
+
]
|
1240
|
+
puts " trailer %10d (0x%08x)" % [
|
1241
|
+
page.lsn_low32_trailer,
|
1242
|
+
page.lsn_low32_trailer,
|
1243
|
+
]
|
1244
|
+
end
|
1245
|
+
|
1246
|
+
if page.misplaced?
|
1247
|
+
page_is_valid = false
|
1248
|
+
puts "Page appears to be misplaced:"
|
1249
|
+
if page.misplaced_offset?
|
1250
|
+
puts " Requested page %d but offset stored in page is %d." % [
|
1251
|
+
page_number,
|
1252
|
+
page.offset,
|
1253
|
+
]
|
1254
|
+
end
|
1255
|
+
if page.misplaced_space?
|
1256
|
+
puts " Space's ID %d does not match page's stored space ID %d." % [
|
1257
|
+
page.space.space_id,
|
1258
|
+
page.space_id,
|
1259
|
+
]
|
1260
|
+
end
|
1261
|
+
end
|
1262
|
+
|
1263
|
+
if page.type == :INDEX && !page_validate_index(page)
|
1264
|
+
page_is_valid = false
|
1265
|
+
end
|
1266
|
+
|
1267
|
+
puts "Page %d appears to be %s!" % [
|
1268
|
+
page_number,
|
1269
|
+
page_is_valid ? "valid" : "corrupted",
|
1270
|
+
]
|
1271
|
+
end
|
1272
|
+
|
1139
1273
|
def page_directory_summary(space, page)
|
1140
1274
|
if page.type != :INDEX
|
1141
1275
|
usage 1, "Page must be an index page"
|
@@ -1634,6 +1768,9 @@ The following modes are supported:
|
|
1634
1768
|
page-account
|
1635
1769
|
Account for a page's usage in FSEGs.
|
1636
1770
|
|
1771
|
+
page-validate
|
1772
|
+
Validate the contents of a page.
|
1773
|
+
|
1637
1774
|
page-directory-summary
|
1638
1775
|
Summarize the record contents of the page directory in a page. If a record
|
1639
1776
|
describer is available, the key of each record will be printed.
|
@@ -1900,6 +2037,8 @@ when "page-dump"
|
|
1900
2037
|
page.dump
|
1901
2038
|
when "page-account"
|
1902
2039
|
page_account(innodb_system, space, @options.page)
|
2040
|
+
when "page-validate"
|
2041
|
+
page_validate(innodb_system, space, @options.page)
|
1903
2042
|
when "page-directory-summary"
|
1904
2043
|
page_directory_summary(space, page)
|
1905
2044
|
when "page-records"
|
data/lib/innodb/page/index.rb
CHANGED
@@ -644,6 +644,26 @@ class Innodb::Page::Index < Innodb::Page
|
|
644
644
|
return record_is_directory_slot?(supremum)
|
645
645
|
end
|
646
646
|
|
647
|
+
def each_directory_offset
|
648
|
+
unless block_given?
|
649
|
+
return enum_for(:each_directory_offset)
|
650
|
+
end
|
651
|
+
|
652
|
+
directory.each do |offset|
|
653
|
+
yield offset unless [pos_infimum, pos_supremum].include?(offset)
|
654
|
+
end
|
655
|
+
end
|
656
|
+
|
657
|
+
def each_directory_record
|
658
|
+
unless block_given?
|
659
|
+
return enum_for(:each_directory_record)
|
660
|
+
end
|
661
|
+
|
662
|
+
each_directory_offset do |offset|
|
663
|
+
yield record(offset)
|
664
|
+
end
|
665
|
+
end
|
666
|
+
|
647
667
|
# A class for cursoring through records starting from an arbitrary point.
|
648
668
|
class RecordCursor
|
649
669
|
def initialize(page, offset, direction)
|
data/lib/innodb/version.rb
CHANGED