innodb_ruby 0.12.0 → 0.14.0
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.
- checksums.yaml +4 -4
- data/bin/innodb_log +9 -3
- data/bin/innodb_space +42 -25
- data/lib/innodb/data_dictionary.rb +11 -2
- data/lib/innodb/data_type.rb +2 -2
- data/lib/innodb/field.rb +1 -1
- data/lib/innodb/index.rb +6 -4
- data/lib/innodb/inode.rb +1 -1
- data/lib/innodb/lsn.rb +3 -3
- data/lib/innodb/page/blob.rb +6 -12
- data/lib/innodb/page/fsp_hdr_xdes.rb +78 -2
- data/lib/innodb/page/ibuf_bitmap.rb +1 -1
- data/lib/innodb/page/index.rb +20 -14
- data/lib/innodb/page/index_compressed.rb +1 -1
- data/lib/innodb/page/inode.rb +1 -1
- data/lib/innodb/page/sys_data_dictionary_header.rb +1 -1
- data/lib/innodb/page/sys_ibuf_header.rb +1 -1
- data/lib/innodb/page/sys_rseg_header.rb +1 -1
- data/lib/innodb/page/trx_sys.rb +1 -1
- data/lib/innodb/page.rb +86 -22
- data/lib/innodb/record.rb +10 -0
- data/lib/innodb/record_describer.rb +5 -6
- data/lib/innodb/space.rb +15 -5
- data/lib/innodb/undo_record.rb +1 -1
- data/lib/innodb/util/buffer_cursor.rb +1 -1
- data/lib/innodb/util/hex_format.rb +32 -0
- data/lib/innodb/version.rb +1 -1
- data/lib/innodb/xdes.rb +1 -1
- data/lib/innodb.rb +1 -1
- metadata +39 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 65c78efba30c942c5529781a0dc7b36816af82d8aa4077d29d535f0727485c02
|
4
|
+
data.tar.gz: 6eb04e7370deee2f220383b36dd9d1dd1d8c454024f7a20fa2a3a8ece386bb14
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ac98dfc4efeb3e42941bba41b021037e480e53a25300f3d4d115eae44e2c6435592f00f2d65934a0e14166e93fc2dd9e376189bd0c8945a138b0e4ece3a16b59
|
7
|
+
data.tar.gz: 449fb6bd1c19690a52aaa065efa6f2465a5aae66be3e1a42b69c2826c8d489babd4979e5ef2c8e840b81629c965d0731da72bc358845306e76b15efa81c34b80
|
data/bin/innodb_log
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "getoptlong"
|
5
|
-
require "ostruct"
|
6
5
|
require "set"
|
7
6
|
require "innodb"
|
8
7
|
|
@@ -60,7 +59,7 @@ def usage(exit_code, message = nil)
|
|
60
59
|
print "Error: #{message}\n" unless message.nil?
|
61
60
|
|
62
61
|
# rubocop:disable Layout/HeredocIndentation
|
63
|
-
print <<
|
62
|
+
print <<END_OF_USAGE
|
64
63
|
|
65
64
|
Usage: innodb_log [-d] [-l <lsn>] -f <log file> <mode>
|
66
65
|
|
@@ -96,7 +95,14 @@ END_OF_USAGE
|
|
96
95
|
exit exit_code
|
97
96
|
end
|
98
97
|
|
99
|
-
|
98
|
+
InnodbLogOptions = Struct.new(
|
99
|
+
:log_files,
|
100
|
+
:dump,
|
101
|
+
:lsn,
|
102
|
+
keyword_init: true
|
103
|
+
)
|
104
|
+
|
105
|
+
@options = InnodbLogOptions.new
|
100
106
|
@options.log_files = []
|
101
107
|
@options.dump = false
|
102
108
|
@options.lsn = nil
|
data/bin/innodb_space
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "getoptlong"
|
5
|
-
require "ostruct"
|
6
5
|
require "histogram/array"
|
7
6
|
require "innodb"
|
8
7
|
|
@@ -118,10 +117,10 @@ def print_lists(lists)
|
|
118
117
|
puts "%-20s%-12i%-12i%-12i%-12i%-12i" % [
|
119
118
|
name,
|
120
119
|
list.base[:length],
|
121
|
-
list.base[:first] && list.base[:first][:page] || 0,
|
122
|
-
list.base[:first] && list.base[:first][:offset] || 0,
|
123
|
-
list.base[:last] && list.base[:last][:page] || 0,
|
124
|
-
list.base[:last] && list.base[:last][:offset] || 0,
|
120
|
+
(list.base[:first] && list.base[:first][:page]) || 0,
|
121
|
+
(list.base[:first] && list.base[:first][:offset]) || 0,
|
122
|
+
(list.base[:last] && list.base[:last][:page]) || 0,
|
123
|
+
(list.base[:last] && list.base[:last][:offset]) || 0,
|
125
124
|
]
|
126
125
|
end
|
127
126
|
end
|
@@ -157,8 +156,8 @@ def print_index_page_summary(pages)
|
|
157
156
|
]
|
158
157
|
|
159
158
|
pages.each do |page_number, page|
|
160
|
-
case
|
161
|
-
when
|
159
|
+
case
|
160
|
+
when page.is_a?(Innodb::Page::Index)
|
162
161
|
puts "%-12i%-8i%-8i%-8i%-8i%-8i" % [
|
163
162
|
page_number,
|
164
163
|
page.page_header[:index_id],
|
@@ -167,7 +166,7 @@ def print_index_page_summary(pages)
|
|
167
166
|
page.free_space,
|
168
167
|
page.records,
|
169
168
|
]
|
170
|
-
when :ALLOCATED
|
169
|
+
when page.type == :ALLOCATED
|
171
170
|
puts "%-12i%-8i%-8i%-8i%-8i%-8i" % [page_number, 0, 0, 0, page.size, 0]
|
172
171
|
end
|
173
172
|
end
|
@@ -430,12 +429,12 @@ def space_index_pages_free_plot(space, start_page)
|
|
430
429
|
index_data = { 0 => { x: [], y: [] } }
|
431
430
|
|
432
431
|
space.each_page(start_page) do |page_number, page|
|
433
|
-
case
|
434
|
-
when
|
432
|
+
case
|
433
|
+
when page.is_a?(Innodb::Page::Index)
|
435
434
|
data = (index_data[page.page_header[:index_id]] ||= { x: [], y: [] })
|
436
435
|
data[:x] << page_number
|
437
436
|
data[:y] << page.free_space
|
438
|
-
when :ALLOCATED
|
437
|
+
when page.type == :ALLOCATED
|
439
438
|
index_data[0][:x] << page_number
|
440
439
|
index_data[0][:y] << page.size
|
441
440
|
end
|
@@ -445,7 +444,7 @@ def space_index_pages_free_plot(space, start_page)
|
|
445
444
|
image_file = "#{image_name}_free.png"
|
446
445
|
|
447
446
|
# Aim for one horizontal pixel per extent, but min 1k and max 10k width.
|
448
|
-
|
447
|
+
(space.pages / space.pages_per_extent).clamp(1_000, 10_000)
|
449
448
|
|
450
449
|
Gnuplot.open do |gp|
|
451
450
|
Gnuplot::Plot.new(gp) do |plot|
|
@@ -476,7 +475,7 @@ end
|
|
476
475
|
|
477
476
|
# rubocop:disable Metrics/BlockNesting
|
478
477
|
def space_extents_illustrate_page_status(space, entry, count_by_identifier, identifiers)
|
479
|
-
entry.each_page_status.
|
478
|
+
entry.each_page_status.with_object("".dup) do |(page_number, page_status), bitmap|
|
480
479
|
if page_number >= space.pages
|
481
480
|
bitmap << " "
|
482
481
|
next
|
@@ -577,8 +576,8 @@ def space_lsn_age_illustrate(space)
|
|
577
576
|
next if page.lsn.zero?
|
578
577
|
|
579
578
|
page_lsn[page_number] = page.lsn
|
580
|
-
lsn_min = page.lsn
|
581
|
-
lsn_max = page.lsn
|
579
|
+
lsn_min = [page.lsn, lsn_min].min
|
580
|
+
lsn_max = [page.lsn, lsn_max].max
|
582
581
|
end
|
583
582
|
lsn_delta = lsn_max - lsn_min
|
584
583
|
|
@@ -606,7 +605,7 @@ def space_lsn_age_illustrate(space)
|
|
606
605
|
|
607
606
|
puts "%12s ╰%-#{width}s╯" % ["", "─" * width]
|
608
607
|
|
609
|
-
_, lsn_freq = page_lsn.
|
608
|
+
_, lsn_freq = page_lsn.compact.histogram(colors.size, min: lsn_min, max: lsn_max)
|
610
609
|
lsn_freq_delta = lsn_freq.max - lsn_freq.min
|
611
610
|
|
612
611
|
lsn_age_histogram = "".dup
|
@@ -690,10 +689,9 @@ def page_account(innodb_system, space, page_number)
|
|
690
689
|
|
691
690
|
page = space.page(page_number)
|
692
691
|
page_type = Innodb::Page::PAGE_TYPE[page.type]
|
693
|
-
puts " Page type is %s (%s
|
692
|
+
puts " Page type is %s (%s)." % [
|
694
693
|
page.type,
|
695
694
|
page_type[:description],
|
696
|
-
page_type[:usage],
|
697
695
|
]
|
698
696
|
|
699
697
|
xdes = space.xdes_for_page(page_number)
|
@@ -922,7 +920,7 @@ def page_validate(_innodb_system, space, page_number)
|
|
922
920
|
end
|
923
921
|
end
|
924
922
|
|
925
|
-
page_is_valid = false if page.
|
923
|
+
page_is_valid = false if page.is_a?(Innodb::Page::Index) && !page_validate_index(page)
|
926
924
|
|
927
925
|
puts "Page %d appears to be %s!" % [
|
928
926
|
page_number,
|
@@ -931,7 +929,7 @@ def page_validate(_innodb_system, space, page_number)
|
|
931
929
|
end
|
932
930
|
|
933
931
|
def page_directory_summary(_space, page)
|
934
|
-
usage(1, "Page must be an index page")
|
932
|
+
usage(1, "Page must be an index page") unless page.is_a?(Innodb::Page::Index)
|
935
933
|
|
936
934
|
puts "%-8s%-8s%-14s%-8s%s" % %w[
|
937
935
|
slot
|
@@ -966,7 +964,7 @@ end
|
|
966
964
|
|
967
965
|
def page_illustrate(page)
|
968
966
|
width = 64
|
969
|
-
unknown_page_content = page.
|
967
|
+
unknown_page_content = page.is_a?(Innodb::Page::Index) && page.record_describer.nil?
|
970
968
|
blocks = Array.new(page.size, unknown_page_content ? "▞" : " ")
|
971
969
|
identifiers = {}
|
972
970
|
identifier_sort = 0
|
@@ -1251,7 +1249,7 @@ def usage(exit_code, message = nil)
|
|
1251
1249
|
end
|
1252
1250
|
|
1253
1251
|
# rubocop:disable Layout/HeredocIndentation
|
1254
|
-
print <<
|
1252
|
+
print <<END_OF_USAGE
|
1255
1253
|
|
1256
1254
|
Usage: innodb_space <options> <mode>
|
1257
1255
|
|
@@ -1484,7 +1482,26 @@ end
|
|
1484
1482
|
Signal.trap(name) { exit } if Signal.list.include?(name)
|
1485
1483
|
end
|
1486
1484
|
|
1487
|
-
|
1485
|
+
InnodbSpaceOptions = Struct.new(
|
1486
|
+
:trace,
|
1487
|
+
:system_space_file,
|
1488
|
+
:system_space_tables,
|
1489
|
+
:data_directory,
|
1490
|
+
:space_file,
|
1491
|
+
:table_name,
|
1492
|
+
:index_name,
|
1493
|
+
:page,
|
1494
|
+
:record,
|
1495
|
+
:level,
|
1496
|
+
:list,
|
1497
|
+
:fseg_id,
|
1498
|
+
:describer,
|
1499
|
+
:illustration_line_width,
|
1500
|
+
:illustration_block_size,
|
1501
|
+
keyword_init: true
|
1502
|
+
)
|
1503
|
+
|
1504
|
+
@options = InnodbSpaceOptions.new
|
1488
1505
|
@options.trace = 0
|
1489
1506
|
@options.system_space_file = nil
|
1490
1507
|
@options.system_space_tables = false
|
@@ -1625,7 +1642,7 @@ if innodb_system && @options.table_name && @options.index_name
|
|
1625
1642
|
page = @options.page ? space.page(@options.page) : index.root
|
1626
1643
|
elsif @options.page
|
1627
1644
|
page = space.page(@options.page)
|
1628
|
-
index = space.index(@options.page) if page
|
1645
|
+
index = space.index(@options.page) if page.is_a?(Innodb::Page::Index) && page&.root?
|
1629
1646
|
end
|
1630
1647
|
|
1631
1648
|
# The non-option argument on the command line is the mode (usually the last,
|
@@ -1678,7 +1695,7 @@ if /^record-/.match(mode) && !page
|
|
1678
1695
|
)
|
1679
1696
|
end
|
1680
1697
|
|
1681
|
-
if /^record-/.match(mode) && page.
|
1698
|
+
if /^record-/.match(mode) && !page.is_a?(Innodb::Page::Index)
|
1682
1699
|
usage(1, "Mode #{mode} may be used only with index pages")
|
1683
1700
|
end
|
1684
1701
|
|
@@ -235,7 +235,14 @@ module Innodb
|
|
235
235
|
system_space.data_dictionary_page.data_dictionary_header[:indexes]
|
236
236
|
end
|
237
237
|
|
238
|
+
# Check if the data dictionary indexes are all available.
|
239
|
+
def found?
|
240
|
+
data_dictionary_indexes.values.map(&:values).flatten.none?(&:zero?)
|
241
|
+
end
|
242
|
+
|
238
243
|
def data_dictionary_index_ids
|
244
|
+
raise "Data Dictionary not found; is the MySQL version supported?" unless found?
|
245
|
+
|
239
246
|
return @data_dictionary_index_ids if @data_dictionary_index_ids
|
240
247
|
|
241
248
|
# TODO: This could probably be done a lot more Ruby-like.
|
@@ -260,7 +267,7 @@ module Innodb
|
|
260
267
|
end
|
261
268
|
|
262
269
|
def data_dictionary_index?(table_name, index_name)
|
263
|
-
return unless data_dictionary_table?(table_name)
|
270
|
+
return false unless data_dictionary_table?(table_name)
|
264
271
|
|
265
272
|
DATA_DICTIONARY_RECORD_DESCRIBERS[table_name.to_sym].include?(index_name.to_sym)
|
266
273
|
end
|
@@ -275,6 +282,8 @@ module Innodb
|
|
275
282
|
# internal data dictionary index with an appropriate
|
276
283
|
# record describer so that records can be recursed.
|
277
284
|
def data_dictionary_index(table_name, index_name)
|
285
|
+
raise "Data Dictionary not found; is the MySQL version supported?" unless found?
|
286
|
+
|
278
287
|
table_entry = data_dictionary_indexes[table_name]
|
279
288
|
raise "Unknown data dictionary table #{table_name}" unless table_entry
|
280
289
|
|
@@ -307,7 +316,7 @@ module Innodb
|
|
307
316
|
return enum_for(:each_data_dictionary_index) unless block_given?
|
308
317
|
|
309
318
|
data_dictionary_indexes.each do |table_name, indexes|
|
310
|
-
indexes.
|
319
|
+
indexes.each_key do |index_name|
|
311
320
|
yield table_name, index_name,
|
312
321
|
data_dictionary_index(table_name, index_name)
|
313
322
|
end
|
data/lib/innodb/data_type.rb
CHANGED
@@ -112,8 +112,8 @@ module Innodb
|
|
112
112
|
@uncomp_fractional = scale / MAX_DIGITS_PER_INTEGER
|
113
113
|
@comp_integral = integral - (@uncomp_integral * MAX_DIGITS_PER_INTEGER)
|
114
114
|
@comp_fractional = scale - (@uncomp_fractional * MAX_DIGITS_PER_INTEGER)
|
115
|
-
@width = @uncomp_integral * 4 + BYTES_PER_DIGIT[@comp_integral] +
|
116
|
-
@comp_fractional * 4 + BYTES_PER_DIGIT[@comp_fractional]
|
115
|
+
@width = (@uncomp_integral * 4) + BYTES_PER_DIGIT[@comp_integral] +
|
116
|
+
(@comp_fractional * 4) + BYTES_PER_DIGIT[@comp_fractional]
|
117
117
|
@name = Innodb::DataType.make_name(base_type, modifiers, properties)
|
118
118
|
end
|
119
119
|
|
data/lib/innodb/field.rb
CHANGED
@@ -121,7 +121,7 @@ module Innodb
|
|
121
121
|
base_type = matches[1].upcase.to_sym
|
122
122
|
return [base_type, []] unless matches[3]
|
123
123
|
|
124
|
-
[base_type, matches[3].sub(/ /, "").split(
|
124
|
+
[base_type, matches[3].sub(/ /, "").split(",").map(&:to_i)]
|
125
125
|
end
|
126
126
|
end
|
127
127
|
end
|
data/lib/innodb/index.rb
CHANGED
@@ -21,7 +21,9 @@ module Innodb
|
|
21
21
|
raise "Page #{root_page_number} couldn't be read" unless @root
|
22
22
|
|
23
23
|
# The root page should be an index page.
|
24
|
-
|
24
|
+
unless @root.is_a?(Innodb::Page::Index)
|
25
|
+
raise "Page #{root_page_number} is a #{@root.type} page, not an INDEX page"
|
26
|
+
end
|
25
27
|
|
26
28
|
# The root page should be the only page at its level.
|
27
29
|
raise "Page #{root_page_number} does not appear to be an index root" if @root.prev || @root.next
|
@@ -53,12 +55,12 @@ module Innodb
|
|
53
55
|
|
54
56
|
# Internal method used by recurse.
|
55
57
|
def _recurse(parent_page, page_proc, link_proc, depth = 0)
|
56
|
-
page_proc.call(parent_page, depth) if page_proc && parent_page.
|
58
|
+
page_proc.call(parent_page, depth) if page_proc && parent_page.is_a?(Innodb::Page::Index)
|
57
59
|
|
58
60
|
parent_page.each_child_page do |child_page_number, child_min_key|
|
59
61
|
child_page = page(child_page_number)
|
60
62
|
child_page.record_describer = record_describer
|
61
|
-
next unless child_page.
|
63
|
+
next unless child_page.is_a?(Innodb::Page::Index)
|
62
64
|
|
63
65
|
link_proc&.call(parent_page, child_page, child_min_key, depth + 1)
|
64
66
|
_recurse(child_page, page_proc, link_proc, depth + 1)
|
@@ -143,7 +145,7 @@ module Innodb
|
|
143
145
|
def each_page_from(page)
|
144
146
|
return enum_for(:each_page_from, page) unless block_given?
|
145
147
|
|
146
|
-
while page
|
148
|
+
while page.is_a?(Innodb::Page::Index)
|
147
149
|
yield page
|
148
150
|
break unless page.next
|
149
151
|
|
data/lib/innodb/inode.rb
CHANGED
data/lib/innodb/lsn.rb
CHANGED
@@ -40,7 +40,7 @@ module Innodb
|
|
40
40
|
fragment = (@lsn_no % LOG_BLOCK_SIZE) - LOG_BLOCK_HEADER_SIZE
|
41
41
|
raise "Invalid fragment #{fragment} for LSN #{@lsn_no}" unless fragment.between?(0, LOG_BLOCK_DATA_SIZE - 1)
|
42
42
|
|
43
|
-
length + (fragment + length) / LOG_BLOCK_DATA_SIZE * LOG_BLOCK_FRAME_SIZE
|
43
|
+
length + ((fragment + length) / LOG_BLOCK_DATA_SIZE * LOG_BLOCK_FRAME_SIZE)
|
44
44
|
end
|
45
45
|
|
46
46
|
# Whether LSN might point to log record data.
|
@@ -82,12 +82,12 @@ module Innodb
|
|
82
82
|
end
|
83
83
|
|
84
84
|
# Transpose group size offset to a group capacity offset.
|
85
|
-
group_offset = offset - (LOG_HEADER_SIZE * (1 + offset / log_size))
|
85
|
+
group_offset = offset - (LOG_HEADER_SIZE * (1 + (offset / log_size)))
|
86
86
|
|
87
87
|
offset = (lsn_offset + group_offset) % group_capacity
|
88
88
|
|
89
89
|
# Transpose group capacity offset to a group size offset.
|
90
|
-
offset + LOG_HEADER_SIZE * (1 + offset / (log_size - LOG_HEADER_SIZE))
|
90
|
+
offset + (LOG_HEADER_SIZE * (1 + (offset / (log_size - LOG_HEADER_SIZE))))
|
91
91
|
end
|
92
92
|
|
93
93
|
# Whether offset points to the data area of an existing log block.
|
data/lib/innodb/page/blob.rb
CHANGED
@@ -32,22 +32,16 @@ module Innodb
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
def
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
(slice_count * slice_size),
|
40
|
-
slice_bytes[0..8].map { |n| "%02x" % n.ord }.join(" "),
|
41
|
-
slice_bytes[8..16].map { |n| "%02x" % n.ord }.join(" "),
|
42
|
-
slice_bytes.join,
|
43
|
-
]
|
44
|
-
end
|
35
|
+
def next_blob_page
|
36
|
+
return unless blob_header[:next]
|
37
|
+
|
38
|
+
space.page(blob_header[:next])
|
45
39
|
end
|
46
40
|
|
47
41
|
def each_region(&block)
|
48
42
|
return enum_for(:each_region) unless block_given?
|
49
43
|
|
50
|
-
super
|
44
|
+
super
|
51
45
|
|
52
46
|
yield Region.new(
|
53
47
|
offset: pos_blob_header,
|
@@ -75,7 +69,7 @@ module Innodb
|
|
75
69
|
puts
|
76
70
|
|
77
71
|
puts "blob data:"
|
78
|
-
|
72
|
+
HexFormat.puts(blob_data)
|
79
73
|
puts
|
80
74
|
|
81
75
|
puts
|
@@ -47,6 +47,22 @@ module Innodb
|
|
47
47
|
keyword_init: true
|
48
48
|
)
|
49
49
|
|
50
|
+
EncryptionHeader = Struct.new(
|
51
|
+
:magic,
|
52
|
+
:master_key_id,
|
53
|
+
:key,
|
54
|
+
:iv,
|
55
|
+
:server_uuid,
|
56
|
+
:checksum,
|
57
|
+
keyword_init: true
|
58
|
+
)
|
59
|
+
|
60
|
+
SdiHeader = Struct.new(
|
61
|
+
:version,
|
62
|
+
:root_page_number,
|
63
|
+
keyword_init: true
|
64
|
+
)
|
65
|
+
|
50
66
|
# A value added to the adjusted exponent stored in the page size field of
|
51
67
|
# the flags in the FSP header.
|
52
68
|
FLAGS_PAGE_SIZE_SHIFT = 9
|
@@ -118,6 +134,22 @@ module Innodb
|
|
118
134
|
entries_in_xdes_array * size_xdes_entry
|
119
135
|
end
|
120
136
|
|
137
|
+
def pos_encryption_header
|
138
|
+
pos_xdes_array + size_xdes_array
|
139
|
+
end
|
140
|
+
|
141
|
+
def size_encryption_header
|
142
|
+
3 + 4 + (32 * 2) + 36 + 4 + 4
|
143
|
+
end
|
144
|
+
|
145
|
+
def pos_sdi_header
|
146
|
+
pos_encryption_header + size_encryption_header
|
147
|
+
end
|
148
|
+
|
149
|
+
def size_sdi_header
|
150
|
+
8
|
151
|
+
end
|
152
|
+
|
121
153
|
# Read the FSP (filespace) header, which contains a few counters and flags,
|
122
154
|
# as well as list base nodes for each list maintained in the filespace.
|
123
155
|
def fsp_header
|
@@ -162,10 +194,32 @@ module Innodb
|
|
162
194
|
end
|
163
195
|
end
|
164
196
|
|
197
|
+
def encryption_header
|
198
|
+
@encryption_header ||= cursor(pos_encryption_header).name("encryption_header") do |c|
|
199
|
+
EncryptionHeader.new(
|
200
|
+
magic: c.name("magic") { c.read_bytes(3) },
|
201
|
+
master_key_id: c.name("master_key_id") { c.read_uint32 },
|
202
|
+
key: c.name("key") { c.read_bytes(32) },
|
203
|
+
iv: c.name("iv") { c.read_bytes(32) },
|
204
|
+
server_uuid: c.name("server_uuid") { c.read_string(36) },
|
205
|
+
checksum: c.name("checksum") { c.read_uint32 }
|
206
|
+
)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def sdi_header
|
211
|
+
@sdi_header ||= cursor(pos_sdi_header).name("sdi_header") do |c|
|
212
|
+
SdiHeader.new(
|
213
|
+
version: c.name("version") { c.read_uint32 },
|
214
|
+
root_page_number: c.name("root_page_number") { c.read_uint32 }
|
215
|
+
)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
165
219
|
def each_region(&block)
|
166
220
|
return enum_for(:each_region) unless block_given?
|
167
221
|
|
168
|
-
super
|
222
|
+
super
|
169
223
|
|
170
224
|
yield Region.new(
|
171
225
|
offset: pos_fsp_header,
|
@@ -179,11 +233,25 @@ module Innodb
|
|
179
233
|
yield Region.new(
|
180
234
|
offset: xdes.offset,
|
181
235
|
length: size_xdes_entry,
|
182
|
-
name: "xdes_#{state}"
|
236
|
+
name: :"xdes_#{state}",
|
183
237
|
info: "Extent Descriptor (#{state})"
|
184
238
|
)
|
185
239
|
end
|
186
240
|
|
241
|
+
yield Region.new(
|
242
|
+
offset: pos_encryption_header,
|
243
|
+
length: size_encryption_header,
|
244
|
+
name: :encryption_header,
|
245
|
+
info: "Encryption Header"
|
246
|
+
)
|
247
|
+
|
248
|
+
yield Region.new(
|
249
|
+
offset: pos_sdi_header,
|
250
|
+
length: size_sdi_header,
|
251
|
+
name: :sdi_header,
|
252
|
+
info: "SDI Header"
|
253
|
+
)
|
254
|
+
|
187
255
|
nil
|
188
256
|
end
|
189
257
|
|
@@ -200,6 +268,14 @@ module Innodb
|
|
200
268
|
pp xdes
|
201
269
|
end
|
202
270
|
puts
|
271
|
+
|
272
|
+
puts "encryption header:"
|
273
|
+
pp encryption_header
|
274
|
+
puts
|
275
|
+
|
276
|
+
puts "serialized dictionary information header:"
|
277
|
+
pp sdi_header
|
278
|
+
puts
|
203
279
|
end
|
204
280
|
end
|
205
281
|
end
|
data/lib/innodb/page/index.rb
CHANGED
@@ -130,7 +130,7 @@ module Innodb
|
|
130
130
|
# Maximum number of fields.
|
131
131
|
RECORD_MAX_N_SYSTEM_FIELDS = 3
|
132
132
|
RECORD_MAX_N_FIELDS = 1024 - 1
|
133
|
-
RECORD_MAX_N_USER_FIELDS = RECORD_MAX_N_FIELDS - RECORD_MAX_N_SYSTEM_FIELDS * 2
|
133
|
+
RECORD_MAX_N_USER_FIELDS = RECORD_MAX_N_FIELDS - (RECORD_MAX_N_SYSTEM_FIELDS * 2)
|
134
134
|
|
135
135
|
# Page direction values possible in the page_header's :direction field.
|
136
136
|
PAGE_DIRECTION = {
|
@@ -314,8 +314,8 @@ module Innodb
|
|
314
314
|
index_id: c.name("index_id") { c.read_uint64 }
|
315
315
|
)
|
316
316
|
|
317
|
-
index.n_heap = index.n_heap_format & (2**15 - 1)
|
318
|
-
index.format = (index.n_heap_format & 1 << 15).zero? ? :redundant : :compact
|
317
|
+
index.n_heap = index.n_heap_format & ((2**15) - 1)
|
318
|
+
index.format = (index.n_heap_format & (1 << 15)).zero? ? :redundant : :compact
|
319
319
|
|
320
320
|
index
|
321
321
|
end
|
@@ -546,7 +546,7 @@ module Innodb
|
|
546
546
|
end
|
547
547
|
|
548
548
|
def make_record_describer
|
549
|
-
if space&.innodb_system && index_id
|
549
|
+
if space&.innodb_system&.data_dictionary&.found? && index_id && !ibuf_index?
|
550
550
|
@record_describer = space.innodb_system.data_dictionary.record_describer_by_index_id(index_id)
|
551
551
|
elsif space
|
552
552
|
@record_describer = space.record_describer
|
@@ -998,7 +998,7 @@ module Innodb
|
|
998
998
|
def each_region(&block)
|
999
999
|
return enum_for(:each_region) unless block_given?
|
1000
1000
|
|
1001
|
-
super
|
1001
|
+
super
|
1002
1002
|
|
1003
1003
|
yield Region.new(
|
1004
1004
|
offset: pos_index_header,
|
@@ -1096,17 +1096,23 @@ module Innodb
|
|
1096
1096
|
pp supremum.record
|
1097
1097
|
puts
|
1098
1098
|
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1099
|
+
if ibuf_index?
|
1100
|
+
puts "(records not dumped due to this being an insert buffer index)"
|
1101
|
+
elsif !record_describer
|
1102
|
+
puts "(records not dumped due to missing record describer or data dictionary)"
|
1103
|
+
else
|
1104
|
+
puts "garbage records:"
|
1105
|
+
each_garbage_record do |rec|
|
1106
|
+
pp rec.record
|
1107
|
+
puts
|
1108
|
+
end
|
1102
1109
|
puts
|
1103
|
-
end
|
1104
|
-
puts
|
1105
1110
|
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
1111
|
+
puts "records:"
|
1112
|
+
each_record do |rec|
|
1113
|
+
pp rec.record
|
1114
|
+
puts
|
1115
|
+
end
|
1110
1116
|
end
|
1111
1117
|
puts
|
1112
1118
|
end
|
@@ -34,7 +34,7 @@ module Innodb
|
|
34
34
|
def free_space
|
35
35
|
free_space_start =
|
36
36
|
size - size_fil_trailer - directory_space - (uncompressed_columns_size * (page_header.n_heap - 2))
|
37
|
-
puts "Free space start == %04x" % [offset * size + free_space_start]
|
37
|
+
puts "Free space start == %04x" % [(offset * size) + free_space_start]
|
38
38
|
c = cursor(free_space_start).backward
|
39
39
|
zero_bytes = 0
|
40
40
|
zero_bytes += 1 while c.read_uint8.zero?
|
data/lib/innodb/page/inode.rb
CHANGED
data/lib/innodb/page/trx_sys.rb
CHANGED
data/lib/innodb/page.rb
CHANGED
@@ -101,11 +101,8 @@ module Innodb
|
|
101
101
|
# Initialize a page by passing in a buffer containing the raw page contents.
|
102
102
|
# The buffer size should match the space's page size.
|
103
103
|
def initialize(space, buffer, page_number = nil)
|
104
|
-
|
105
|
-
|
106
|
-
end
|
107
|
-
|
108
|
-
raise "Buffer size #{buffer.size} is different than space page size" unless space.page_size == buffer.size
|
104
|
+
raise "Page can't be initialized from nil space or buffer (space: #{space}, buffer: #{buffer})" unless buffer
|
105
|
+
raise "Buffer size #{buffer.size} is different than space page size" if space && space.page_size != buffer.size
|
109
106
|
|
110
107
|
@space = space
|
111
108
|
@buffer = buffer
|
@@ -141,7 +138,7 @@ module Innodb
|
|
141
138
|
# return value of the block.
|
142
139
|
def cursor(buffer_offset)
|
143
140
|
new_cursor = BufferCursor.new(@buffer, buffer_offset)
|
144
|
-
new_cursor.push_name("space[#{space
|
141
|
+
new_cursor.push_name("space[#{space&.name || 'unknown'}]")
|
145
142
|
new_cursor.push_name("page[#{name}]")
|
146
143
|
|
147
144
|
if block_given?
|
@@ -205,74 +202,137 @@ module Innodb
|
|
205
202
|
ALLOCATED: {
|
206
203
|
value: 0,
|
207
204
|
description: "Freshly allocated",
|
208
|
-
usage: "page type field has not been initialized",
|
209
205
|
},
|
210
206
|
UNDO_LOG: {
|
211
207
|
value: 2,
|
212
208
|
description: "Undo log",
|
213
|
-
usage: "stores previous values of modified records",
|
214
209
|
},
|
215
210
|
INODE: {
|
216
211
|
value: 3,
|
217
212
|
description: "File segment inode",
|
218
|
-
usage: "bookkeeping for file segments",
|
219
213
|
},
|
220
214
|
IBUF_FREE_LIST: {
|
221
215
|
value: 4,
|
222
216
|
description: "Insert buffer free list",
|
223
|
-
usage: "bookkeeping for insert buffer free space management",
|
224
217
|
},
|
225
218
|
IBUF_BITMAP: {
|
226
219
|
value: 5,
|
227
220
|
description: "Insert buffer bitmap",
|
228
|
-
usage: "bookkeeping for insert buffer writes to be merged",
|
229
221
|
},
|
230
222
|
SYS: {
|
231
223
|
value: 6,
|
232
224
|
description: "System internal",
|
233
|
-
usage: "used for various purposes in the system tablespace",
|
234
225
|
},
|
235
226
|
TRX_SYS: {
|
236
227
|
value: 7,
|
237
228
|
description: "Transaction system header",
|
238
|
-
usage: "bookkeeping for the transaction system in system tablespace",
|
239
229
|
},
|
240
230
|
FSP_HDR: {
|
241
231
|
value: 8,
|
242
232
|
description: "File space header",
|
243
|
-
usage: "header page (page 0) for each tablespace file",
|
244
233
|
},
|
245
234
|
XDES: {
|
246
235
|
value: 9,
|
247
236
|
description: "Extent descriptor",
|
248
|
-
usage: "header page for subsequent blocks of 16,384 pages",
|
249
237
|
},
|
250
238
|
BLOB: {
|
251
239
|
value: 10,
|
252
240
|
description: "Uncompressed BLOB",
|
253
|
-
usage: "externally-stored uncompressed BLOB column data",
|
254
241
|
},
|
255
242
|
ZBLOB: {
|
256
243
|
value: 11,
|
257
244
|
description: "First compressed BLOB",
|
258
|
-
usage: "externally-stored compressed BLOB column data, first page",
|
259
245
|
},
|
260
246
|
ZBLOB2: {
|
261
247
|
value: 12,
|
262
248
|
description: "Subsequent compressed BLOB",
|
263
|
-
|
249
|
+
},
|
250
|
+
UNKNOWN: {
|
251
|
+
value: 13,
|
252
|
+
description: "Unknown",
|
253
|
+
},
|
254
|
+
COMPRESSED: {
|
255
|
+
value: 14,
|
256
|
+
description: "Compressed",
|
257
|
+
},
|
258
|
+
ENCRYPTED: {
|
259
|
+
value: 15,
|
260
|
+
description: "Encrypted",
|
261
|
+
},
|
262
|
+
COMPRESSED_AND_ENCRYPTED: {
|
263
|
+
value: 16,
|
264
|
+
description: "Compressed and Encrypted",
|
265
|
+
},
|
266
|
+
ENCRYPTED_RTREE: {
|
267
|
+
value: 17,
|
268
|
+
description: "Encrypted R-tree",
|
269
|
+
},
|
270
|
+
SDI_BLOB: {
|
271
|
+
value: 18,
|
272
|
+
description: "Uncompressed SDI BLOB",
|
273
|
+
},
|
274
|
+
SDI_ZBLOB: {
|
275
|
+
value: 19,
|
276
|
+
description: "Compressed SDI BLOB",
|
277
|
+
},
|
278
|
+
LEGACY_DBLWR: {
|
279
|
+
value: 20,
|
280
|
+
description: "Legacy doublewrite buffer",
|
281
|
+
},
|
282
|
+
RSEG_ARRAY: {
|
283
|
+
value: 21,
|
284
|
+
description: "Rollback Segment Array",
|
285
|
+
},
|
286
|
+
LOB_INDEX: {
|
287
|
+
value: 22,
|
288
|
+
description: "Index of uncompressed LOB",
|
289
|
+
},
|
290
|
+
LOB_DATA: {
|
291
|
+
value: 23,
|
292
|
+
description: "Data of uncompressed LOB",
|
293
|
+
},
|
294
|
+
LOB_FIRST: {
|
295
|
+
value: 24,
|
296
|
+
description: "First page of an uncompressed LOB",
|
297
|
+
},
|
298
|
+
ZLOB_FIRST: {
|
299
|
+
value: 25,
|
300
|
+
description: "First page of a compressed LOB",
|
301
|
+
},
|
302
|
+
ZLOB_DATA: {
|
303
|
+
value: 26,
|
304
|
+
description: "Data of compressed LOB",
|
305
|
+
},
|
306
|
+
ZLOB_INDEX: {
|
307
|
+
value: 27,
|
308
|
+
description: "Index of compressed LOB",
|
309
|
+
},
|
310
|
+
ZLOB_FRAG: {
|
311
|
+
value: 28,
|
312
|
+
description: "Fragment of compressed LOB",
|
313
|
+
},
|
314
|
+
ZLOB_FRAG_ENTRY: {
|
315
|
+
value: 29,
|
316
|
+
description: "Index of fragment for compressed LOB",
|
317
|
+
},
|
318
|
+
SDI: {
|
319
|
+
value: 17_853,
|
320
|
+
description: "Serialized Dictionary Information",
|
321
|
+
},
|
322
|
+
RTREE: {
|
323
|
+
value: 17_854,
|
324
|
+
description: "R-tree index",
|
264
325
|
},
|
265
326
|
INDEX: {
|
266
327
|
value: 17_855,
|
267
328
|
description: "B+Tree index",
|
268
|
-
usage: "table and index data stored in B+Tree structure",
|
269
329
|
},
|
270
330
|
}.freeze
|
271
331
|
|
272
332
|
PAGE_TYPE_BY_VALUE = PAGE_TYPE.each_with_object({}) { |(k, v), h| h[v[:value]] = k }
|
273
333
|
|
274
334
|
# A page number representing "undefined" values, (4294967295).
|
275
|
-
UNDEFINED_PAGE_NUMBER = 2**32 - 1
|
335
|
+
UNDEFINED_PAGE_NUMBER = (2**32) - 1
|
276
336
|
|
277
337
|
# A helper to check if a page number is the undefined page number.
|
278
338
|
def self.undefined?(page_number)
|
@@ -285,6 +345,10 @@ module Innodb
|
|
285
345
|
page_number unless undefined?(page_number)
|
286
346
|
end
|
287
347
|
|
348
|
+
def self.page_type_by_value(value)
|
349
|
+
PAGE_TYPE_BY_VALUE[value] || value
|
350
|
+
end
|
351
|
+
|
288
352
|
# Return the "fil" header from the page, which is common for all page types.
|
289
353
|
def fil_header
|
290
354
|
@fil_header ||= cursor(pos_fil_header).name("fil_header") do |c|
|
@@ -294,7 +358,7 @@ module Innodb
|
|
294
358
|
prev: c.name("prev") { Innodb::Page.maybe_undefined(c.read_uint32) },
|
295
359
|
next: c.name("next") { Innodb::Page.maybe_undefined(c.read_uint32) },
|
296
360
|
lsn: c.name("lsn") { c.read_uint64 },
|
297
|
-
type: c.name("type") {
|
361
|
+
type: c.name("type") { Innodb::Page.page_type_by_value(c.read_uint16) },
|
298
362
|
flush_lsn: c.name("flush_lsn") { c.read_uint64 },
|
299
363
|
space_id: c.name("space_id") { c.read_uint32 }
|
300
364
|
)
|
@@ -405,7 +469,7 @@ module Innodb
|
|
405
469
|
|
406
470
|
# Is the page in the doublewrite buffer?
|
407
471
|
def in_doublewrite_buffer?
|
408
|
-
space&.system_space? && space
|
472
|
+
space&.system_space? && space.doublewrite_page?(offset)
|
409
473
|
end
|
410
474
|
|
411
475
|
# Is the space ID stored in the header different from that of the space
|
data/lib/innodb/record.rb
CHANGED
@@ -39,6 +39,16 @@ module Innodb
|
|
39
39
|
row&.map { |r| "%s=%s" % [r.name, r.value.inspect] }&.join(", ")
|
40
40
|
end
|
41
41
|
|
42
|
+
def full_value_with_externs_for_field(field)
|
43
|
+
blob_value = field.value
|
44
|
+
extern_page = field.extern && page.space.page(field.extern.page_number)
|
45
|
+
while extern_page
|
46
|
+
blob_value += extern_page.blob_data
|
47
|
+
extern_page = extern_page.next_blob_page
|
48
|
+
end
|
49
|
+
blob_value
|
50
|
+
end
|
51
|
+
|
42
52
|
def undo
|
43
53
|
return nil unless roll_pointer
|
44
54
|
return unless (innodb_system = @page.space.innodb_system)
|
@@ -119,16 +119,15 @@ module Innodb
|
|
119
119
|
|
120
120
|
def generate_class(name = "Describer_#{object_id}")
|
121
121
|
str = "class #{name}\n".dup
|
122
|
-
str << " type %s\n"
|
123
|
-
description[:type].inspect,
|
124
|
-
]
|
122
|
+
str << format(" type %s\n", description[:type].inspect)
|
125
123
|
%i[key row].each do |group|
|
126
124
|
description[group].each do |item|
|
127
|
-
str <<
|
125
|
+
str << format(
|
126
|
+
" %s %s, %s\n",
|
128
127
|
group,
|
129
128
|
item[:name].inspect,
|
130
|
-
item[:type].map(&:inspect).join(", ")
|
131
|
-
|
129
|
+
item[:type].map(&:inspect).join(", ")
|
130
|
+
)
|
132
131
|
end
|
133
132
|
end
|
134
133
|
str << "end\n"
|
data/lib/innodb/space.rb
CHANGED
@@ -276,6 +276,12 @@ module Innodb
|
|
276
276
|
fsp[:space_id]
|
277
277
|
end
|
278
278
|
|
279
|
+
def checked_page_class!(page, expected_class)
|
280
|
+
return page if page.instance_of?(expected_class)
|
281
|
+
|
282
|
+
raise "Page #{page.offset} is not the correct type, found: #{page.class}, expected: #{expected_class}"
|
283
|
+
end
|
284
|
+
|
279
285
|
# Return the page number for the space's TRX_SYS page.
|
280
286
|
def page_trx_sys
|
281
287
|
5
|
@@ -283,13 +289,15 @@ module Innodb
|
|
283
289
|
|
284
290
|
# Get the Innodb::Page::TrxSys page for a system space.
|
285
291
|
def trx_sys
|
286
|
-
|
292
|
+
raise "Transaction System is only available in system spaces" unless system_space?
|
293
|
+
|
294
|
+
checked_page_class!(page(page_trx_sys), Innodb::Page::TrxSys)
|
287
295
|
end
|
288
296
|
|
289
297
|
def rseg_page?(page_number)
|
290
298
|
return false unless trx_sys
|
291
299
|
|
292
|
-
|
300
|
+
trx_sys.rsegs.any? { |rseg| rseg.space_id.zero? && rseg.page_number == page_number }
|
293
301
|
end
|
294
302
|
|
295
303
|
# Return the page number for the space's SYS data dictionary header.
|
@@ -299,7 +307,9 @@ module Innodb
|
|
299
307
|
|
300
308
|
# Get the Innodb::Page::SysDataDictionaryHeader page for a system space.
|
301
309
|
def data_dictionary_page
|
302
|
-
|
310
|
+
raise "Data Dictionary is only available in system spaces" unless system_space?
|
311
|
+
|
312
|
+
checked_page_class!(page(page_sys_data_dictionary), Innodb::Page::SysDataDictionaryHeader)
|
303
313
|
end
|
304
314
|
|
305
315
|
# Get an Innodb::List object for a specific list by list name.
|
@@ -327,7 +337,7 @@ module Innodb
|
|
327
337
|
# for IBD files, if they haven't added indexes online.
|
328
338
|
(3...@pages).each do |page_number|
|
329
339
|
page = page(page_number)
|
330
|
-
yield page_number if page.
|
340
|
+
yield page_number if page.is_a?(Innodb::Page::Index) && page.root?
|
331
341
|
end
|
332
342
|
end
|
333
343
|
|
@@ -358,7 +368,7 @@ module Innodb
|
|
358
368
|
def each_inode(&block)
|
359
369
|
return enum_for(:each_inode) unless block_given?
|
360
370
|
|
361
|
-
each_inode_list
|
371
|
+
each_inode_list do |_name, list|
|
362
372
|
list.each do |page|
|
363
373
|
page.each_allocated_inode(&block)
|
364
374
|
end
|
data/lib/innodb/undo_record.rb
CHANGED
@@ -238,7 +238,7 @@ module Innodb
|
|
238
238
|
end
|
239
239
|
|
240
240
|
def row_string
|
241
|
-
row&.
|
241
|
+
row&.compact&.map { |r| r && format("%s=%s", r[:name], r[:value].inspect) }&.join(", ")
|
242
242
|
end
|
243
243
|
|
244
244
|
def string
|
@@ -76,7 +76,7 @@ class BufferCursor
|
|
76
76
|
# position, raw byte buffer, and array of names.
|
77
77
|
def print_trace(_cursor, position, bytes, name)
|
78
78
|
slice_size = 16
|
79
|
-
bytes.each_slice(slice_size).
|
79
|
+
bytes.each_slice(slice_size).with_index do |slice_bytes, slice_count|
|
80
80
|
@trace_io.puts "%06i %s %-32s %s" % [
|
81
81
|
position + (slice_count * slice_size),
|
82
82
|
direction == :backward ? "←" : "→",
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module HexFormat
|
4
|
+
LINE_SIZE = 16
|
5
|
+
GROUP_SIZE = 8
|
6
|
+
GROUP_FORMAT_LENGTH = ((LINE_SIZE.to_f / GROUP_SIZE).ceil * (GROUP_SIZE * 3))
|
7
|
+
|
8
|
+
def self.format_group(data)
|
9
|
+
data.map { |n| "%02x" % n.ord }.join(" ")
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.format_groups(data, size)
|
13
|
+
data.each_slice(size).map { |g| format_group(g) }.join(" ")
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.format_printable(data)
|
17
|
+
data.join.gsub(/[^[:print:]]/, ".")
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.format_hex(data)
|
21
|
+
data.chars.each_slice(LINE_SIZE).with_index do |bytes, i|
|
22
|
+
yield format("%08i %-#{GROUP_FORMAT_LENGTH}s |%-#{LINE_SIZE}s|",
|
23
|
+
(i * LINE_SIZE), format_groups(bytes, GROUP_SIZE), format_printable(bytes))
|
24
|
+
end
|
25
|
+
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.puts(data, io: $stdout)
|
30
|
+
format_hex(data) { |line| io.puts(line) }
|
31
|
+
end
|
32
|
+
end
|
data/lib/innodb/version.rb
CHANGED
data/lib/innodb/xdes.rb
CHANGED
@@ -118,7 +118,7 @@ module Innodb
|
|
118
118
|
def each_page_status
|
119
119
|
return enum_for(:each_page_status) unless block_given?
|
120
120
|
|
121
|
-
bitmap.each_byte.
|
121
|
+
bitmap.each_byte.with_index do |byte, byte_index|
|
122
122
|
(0..3).each do |page_offset|
|
123
123
|
page_number = start_page + (byte_index * 4) + page_offset
|
124
124
|
page_bits = ((byte >> (page_offset * BITS_PER_PAGE)) & BITMAP_BV_ALL)
|
data/lib/innodb.rb
CHANGED
@@ -14,10 +14,10 @@ module Innodb
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
require "pp"
|
18
17
|
require "digest/crc32c"
|
19
18
|
require "innodb/util/buffer_cursor"
|
20
19
|
require "innodb/util/read_bits_at_offset"
|
20
|
+
require "innodb/util/hex_format"
|
21
21
|
|
22
22
|
require "innodb/version"
|
23
23
|
require "innodb/stats"
|
metadata
CHANGED
@@ -1,16 +1,30 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: innodb_ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Cole
|
8
8
|
- Davi Arnaut
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2024-11-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bigdecimal
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: 3.1.8
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: 3.1.8
|
14
28
|
- !ruby/object:Gem::Dependency
|
15
29
|
name: bindata
|
16
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -51,6 +65,20 @@ dependencies:
|
|
51
65
|
- - ">="
|
52
66
|
- !ruby/object:Gem::Version
|
53
67
|
version: 0.4.1
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: getoptlong
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 0.2.1
|
75
|
+
type: :runtime
|
76
|
+
prerelease: false
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: 0.2.1
|
54
82
|
- !ruby/object:Gem::Dependency
|
55
83
|
name: histogram
|
56
84
|
requirement: !ruby/object:Gem::Requirement
|
@@ -85,14 +113,14 @@ dependencies:
|
|
85
113
|
requirements:
|
86
114
|
- - "~>"
|
87
115
|
- !ruby/object:Gem::Version
|
88
|
-
version: 3.
|
116
|
+
version: 3.11.0
|
89
117
|
type: :development
|
90
118
|
prerelease: false
|
91
119
|
version_requirements: !ruby/object:Gem::Requirement
|
92
120
|
requirements:
|
93
121
|
- - "~>"
|
94
122
|
- !ruby/object:Gem::Version
|
95
|
-
version: 3.
|
123
|
+
version: 3.11.0
|
96
124
|
- !ruby/object:Gem::Dependency
|
97
125
|
name: rubocop
|
98
126
|
requirement: !ruby/object:Gem::Requirement
|
@@ -174,14 +202,16 @@ files:
|
|
174
202
|
- lib/innodb/undo_log.rb
|
175
203
|
- lib/innodb/undo_record.rb
|
176
204
|
- lib/innodb/util/buffer_cursor.rb
|
205
|
+
- lib/innodb/util/hex_format.rb
|
177
206
|
- lib/innodb/util/read_bits_at_offset.rb
|
178
207
|
- lib/innodb/version.rb
|
179
208
|
- lib/innodb/xdes.rb
|
180
209
|
homepage: https://github.com/jeremycole/innodb_ruby
|
181
210
|
licenses:
|
182
211
|
- BSD-3-Clause
|
183
|
-
metadata:
|
184
|
-
|
212
|
+
metadata:
|
213
|
+
rubygems_mfa_required: 'false'
|
214
|
+
post_install_message:
|
185
215
|
rdoc_options: []
|
186
216
|
require_paths:
|
187
217
|
- lib
|
@@ -196,8 +226,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
196
226
|
- !ruby/object:Gem::Version
|
197
227
|
version: '0'
|
198
228
|
requirements: []
|
199
|
-
rubygems_version: 3.
|
200
|
-
signing_key:
|
229
|
+
rubygems_version: 3.5.16
|
230
|
+
signing_key:
|
201
231
|
specification_version: 4
|
202
232
|
summary: InnoDB data file parser
|
203
233
|
test_files: []
|