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.
- checksums.yaml +5 -5
- data/README.md +5 -6
- data/bin/innodb_log +13 -18
- data/bin/innodb_space +377 -757
- data/lib/innodb.rb +4 -5
- data/lib/innodb/checksum.rb +26 -24
- data/lib/innodb/data_dictionary.rb +490 -550
- data/lib/innodb/data_type.rb +362 -326
- data/lib/innodb/field.rb +102 -89
- data/lib/innodb/fseg_entry.rb +22 -26
- data/lib/innodb/history.rb +21 -21
- data/lib/innodb/history_list.rb +72 -76
- data/lib/innodb/ibuf_bitmap.rb +36 -36
- data/lib/innodb/ibuf_index.rb +6 -2
- data/lib/innodb/index.rb +245 -276
- data/lib/innodb/inode.rb +154 -155
- data/lib/innodb/list.rb +191 -183
- data/lib/innodb/log.rb +139 -110
- data/lib/innodb/log_block.rb +100 -91
- data/lib/innodb/log_group.rb +53 -64
- data/lib/innodb/log_reader.rb +97 -96
- data/lib/innodb/log_record.rb +328 -279
- data/lib/innodb/lsn.rb +86 -81
- data/lib/innodb/page.rb +417 -414
- data/lib/innodb/page/blob.rb +82 -83
- data/lib/innodb/page/fsp_hdr_xdes.rb +174 -165
- data/lib/innodb/page/ibuf_bitmap.rb +34 -34
- data/lib/innodb/page/index.rb +964 -943
- data/lib/innodb/page/index_compressed.rb +34 -34
- data/lib/innodb/page/inode.rb +103 -112
- data/lib/innodb/page/sys.rb +13 -15
- data/lib/innodb/page/sys_data_dictionary_header.rb +81 -59
- data/lib/innodb/page/sys_ibuf_header.rb +45 -42
- data/lib/innodb/page/sys_rseg_header.rb +88 -82
- data/lib/innodb/page/trx_sys.rb +204 -182
- data/lib/innodb/page/undo_log.rb +106 -92
- data/lib/innodb/record.rb +121 -160
- data/lib/innodb/record_describer.rb +66 -68
- data/lib/innodb/space.rb +380 -418
- data/lib/innodb/stats.rb +33 -35
- data/lib/innodb/system.rb +149 -171
- data/lib/innodb/undo_log.rb +129 -107
- data/lib/innodb/undo_record.rb +255 -247
- data/lib/innodb/util/buffer_cursor.rb +81 -79
- data/lib/innodb/util/read_bits_at_offset.rb +2 -1
- data/lib/innodb/version.rb +2 -2
- data/lib/innodb/xdes.rb +144 -142
- metadata +80 -11
data/lib/innodb/stats.rb
CHANGED
@@ -1,46 +1,44 @@
|
|
1
|
-
#
|
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
|
-
|
6
|
-
|
5
|
+
module Innodb
|
6
|
+
class Stats
|
7
|
+
@data = Hash.new(0)
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
end
|
19
|
+
# Get a statistic by name.
|
20
|
+
def self.get(name)
|
21
|
+
@data[name]
|
22
|
+
end
|
29
23
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
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
|
-
|
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
|
-
#
|
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
|
-
|
6
|
-
|
7
|
-
|
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
|
-
|
37
|
-
|
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
|
-
|
13
|
+
# Array of space names for which a space file was not found.
|
14
|
+
attr_reader :orphans
|
43
15
|
|
44
|
-
|
45
|
-
|
16
|
+
# The Innodb::DataDictionary for this system.
|
17
|
+
attr_reader :data_dictionary
|
46
18
|
|
47
|
-
|
48
|
-
|
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
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
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
|
-
|
59
|
-
|
35
|
+
@spaces = {}
|
36
|
+
@orphans = []
|
37
|
+
@config = {
|
38
|
+
datadir: File.dirname(data_filenames.first),
|
39
|
+
}
|
60
40
|
|
61
|
-
|
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
|
-
|
69
|
-
|
70
|
-
orphans << space_file
|
71
|
-
end
|
43
|
+
@data_dictionary = Innodb::DataDictionary.new(system_space)
|
44
|
+
end
|
72
45
|
|
73
|
-
|
74
|
-
|
75
|
-
|
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
|
-
|
85
|
-
|
86
|
-
|
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
|
-
|
90
|
-
raise "Table with space ID #{space_id} not found"
|
55
|
+
spaces[space.space_id.to_i] = space
|
91
56
|
end
|
92
57
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
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
|
-
|
99
|
-
|
100
|
-
|
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
|
-
|
105
|
-
|
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
|
109
|
-
|
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
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
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
|
-
|
118
|
-
yield record["NAME"]
|
92
|
+
spaces[space_id]
|
119
93
|
end
|
120
94
|
|
121
|
-
|
122
|
-
|
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
|
-
|
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
|
-
|
131
|
-
yield space_name
|
103
|
+
space(table_record["SPACE"])
|
132
104
|
end
|
133
105
|
|
134
|
-
|
135
|
-
|
106
|
+
# Iterate through all table names.
|
107
|
+
def each_table_name
|
108
|
+
return enum_for(:each_table_name) unless block_given?
|
136
109
|
|
137
|
-
|
138
|
-
|
139
|
-
|
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
|
-
|
144
|
-
yield record["NAME"]
|
114
|
+
nil
|
145
115
|
end
|
146
116
|
|
147
|
-
|
148
|
-
|
117
|
+
# Iterate throught all orphaned spaces.
|
118
|
+
def each_orphan(&block)
|
119
|
+
return enum_for(:each_orphan) unless block_given?
|
149
120
|
|
150
|
-
|
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
|
-
|
157
|
-
yield record["NAME"]
|
123
|
+
nil
|
158
124
|
end
|
159
125
|
|
160
|
-
|
161
|
-
|
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
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
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
|
-
|
172
|
-
|
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
|
-
|
176
|
-
|
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
|
-
|
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
|
-
|
186
|
-
|
187
|
-
|
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
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
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
|
-
|
198
|
-
|
199
|
-
|
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
|
-
|
210
|
-
|
211
|
-
|
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
|
-
|
214
|
-
|
215
|
-
|
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
|
-
|
218
|
-
|
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
|
-
|
228
|
-
|
204
|
+
def history
|
205
|
+
Innodb::History.new(self)
|
206
|
+
end
|
229
207
|
end
|
230
208
|
end
|