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/stats.rb CHANGED
@@ -1,46 +1,44 @@
1
- # -*- encoding : utf-8 -*-
1
+ # frozen_string_literal: true
2
2
 
3
3
  # Collect stats globally within innodb_ruby for comparison purposes and for
4
4
  # correctness checking.
5
- class Innodb::Stats
6
- @@data = Hash.new(0)
5
+ module Innodb
6
+ class Stats
7
+ @data = Hash.new(0)
7
8
 
8
- # Return the data hash directly.
9
- def self.data
10
- @@data
11
- end
12
-
13
- # Increment a statistic by name (typically a symbol), optionally by a value
14
- # provided.
15
- def self.increment(name, value=1)
16
- @@data[name] += value
17
- end
9
+ class << self
10
+ attr_reader :data
11
+ end
18
12
 
19
- # Get a statistic by name.
20
- def self.get(name)
21
- @@data[name]
22
- end
13
+ # Increment a statistic by name (typically a symbol), optionally by a value
14
+ # provided.
15
+ def self.increment(name, value = 1)
16
+ @data[name] += value
17
+ end
23
18
 
24
- # Reset all statistics.
25
- def self.reset
26
- @@data.clear
27
- nil
28
- end
19
+ # Get a statistic by name.
20
+ def self.get(name)
21
+ @data[name]
22
+ end
29
23
 
30
- # Print a simple report of collected statistics, optionally to the IO object
31
- # provided, or by default to STDOUT.
32
- def self.print_report(io=STDOUT)
33
- io.puts "%-50s%10s" % [
34
- "Statistic",
35
- "Count",
36
- ]
37
- @@data.sort.each do |name, count|
38
- io.puts "%-50s%10i" % [
39
- name,
40
- count
41
- ]
24
+ # Reset all statistics.
25
+ def self.reset
26
+ @data.clear
27
+ nil
42
28
  end
43
29
 
44
- nil
30
+ # Print a simple report of collected statistics, optionally to the IO object
31
+ # provided, or by default to STDOUT.
32
+ def self.print_report(io = $stdout)
33
+ io.puts "%-50s%10s" % %w[Statistic Count]
34
+ @data.sort.each do |name, count|
35
+ io.puts "%-50s%10i" % [
36
+ name,
37
+ count,
38
+ ]
39
+ end
40
+
41
+ nil
42
+ end
45
43
  end
46
44
  end
data/lib/innodb/system.rb CHANGED
@@ -1,230 +1,208 @@
1
- # -*- encoding : utf-8 -*-
1
+ # frozen_string_literal: true
2
2
 
3
3
  # A class representing an entire InnoDB system, having a system tablespace
4
4
  # and any number of attached single-table tablespaces.
5
- class Innodb::System
6
- # A hash of configuration options by configuration key.
7
- attr_reader :config
8
-
9
- # A hash of spaces by space ID.
10
- attr_reader :spaces
11
-
12
- # Array of space names for which a space file was not found.
13
- attr_reader :orphans
14
-
15
- # The Innodb::DataDictionary for this system.
16
- attr_reader :data_dictionary
17
-
18
- # The space ID of the system space, always 0.
19
- SYSTEM_SPACE_ID = 0
20
-
21
- def initialize(arg)
22
- if arg.is_a?(Array) && arg.size > 1
23
- data_filenames = arg
24
- else
25
- arg = arg.first if arg.is_a?(Array)
26
- if File.directory?(arg)
27
- data_filenames = Dir.glob(arg + "/ibdata?").sort
28
- if data_filenames.empty?
29
- raise "Couldn't find any ibdata files in #{arg}"
30
- end
31
- else
32
- data_filenames = [arg]
33
- end
34
- end
5
+ module Innodb
6
+ class System
7
+ # A hash of configuration options by configuration key.
8
+ attr_reader :config
35
9
 
36
- @spaces = {}
37
- @orphans = []
38
- @config = {
39
- :datadir => File.dirname(data_filenames.first),
40
- }
10
+ # A hash of spaces by space ID.
11
+ attr_reader :spaces
41
12
 
42
- add_space_file(data_filenames)
13
+ # Array of space names for which a space file was not found.
14
+ attr_reader :orphans
43
15
 
44
- @data_dictionary = Innodb::DataDictionary.new(system_space)
45
- end
16
+ # The Innodb::DataDictionary for this system.
17
+ attr_reader :data_dictionary
46
18
 
47
- # A helper to get the system space.
48
- def system_space
49
- spaces[SYSTEM_SPACE_ID]
50
- end
19
+ # The space ID of the system space, always 0.
20
+ SYSTEM_SPACE_ID = 0
51
21
 
52
- # Add an already-constructed Innodb::Space object.
53
- def add_space(space)
54
- unless space.is_a?(Innodb::Space)
55
- raise "Object was not an Innodb::Space"
56
- end
22
+ def initialize(arg, data_directory: nil)
23
+ if arg.is_a?(Array) && arg.size > 1
24
+ data_filenames = arg
25
+ else
26
+ arg = arg.first if arg.is_a?(Array)
27
+ if File.directory?(arg)
28
+ data_filenames = Dir.glob("#{arg}/ibdata?").sort
29
+ raise "Couldn't find any ibdata files in #{arg}" if data_filenames.empty?
30
+ else
31
+ data_filenames = [arg]
32
+ end
33
+ end
57
34
 
58
- spaces[space.space_id.to_i] = space
59
- end
35
+ @spaces = {}
36
+ @orphans = []
37
+ @config = {
38
+ data_directory: data_directory || File.dirname(data_filenames.first),
39
+ }
60
40
 
61
- # Add a space by filename.
62
- def add_space_file(space_filenames)
63
- space = Innodb::Space.new(space_filenames)
64
- space.innodb_system = self
65
- add_space(space)
66
- end
41
+ add_space_file(data_filenames)
67
42
 
68
- # Add an orphaned space.
69
- def add_space_orphan(space_file)
70
- orphans << space_file
71
- end
43
+ @data_dictionary = Innodb::DataDictionary.new(system_space)
44
+ end
72
45
 
73
- # Add a space by table name, constructing an appropriate filename
74
- # from the provided table name.
75
- def add_table(table_name)
76
- space_file = "%s/%s.ibd" % [config[:datadir], table_name]
77
- if File.exist?(space_file)
78
- add_space_file(space_file)
79
- else
80
- add_space_orphan(table_name)
46
+ # A helper to get the system space.
47
+ def system_space
48
+ spaces[SYSTEM_SPACE_ID]
81
49
  end
82
- end
83
50
 
84
- # Return an Innodb::Space object for a given space ID, looking up
85
- # and adding the single-table space if necessary.
86
- def space(space_id)
87
- return spaces[space_id] if spaces[space_id]
51
+ # Add an already-constructed Innodb::Space object.
52
+ def add_space(space)
53
+ raise "Object was not an Innodb::Space" unless space.is_a?(Innodb::Space)
88
54
 
89
- unless table_record = data_dictionary.table_by_space_id(space_id)
90
- raise "Table with space ID #{space_id} not found"
55
+ spaces[space.space_id.to_i] = space
91
56
  end
92
57
 
93
- add_table(table_record["NAME"])
94
-
95
- spaces[space_id]
96
- end
58
+ # Add a space by filename.
59
+ def add_space_file(space_filenames)
60
+ space = Innodb::Space.new(space_filenames)
61
+ space.innodb_system = self
62
+ add_space(space)
63
+ end
97
64
 
98
- # Return an Innodb::Space object by table name.
99
- def space_by_table_name(table_name)
100
- unless table_record = data_dictionary.table_by_name(table_name)
101
- raise "Table #{table_name} not found"
65
+ # Add an orphaned space.
66
+ def add_space_orphan(space_file)
67
+ orphans << space_file
102
68
  end
103
69
 
104
- if table_record["SPACE"] == 0
105
- return nil
70
+ # Add a space by table name, constructing an appropriate filename
71
+ # from the provided table name.
72
+ def add_table(table_name)
73
+ space_file = "%s/%s.ibd" % [config[:data_directory], table_name]
74
+ if File.exist?(space_file)
75
+ add_space_file(space_file)
76
+ else
77
+ add_space_orphan(table_name)
78
+ end
106
79
  end
107
80
 
108
- space(table_record["SPACE"])
109
- end
81
+ # Return an Innodb::Space object for a given space ID, looking up
82
+ # and adding the single-table space if necessary.
83
+ def space(space_id)
84
+ return spaces[space_id] if spaces[space_id]
110
85
 
111
- # Iterate through all table names.
112
- def each_table_name
113
- unless block_given?
114
- return enum_for(:each_table_name)
115
- end
86
+ unless (table_record = data_dictionary.table_by_space_id(space_id))
87
+ raise "Table with space ID #{space_id} not found"
88
+ end
89
+
90
+ add_table(table_record["NAME"])
116
91
 
117
- data_dictionary.each_table do |record|
118
- yield record["NAME"]
92
+ spaces[space_id]
119
93
  end
120
94
 
121
- nil
122
- end
95
+ # Return an Innodb::Space object by table name.
96
+ def space_by_table_name(table_name)
97
+ unless (table_record = data_dictionary.table_by_name(table_name))
98
+ raise "Table #{table_name} not found"
99
+ end
123
100
 
124
- # Iterate throught all orphaned spaces.
125
- def each_orphan
126
- unless block_given?
127
- return enum_for(:each_orphan)
128
- end
101
+ return if table_record["SPACE"].zero?
129
102
 
130
- orphans.each do |space_name|
131
- yield space_name
103
+ space(table_record["SPACE"])
132
104
  end
133
105
 
134
- nil
135
- end
106
+ # Iterate through all table names.
107
+ def each_table_name
108
+ return enum_for(:each_table_name) unless block_given?
136
109
 
137
- # Iterate through all column names by table name.
138
- def each_column_name_by_table_name(table_name)
139
- unless block_given?
140
- return enum_for(:each_column_name_by_table_name, table_name)
141
- end
110
+ data_dictionary.each_table do |record|
111
+ yield record["NAME"]
112
+ end
142
113
 
143
- data_dictionary.each_column_by_table_name(table_name) do |record|
144
- yield record["NAME"]
114
+ nil
145
115
  end
146
116
 
147
- nil
148
- end
117
+ # Iterate throught all orphaned spaces.
118
+ def each_orphan(&block)
119
+ return enum_for(:each_orphan) unless block_given?
149
120
 
150
- # Iterate through all index names by table name.
151
- def each_index_name_by_table_name(table_name)
152
- unless block_given?
153
- return enum_for(:each_index_name_by_table_name, table_name)
154
- end
121
+ orphans.each(&block)
155
122
 
156
- data_dictionary.each_index_by_table_name(table_name) do |record|
157
- yield record["NAME"]
123
+ nil
158
124
  end
159
125
 
160
- nil
161
- end
126
+ # Iterate through all column names by table name.
127
+ def each_column_name_by_table_name(table_name)
128
+ return enum_for(:each_column_name_by_table_name, table_name) unless block_given?
162
129
 
163
- # Iterate through all field names in a given index by table name
164
- # and index name.
165
- def each_index_field_name_by_index_name(table_name, index_name)
166
- unless block_given?
167
- return enum_for(:each_index_field_name_by_index_name,
168
- table_name, index_name)
130
+ data_dictionary.each_column_by_table_name(table_name) do |record|
131
+ yield record["NAME"]
132
+ end
133
+
134
+ nil
169
135
  end
170
136
 
171
- data_dictionary.each_field_by_index_name(table_name, index_name) do |record|
172
- yield record["COL_NAME"]
137
+ # Iterate through all index names by table name.
138
+ def each_index_name_by_table_name(table_name)
139
+ return enum_for(:each_index_name_by_table_name, table_name) unless block_given?
140
+
141
+ data_dictionary.each_index_by_table_name(table_name) do |record|
142
+ yield record["NAME"]
143
+ end
144
+
145
+ nil
173
146
  end
174
147
 
175
- nil
176
- end
148
+ # Iterate through all field names in a given index by table name
149
+ # and index name.
150
+ def each_index_field_name_by_index_name(table_name, index_name)
151
+ return enum_for(:each_index_field_name_by_index_name, table_name, index_name) unless block_given?
152
+
153
+ data_dictionary.each_field_by_index_name(table_name, index_name) do |record|
154
+ yield record["COL_NAME"]
155
+ end
177
156
 
178
- # Return the table name given a table ID.
179
- def table_name_by_id(table_id)
180
- if table_record = data_dictionary.table_by_id(table_id)
181
- table_record["NAME"]
157
+ nil
182
158
  end
183
- end
184
159
 
185
- # Return the index name given an index ID.
186
- def index_name_by_id(index_id)
187
- if index_record = data_dictionary.index_by_id(index_id)
188
- index_record["NAME"]
160
+ # Return the table name given a table ID.
161
+ def table_name_by_id(table_id)
162
+ data_dictionary.table_by_id(table_id).fetch("NAME", nil)
189
163
  end
190
- end
191
164
 
192
- # Return the clustered index name given a table name.
193
- def clustered_index_by_table_name(table_name)
194
- data_dictionary.clustered_index_name_by_table_name(table_name)
195
- end
165
+ # Return the index name given an index ID.
166
+ def index_name_by_id(index_id)
167
+ data_dictionary.index_by_id(index_id).fetch("NAME", nil)
168
+ end
196
169
 
197
- # Return an array of the table name and index name given an index ID.
198
- def table_and_index_name_by_id(index_id)
199
- if dd_index = data_dictionary.data_dictionary_index_ids[index_id]
200
- # This is a data dictionary index, which won't be found in the data
201
- # dictionary itself.
202
- [dd_index[:table], dd_index[:index]]
203
- elsif index_record = data_dictionary.index_by_id(index_id)
204
- # This is a system or user index.
205
- [table_name_by_id(index_record["TABLE_ID"]), index_record["NAME"]]
170
+ # Return the clustered index name given a table name.
171
+ def clustered_index_by_table_name(table_name)
172
+ data_dictionary.clustered_index_name_by_table_name(table_name)
206
173
  end
207
- end
208
174
 
209
- # Return an Innodb::Index object given a table name and index name.
210
- def index_by_name(table_name, index_name)
211
- index_record = data_dictionary.index_by_name(table_name, index_name)
175
+ # Return an array of the table name and index name given an index ID.
176
+ def table_and_index_name_by_id(index_id)
177
+ if (dd_index = data_dictionary.data_dictionary_index_ids[index_id])
178
+ # This is a data dictionary index, which won't be found in the data
179
+ # dictionary itself.
180
+ [dd_index[:table], dd_index[:index]]
181
+ elsif (index_record = data_dictionary.index_by_id(index_id))
182
+ # This is a system or user index.
183
+ [table_name_by_id(index_record["TABLE_ID"]), index_record["NAME"]]
184
+ end
185
+ end
212
186
 
213
- index_space = space(index_record["SPACE"])
214
- describer = data_dictionary.record_describer_by_index_name(table_name, index_name)
215
- index = index_space.index(index_record["PAGE_NO"], describer)
187
+ # Return an Innodb::Index object given a table name and index name.
188
+ def index_by_name(table_name, index_name)
189
+ index_record = data_dictionary.index_by_name(table_name, index_name)
216
190
 
217
- index
218
- end
191
+ index_space = space(index_record["SPACE"])
192
+ describer = data_dictionary.record_describer_by_index_name(table_name, index_name)
193
+ index_space.index(index_record["PAGE_NO"], describer)
194
+ end
195
+
196
+ # Return the clustered index given a table ID.
197
+ def clustered_index_by_table_id(table_id)
198
+ table_name = table_name_by_id(table_id)
199
+ return unless table_name
219
200
 
220
- # Return the clustered index given a table ID.
221
- def clustered_index_by_table_id(table_id)
222
- if table_name = table_name_by_id(table_id)
223
201
  index_by_name(table_name, clustered_index_by_table_name(table_name))
224
202
  end
225
- end
226
203
 
227
- def history
228
- Innodb::History.new(self)
204
+ def history
205
+ Innodb::History.new(self)
206
+ end
229
207
  end
230
208
  end