innodb_ruby 0.12.0 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|