innodb_ruby 0.9.16 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +5 -6
  3. data/bin/innodb_log +13 -18
  4. data/bin/innodb_space +377 -757
  5. data/lib/innodb.rb +4 -5
  6. data/lib/innodb/checksum.rb +26 -24
  7. data/lib/innodb/data_dictionary.rb +490 -550
  8. data/lib/innodb/data_type.rb +362 -326
  9. data/lib/innodb/field.rb +102 -89
  10. data/lib/innodb/fseg_entry.rb +22 -26
  11. data/lib/innodb/history.rb +21 -21
  12. data/lib/innodb/history_list.rb +72 -76
  13. data/lib/innodb/ibuf_bitmap.rb +36 -36
  14. data/lib/innodb/ibuf_index.rb +6 -2
  15. data/lib/innodb/index.rb +245 -276
  16. data/lib/innodb/inode.rb +154 -155
  17. data/lib/innodb/list.rb +191 -183
  18. data/lib/innodb/log.rb +139 -110
  19. data/lib/innodb/log_block.rb +100 -91
  20. data/lib/innodb/log_group.rb +53 -64
  21. data/lib/innodb/log_reader.rb +97 -96
  22. data/lib/innodb/log_record.rb +328 -279
  23. data/lib/innodb/lsn.rb +86 -81
  24. data/lib/innodb/page.rb +417 -414
  25. data/lib/innodb/page/blob.rb +82 -83
  26. data/lib/innodb/page/fsp_hdr_xdes.rb +174 -165
  27. data/lib/innodb/page/ibuf_bitmap.rb +34 -34
  28. data/lib/innodb/page/index.rb +964 -943
  29. data/lib/innodb/page/index_compressed.rb +34 -34
  30. data/lib/innodb/page/inode.rb +103 -112
  31. data/lib/innodb/page/sys.rb +13 -15
  32. data/lib/innodb/page/sys_data_dictionary_header.rb +81 -59
  33. data/lib/innodb/page/sys_ibuf_header.rb +45 -42
  34. data/lib/innodb/page/sys_rseg_header.rb +88 -82
  35. data/lib/innodb/page/trx_sys.rb +204 -182
  36. data/lib/innodb/page/undo_log.rb +106 -92
  37. data/lib/innodb/record.rb +121 -160
  38. data/lib/innodb/record_describer.rb +66 -68
  39. data/lib/innodb/space.rb +380 -418
  40. data/lib/innodb/stats.rb +33 -35
  41. data/lib/innodb/system.rb +149 -171
  42. data/lib/innodb/undo_log.rb +129 -107
  43. data/lib/innodb/undo_record.rb +255 -247
  44. data/lib/innodb/util/buffer_cursor.rb +81 -79
  45. data/lib/innodb/util/read_bits_at_offset.rb +2 -1
  46. data/lib/innodb/version.rb +2 -2
  47. data/lib/innodb/xdes.rb +144 -142
  48. metadata +80 -11
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)
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
+ datadir: 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[:datadir], 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