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.
@@ -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"
@@ -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)
@@ -1,5 +1,5 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
 
3
3
  module Innodb
4
- VERSION = "0.9.14"
4
+ VERSION = "0.9.15"
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.14
4
+ version: 0.9.15
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: