innodb_ruby 0.9.14 → 0.12.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.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +5 -6
  3. data/bin/innodb_log +13 -18
  4. data/bin/innodb_space +654 -778
  5. data/lib/innodb/checksum.rb +26 -24
  6. data/lib/innodb/data_dictionary.rb +490 -550
  7. data/lib/innodb/data_type.rb +362 -325
  8. data/lib/innodb/field.rb +102 -89
  9. data/lib/innodb/fseg_entry.rb +22 -26
  10. data/lib/innodb/history.rb +21 -21
  11. data/lib/innodb/history_list.rb +72 -76
  12. data/lib/innodb/ibuf_bitmap.rb +36 -36
  13. data/lib/innodb/ibuf_index.rb +6 -2
  14. data/lib/innodb/index.rb +245 -276
  15. data/lib/innodb/inode.rb +166 -124
  16. data/lib/innodb/list.rb +196 -183
  17. data/lib/innodb/log.rb +139 -110
  18. data/lib/innodb/log_block.rb +100 -91
  19. data/lib/innodb/log_group.rb +53 -64
  20. data/lib/innodb/log_reader.rb +97 -96
  21. data/lib/innodb/log_record.rb +328 -279
  22. data/lib/innodb/lsn.rb +86 -81
  23. data/lib/innodb/page/blob.rb +82 -83
  24. data/lib/innodb/page/fsp_hdr_xdes.rb +174 -165
  25. data/lib/innodb/page/ibuf_bitmap.rb +34 -34
  26. data/lib/innodb/page/index.rb +965 -924
  27. data/lib/innodb/page/index_compressed.rb +34 -34
  28. data/lib/innodb/page/inode.rb +103 -112
  29. data/lib/innodb/page/sys.rb +13 -15
  30. data/lib/innodb/page/sys_data_dictionary_header.rb +81 -59
  31. data/lib/innodb/page/sys_ibuf_header.rb +45 -42
  32. data/lib/innodb/page/sys_rseg_header.rb +88 -82
  33. data/lib/innodb/page/trx_sys.rb +204 -182
  34. data/lib/innodb/page/undo_log.rb +106 -92
  35. data/lib/innodb/page.rb +417 -414
  36. data/lib/innodb/record.rb +121 -164
  37. data/lib/innodb/record_describer.rb +66 -68
  38. data/lib/innodb/space.rb +381 -413
  39. data/lib/innodb/stats.rb +33 -35
  40. data/lib/innodb/system.rb +149 -171
  41. data/lib/innodb/undo_log.rb +129 -107
  42. data/lib/innodb/undo_record.rb +255 -247
  43. data/lib/innodb/util/buffer_cursor.rb +81 -79
  44. data/lib/innodb/util/read_bits_at_offset.rb +2 -1
  45. data/lib/innodb/version.rb +2 -2
  46. data/lib/innodb/xdes.rb +144 -142
  47. data/lib/innodb.rb +4 -5
  48. metadata +100 -25
data/lib/innodb/record.rb CHANGED
@@ -1,199 +1,156 @@
1
- # -*- encoding : utf-8 -*-
1
+ # frozen_string_literal: true
2
2
 
3
- class Innodb::Record
4
- attr_reader :page
5
- attr_accessor :record
3
+ require "forwardable"
6
4
 
7
- def initialize(page, record)
8
- @page = page
9
- @record = record
10
- end
11
-
12
- def header
13
- record[:header]
14
- end
15
-
16
- def next
17
- header[:next]
18
- end
19
-
20
- def type
21
- header[:type]
22
- end
5
+ module Innodb
6
+ class Record
7
+ extend Forwardable
23
8
 
24
- def heap_number
25
- header[:heap_number]
26
- end
27
-
28
- def n_owned
29
- header[:n_owned]
30
- end
31
-
32
- def deleted?
33
- header[:deleted]
34
- end
35
-
36
- def min_rec?
37
- header[:min_rec]
38
- end
9
+ attr_reader :page
10
+ attr_accessor :record
39
11
 
40
- def offset
41
- record[:offset]
42
- end
43
-
44
- def length
45
- record[:length]
46
- end
47
-
48
- def next
49
- record[:next]
50
- end
51
-
52
- def key
53
- record[:key]
54
- end
12
+ def initialize(page, record)
13
+ @page = page
14
+ @record = record
15
+ end
55
16
 
56
- def key_string
57
- key && key.map { |r| "%s=%s" % [r[:name], r[:value].inspect] }.join(", ")
58
- end
17
+ def_delegator :record, :header
18
+ def_delegator :record, :offset
19
+ def_delegator :record, :length
20
+ def_delegator :record, :next
21
+ def_delegator :record, :key
22
+ def_delegator :record, :row
23
+ def_delegator :record, :transaction_id
24
+ def_delegator :record, :roll_pointer
25
+ def_delegator :record, :child_page_number
26
+
27
+ def_delegator :header, :type
28
+ def_delegator :header, :heap_number
29
+ def_delegator :header, :n_owned
30
+ def_delegator :header, :heap_number
31
+ def_delegator :header, :deleted?
32
+ def_delegator :header, :min_rec?
33
+
34
+ def key_string
35
+ key&.map { |r| "%s=%s" % [r.name, r.value.inspect] }&.join(", ")
36
+ end
59
37
 
60
- def row
61
- record[:row]
62
- end
38
+ def row_string
39
+ row&.map { |r| "%s=%s" % [r.name, r.value.inspect] }&.join(", ")
40
+ end
63
41
 
64
- def row_string
65
- row && row.map { |r| "%s=%s" % [r[:name], r[:value].inspect] }.join(", ")
66
- end
42
+ def undo
43
+ return nil unless roll_pointer
44
+ return unless (innodb_system = @page.space.innodb_system)
67
45
 
68
- def transaction_id
69
- record[:transaction_id]
70
- end
46
+ undo_page = innodb_system.system_space.page(roll_pointer.undo_log.page)
47
+ return unless undo_page
71
48
 
72
- def roll_pointer
73
- record[:roll_pointer]
74
- end
49
+ new_undo_record = Innodb::UndoRecord.new(undo_page, roll_pointer.undo_log.offset)
50
+ new_undo_record.index_page = page
51
+ new_undo_record
52
+ end
75
53
 
76
- def undo
77
- return nil unless roll_pointer
54
+ def each_undo_record
55
+ return enum_for(:each_undo_record) unless block_given?
78
56
 
79
- if innodb_system = @page.space.innodb_system
80
- undo_space = innodb_system.system_space
81
- if undo_page = undo_space.page(roll_pointer[:undo_log][:page])
82
- new_undo_record = Innodb::UndoRecord.new(undo_page, roll_pointer[:undo_log][:offset])
83
- new_undo_record.index_page = page
84
- new_undo_record
57
+ undo_record = undo
58
+ while undo_record
59
+ yield undo_record
60
+ undo_record = undo_record.prev_by_history
85
61
  end
86
- end
87
- end
88
-
89
- def each_undo_record
90
- unless block_given?
91
- return enum_for(:each_undo_record)
92
- end
93
62
 
94
- undo_record = undo
95
- while undo_record
96
- yield undo_record
97
- undo_record = undo_record.prev_by_history
63
+ nil
98
64
  end
99
65
 
100
- nil
101
- end
102
-
103
- def child_page_number
104
- record[:child_page_number]
105
- end
106
-
107
- def string
108
- if child_page_number
109
- "(%s) → #%s" % [key_string, child_page_number]
110
- else
111
- "(%s) → (%s)" % [key_string, row_string]
66
+ def string
67
+ if child_page_number
68
+ "(%s) → #%s" % [key_string, child_page_number]
69
+ else
70
+ "(%s) → (%s)" % [key_string, row_string]
71
+ end
112
72
  end
113
- end
114
73
 
115
- def uncached_fields
116
- fields_hash = {}
117
- [:key, :row].each do |group|
118
- if record[group]
119
- record[group].each do |column|
120
- fields_hash[column[:name]] = column[:value]
74
+ def uncached_fields
75
+ fields_hash = {}
76
+ %i[key row].each do |group|
77
+ record[group]&.each do |column|
78
+ fields_hash[column.name] = column.value
121
79
  end
122
80
  end
81
+ fields_hash
123
82
  end
124
- fields_hash
125
- end
126
83
 
127
- def fields
128
- @fields ||= uncached_fields
129
- end
84
+ def fields
85
+ @fields ||= uncached_fields
86
+ end
87
+
88
+ # Compare two arrays of fields to determine if they are equal. This follows
89
+ # the same comparison rules as strcmp and others:
90
+ # 0 = a is equal to b
91
+ # -1 = a is less than b
92
+ # +1 = a is greater than b
93
+ def compare_key(other_key)
94
+ Innodb::Stats.increment :compare_key
95
+
96
+ return 0 if other_key.nil? && key.nil?
97
+ return -1 if other_key.nil? || (!key.nil? && other_key.size < key.size)
98
+ return +1 if key.nil? || (!other_key.nil? && other_key.size > key.size)
99
+
100
+ key.each_index do |i|
101
+ Innodb::Stats.increment :compare_key_field_comparison
102
+ return -1 if other_key[i] < key[i].value
103
+ return +1 if other_key[i] > key[i].value
104
+ end
130
105
 
131
- # Compare two arrays of fields to determine if they are equal. This follows
132
- # the same comparison rules as strcmp and others:
133
- # 0 = a is equal to b
134
- # -1 = a is less than b
135
- # +1 = a is greater than b
136
- def compare_key(other_key)
137
- Innodb::Stats.increment :compare_key
138
-
139
- return 0 if other_key.nil? && key.nil?
140
- return -1 if other_key.nil? || (!key.nil? && other_key.size < key.size)
141
- return +1 if key.nil? || (!other_key.nil? && other_key.size > key.size)
142
-
143
- key.each_index do |i|
144
- Innodb::Stats.increment :compare_key_field_comparison
145
- return -1 if other_key[i] < key[i][:value]
146
- return +1 if other_key[i] > key[i][:value]
106
+ 0
147
107
  end
148
108
 
149
- return 0
150
- end
109
+ def dump
110
+ puts "Record at offset %i" % offset
111
+ puts
151
112
 
152
- def dump
153
- puts "Record at offset %i" % offset
154
- puts
155
-
156
- puts "Header:"
157
- puts " %-20s: %i" % ["Next record offset", header[:next]]
158
- puts " %-20s: %i" % ["Heap number", header[:heap_number]]
159
- puts " %-20s: %s" % ["Type", header[:type]]
160
- puts " %-20s: %s" % ["Deleted", header[:deleted]]
161
- puts " %-20s: %s" % ["Length", header[:length]]
162
- puts
163
-
164
- if page.leaf?
165
- puts "System fields:"
166
- puts " Transaction ID: %s" % transaction_id
167
- puts " Roll Pointer:"
168
- puts " Undo Log: page %i, offset %i" % [
169
- roll_pointer[:undo_log][:page],
170
- roll_pointer[:undo_log][:offset],
171
- ]
172
- puts " Rollback Segment ID: %i" % roll_pointer[:rseg_id]
173
- puts " Insert: %s" % roll_pointer[:is_insert]
113
+ puts "Header:"
114
+ puts " %-20s: %i" % ["Next record offset", header.next]
115
+ puts " %-20s: %i" % ["Heap number", header.heap_number]
116
+ puts " %-20s: %s" % ["Type", header.type]
117
+ puts " %-20s: %s" % ["Deleted", header.deleted?]
118
+ puts " %-20s: %s" % ["Length", header.length]
174
119
  puts
175
- end
176
120
 
177
- puts "Key fields:"
178
- key.each do |field|
179
- puts " %s: %s" % [
180
- field[:name],
181
- field[:value].inspect,
182
- ]
183
- end
184
- puts
121
+ if page.leaf?
122
+ puts "System fields:"
123
+ puts " Transaction ID: %s" % transaction_id
124
+ puts " Roll Pointer:"
125
+ puts " Undo Log: page %i, offset %i" % [
126
+ roll_pointer.undo_log.page,
127
+ roll_pointer.undo_log.offset,
128
+ ]
129
+ puts " Rollback Segment ID: %i" % roll_pointer.rseg_id
130
+ puts " Insert: %s" % roll_pointer.is_insert
131
+ puts
132
+ end
185
133
 
186
- if page.leaf?
187
- puts "Non-key fields:"
188
- row.each do |field|
134
+ puts "Key fields:"
135
+ key.each do |field|
189
136
  puts " %s: %s" % [
190
- field[:name],
191
- field[:value].inspect,
137
+ field.name,
138
+ field.value.inspect,
192
139
  ]
193
140
  end
194
141
  puts
195
- else
196
- puts "Child page number: %i" % child_page_number
142
+
143
+ if page.leaf?
144
+ puts "Non-key fields:"
145
+ row.each do |field|
146
+ puts " %s: %s" % [
147
+ field.name,
148
+ field.value.inspect,
149
+ ]
150
+ end
151
+ else
152
+ puts "Child page number: %i" % child_page_number
153
+ end
197
154
  puts
198
155
  end
199
156
  end
@@ -1,4 +1,4 @@
1
- # -*- encoding : utf-8 -*-
1
+ # frozen_string_literal: true
2
2
 
3
3
  #
4
4
  # A class to describe record layouts for InnoDB indexes. Designed to be usable
@@ -54,87 +54,85 @@
54
54
  # my_table_clustered.row "age", :INT, :UNSIGNED
55
55
  #
56
56
 
57
- class Innodb::RecordDescriber
58
- # Internal method to initialize the class's instance variable on access.
59
- def self.static_description
60
- @static_description ||= {
61
- :type => nil,
62
- :key => [],
63
- :row => []
64
- }
65
- end
57
+ module Innodb
58
+ class RecordDescriber
59
+ # Internal method to initialize the class's instance variable on access.
60
+ def self.static_description
61
+ @static_description ||= { type: nil, key: [], row: [] }
62
+ end
66
63
 
67
- # A 'type' method to be used from the DSL.
68
- def self.type(type)
69
- static_description[:type] = type
70
- end
64
+ # A 'type' method to be used from the DSL.
65
+ def self.type(type)
66
+ static_description[:type] = type
67
+ end
71
68
 
72
- # An internal method wrapped with 'key' and 'row' helpers.
73
- def self.add_static_field(group, name, type)
74
- static_description[group] << { :name => name, :type => type }
75
- end
69
+ # An internal method wrapped with 'key' and 'row' helpers.
70
+ def self.add_static_field(group, name, type)
71
+ static_description[group] << { name: name, type: type }
72
+ end
76
73
 
77
- # A 'key' method to be used from the DSL.
78
- def self.key(name, *type)
79
- add_static_field :key, name, type
80
- end
74
+ # A 'key' method to be used from the DSL.
75
+ def self.key(name, *type)
76
+ add_static_field :key, name, type
77
+ end
81
78
 
82
- # A 'row' method to be used from the DSL.
83
- def self.row(name, *type)
84
- add_static_field :row, name, type
85
- end
79
+ # A 'row' method to be used from the DSL.
80
+ def self.row(name, *type)
81
+ add_static_field :row, name, type
82
+ end
86
83
 
87
- attr_accessor :description
84
+ attr_accessor :description
88
85
 
89
- def initialize
90
- @description = self.class.static_description.dup
91
- @description[:key] = @description[:key].dup
92
- @description[:row] = @description[:row].dup
93
- end
86
+ def initialize
87
+ @description = self.class.static_description.dup
88
+ @description[:key] = @description[:key].dup
89
+ @description[:row] = @description[:row].dup
90
+ end
94
91
 
95
- # Set the type of this record (:clustered or :secondary).
96
- def type(type)
97
- description[:type] = type
98
- end
92
+ # Set the type of this record (:clustered or :secondary).
93
+ def type(type)
94
+ description[:type] = type
95
+ end
99
96
 
100
- # An internal method wrapped with 'key' and 'row' helpers.
101
- def add_field(group, name, type)
102
- description[group] << { :name => name, :type => type }
103
- end
97
+ # An internal method wrapped with 'key' and 'row' helpers.
98
+ def add_field(group, name, type)
99
+ description[group] << { name: name, type: type }
100
+ end
104
101
 
105
- # Add a key column to the record description.
106
- def key(name, *type)
107
- add_field :key, name, type
108
- end
102
+ # Add a key column to the record description.
103
+ def key(name, *type)
104
+ add_field :key, name, type
105
+ end
109
106
 
110
- # Add a row (non-key) column to the record description.
111
- def row(name, *type)
112
- add_field :row, name, type
113
- end
107
+ # Add a row (non-key) column to the record description.
108
+ def row(name, *type)
109
+ add_field :row, name, type
110
+ end
114
111
 
115
- def field_names
116
- names = []
117
- [:key, :row].each do |group|
118
- names += description[group].map { |n| n[:name] }
112
+ def field_names
113
+ names = []
114
+ %i[key row].each do |group|
115
+ names += description[group].map { |n| n[:name] }
116
+ end
117
+ names
119
118
  end
120
- names
121
- end
122
119
 
123
- def generate_class(name="Describer_#{object_id}")
124
- str = "class #{name}\n"
125
- str << " type %s\n" % [
126
- description[:type].inspect
127
- ]
128
- [:key, :row].each do |group|
129
- description[group].each do |item|
130
- str << " %s %s, %s\n" % [
131
- group,
132
- item[:name].inspect,
133
- item[:type].map { |s| s.inspect }.join(", "),
134
- ]
120
+ def generate_class(name = "Describer_#{object_id}")
121
+ str = "class #{name}\n".dup
122
+ str << " type %s\n" % [
123
+ description[:type].inspect,
124
+ ]
125
+ %i[key row].each do |group|
126
+ description[group].each do |item|
127
+ str << " %s %s, %s\n" % [
128
+ group,
129
+ item[:name].inspect,
130
+ item[:type].map(&:inspect).join(", "),
131
+ ]
132
+ end
135
133
  end
134
+ str << "end\n"
135
+ str
136
136
  end
137
- str << "end\n"
138
- str
139
137
  end
140
138
  end