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.
@@ -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: