flydata 0.2.30 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/bin/flydata +6 -1
- data/flydata-core/lib/flydata-core/table_def/mysql_table_def.rb +18 -15
- data/flydata-core/spec/table_def/mysql_table_def_spec.rb +132 -0
- data/flydata.gemspec +5 -4
- data/lib/flydata/cli.rb +5 -3
- data/lib/flydata/command/setup.rb +7 -2
- data/lib/flydata/command/sync.rb +62 -8
- data/lib/flydata/compatibility_check.rb +2 -2
- data/lib/flydata/errors.rb +34 -0
- data/lib/flydata/fluent-plugins/mysql/dml_record_handler.rb +14 -9
- data/lib/flydata/helpers.rb +1 -17
- data/spec/flydata/cli_spec.rb +2 -2
- data/spec/flydata/fluent-plugins/in_mysql_binlog_flydata_spec.rb +25 -9
- data/spec/flydata/parser/mysql/alter_table_parser_spec.rb +2 -2
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 68f311d20207752e80dd5fb47b905b085e840520
|
4
|
+
data.tar.gz: 6bfa38fa63a7db7e1f4b7109324017e99c82c117
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 01469b9c9b268bc8dad0bda81a3dbcc3a98a55901108cac17b50a6688313485f1d7cdd8a01b26ea20cbea0d8fa6f4c096055394f55cea58ee59a949acb2963fe
|
7
|
+
data.tar.gz: cde53114405b00f034e7444fd0b9ba9df9519a2cd3979eade6a99d48e80e326615a1ba16fb0d5c014c51d23272ca5cf2257b2f318135ad6efef858f4d6d4479b
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/bin/flydata
CHANGED
@@ -28,37 +28,37 @@ class MysqlTableDef
|
|
28
28
|
end
|
29
29
|
|
30
30
|
TYPE_MAP_M2F = {
|
31
|
-
'bigint' => {type: 'int8'},
|
32
|
-
'binary' => {type: 'binary', override: PROC_override_varbinary},
|
33
|
-
'bit' => {type: 'bit'},
|
31
|
+
'bigint' => {type: 'int8', def_width: '20'},
|
32
|
+
'binary' => {type: 'binary', def_width: '1', override: PROC_override_varbinary},
|
33
|
+
'bit' => {type: 'bit', def_width: '1'},
|
34
34
|
'blob' => {type: 'varbinary(65535)'},
|
35
|
-
'bool' => {type: 'int1'},
|
36
|
-
'boolean' => {type: 'int1'},
|
37
|
-
'char' => {type: 'varchar', override: PROC_override_varchar},
|
35
|
+
'bool' => {type: 'int1', def_width: '1'},
|
36
|
+
'boolean' => {type: 'int1', def_width: '1'},
|
37
|
+
'char' => {type: 'varchar', def_width: '1', override: PROC_override_varchar},
|
38
38
|
'date' => {type: 'date'},
|
39
39
|
'datetime' => {type: 'datetime'},
|
40
|
-
'dec' => {type: 'numeric'},
|
41
|
-
'decimal' => {type: 'numeric'},
|
40
|
+
'dec' => {type: 'numeric', def_width: '10,0'},
|
41
|
+
'decimal' => {type: 'numeric', def_width: '10,0'},
|
42
42
|
'double' => {type: 'float8'},
|
43
43
|
'double precision' => {type: 'float8'},
|
44
44
|
'enum' => {type: 'enum'},
|
45
|
-
'fixed' => {type: 'numeric'},
|
45
|
+
'fixed' => {type: 'numeric', def_width: '10,0'},
|
46
46
|
'float' => {type: 'float4'},
|
47
|
-
'int' => {type: 'int4'},
|
48
|
-
'integer' => {type: 'int4'},
|
47
|
+
'int' => {type: 'int4', def_width: '11'},
|
48
|
+
'integer' => {type: 'int4', def_width: '11'},
|
49
49
|
'longblob' => {type: 'varbinary(4294967295)'},
|
50
50
|
'longtext' => {type: 'text'},
|
51
51
|
'mediumblob' => {type: 'varbinary(16777215)'},
|
52
|
-
'mediumint' => {type: 'int3'},
|
52
|
+
'mediumint' => {type: 'int3', def_width: '9'},
|
53
53
|
'mediumtext' => {type: 'text'},
|
54
|
-
'numeric' => {type: 'numeric'},
|
54
|
+
'numeric' => {type: 'numeric', def_width: '10,0'},
|
55
55
|
'set' => {type: 'set'},
|
56
|
-
'smallint' => {type: 'int2'},
|
56
|
+
'smallint' => {type: 'int2', def_width: '6'},
|
57
57
|
'text' => {type: 'text'},
|
58
58
|
'time' => {type: 'time'},
|
59
59
|
'timestamp' => {type: 'datetime'},
|
60
60
|
'tinyblob' => {type: 'varbinary(255)'},
|
61
|
-
'tinyint' => {type: 'int1'},
|
61
|
+
'tinyint' => {type: 'int1', def_width: '4'},
|
62
62
|
'tinytext' => {type: 'text'},
|
63
63
|
'varbinary' => {type: 'varbinary', override: PROC_override_varbinary},
|
64
64
|
'varchar' => {type: 'varchar', override: PROC_override_varchar},
|
@@ -69,6 +69,9 @@ class MysqlTableDef
|
|
69
69
|
flydata_type = type_hash[:type]
|
70
70
|
if /^#{mysql_type}\(|^#{mysql_type}$/.match(type)
|
71
71
|
ret_type = type.gsub(/^#{mysql_type}/, flydata_type)
|
72
|
+
if type_hash.has_key?(:def_width) && !/\(.+\)/.match(ret_type)
|
73
|
+
ret_type += "(#{type_hash[:def_width]})"
|
74
|
+
end
|
72
75
|
if type_hash[:override]
|
73
76
|
ret_type = type_hash[:override].call(ret_type, mysql_type, flydata_type)
|
74
77
|
end
|
@@ -199,6 +199,138 @@ describe MysqlTableDef do
|
|
199
199
|
end
|
200
200
|
end
|
201
201
|
end
|
202
|
+
|
203
|
+
describe '.convert_to_flydata_type' do
|
204
|
+
subject { described_class.convert_to_flydata_type(mysql_type) }
|
205
|
+
shared_examples "converting the mysql data type to the expected flydata type" do
|
206
|
+
# Use the context description as the value of "mysql_type"
|
207
|
+
# RSpec.current_example.meatadata[:example_group] => the shared_examples "converting the mysql data type to the expected flydata type"
|
208
|
+
# [:parent_example_group] => the context including the shared examples (e.g. context "bigint")
|
209
|
+
# [:description] => the name of the example group (e.g. "bigint")
|
210
|
+
let(:mysql_type) { RSpec.current_example.metadata[:example_group][:parent_example_group][:description] }
|
211
|
+
it do
|
212
|
+
expect(subject).to eq flydata_type
|
213
|
+
end
|
214
|
+
end
|
215
|
+
context "with no-width mysql data type" do
|
216
|
+
context "bigint" do
|
217
|
+
let(:flydata_type) { 'int8(20)' }
|
218
|
+
it_behaves_like "converting the mysql data type to the expected flydata type"
|
219
|
+
end
|
220
|
+
context "binary" do
|
221
|
+
let(:flydata_type) { 'binary(4)' }
|
222
|
+
it_behaves_like "converting the mysql data type to the expected flydata type"
|
223
|
+
end
|
224
|
+
context "bit" do
|
225
|
+
let(:flydata_type) { 'bit(1)' }
|
226
|
+
it_behaves_like "converting the mysql data type to the expected flydata type"
|
227
|
+
end
|
228
|
+
context "blob" do
|
229
|
+
let(:flydata_type) { 'varbinary(65535)' }
|
230
|
+
it_behaves_like "converting the mysql data type to the expected flydata type"
|
231
|
+
end
|
232
|
+
context "bool" do
|
233
|
+
let(:flydata_type) { 'int1(1)' }
|
234
|
+
it_behaves_like "converting the mysql data type to the expected flydata type"
|
235
|
+
end
|
236
|
+
context "boolean" do
|
237
|
+
let(:flydata_type) { 'int1(1)' }
|
238
|
+
it_behaves_like "converting the mysql data type to the expected flydata type"
|
239
|
+
end
|
240
|
+
context "char" do
|
241
|
+
let(:flydata_type) { 'varchar(3)' }
|
242
|
+
it_behaves_like "converting the mysql data type to the expected flydata type"
|
243
|
+
end
|
244
|
+
context "date" do
|
245
|
+
let(:flydata_type) { 'date' }
|
246
|
+
it_behaves_like "converting the mysql data type to the expected flydata type"
|
247
|
+
end
|
248
|
+
context "datetime" do
|
249
|
+
let(:flydata_type) { 'datetime' }
|
250
|
+
it_behaves_like "converting the mysql data type to the expected flydata type"
|
251
|
+
end
|
252
|
+
context "dec" do
|
253
|
+
let(:flydata_type) { 'numeric(10,0)' }
|
254
|
+
it_behaves_like "converting the mysql data type to the expected flydata type"
|
255
|
+
end
|
256
|
+
context "decimal" do
|
257
|
+
let(:flydata_type) { 'numeric(10,0)' }
|
258
|
+
it_behaves_like "converting the mysql data type to the expected flydata type"
|
259
|
+
end
|
260
|
+
context "double" do
|
261
|
+
let(:flydata_type) { 'float8' }
|
262
|
+
it_behaves_like "converting the mysql data type to the expected flydata type"
|
263
|
+
end
|
264
|
+
context "fixed" do
|
265
|
+
let(:flydata_type) { 'numeric(10,0)' }
|
266
|
+
it_behaves_like "converting the mysql data type to the expected flydata type"
|
267
|
+
end
|
268
|
+
context "float" do
|
269
|
+
let(:flydata_type) { 'float4' }
|
270
|
+
it_behaves_like "converting the mysql data type to the expected flydata type"
|
271
|
+
end
|
272
|
+
context "int" do
|
273
|
+
let(:flydata_type) { 'int4(11)' }
|
274
|
+
it_behaves_like "converting the mysql data type to the expected flydata type"
|
275
|
+
end
|
276
|
+
context "integer" do
|
277
|
+
let(:flydata_type) { 'int4(11)' }
|
278
|
+
it_behaves_like "converting the mysql data type to the expected flydata type"
|
279
|
+
end
|
280
|
+
context "longblob" do
|
281
|
+
let(:flydata_type) { 'varbinary(4294967295)' }
|
282
|
+
it_behaves_like "converting the mysql data type to the expected flydata type"
|
283
|
+
end
|
284
|
+
context "longtext" do
|
285
|
+
let(:flydata_type) { 'text' }
|
286
|
+
it_behaves_like "converting the mysql data type to the expected flydata type"
|
287
|
+
end
|
288
|
+
context "mediumblob" do
|
289
|
+
let(:flydata_type) { 'varbinary(16777215)' }
|
290
|
+
it_behaves_like "converting the mysql data type to the expected flydata type"
|
291
|
+
end
|
292
|
+
context "mediumint" do
|
293
|
+
let(:flydata_type) { 'int3(9)' }
|
294
|
+
it_behaves_like "converting the mysql data type to the expected flydata type"
|
295
|
+
end
|
296
|
+
context "mediumtext" do
|
297
|
+
let(:flydata_type) { 'text' }
|
298
|
+
it_behaves_like "converting the mysql data type to the expected flydata type"
|
299
|
+
end
|
300
|
+
context "numeric" do
|
301
|
+
let(:flydata_type) { 'numeric(10,0)' }
|
302
|
+
it_behaves_like "converting the mysql data type to the expected flydata type"
|
303
|
+
end
|
304
|
+
context "smallint" do
|
305
|
+
let(:flydata_type) { 'int2(6)' }
|
306
|
+
it_behaves_like "converting the mysql data type to the expected flydata type"
|
307
|
+
end
|
308
|
+
context "text" do
|
309
|
+
let(:flydata_type) { 'text' }
|
310
|
+
it_behaves_like "converting the mysql data type to the expected flydata type"
|
311
|
+
end
|
312
|
+
context "time" do
|
313
|
+
let(:flydata_type) { 'time' }
|
314
|
+
it_behaves_like "converting the mysql data type to the expected flydata type"
|
315
|
+
end
|
316
|
+
context "timestamp" do
|
317
|
+
let(:flydata_type) { 'datetime' }
|
318
|
+
it_behaves_like "converting the mysql data type to the expected flydata type"
|
319
|
+
end
|
320
|
+
context "tinyblob" do
|
321
|
+
let(:flydata_type) { 'varbinary(255)' }
|
322
|
+
it_behaves_like "converting the mysql data type to the expected flydata type"
|
323
|
+
end
|
324
|
+
context "tinyint" do
|
325
|
+
let(:flydata_type) { 'int1(4)' }
|
326
|
+
it_behaves_like "converting the mysql data type to the expected flydata type"
|
327
|
+
end
|
328
|
+
context "tinytext" do
|
329
|
+
let(:flydata_type) { 'text' }
|
330
|
+
it_behaves_like "converting the mysql data type to the expected flydata type"
|
331
|
+
end
|
332
|
+
end
|
333
|
+
end
|
202
334
|
end
|
203
335
|
|
204
336
|
end
|
data/flydata.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: flydata 0.
|
5
|
+
# stub: flydata 0.3.0 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "flydata"
|
9
|
-
s.version = "0.
|
9
|
+
s.version = "0.3.0"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib"]
|
13
13
|
s.authors = ["Koichi Fujikawa", "Masashi Miyazaki", "Matthew Luu", "Mak Inada", "Sriram NS"]
|
14
|
-
s.date = "2015-
|
14
|
+
s.date = "2015-02-11"
|
15
15
|
s.description = "FlyData Agent"
|
16
16
|
s.email = "sysadmin@flydata.com"
|
17
17
|
s.executables = ["fdmysqldump", "flydata", "serverinfo"]
|
@@ -93,6 +93,7 @@ Gem::Specification.new do |s|
|
|
93
93
|
"lib/flydata/compatibility_check.rb",
|
94
94
|
"lib/flydata/credentials.rb",
|
95
95
|
"lib/flydata/cron.rb",
|
96
|
+
"lib/flydata/errors.rb",
|
96
97
|
"lib/flydata/fluent-plugins/idle_event_detector.rb",
|
97
98
|
"lib/flydata/fluent-plugins/in_mysql_binlog_flydata.rb",
|
98
99
|
"lib/flydata/fluent-plugins/mysql/alter_table_query_handler.rb",
|
@@ -149,7 +150,7 @@ Gem::Specification.new do |s|
|
|
149
150
|
]
|
150
151
|
s.homepage = "http://flydata.com/"
|
151
152
|
s.licenses = ["All right reserved."]
|
152
|
-
s.rubygems_version = "2.
|
153
|
+
s.rubygems_version = "2.4.3"
|
153
154
|
s.summary = "FlyData Agent"
|
154
155
|
|
155
156
|
if s.respond_to? :specification_version then
|
data/lib/flydata/cli.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'slop'
|
2
2
|
require_relative 'command_logger'
|
3
|
+
require_relative 'errors'
|
3
4
|
|
4
5
|
module Flydata
|
5
6
|
class Cli
|
@@ -42,15 +43,16 @@ module Flydata
|
|
42
43
|
cmd_obj = cmd_cls.new(options)
|
43
44
|
sub_cmd ? cmd_obj.send(sub_cmd,*@args) : cmd_obj.run(*@args)
|
44
45
|
else
|
45
|
-
$stderr.puts usage_text
|
46
|
+
$stderr.puts usage_text
|
46
47
|
return
|
47
48
|
end
|
48
49
|
rescue => e
|
49
50
|
#raise e
|
50
|
-
$stderr.puts "! #{e.to_s}"
|
51
51
|
$stderr.puts
|
52
52
|
$stderr.puts
|
53
|
-
$stderr.puts
|
53
|
+
$stderr.puts "!! #{e.to_s}"
|
54
|
+
$stderr.puts
|
55
|
+
$stderr.puts e.respond_to?(:description) ? e.description : AgentError.description
|
54
56
|
log_error_with_backtrace('Error occured during command.', {error: e, args: @args})
|
55
57
|
raise e if FLYDATA_DEBUG
|
56
58
|
exit 1
|
@@ -93,8 +93,13 @@ What's next?
|
|
93
93
|
elsif has_registered_redshift_mysql_data_entries?
|
94
94
|
de = retrieve_data_entries.first
|
95
95
|
if File.exists?(Flydata::FileUtil::SyncFileManager.new(de).binlog_path)
|
96
|
-
Flydata::Command::Sender.new
|
97
|
-
|
96
|
+
sender = Flydata::Command::Sender.new
|
97
|
+
if sender.process_exist?
|
98
|
+
sender.stop(quiet: true)
|
99
|
+
true
|
100
|
+
else
|
101
|
+
false
|
102
|
+
end
|
98
103
|
else
|
99
104
|
last_message = INITIAL_SYNC_MESSAGE_TEMPLATE
|
100
105
|
false
|
data/lib/flydata/command/sync.rb
CHANGED
@@ -13,9 +13,11 @@ require 'flydata-core/table_def'
|
|
13
13
|
|
14
14
|
module Flydata
|
15
15
|
module Command
|
16
|
+
|
16
17
|
class Sync < Base
|
17
18
|
include Helpers
|
18
19
|
INSERT_PROGRESS_INTERVAL = 1000
|
20
|
+
SERVER_DATA_PROCESSING_TIMEOUT = 600 # seconds
|
19
21
|
|
20
22
|
# for dump.pos file
|
21
23
|
STATUS_PARSING = 'PARSING'
|
@@ -102,8 +104,21 @@ module Flydata
|
|
102
104
|
de = retrieve_sync_data_entry unless de
|
103
105
|
de = load_sync_info(de,tables)
|
104
106
|
validate_initial_sync_status(de, tables)
|
105
|
-
|
106
|
-
|
107
|
+
begin
|
108
|
+
flush_buffer_and_stop unless @initial_sync
|
109
|
+
sync_mysql_to_redshift(de)
|
110
|
+
rescue ServerDataProcessingTimeout => e
|
111
|
+
ee = ServerDataProcessingTimeout.new("Delayed Data Processing")
|
112
|
+
ee.description = <<EOS
|
113
|
+
Data processing is taking more than expected. Please contact support@flydata.com to check the system status.
|
114
|
+
Once checked, you can resume sync with the following command.
|
115
|
+
|
116
|
+
flydata start
|
117
|
+
|
118
|
+
EOS
|
119
|
+
ee.set_backtrace e.backtrace
|
120
|
+
raise ee
|
121
|
+
end
|
107
122
|
complete
|
108
123
|
end
|
109
124
|
|
@@ -114,7 +129,17 @@ module Flydata
|
|
114
129
|
end
|
115
130
|
|
116
131
|
def flush
|
117
|
-
|
132
|
+
begin
|
133
|
+
flush_buffer_and_stop
|
134
|
+
rescue ServerDataProcessingTimeout => e
|
135
|
+
ee = ServerDataProcessingTimeout.new("Delayed Data Processing")
|
136
|
+
ee.description = <<EOS
|
137
|
+
Data processing is taking more than expected. Please contact support@flydata.com to check the system status.
|
138
|
+
|
139
|
+
EOS
|
140
|
+
ee.set_backtrace e.backtrace
|
141
|
+
raise ee
|
142
|
+
end
|
118
143
|
log_info_stdout("Buffers have been flushed and the sender process has been stopped.")
|
119
144
|
end
|
120
145
|
|
@@ -136,7 +161,20 @@ module Flydata
|
|
136
161
|
all_tables = de['mysql_data_entry_preference']['tables']
|
137
162
|
verify_input_tables(tables, all_tables)
|
138
163
|
|
139
|
-
|
164
|
+
begin
|
165
|
+
wait_for_server_buffer(SERVER_DATA_PROCESSING_TIMEOUT)
|
166
|
+
rescue ServerDataProcessingTimeout => e
|
167
|
+
ee = ServerDataProcessingTimeout.new("Delayed Data Processing")
|
168
|
+
ee.description = <<EOS
|
169
|
+
Data processing is taking more than expected. Please contact support@flydata.com to check the system status.
|
170
|
+
Once checked, you can continue sync reset with the following command
|
171
|
+
|
172
|
+
flydata sync:reset #{tables.empty? ? '' : tables.join(" ")}
|
173
|
+
|
174
|
+
EOS
|
175
|
+
ee.set_backtrace e.backtrace
|
176
|
+
raise ee
|
177
|
+
end
|
140
178
|
cleanup_sync_server(de, tables) unless opts.client?
|
141
179
|
sync_fm = Flydata::FileUtil::SyncFileManager.new(de)
|
142
180
|
delete_files = [
|
@@ -158,25 +196,41 @@ module Flydata
|
|
158
196
|
log_info_stdout("Reset completed successfully.")
|
159
197
|
end
|
160
198
|
|
161
|
-
def wait_for_server_buffer
|
199
|
+
def wait_for_server_buffer(timeout = 0)
|
200
|
+
start_time = Time.now
|
162
201
|
log_info_stdout("Waiting for the server buffer to get empty.")
|
202
|
+
prev_message =nil
|
163
203
|
while (status = check) && (status['state'] == 'processing')
|
204
|
+
prev_message = status['message']
|
205
|
+
if timeout > 0 && Time.now - start_time > timeout
|
206
|
+
raise ServerDataProcessingTimeout.new
|
207
|
+
end
|
164
208
|
print_progress(status)
|
165
209
|
sleep 10
|
166
210
|
end
|
167
211
|
end
|
168
212
|
|
169
|
-
def wait_for_server_data_processing
|
213
|
+
def wait_for_server_data_processing(timeout = 0)
|
170
214
|
state = :PROCESS
|
215
|
+
start_time = Time.now
|
171
216
|
log_info_stdout("Uploading data to Redshift...")
|
172
217
|
sleep 10
|
173
218
|
status = nil
|
219
|
+
prev_message =nil
|
174
220
|
while (status = check)
|
175
221
|
if state == :PROCESS && status['state'] == 'uploading'
|
176
222
|
log_info_stdout(" -> Done")
|
177
223
|
state = :UPLOAD
|
178
224
|
log_info_stdout("Finishing data upload...")
|
179
225
|
end
|
226
|
+
if status['message'] != prev_message
|
227
|
+
# making some progress. Reset timer
|
228
|
+
start_time = Time.now
|
229
|
+
end
|
230
|
+
prev_message = status['message']
|
231
|
+
if timeout > 0 && Time.now - start_time > timeout
|
232
|
+
raise ServerDataProcessingTimeout.new
|
233
|
+
end
|
180
234
|
print_progress(status)
|
181
235
|
sleep 10
|
182
236
|
end
|
@@ -606,7 +660,7 @@ EOM
|
|
606
660
|
return unless dump_pos_info[:status] == STATUS_WAITING
|
607
661
|
binlog_pos = dump_pos_info[:binlog_pos]
|
608
662
|
|
609
|
-
wait_for_server_data_processing
|
663
|
+
wait_for_server_data_processing(SERVER_DATA_PROCESSING_TIMEOUT)
|
610
664
|
tables = de['mysql_data_entry_preference']['tables']
|
611
665
|
sync_fm.save_table_binlog_pos(tables, binlog_pos)
|
612
666
|
sync_fm.save_dump_pos(STATUS_COMPLETE, '', -1, binlog_pos)
|
@@ -670,7 +724,7 @@ Thank you for using FlyData!
|
|
670
724
|
def flush_buffer_and_stop
|
671
725
|
sender = Flydata::Command::Sender.new
|
672
726
|
sender.flush_client_buffer
|
673
|
-
wait_for_server_data_processing
|
727
|
+
wait_for_server_data_processing(SERVER_DATA_PROCESSING_TIMEOUT)
|
674
728
|
sender.stop(quiet: true)
|
675
729
|
end
|
676
730
|
end
|
@@ -137,8 +137,8 @@ module Flydata
|
|
137
137
|
end
|
138
138
|
end
|
139
139
|
|
140
|
-
def
|
141
|
-
sys_var_to_check = {'@@binlog_format'=>'ROW', '@@binlog_checksum'=>'NONE', '@@log_bin_use_v1_row_events'=>1}
|
140
|
+
def check_mysql_parameters_compat
|
141
|
+
sys_var_to_check = {'@@binlog_format'=>'ROW', '@@binlog_checksum'=>'NONE', '@@log_bin_use_v1_row_events'=>1, '@@log_slave_updates'=>1}
|
142
142
|
errors={}
|
143
143
|
|
144
144
|
client = Mysql2::Client.new(@db_opts)
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Flydata
|
2
|
+
|
3
|
+
class AgentError < StandardError
|
4
|
+
def self.description
|
5
|
+
text = <<-EOM
|
6
|
+
Fix the issue and try again. If the problem continues, please contact support@flydata.com
|
7
|
+
|
8
|
+
EOM
|
9
|
+
|
10
|
+
flydata_log = File.join(FLYDATA_HOME, 'flydata.log')
|
11
|
+
if File.exists?(flydata_log)
|
12
|
+
text += <<-EOM
|
13
|
+
Also check the Agent log.
|
14
|
+
Log path: #{flydata_log}
|
15
|
+
EOM
|
16
|
+
end
|
17
|
+
text
|
18
|
+
end
|
19
|
+
|
20
|
+
def description
|
21
|
+
if instance_variable_defined?(:@description) && @description
|
22
|
+
@description
|
23
|
+
else
|
24
|
+
self.class.description
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_writer :description
|
29
|
+
end
|
30
|
+
|
31
|
+
class ServerDataProcessingTimeout < AgentError
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -3,6 +3,7 @@ require_relative 'binlog_record_handler'
|
|
3
3
|
module Mysql
|
4
4
|
class DmlRecordHandler < BinlogRecordHandler
|
5
5
|
ROW = :row
|
6
|
+
OLD = :old
|
6
7
|
INTEGER_TYPES = {'TINY' => 1,
|
7
8
|
'SHORT' => 2,
|
8
9
|
'INT24' => 3,
|
@@ -36,7 +37,8 @@ module Mysql
|
|
36
37
|
|
37
38
|
def emit_update(record)
|
38
39
|
emit_rows(:update, record) do |row|
|
39
|
-
|
40
|
+
# For update, row has two arrays (old and new values)
|
41
|
+
{ OLD => row.first, ROW => row.last }
|
40
42
|
end
|
41
43
|
end
|
42
44
|
|
@@ -44,10 +46,13 @@ module Mysql
|
|
44
46
|
emit_record(type, record) do |opt|
|
45
47
|
table_name = record['table_name']
|
46
48
|
records = record["rows"].collect do |row|
|
47
|
-
|
48
|
-
|
49
|
+
row_values = { ROW => row }
|
50
|
+
row_values = yield(row) if block_given? # Give the caller a chance to generate the correct row values
|
51
|
+
row_types = row_values.keys
|
52
|
+
row_kinds = row_types.inject({}) {|m, k| m[k] = convert_to_flydata_row_format(table_name, row_values[k]); m}
|
53
|
+
encode_signless_integer(row_kinds, record["columns"], row_types)
|
54
|
+
row_kinds
|
49
55
|
end
|
50
|
-
encode_signless_integer(records, record["columns"])
|
51
56
|
records
|
52
57
|
end
|
53
58
|
end
|
@@ -70,19 +75,19 @@ module Mysql
|
|
70
75
|
end
|
71
76
|
end
|
72
77
|
|
73
|
-
def encode_signless_integer(
|
74
|
-
|
75
|
-
record[
|
78
|
+
def encode_signless_integer(record, column_types, row_types)
|
79
|
+
row_types.each do |row_type|
|
80
|
+
record[row_type].keys.each do |position|
|
76
81
|
index = position.to_i - 1
|
77
82
|
column_type = column_types[index]
|
78
83
|
if INTEGER_TYPES.keys.include?(column_type)
|
79
84
|
# It's a signless integer.
|
80
|
-
intval = record[
|
85
|
+
intval = record[row_type][position]
|
81
86
|
next unless (intval.kind_of?(Numeric) || intval =~ /^-?[\d]+$/)
|
82
87
|
width = INTEGER_TYPES[column_type] * 2 # * 2 because a single byte requires two characters (e.g. ff)
|
83
88
|
signless_val = SIGNLESS_INTEGER_PREFIX
|
84
89
|
signless_val += sprintf("%0#{width}x", intval).gsub(/\.\.f/, 'f' * width).slice(-width..-1)
|
85
|
-
record[
|
90
|
+
record[row_type][position] = signless_val
|
86
91
|
end
|
87
92
|
end
|
88
93
|
end
|
data/lib/flydata/helpers.rb
CHANGED
@@ -12,25 +12,9 @@ module Flydata
|
|
12
12
|
[klass, method]
|
13
13
|
end
|
14
14
|
|
15
|
-
def usage_text
|
15
|
+
def usage_text
|
16
16
|
text = ""
|
17
17
|
|
18
|
-
if err
|
19
|
-
text += <<-EOM
|
20
|
-
Fix the issue and try again. If the problem continues, please contact support@flydata.com
|
21
|
-
|
22
|
-
EOM
|
23
|
-
|
24
|
-
flydata_log = File.join(FLYDATA_HOME, 'flydata.log')
|
25
|
-
if File.exists?(flydata_log)
|
26
|
-
text += <<-EOM
|
27
|
-
Also check the Agent log.
|
28
|
-
Log path: #{flydata_log}
|
29
|
-
EOM
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
text += ""
|
34
18
|
text += '-' * 64
|
35
19
|
text += "\n"
|
36
20
|
text += <<-EOM
|
data/spec/flydata/cli_spec.rb
CHANGED
@@ -27,7 +27,7 @@ module Flydata
|
|
27
27
|
context 'with options' do
|
28
28
|
let(:options) { %w(-a --host-name localhost) }
|
29
29
|
it 'returns with an error' do
|
30
|
-
expect($stderr).to receive(:puts).with('
|
30
|
+
expect($stderr).to receive(:puts).with('!! Unknown options -a, --host-name').once
|
31
31
|
allow($stderr).to receive(:puts)
|
32
32
|
|
33
33
|
expect{ subject.run }.to terminate.with_code(1)
|
@@ -62,7 +62,7 @@ module Flydata
|
|
62
62
|
context 'with optionss' do
|
63
63
|
let(:options) { %w(-a --host-name localhost) }
|
64
64
|
it 'returns an error' do
|
65
|
-
expect($stderr).to receive(:puts).with('
|
65
|
+
expect($stderr).to receive(:puts).with('!! Unknown options -a, --host-name').once
|
66
66
|
allow($stderr).to receive(:puts)
|
67
67
|
|
68
68
|
expect{ subject.run }.to terminate.with_code(1)
|
@@ -164,9 +164,10 @@ EOT
|
|
164
164
|
rows = [rows] unless rows.kind_of?(Array)
|
165
165
|
@seq ||= TEST_SEQUENCE_NUM
|
166
166
|
records = rows.collect do |row|
|
167
|
+
record = row.kind_of?(Hash) && row.keys.include?(:row) ? row : { row: row }
|
167
168
|
@seq += 1
|
168
|
-
{ :type=>type, :table_name=>table, :respect_order=>true,
|
169
|
-
:src_pos=>"#{binlog_file}\t#{position}", :table_rev=>1
|
169
|
+
record.merge({ :type=>type, :table_name=>table, :respect_order=>true,
|
170
|
+
:seq=>@seq, :src_pos=>"#{binlog_file}\t#{position}", :table_rev=>1 })
|
170
171
|
end
|
171
172
|
expect_emitted_records(event, records)
|
172
173
|
end
|
@@ -289,21 +290,30 @@ EOT
|
|
289
290
|
context 'when received update event' do
|
290
291
|
it do
|
291
292
|
expect_emitted_records_with_rows(update_event, :update, TEST_TABLE, 2528, "mysql-bin.000048",
|
292
|
-
[{"1"=>"0SL00000001", "2"=>"
|
293
|
+
[{old:{"1"=>"0SL00000001", "2"=>"foo"},
|
294
|
+
row:{"1"=>"0SL00000001", "2"=>"wow"}},
|
295
|
+
{old:{"1"=>"0SL00000003", "2"=>"hoge"},
|
296
|
+
row:{"1"=>"0SL00000003", "2"=>"fuga"}}])
|
293
297
|
end
|
294
298
|
end
|
295
299
|
|
296
300
|
context 'when received update event with two byte utf8 chars' do
|
297
301
|
it do
|
298
302
|
expect_emitted_records_with_rows(update_two_byte_event, :update, TEST_TABLE, 2528, "mysql-bin.000048",
|
299
|
-
[{"1"=>"0SL00000001", "2"=>"
|
303
|
+
[{old:{"1"=>"0SL00000001", "2"=>"føø"},
|
304
|
+
row:{"1"=>"0SL00000001", "2"=>"∑ø∑"}},
|
305
|
+
{old:{"1"=>"0SL00000003", "2"=>"høgé"},
|
306
|
+
row:{"1"=>"0SL00000003", "2"=>"fügå"}}])
|
300
307
|
end
|
301
308
|
end
|
302
309
|
|
303
310
|
context 'when received update event with three byte utf8 chars' do
|
304
311
|
it do
|
305
312
|
expect_emitted_records_with_rows(update_three_byte_event, :update, TEST_TABLE, 2528, "mysql-bin.000048",
|
306
|
-
[{"1"=>"0SL00000001", "2"=>"
|
313
|
+
[{old:{"1"=>"0SL00000001", "2"=>"富无无"},
|
314
|
+
row:{"1"=>"0SL00000001", "2"=>"很兴奋"}},
|
315
|
+
{old:{"1"=>"0SL00000003", "2"=>"切实切实"},
|
316
|
+
row:{"1"=>"0SL00000003", "2"=>"興奮虎"}}])
|
307
317
|
end
|
308
318
|
end
|
309
319
|
|
@@ -317,7 +327,7 @@ EOT
|
|
317
327
|
table_rev: 2, # increment revision
|
318
328
|
seq: 2,
|
319
329
|
actions: [{
|
320
|
-
action: :add_column, column: "sum", :type=>'int4', :query=>'add column sum integer'}],
|
330
|
+
action: :add_column, column: "sum", :type=>'int4(11)', :query=>'add column sum integer'}],
|
321
331
|
})
|
322
332
|
end
|
323
333
|
end
|
@@ -395,7 +405,10 @@ EOT
|
|
395
405
|
it 'logs a warning and emits FET with a blank binlog file name, when it receives an update event' do
|
396
406
|
expect($log).to receive(:warn).with("Binlog file name is empty. Rotate event not received!").once
|
397
407
|
expect_emitted_records_with_rows(update_event, :update, TEST_TABLE, 2528, "",
|
398
|
-
[{"1"=>"0SL00000001", "2"=>"
|
408
|
+
[{old:{"1"=>"0SL00000001", "2"=>"foo"},
|
409
|
+
row:{"1"=>"0SL00000001", "2"=>"wow"}},
|
410
|
+
{old:{"1"=>"0SL00000003", "2"=>"hoge"},
|
411
|
+
row:{"1"=>"0SL00000003", "2"=>"fuga"}}])
|
399
412
|
end
|
400
413
|
|
401
414
|
it 'logs a warning emits FET with a blank binlog file name, when it receives a delete event' do
|
@@ -409,7 +422,10 @@ EOT
|
|
409
422
|
expect_emitted_records_with_rows(insert_event, :insert, TEST_TABLE, 628, "",
|
410
423
|
[{"1"=>"0SL00000001", "2"=>"foo"}, {"1"=>"0SL00000002", "2"=>"var"}, {"1"=>"0SL00000003", "2"=>"hoge"}])
|
411
424
|
expect_emitted_records_with_rows(update_event, :update, TEST_TABLE, 2528, "",
|
412
|
-
[{"1"=>"0SL00000001", "2"=>"
|
425
|
+
[{old:{"1"=>"0SL00000001", "2"=>"foo"},
|
426
|
+
row:{"1"=>"0SL00000001", "2"=>"wow"}},
|
427
|
+
{old:{"1"=>"0SL00000003", "2"=>"hoge"},
|
428
|
+
row:{"1"=>"0SL00000003", "2"=>"fuga"}}])
|
413
429
|
expect_emitted_records_with_rows(insert_event, :insert, TEST_TABLE, 628, "",
|
414
430
|
[{"1"=>"0SL00000001", "2"=>"foo"}, {"1"=>"0SL00000002", "2"=>"var"}, {"1"=>"0SL00000003", "2"=>"hoge"}])
|
415
431
|
expect_emitted_records_with_rows(delete_event, :delete, TEST_TABLE, 5324, "",
|
@@ -475,7 +491,7 @@ EOT
|
|
475
491
|
event = update_event
|
476
492
|
event['table_name'] = TEST_TABLE_APPEND_ONLY
|
477
493
|
expect_emitted_records_with_rows(event, :update, TEST_TABLE_APPEND_ONLY, 2528, "mysql-bin.000048",
|
478
|
-
[{"1"=>"0SL00000001", "2"=>"wow"}, {"1"=>"0SL00000003", "2"=>"fuga"}])
|
494
|
+
[{old:{"1"=>"0SL00000001", "2"=>"foo"}, row:{"1"=>"0SL00000001", "2"=>"wow"}}, {old:{"1"=>"0SL00000003", "2"=>"hoge"}, row:{"1"=>"0SL00000003", "2"=>"fuga"}}])
|
479
495
|
end
|
480
496
|
|
481
497
|
it 'emits a record when it receives a delete event for non-append only table' do
|
@@ -136,7 +136,7 @@ describe 'MysqlAlterTableParser' do
|
|
136
136
|
},{
|
137
137
|
action: :add_column,
|
138
138
|
column: "value2",
|
139
|
-
type: "int4",
|
139
|
+
type: "int4(11)",
|
140
140
|
auto_increment: true,
|
141
141
|
query: "add (value1 varchar(26) not null default 'flydata', value2 int auto_increment)"
|
142
142
|
}]
|
@@ -160,7 +160,7 @@ describe 'MysqlAlterTableParser' do
|
|
160
160
|
},{
|
161
161
|
action: :add_column,
|
162
162
|
column: "value2",
|
163
|
-
type: "int4",
|
163
|
+
type: "int4(11)",
|
164
164
|
auto_increment: true,
|
165
165
|
query: "add (`value1` varchar(26) not null default 'flydata', `value2` int auto_increment)"
|
166
166
|
}]
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flydata
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Koichi Fujikawa
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2015-
|
15
|
+
date: 2015-02-11 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: rest-client
|
@@ -496,6 +496,7 @@ files:
|
|
496
496
|
- lib/flydata/compatibility_check.rb
|
497
497
|
- lib/flydata/credentials.rb
|
498
498
|
- lib/flydata/cron.rb
|
499
|
+
- lib/flydata/errors.rb
|
499
500
|
- lib/flydata/fluent-plugins/idle_event_detector.rb
|
500
501
|
- lib/flydata/fluent-plugins/in_mysql_binlog_flydata.rb
|
501
502
|
- lib/flydata/fluent-plugins/mysql/alter_table_query_handler.rb
|
@@ -569,7 +570,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
569
570
|
version: '0'
|
570
571
|
requirements: []
|
571
572
|
rubyforge_project:
|
572
|
-
rubygems_version: 2.
|
573
|
+
rubygems_version: 2.4.3
|
573
574
|
signing_key:
|
574
575
|
specification_version: 4
|
575
576
|
summary: FlyData Agent
|