Class: Flydata::Command::Sync
- Inherits:
-
Base
- Object
- Base
- Flydata::Command::Sync
show all
- Includes:
- Helpers
- Defined in:
- lib/flydata/command/sync.rb
Defined Under Namespace
Classes: SyncDataEntryError
Constant Summary
collapse
- INSERT_PROGRESS_INTERVAL =
1000
- SERVER_DATA_PROCESSING_TIMEOUT =
600
- STATUS_PARSING =
'PARSING'
- STATUS_WAITING =
'WAITING'
- STATUS_COMPLETE =
'COMPLETE'
Constants included
from Helpers
Helpers::UNIT_PREFIX
Instance Attribute Summary collapse
Attributes inherited from Base
#opts
Class Method Summary
collapse
Instance Method Summary
collapse
Methods included from Helpers
as_size, development?, env_mode, env_suffix, flydata_api_host_file, flydata_conf_file, flydata_version, format_menu_list, parse_command, retry_on, to_command_class, usage_text
Methods inherited from Base
#ask_input_table_name, #ask_yes_no, #choose_one, #flydata, #initialize, #newline, #register_crontab, #retrieve_data_entries, #separator
#before_logging, #log_error_stderr, #log_info_stdout, #log_warn_stderr
Instance Attribute Details
#ddl_tables ⇒ Object
Returns the value of attribute ddl_tables.
27
28
29
|
# File 'lib/flydata/command/sync.rb', line 27
def ddl_tables
@ddl_tables
end
|
#initial_sync(tables, de = nil) ⇒ Object
Returns the value of attribute initial_sync.
27
28
29
|
# File 'lib/flydata/command/sync.rb', line 27
def initial_sync
@initial_sync
end
|
#new_tables ⇒ Object
Returns the value of attribute new_tables.
27
28
29
|
# File 'lib/flydata/command/sync.rb', line 27
def new_tables
@new_tables
end
|
Class Method Details
.slop ⇒ Object
32
33
34
35
36
37
38
39
40
|
# File 'lib/flydata/command/sync.rb', line 32
def self.slop
Slop.new do
on 'c', 'skip-cleanup', 'Skip server cleanup'
on 'y', 'yes', 'Skip command prompt assuming yes to all questions. Use this for batch operation.'
on 'd', 'dump-file', 'Dump mysqldump into a file. Use this for debugging after making sure the free space.'
on 's', 'dump-stream', 'Dump mysqldump stream instead of saving dump file. It might cause timeout error if db size is larger than 10GB.'
on 'n', 'no-flydata-start', 'Don\'t start the flydata agent after initial sync.'
end
end
|
.slop_flush ⇒ Object
125
126
127
128
129
|
# File 'lib/flydata/command/sync.rb', line 125
def self.slop_flush
Slop.new do
on 'y', 'yes', 'Skip command prompt assuming yes to all questions. Use this for batch operation.'
end
end
|
.slop_generate_table_ddl ⇒ Object
269
270
271
272
273
274
275
276
|
# File 'lib/flydata/command/sync.rb', line 269
def self.slop_generate_table_ddl
Slop.new do
on 'c', 'ctl-only', 'Only generate FlyData Control definitions'
on 'y', 'yes', 'Skip command prompt assuming yes to all questions. Use this for batch operation.'
on 's', 'skip-primary-key-check', 'Skip primary key check when generating DDL'
on 'all-tables', 'Generate all table schema'
end
end
|
.slop_reset ⇒ Object
146
147
148
149
150
151
|
# File 'lib/flydata/command/sync.rb', line 146
def self.slop_reset
Slop.new do
on 'c', 'client', 'Resets client only.'
on 'y', 'yes', 'Skip command prompt assuming yes to all questions. Use this for batch operation.'
end
end
|
Instance Method Details
#check ⇒ Object
245
246
247
248
249
250
251
252
253
254
255
|
# File 'lib/flydata/command/sync.rb', line 245
def check
de = retrieve_sync_data_entry
retry_on(RestClient::Exception) do
status = do_check(de)
if status['complete']
nil
else
status
end
end
end
|
#flush ⇒ Object
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
# File 'lib/flydata/command/sync.rb', line 131
def flush
begin
flush_buffer_and_stop
rescue ServerDataProcessingTimeout => e
ee = ServerDataProcessingTimeout.new("Delayed Data Processing")
ee.description = " Data processing is taking more than expected. Please contact [email protected] to check the system status.\n\n"
ee.set_backtrace e.backtrace
raise ee
end
log_info_stdout("Buffers have been flushed and the sender process has been stopped.")
end
|
#generate_table_ddl(*tables) ⇒ Object
278
279
280
281
282
283
|
# File 'lib/flydata/command/sync.rb', line 278
def generate_table_ddl(*tables)
de = retrieve_sync_data_entry
dp = flydata.data_port.get
Flydata::MysqlCompatibilityCheck.new(dp, de['mysql_data_entry_preference']).check
do_generate_table_ddl(de, tables)
end
|
#handle_mysql_sync(tables = nil) ⇒ Object
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
# File 'lib/flydata/command/sync.rb', line 75
def handle_mysql_sync(tables=nil)
de = retrieve_sync_data_entry
set_current_tables(de)
verify_input_tables(tables, de['mysql_data_entry_preference']['tables'])
unless @new_tables.empty?
say("We've noticed that these tables have not been synced yet: #{@new_tables.join(", ")}")
unless @ddl_tables.empty?
say(" WARNING: We've noticed that at least one of these tables have not had their DDL generated yet.")
say(" We recommend you run our 'flydata sync:generate_table_ddl > create_table.sql'")
say(" to generate SQL to run on Redshift to create the correct tables")
say(" Without running this sql on your Redshift cluster, there may be issues with your data")
end
if ask_yes_no("Do you want to run initial sync on all of these tables now?")
tables = @initial_sync ? [] : @new_tables
initial_sync(tables, de)
else
unless @ddl_tables.empty?
say(" You can generate DDL SQL for your new tables by running this command")
say(" $> flydata sync:generate_table_ddl > create_table.sql")
end
puts "Without syncing these tables, we cannot start the flydata process"
raise "Please try again"
end
end
end
|
#reset(*tables) ⇒ Object
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
|
# File 'lib/flydata/command/sync.rb', line 153
def reset(*tables)
msg = tables.empty? ? '' : " for these tables : #{tables.join(" ")}"
return unless ask_yes_no("This resets the current sync#{msg}. Are you sure?")
sender = Flydata::Command::Sender.new
sender.flush_client_buffer
sender.stop
de = retrieve_sync_data_entry
all_tables = de['mysql_data_entry_preference']['tables']
verify_input_tables(tables, all_tables)
begin
wait_for_server_buffer(SERVER_DATA_PROCESSING_TIMEOUT)
rescue ServerDataProcessingTimeout => e
ee = ServerDataProcessingTimeout.new("Delayed Data Processing")
ee.description = " Data processing is taking more than expected. Please contact [email protected] to check the system status.\n Once checked, you can continue sync reset with the following command\n\n flydata sync:reset \#{tables.empty? ? '' : tables.join(\" \")}\n\n"
ee.set_backtrace e.backtrace
raise ee
end
cleanup_sync_server(de, tables) unless opts.client?
sync_fm = Flydata::FileUtil::SyncFileManager.new(de)
delete_files = [
sync_fm.dump_file_path,
sync_fm.dump_pos_path,
sync_fm.mysql_table_marshal_dump_path,
sync_fm.sync_info_file,
sync_fm.table_position_file_paths(*tables),
sync_fm.table_binlog_pos_paths(*tables),
sync_fm.table_binlog_pos_init_paths(*tables),
sync_fm.table_rev_file_paths(*tables),
sync_fm.table_ddl_file_paths(*tables)
]
delete_files << sync_fm.binlog_path if tables.empty? or all_tables.empty?
delete_files.flatten.each do |path|
FileUtils.rm(path) if File.exists?(path)
end
sync_fm.close
log_info_stdout("Reset completed successfully.")
end
|
#run(*tables) ⇒ Object
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
# File 'lib/flydata/command/sync.rb', line 42
def run(*tables)
sender = Flydata::Command::Sender.new
if (sender.process_exist?)
if tables.empty?
log_warn_stderr("FlyData Agent is already running. If you'd like to restart FlyData Sync from scratch, run 'flydata sync:reset' first.")
else
log_warn_stderr("Flydata Agent is already running. If you'd like to Sync the table(s), run 'flydata sync:flush' first.")
end
exit 1
end
handle_mysql_sync(tables)
unless opts.no_flydata_start?
log_info_stdout("Starting FlyData Agent...")
Flydata::Command::Sender.new.start(quiet: true)
log_info_stdout(" -> Done")
end
dashboard_url = "#{flydata.flydata_api_host}/dashboard"
redshift_console_url = "#{flydata.flydata_api_host}/redshift_clusters/query/new"
last_message = ALL_DONE_MESSAGE_TEMPLATE % [redshift_console_url, dashboard_url]
log_info_stdout(last_message)
end
|
#skip ⇒ Object
258
259
260
261
262
263
264
265
266
267
|
# File 'lib/flydata/command/sync.rb', line 258
def skip
de = retrieve_sync_data_entry
sync_fm = Flydata::FileUtil::SyncFileManager.new(de)
binlog_path = sync_fm.binlog_path
sync_fm.close
`touch #{binlog_path}`
log_info_stdout("Created an empty binlog position file.")
log_info_stdout("-> #{binlog_path}")
log_info_stdout("Run 'flydata start' to start continuous sync.")
end
|
#try_mysql_sync ⇒ Object
69
70
71
72
73
|
# File 'lib/flydata/command/sync.rb', line 69
def try_mysql_sync
handle_mysql_sync()
rescue SyncDataEntryError
return
end
|
#wait_for_server_buffer(timeout = 0) ⇒ Object
199
200
201
202
203
204
205
206
207
208
209
210
211
|
# File 'lib/flydata/command/sync.rb', line 199
def wait_for_server_buffer(timeout = 0)
start_time = Time.now
log_info_stdout("Waiting for the server buffer to get empty.")
prev_message =nil
while (status = check) && (status['state'] == 'processing')
prev_message = status['message']
if timeout > 0 && Time.now - start_time > timeout
raise ServerDataProcessingTimeout.new
end
print_progress(status)
sleep 10
end
end
|
#wait_for_server_data_processing(timeout = 0) ⇒ Object
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
|
# File 'lib/flydata/command/sync.rb', line 213
def wait_for_server_data_processing(timeout = 0)
state = :PROCESS
start_time = Time.now
log_info_stdout("Uploading data to Redshift...")
sleep 10
status = nil
prev_message =nil
while (status = check)
if state == :PROCESS && status['state'] == 'uploading'
log_info_stdout(" -> Done")
state = :UPLOAD
log_info_stdout("Finishing data upload...")
end
if status['message'] != prev_message
start_time = Time.now
end
prev_message = status['message']
if timeout > 0 && Time.now - start_time > timeout
raise ServerDataProcessingTimeout.new
end
print_progress(status)
sleep 10
end
if (state == :PROCESS)
log_info_stdout(" -> Done")
log_info_stdout("Finishing data upload...")
end
log_info_stdout(" -> Done")
end
|