flydata 0.7.15 → 0.7.16
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/flydata-core/lib/flydata-core/table_def/redshift_table_def.rb +3 -0
- data/flydata-core/spec/table_def/redshift_table_def_spec.rb +19 -0
- data/flydata.gemspec +0 -0
- data/lib/flydata/command/sync.rb +63 -55
- data/lib/flydata/fluent-plugins/in_postgresql_query_based_flydata.rb +1 -0
- data/lib/flydata/helper/action/repair.rb +13 -0
- data/lib/flydata/helper/action_ownership.rb +1 -0
- data/lib/flydata/plugin_support/context.rb +1 -0
- data/lib/flydata/query_based_sync/client.rb +3 -0
- data/spec/flydata/helper/action/repair_spec.rb +21 -0
- data/spec/flydata/helper/action_ownership_spec.rb +1 -1
- data/spec/flydata/query_based_sync/query_based_sync_context.rb +3 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aafcbf0332b985cd94a8fa83302bbccdb5ef86f1
|
4
|
+
data.tar.gz: f6842935284bacbd7cc5046f640c65c376b28bfb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8f6ef145d7f026237e35dd351f306b815a901e654a3fa67bc1ddd251fcad5fbc003c5780e2b93260f670f3692efcf78160c8ea688466f70eea91ebe12a3ade8d
|
7
|
+
data.tar.gz: 268449b51660a61f40aa8a731107630c2876c41b656ef4063b2eb41b925162d942c2963017d15a83d91dd78366cacc698d3c8c51d43bc6e2af5fe55b7865d0e4
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.7.
|
1
|
+
0.7.16
|
@@ -275,6 +275,9 @@ EOS
|
|
275
275
|
# strip outer single-quotes
|
276
276
|
default_value = $1 if /^'(.*)'$/m.match(default_value)
|
277
277
|
end
|
278
|
+
if default_value.kind_of?(String) &&/^NULL$/i.match(default_value)
|
279
|
+
return NULL_STR
|
280
|
+
end
|
278
281
|
if flydata_type.start_with?('year')
|
279
282
|
value = convert_year_into_date(remove_single_quote(default_value))
|
280
283
|
begin
|
@@ -420,6 +420,13 @@ EOT
|
|
420
420
|
let(:default_value_sql) { "'0001-01-01 00:00:00.000000'" }
|
421
421
|
it_behaves_like *examples
|
422
422
|
end
|
423
|
+
|
424
|
+
context 'when default_value has PostgreSQL-style NULL with cast' do
|
425
|
+
let(:default_value) { "NULL::timestamp without time zone" }
|
426
|
+
let(:default_value_sql) { "NULL" }
|
427
|
+
|
428
|
+
it_behaves_like *examples
|
429
|
+
end
|
423
430
|
end
|
424
431
|
|
425
432
|
context 'with datetimetz column def' do
|
@@ -548,6 +555,18 @@ EOT
|
|
548
555
|
|
549
556
|
it_behaves_like *examples
|
550
557
|
end
|
558
|
+
|
559
|
+
context 'when default_value has PostgreSQL-style NULL with cast' do
|
560
|
+
let(:default_value) { "NULL::numeric" }
|
561
|
+
let(:default_value_sql) { "NULL" }
|
562
|
+
before do
|
563
|
+
column[:column] = "value"
|
564
|
+
column[:type] = "numeric(28,2)"
|
565
|
+
end
|
566
|
+
let(:type_sql) { %Q|"value" numeric(28,2)| }
|
567
|
+
|
568
|
+
it_behaves_like *examples
|
569
|
+
end
|
551
570
|
end
|
552
571
|
|
553
572
|
context 'with bit column def' do
|
data/flydata.gemspec
CHANGED
Binary file
|
data/lib/flydata/command/sync.rb
CHANGED
@@ -341,7 +341,7 @@ EOS
|
|
341
341
|
message += "\n"
|
342
342
|
end
|
343
343
|
if pos_mismatch_tables
|
344
|
-
message += " - Incorrect table position
|
344
|
+
message += " - Incorrect table position. This may not be a real issue, caused by pending upload chunks. Run sync:flush and try again.\n"
|
345
345
|
pos_mismatch_tables.each do |bt|
|
346
346
|
message += " table:#{bt[:table]}, agent position:#{bt[:agent_seq] ? bt[:agent_seq] : '(missing)'}, server position:#{bt[:server_seq]}\n"
|
347
347
|
end
|
@@ -389,7 +389,8 @@ EOS
|
|
389
389
|
# to wait, but there *are* cases where active data processing takes
|
390
390
|
# more than 3 minutes between 2 chunk processing if COPY command
|
391
391
|
# takes minutes to process.
|
392
|
-
flush_buffer_and_stop(@full_tables, force: false, timeout: 180
|
392
|
+
flush_buffer_and_stop(@full_tables, force: false, timeout: 180,
|
393
|
+
dont_wait_upload: true)
|
393
394
|
rescue ServerDataProcessingTimeout => e
|
394
395
|
data_stuck_at = e.state
|
395
396
|
end
|
@@ -468,13 +469,28 @@ EOS
|
|
468
469
|
return true
|
469
470
|
end
|
470
471
|
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
472
|
+
if corrupt_master_pos_files
|
473
|
+
# TODO This case can be repaied by implementing the following steps.
|
474
|
+
# 1. Flush all pending data (buffer & query queue items) except for
|
475
|
+
# ones blocked by a gap.
|
476
|
+
# 2. Pick the latest src_pos value from table_status and put as the
|
477
|
+
# sent.pos.
|
478
|
+
# 3. Rerun sync:repair
|
479
|
+
#
|
480
|
+
log_info_stdout ""
|
481
|
+
log_info_stdout "Master position file(s) is broken. Full sync reset is necessary to solve the issue."
|
482
|
+
return false
|
483
|
+
end
|
484
|
+
|
485
|
+
broken_tables = []
|
486
|
+
broken_tables = gap_tables.collect{|bt| bt[:table] } if gap_tables
|
487
|
+
|
488
|
+
if broken_tables.empty? && !corrupt_master_pos_files &&
|
489
|
+
!status.include?(:ABNORMAL_SHUTDOWN)
|
490
|
+
log_info_stdout ""
|
491
|
+
log_info_stdout "Sync is in good condition. Nothing to repair."
|
492
|
+
return true
|
493
|
+
end
|
478
494
|
|
479
495
|
# table_status will be created at the end of initial sync.
|
480
496
|
# ignore tables that have no table_status, i.e. tables never got init-synced before.
|
@@ -485,14 +501,9 @@ EOS
|
|
485
501
|
The following issues have been found and will be repaired.
|
486
502
|
|
487
503
|
EOS
|
488
|
-
log_info_stdout <<EOS unless
|
504
|
+
log_info_stdout <<EOS unless broken_tables.empty?
|
489
505
|
- Sync is broken due to missing data for the following tables
|
490
|
-
#{
|
491
|
-
|
492
|
-
EOS
|
493
|
-
log_info_stdout <<EOS if corrupt_master_pos_files
|
494
|
-
- Sync is broken due to corrupt master position files
|
495
|
-
#{corrupt_master_pos_files.join("\n ")}
|
506
|
+
#{broken_tables.join("\n ")}
|
496
507
|
|
497
508
|
EOS
|
498
509
|
log_info_stdout <<EOS if status.include? :ABNORMAL_SHUTDOWN
|
@@ -516,25 +527,12 @@ EOS
|
|
516
527
|
# the table status has no src_pos (which is rare.) Skip the table
|
517
528
|
next
|
518
529
|
end
|
519
|
-
if
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
next
|
526
|
-
end
|
527
|
-
if sent_source_pos.nil? || sent_source_pos < table_source_pos
|
528
|
-
sent_source_pos = table_source_pos
|
529
|
-
end
|
530
|
-
else
|
531
|
-
if tables.include?(table)
|
532
|
-
if sent_source_pos.nil? || sent_source_pos > table_source_pos
|
533
|
-
if oldest_source_pos && table_source_pos < oldest_source_pos
|
534
|
-
unrepairable_tables << table
|
535
|
-
else
|
536
|
-
sent_source_pos = table_source_pos
|
537
|
-
end
|
530
|
+
if broken_tables.include?(table)
|
531
|
+
if sent_source_pos.nil? || sent_source_pos > table_source_pos
|
532
|
+
if oldest_source_pos && table_source_pos < oldest_source_pos
|
533
|
+
unrepairable_tables << table
|
534
|
+
else
|
535
|
+
sent_source_pos = table_source_pos
|
538
536
|
end
|
539
537
|
end
|
540
538
|
end
|
@@ -561,30 +559,26 @@ EOS
|
|
561
559
|
end
|
562
560
|
master_source_pos = context.resume_pos(sent_source_pos)
|
563
561
|
|
564
|
-
# Delete agent buffer
|
565
|
-
log_info_stdout "Deleting data in the agent buffer..."
|
566
|
-
files = Flydata::Agent.new(FLYDATA_HOME).delete_buffer_files
|
567
|
-
unless files.empty?
|
568
|
-
$log.debug "Deleted buffer files\n " + files.join("\n ")
|
569
|
-
end
|
570
|
-
|
571
562
|
# Delete query queue items for the tables
|
572
563
|
log_info_stdout "Deleting data stuck in the server buffer..."
|
573
|
-
cleanup_sync_server(de,
|
564
|
+
cleanup_sync_server(de, broken_tables, queue_only: true) unless broken_tables.empty?
|
574
565
|
|
575
566
|
# Save the positions (source_pos and seq)
|
576
567
|
log_info_stdout "Fixing table positions..."
|
577
568
|
synced_tables.each do |table|
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
569
|
+
if broken_tables.include?(table)
|
570
|
+
table_source_pos = table_status_hash[table]["source_pos"]
|
571
|
+
if table_source_pos.nil? || table_source_pos.empty?
|
572
|
+
# no init sync has happened to the table. No need to set positions.
|
573
|
+
next
|
574
|
+
end
|
575
|
+
pos = table_status_hash[table]["seq"]
|
576
|
+
else
|
577
|
+
# use "default" positions supplied by #save_table_positions
|
578
|
+
table_source_pos = nil
|
579
|
+
pos = nil
|
580
|
+
end
|
581
|
+
old_source_pos, old_pos = save_table_positions(table, table_source_pos, pos, context)
|
588
582
|
end
|
589
583
|
|
590
584
|
log_info_stdout "Fixing the master position files..."
|
@@ -1070,6 +1064,10 @@ EOM
|
|
1070
1064
|
break
|
1071
1065
|
end
|
1072
1066
|
|
1067
|
+
if state == :UPLOAD && option[:dont_wait_upload]
|
1068
|
+
break
|
1069
|
+
end
|
1070
|
+
|
1073
1071
|
if status['message'] != prev_message
|
1074
1072
|
# making some progress. Reset timer
|
1075
1073
|
start_time = Time.now
|
@@ -1081,7 +1079,7 @@ EOM
|
|
1081
1079
|
print_progress(status)
|
1082
1080
|
sleep 10
|
1083
1081
|
end
|
1084
|
-
if
|
1082
|
+
if state == :PROCESS && !option[:dont_wait_upload]
|
1085
1083
|
# :UPLOAD state was skipped due to no data
|
1086
1084
|
log_info_stdout(" -> Done")
|
1087
1085
|
log_info_stdout("Finishing data upload...")
|
@@ -1312,7 +1310,8 @@ Thank you for using FlyData!
|
|
1312
1310
|
|
1313
1311
|
timeout = options.has_key?(:timeout) ? options[:timeout]
|
1314
1312
|
: SERVER_DATA_PROCESSING_TIMEOUT
|
1315
|
-
wait_for_server_data_processing(
|
1313
|
+
wait_for_server_data_processing(timeout: timeout, tables: tables,
|
1314
|
+
dont_wait_upload: options[:dont_wait_upload])
|
1316
1315
|
end
|
1317
1316
|
|
1318
1317
|
# Utility methods
|
@@ -1459,8 +1458,17 @@ Thank you for using FlyData!
|
|
1459
1458
|
def save_table_positions(table, source_pos, pos, context)
|
1460
1459
|
de = data_entry
|
1461
1460
|
sync_fm = create_sync_file_manager(de)
|
1461
|
+
|
1462
|
+
master_sent_source_pos = sync_fm.load_sent_source_pos
|
1462
1463
|
old_source_pos = sync_fm.get_table_source_pos(table)
|
1463
1464
|
old_pos = sync_fm.get_table_position(table)
|
1465
|
+
|
1466
|
+
source_pos ||= old_source_pos
|
1467
|
+
source_pos ||= master_sent_source_pos
|
1468
|
+
raise "master sent source pos is missing" unless source_pos
|
1469
|
+
pos ||= old_pos
|
1470
|
+
raise "table pos is missing for table '#{table}'" unless pos
|
1471
|
+
|
1464
1472
|
if pos.to_i != old_pos.to_i
|
1465
1473
|
sync_fm.save_table_position(table, pos)
|
1466
1474
|
$log.debug "table pos updated. table:#{table} pos:#{old_pos} -> #{pos}"
|
@@ -32,6 +32,7 @@ class PostgresqlQueryBasedFlydataInput < Input
|
|
32
32
|
tag: @tag, sync_fm: @sync_fm, omit_events: @omit_events,
|
33
33
|
table_revs: @table_revs, dbconf: @dbconf,
|
34
34
|
cur_src_pos_file: @source_position_file,
|
35
|
+
cur_sent_pos_file: @sent_position_file,
|
35
36
|
table_src_pos_files: @table_src_pos_files,
|
36
37
|
table_meta: @table_meta,
|
37
38
|
params: {
|
@@ -48,6 +48,7 @@ module Flydata
|
|
48
48
|
self.new(:stop_agent, true, Action::StopAgent),
|
49
49
|
self.new(:restart_agent, true, Action::RestartAgent),
|
50
50
|
self.new(:update_helper_config, false, Action::UpdateHelperConfig),
|
51
|
+
self.new(:repair, true, Action::Repair),
|
51
52
|
].inject({}) do |h, action|
|
52
53
|
h[action.action_name] = action
|
53
54
|
h
|
@@ -101,6 +101,9 @@ module QueryBasedSync
|
|
101
101
|
|
102
102
|
# Set the current snapshot to master(resume) binlog.pos file
|
103
103
|
context.cur_src_pos_file.save(context.table_meta.current_snapshot)
|
104
|
+
# Also set the same value to the sent.binlog.pos file as the file is
|
105
|
+
# required by the agent commands.
|
106
|
+
context.cur_sent_pos_file.save(context.table_meta.current_snapshot)
|
104
107
|
|
105
108
|
log_info("Updated source position -", resume_pos:context.table_meta.current_snapshot)
|
106
109
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require_relative '../helper_shared_context'
|
3
|
+
require 'flydata/helper/action/repair'
|
4
|
+
|
5
|
+
module Flydata
|
6
|
+
module Helper
|
7
|
+
module Action
|
8
|
+
describe Repair do
|
9
|
+
include_context 'helper context'
|
10
|
+
|
11
|
+
describe "#execute" do
|
12
|
+
subject { described_class.new(config).execute }
|
13
|
+
it "executes the repair action" do
|
14
|
+
expect(Open3).to receive(:capture3).with({}, "flydata sync:repair -y")
|
15
|
+
subject
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -36,13 +36,13 @@ module Flydata
|
|
36
36
|
describe '.action_ownership_map' do
|
37
37
|
subject { described_class.action_ownership_map }
|
38
38
|
it do
|
39
|
-
expect(subject.size).to eq(6)
|
40
39
|
expect(subject.include?(:check_remote_actions)).to be(true)
|
41
40
|
expect(subject.include?(:check_abnormal_shutdown)).to be(true)
|
42
41
|
expect(subject.include?(:send_logs)).to be(true)
|
43
42
|
expect(subject.include?(:stop_agent)).to be(true)
|
44
43
|
expect(subject.include?(:restart_agent)).to be(true)
|
45
44
|
expect(subject.include?(:update_helper_config)).to be(true)
|
45
|
+
expect(subject.include?(:repair)).to be(true)
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
@@ -69,12 +69,14 @@ shared_context 'query based sync context' do
|
|
69
69
|
]
|
70
70
|
} }
|
71
71
|
let(:cur_src_pos_file) { double('cur_src_pos_file') }
|
72
|
+
let(:cur_sent_pos_file) { double('cur_sent_pos_file') }
|
72
73
|
let(:table_1_src_pos_file) { double('table_1_src_pos_file') }
|
73
74
|
let(:table_2_src_pos_file) { double('table_2_src_pos_file') }
|
74
75
|
let(:table_3_src_pos_file) { double('table_3_src_pos_file') }
|
75
76
|
let(:context) {
|
76
77
|
Flydata::PluginSupport::Context.new(
|
77
78
|
cur_src_pos_file: cur_src_pos_file,
|
79
|
+
cur_sent_pos_file: cur_sent_pos_file,
|
78
80
|
tables: %w(table_1 table_2 table_3),
|
79
81
|
tag: 'test_tag',
|
80
82
|
sync_fm: sync_fm,
|
@@ -107,6 +109,7 @@ shared_context 'query based sync context' do
|
|
107
109
|
allow(table_meta).to receive(:[]).with(:table_1).and_return(table_meta_1)
|
108
110
|
allow(table_meta).to receive(:current_snapshot).and_return(current_snapshot)
|
109
111
|
allow(cur_src_pos_file).to receive(:save).with(current_snapshot)
|
112
|
+
allow(cur_sent_pos_file).to receive(:save).with(current_snapshot)
|
110
113
|
setup_dummy_objects
|
111
114
|
end
|
112
115
|
end
|
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.7.
|
4
|
+
version: 0.7.16
|
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:
|
15
|
+
date: 2017-01-11 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: rest-client
|
@@ -681,6 +681,7 @@ files:
|
|
681
681
|
- lib/flydata/helper/action/agent_action.rb
|
682
682
|
- lib/flydata/helper/action/check_abnormal_shutdown.rb
|
683
683
|
- lib/flydata/helper/action/check_remote_actions.rb
|
684
|
+
- lib/flydata/helper/action/repair.rb
|
684
685
|
- lib/flydata/helper/action/restart_agent.rb
|
685
686
|
- lib/flydata/helper/action/send_logs.rb
|
686
687
|
- lib/flydata/helper/action/stop_agent.rb
|
@@ -835,6 +836,7 @@ files:
|
|
835
836
|
- spec/flydata/fluent-plugins/sync_source_plugin_context.rb
|
836
837
|
- spec/flydata/helper/action/check_abnormal_shutdown_spec.rb
|
837
838
|
- spec/flydata/helper/action/check_remote_actions_spec.rb
|
839
|
+
- spec/flydata/helper/action/repair_spec.rb
|
838
840
|
- spec/flydata/helper/action/restart_agent_spec.rb
|
839
841
|
- spec/flydata/helper/action/send_logs_spec.rb
|
840
842
|
- spec/flydata/helper/action/stop_agent_spec.rb
|
@@ -908,7 +910,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
908
910
|
version: '0'
|
909
911
|
requirements: []
|
910
912
|
rubyforge_project:
|
911
|
-
rubygems_version: 2.
|
913
|
+
rubygems_version: 2.4.3
|
912
914
|
signing_key:
|
913
915
|
specification_version: 4
|
914
916
|
summary: FlyData Agent
|