flydata 0.5.7 → 0.5.8
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.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/flydata-core/lib/flydata-core/mysql/compatibility_checker.rb +3 -5
- data/flydata-core/lib/flydata-core/mysql/config.rb +3 -0
- data/flydata-core/spec/mysql/config_spec.rb +5 -5
- data/flydata.gemspec +3 -3
- data/lib/flydata/command/sender.rb +8 -2
- data/lib/flydata/command/sync.rb +102 -90
- data/lib/flydata/helper/scheduler.rb +11 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4c79a1c7705cdd2112d4fd3465f311bf31583471
|
4
|
+
data.tar.gz: b5a6e9d153bbf84dca5d582de5bc5df460d01a96
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 30e4e6fee11a8ba1b76f0e7c14e05f5d723a90655fc0e4cc0e42724f6edcef4d73514cf5d970becf3178a224172a9aa33d4fbe1bbbf27e4a0c0b73419b15fe34
|
7
|
+
data.tar.gz: 9ae07ffd9eb356a7947f5c8c1331f48181cc1ac8f76392f5c2d92122f4cfff38ef6f2d94e4ac001914bbb1d537423ff6ba060650d9776154b8b865285601cb77
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.5.
|
1
|
+
0.5.8
|
@@ -1,15 +1,13 @@
|
|
1
1
|
require 'flydata-core/errors'
|
2
|
+
require 'flydata-core/mysql/config'
|
2
3
|
require 'mysql2'
|
3
4
|
|
4
5
|
module FlydataCore
|
5
6
|
module Mysql
|
6
7
|
class CompatibilityChecker
|
7
8
|
def initialize(option = {})
|
8
|
-
|
9
|
-
|
10
|
-
option[:host] = '127.0.0.1' # avoid socket access which Agent never uses
|
11
|
-
end
|
12
|
-
@option = option || {}
|
9
|
+
option ||= {}
|
10
|
+
@option = option.merge FlydataCore::Mysql::Config.build_mysql_db_opts(option)
|
13
11
|
end
|
14
12
|
|
15
13
|
def do_check(option = @option, &block)
|
@@ -19,7 +19,7 @@ module FlydataCore
|
|
19
19
|
|
20
20
|
context 'with basic conf' do
|
21
21
|
it { is_expected.to eq(
|
22
|
-
host: '
|
22
|
+
host: '127.0.0.1',
|
23
23
|
port: 1234,
|
24
24
|
username: 'testuser',
|
25
25
|
password: 'password',
|
@@ -33,7 +33,7 @@ module FlydataCore
|
|
33
33
|
context 'when ssl_ca is not empty' do
|
34
34
|
let(:conf) { base_conf.merge('ssl_ca' => 'test_path') }
|
35
35
|
it { is_expected.to eq(
|
36
|
-
host: '
|
36
|
+
host: '127.0.0.1',
|
37
37
|
port: 1234,
|
38
38
|
username: 'testuser',
|
39
39
|
password: 'password',
|
@@ -47,7 +47,7 @@ module FlydataCore
|
|
47
47
|
context 'when ssl_ca is empty' do
|
48
48
|
let(:conf) { base_conf.merge('ssl_ca' => '') }
|
49
49
|
it { is_expected.to eq(
|
50
|
-
host: '
|
50
|
+
host: '127.0.0.1',
|
51
51
|
port: 1234,
|
52
52
|
username: 'testuser',
|
53
53
|
password: 'password',
|
@@ -62,7 +62,7 @@ module FlydataCore
|
|
62
62
|
context 'when ssl_cipher is not empty' do
|
63
63
|
let(:conf) { base_conf.merge('ssl_cipher' => 'AAAA::BBBB') }
|
64
64
|
it { is_expected.to eq(
|
65
|
-
host: '
|
65
|
+
host: '127.0.0.1',
|
66
66
|
port: 1234,
|
67
67
|
username: 'testuser',
|
68
68
|
password: 'password',
|
@@ -76,7 +76,7 @@ module FlydataCore
|
|
76
76
|
context 'when ssl_cipher is empty' do
|
77
77
|
let(:conf) { base_conf.merge('ssl_cipher' => '') }
|
78
78
|
it { is_expected.to eq(
|
79
|
-
host: '
|
79
|
+
host: '127.0.0.1',
|
80
80
|
port: 1234,
|
81
81
|
username: 'testuser',
|
82
82
|
password: 'password',
|
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.
|
5
|
+
# stub: flydata 0.5.8 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "flydata"
|
9
|
-
s.version = "0.5.
|
9
|
+
s.version = "0.5.8"
|
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-09-
|
14
|
+
s.date = "2015-09-25"
|
15
15
|
s.description = "FlyData Agent"
|
16
16
|
s.email = "sysadmin@flydata.com"
|
17
17
|
s.executables = ["fdmysqldump", "flydata", "serverinfo"]
|
@@ -23,8 +23,14 @@ module Flydata
|
|
23
23
|
end
|
24
24
|
|
25
25
|
if agent_locked?
|
26
|
-
|
27
|
-
|
26
|
+
log_info_stdout("Agent was not shut down properly. Agent will check the status and fix itself if necessary.")
|
27
|
+
repair_opts = Flydata::Command::Sync.slop_repair
|
28
|
+
repair_opts.parse!(["-y"])
|
29
|
+
sync = Flydata::Command::Sync.new(repair_opts)
|
30
|
+
sync.send(:_repair) # call internal method to bypass command lock
|
31
|
+
if agent_locked?
|
32
|
+
raise "Agent was not able to recover from the previous unexpected shutdown. Please contact support@lyfdata.com to resolve the issue."
|
33
|
+
end
|
28
34
|
end
|
29
35
|
|
30
36
|
# Ends orphan_proceses if there is any
|
data/lib/flydata/command/sync.rb
CHANGED
@@ -310,7 +310,106 @@ EOS
|
|
310
310
|
end
|
311
311
|
run_exclusive :fix_binlogpos
|
312
312
|
|
313
|
+
# Command: flydata sync:repair
|
314
|
+
# - Arguments
|
315
|
+
def self.slop_repair
|
316
|
+
Slop.new do
|
317
|
+
on 'y', 'yes', 'Skip command prompt assuming yes to all questions. Use this for batch operation.'
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
313
321
|
def repair
|
322
|
+
_repair
|
323
|
+
end
|
324
|
+
run_exclusive :repair
|
325
|
+
|
326
|
+
def check(options = {})
|
327
|
+
status, pos_mismatch_tables, gap_tables = _check(options)
|
328
|
+
|
329
|
+
if status.include? :OK
|
330
|
+
message = "\nNo errors are found. Sync is clean.\n"
|
331
|
+
else
|
332
|
+
message = "\nFollowing errors are found.\n"
|
333
|
+
|
334
|
+
if status.include? :STUCK_AT_PROCESS
|
335
|
+
message += " - Data is stuck while processing\n"
|
336
|
+
end
|
337
|
+
if status.include? :STUCK_AT_UPLOAD
|
338
|
+
message += " - Data is stuck while uploading\n"
|
339
|
+
end
|
340
|
+
if status.include? :ABNORMAL_SHUTDOWN
|
341
|
+
message += " - Agent was not shut down correctly\n"
|
342
|
+
end
|
343
|
+
if gap_tables
|
344
|
+
message += " - Sync data is missing for the following table(s)\n"
|
345
|
+
gap_tables.each do |bt|
|
346
|
+
message += " table:#{bt[:table]}\n"
|
347
|
+
end
|
348
|
+
message += "\n"
|
349
|
+
end
|
350
|
+
if pos_mismatch_tables
|
351
|
+
message += " - Incorrect table position(s)\n"
|
352
|
+
pos_mismatch_tables.each do |bt|
|
353
|
+
message += " table:#{bt[:table]}, agent position:#{bt[:agent_seq] ? bt[:agent_seq] : '(missing)'}, server position:#{bt[:server_seq]}\n"
|
354
|
+
end
|
355
|
+
message += "\n"
|
356
|
+
end
|
357
|
+
end
|
358
|
+
log_info_stdout message
|
359
|
+
end
|
360
|
+
run_exclusive :check
|
361
|
+
|
362
|
+
private
|
363
|
+
|
364
|
+
def _check(options = {})
|
365
|
+
options[:stop_agent] ||= false
|
366
|
+
|
367
|
+
set_current_tables
|
368
|
+
sender = Flydata::Command::Sender.new
|
369
|
+
start_process = !options[:stop_agent] && sender.process_exist?
|
370
|
+
pos_mismatch_tables = nil
|
371
|
+
gap_tables = nil
|
372
|
+
data_stuck_at = nil
|
373
|
+
abnormal_shutdown = false
|
374
|
+
begin
|
375
|
+
begin
|
376
|
+
flush_buffer_and_stop(@full_tables, force: false, timeout: 55)
|
377
|
+
rescue ServerDataProcessingTimeout => e
|
378
|
+
data_stuck_at = e.state
|
379
|
+
end
|
380
|
+
|
381
|
+
# Agent is stopped but locked. There was an abnormal shutdown.
|
382
|
+
abnormal_shutdown = sender.agent_locked?
|
383
|
+
table_status_hash = get_table_status(@full_tables)
|
384
|
+
pos_mismatch_tables = check_position_files(table_status_hash)
|
385
|
+
gap_tables = check_gaps(table_status_hash)
|
386
|
+
ensure
|
387
|
+
Flydata::Command::Sender.new.start(quiet: true) if start_process
|
388
|
+
end
|
389
|
+
|
390
|
+
status = []
|
391
|
+
if data_stuck_at == :PROCESS
|
392
|
+
status << :STUCK_AT_PROCESS
|
393
|
+
end
|
394
|
+
if data_stuck_at == :UPLOAD
|
395
|
+
status << :STUCK_AT_UPLOAD
|
396
|
+
end
|
397
|
+
if gap_tables
|
398
|
+
status << :TABLE_GAPS
|
399
|
+
end
|
400
|
+
if pos_mismatch_tables
|
401
|
+
status << :TABLE_POS_MISMATCH
|
402
|
+
end
|
403
|
+
if abnormal_shutdown
|
404
|
+
status << :ABNORMAL_SHUTDOWN
|
405
|
+
end
|
406
|
+
if status.empty?
|
407
|
+
status << :OK
|
408
|
+
end
|
409
|
+
[status, pos_mismatch_tables, gap_tables, table_status_hash]
|
410
|
+
end
|
411
|
+
|
412
|
+
def _repair
|
314
413
|
de = data_entry
|
315
414
|
set_current_tables
|
316
415
|
# Stop agent. Check sync and make sure the state is :STUCK_AT_UPLOAD
|
@@ -325,12 +424,13 @@ EOS
|
|
325
424
|
end
|
326
425
|
|
327
426
|
if status.include? :OK
|
328
|
-
log_info_stdout
|
427
|
+
log_info_stdout ""
|
329
428
|
log_info_stdout "Sync is in good condition. Nothing to repair."
|
330
429
|
return
|
331
430
|
end
|
332
431
|
|
333
|
-
|
432
|
+
gt = []
|
433
|
+
pt = []
|
334
434
|
gt = gap_tables.collect{|bt| bt[:table] } if gap_tables
|
335
435
|
pt = pos_mismatch_tables.collect{|bt| bt[:table] } if pos_mismatch_tables
|
336
436
|
tables = gt | pt # position mismatch can be due to query queue items discarded by the copy handler so it also needs to be in the target table list.
|
@@ -422,94 +522,6 @@ EOS
|
|
422
522
|
|
423
523
|
log_info_stdout "Repair is done. Start Agent with `flydata start` command."
|
424
524
|
end
|
425
|
-
run_exclusive :repair
|
426
|
-
|
427
|
-
|
428
|
-
def check(options = {})
|
429
|
-
status, pos_mismatch_tables, gap_tables = _check(options)
|
430
|
-
|
431
|
-
if status.include? :OK
|
432
|
-
message = "\nNo errors are found. Sync is clean.\n"
|
433
|
-
else
|
434
|
-
message = "\nFollowing errors are found.\n"
|
435
|
-
|
436
|
-
if status.include? :STUCK_AT_PROCESS
|
437
|
-
message += " - Data is stuck while processing\n"
|
438
|
-
end
|
439
|
-
if status.include? :STUCK_AT_UPLOAD
|
440
|
-
message += " - Data is stuck while uploading\n"
|
441
|
-
end
|
442
|
-
if status.include? :ABNORMAL_SHUTDOWN
|
443
|
-
message += " - Agent was not shut down correctly\n"
|
444
|
-
end
|
445
|
-
if gap_tables
|
446
|
-
message += " - Sync data is missing for the following table(s)\n"
|
447
|
-
gap_tables.each do |bt|
|
448
|
-
message += " table:#{bt[:table]}\n"
|
449
|
-
end
|
450
|
-
message += "\n"
|
451
|
-
end
|
452
|
-
if pos_mismatch_tables
|
453
|
-
message += " - Incorrect table position(s)\n"
|
454
|
-
pos_mismatch_tables.each do |bt|
|
455
|
-
message += " table:#{bt[:table]}, agent position:#{bt[:agent_seq] ? bt[:agent_seq] : '(missing)'}, server position:#{bt[:server_seq]}\n"
|
456
|
-
end
|
457
|
-
message += "\n"
|
458
|
-
end
|
459
|
-
end
|
460
|
-
log_info_stdout message
|
461
|
-
end
|
462
|
-
run_exclusive :check
|
463
|
-
|
464
|
-
def _check(options = {})
|
465
|
-
options[:stop_agent] ||= false
|
466
|
-
|
467
|
-
set_current_tables
|
468
|
-
sender = Flydata::Command::Sender.new
|
469
|
-
start_process = !options[:stop_agent] && sender.process_exist?
|
470
|
-
pos_mismatch_tables = nil
|
471
|
-
gap_tables = nil
|
472
|
-
data_stuck_at = nil
|
473
|
-
abnormal_shutdown = false
|
474
|
-
begin
|
475
|
-
begin
|
476
|
-
flush_buffer_and_stop(@full_tables, force: false, timeout: 55)
|
477
|
-
rescue ServerDataProcessingTimeout => e
|
478
|
-
data_stuck_at = e.state
|
479
|
-
end
|
480
|
-
|
481
|
-
# Agent is stopped but locked. There was an abnormal shutdown.
|
482
|
-
abnormal_shutdown = sender.agent_locked?
|
483
|
-
table_status_hash = get_table_status(@full_tables)
|
484
|
-
pos_mismatch_tables = check_position_files(table_status_hash)
|
485
|
-
gap_tables = check_gaps(table_status_hash)
|
486
|
-
ensure
|
487
|
-
Flydata::Command::Sender.new.start(quiet: true) if start_process
|
488
|
-
end
|
489
|
-
|
490
|
-
status = []
|
491
|
-
if data_stuck_at == :PROCESS
|
492
|
-
status << :STUCK_AT_PROCESS
|
493
|
-
end
|
494
|
-
if data_stuck_at == :UPLOAD
|
495
|
-
status << :STUCK_AT_UPLOAD
|
496
|
-
end
|
497
|
-
if gap_tables
|
498
|
-
status << :TABLE_GAPS
|
499
|
-
end
|
500
|
-
if pos_mismatch_tables
|
501
|
-
status << :TABLE_POS_MISMATCH
|
502
|
-
end
|
503
|
-
if abnormal_shutdown
|
504
|
-
status << :ABNORMAL_SHUTDOWN
|
505
|
-
end
|
506
|
-
if status.empty?
|
507
|
-
status << :OK
|
508
|
-
end
|
509
|
-
[status, pos_mismatch_tables, gap_tables, table_status_hash]
|
510
|
-
end
|
511
|
-
|
512
|
-
private
|
513
525
|
|
514
526
|
# Initial sync
|
515
527
|
|
@@ -6,6 +6,7 @@ module Flydata
|
|
6
6
|
include FlydataCore::Logger
|
7
7
|
|
8
8
|
RUN_INTERVAL = 1.0 #second
|
9
|
+
RUN_GC_INTERVAL = 60.0 * 5 #seconds
|
9
10
|
|
10
11
|
def initialize(helper_conf, server)
|
11
12
|
@stop_flag = ServerEngine::BlockingFlag.new
|
@@ -96,9 +97,19 @@ module Flydata
|
|
96
97
|
end
|
97
98
|
end
|
98
99
|
|
100
|
+
run_gc_if_needed
|
99
101
|
wait_until_next_turn(start_time)
|
100
102
|
end
|
101
103
|
|
104
|
+
def run_gc_if_needed
|
105
|
+
now = Time.now
|
106
|
+
@last_gc_time ||= now
|
107
|
+
if (@last_gc_time + RUN_GC_INTERVAL) < now
|
108
|
+
GC.start
|
109
|
+
@last_gc_time = now
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
102
113
|
def wait_until_next_turn(start_time)
|
103
114
|
next_time = start_time + RUN_INTERVAL
|
104
115
|
sleep_time = next_time - Time.now.to_f
|
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.5.
|
4
|
+
version: 0.5.8
|
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-09-
|
15
|
+
date: 2015-09-25 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: rest-client
|