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