flydata 0.3.16 → 0.3.17

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/flydata-core/lib/flydata-core/record/record.rb +13 -0
  4. data/flydata-core/lib/flydata-core/table_def/mysql_table_def.rb +107 -5
  5. data/flydata-core/lib/flydata-core/table_def/redshift_table_def.rb +62 -11
  6. data/flydata-core/spec/table_def/mysql_table_def_spec.rb +37 -1
  7. data/flydata-core/spec/table_def/mysql_to_redshift_table_def_spec.rb +120 -0
  8. data/flydata-core/spec/table_def/mysqldump_test_column_charset.dump +45 -0
  9. data/flydata-core/spec/table_def/redshift_table_def_spec.rb +70 -88
  10. data/flydata.gemspec +13 -8
  11. data/lib/flydata/command/setup.rb +4 -4
  12. data/lib/flydata/command/sync.rb +18 -29
  13. data/lib/flydata/compatibility_check.rb +2 -2
  14. data/lib/flydata/fluent-plugins/in_mysql_binlog_flydata.rb +15 -10
  15. data/lib/flydata/fluent-plugins/mysql/binlog_record_handler.rb +6 -3
  16. data/lib/flydata/fluent-plugins/mysql/dml_record_handler.rb +15 -8
  17. data/lib/flydata/fluent-plugins/mysql/table_meta.rb +6 -34
  18. data/lib/flydata/{fluent-plugins/mysql → mysql}/binlog_position.rb +2 -0
  19. data/lib/flydata/{util → mysql}/mysql_util.rb +34 -1
  20. data/lib/flydata/mysql/table_ddl.rb +118 -0
  21. data/lib/flydata/parser/mysql/dump_parser.rb +5 -5
  22. data/lib/flydata/parser/mysql/mysql_alter_table.treetop +29 -5
  23. data/lib/flydata/sync_file_manager.rb +15 -2
  24. data/spec/flydata/command/sync_spec.rb +22 -1
  25. data/spec/flydata/fluent-plugins/in_mysql_binlog_flydata_spec.rb +7 -2
  26. data/spec/flydata/fluent-plugins/mysql/dml_record_handler_spec.rb +130 -0
  27. data/spec/flydata/fluent-plugins/mysql/shared_query_handler_context.rb +1 -0
  28. data/spec/flydata/fluent-plugins/mysql/table_meta_spec.rb +14 -8
  29. data/spec/flydata/fluent-plugins/mysql/truncate_query_handler_spec.rb +2 -1
  30. data/spec/flydata/{fluent-plugins/mysql → mysql}/binlog_position_spec.rb +3 -2
  31. data/spec/flydata/{util → mysql}/mysql_util_spec.rb +2 -2
  32. data/spec/flydata/mysql/table_ddl_spec.rb +193 -0
  33. data/spec/flydata/parser/mysql/alter_table_parser_spec.rb +37 -9
  34. data/spec/flydata/sync_file_manager_spec.rb +102 -27
  35. metadata +12 -7
@@ -1,6 +1,6 @@
1
1
  require 'mysql2'
2
2
  require 'flydata/command_loggable'
3
- require 'flydata/util/mysql_util'
3
+ require 'flydata/mysql/mysql_util'
4
4
 
5
5
  module Flydata
6
6
 
@@ -123,7 +123,7 @@ module Flydata
123
123
  end
124
124
 
125
125
  def check_mysql_protocol_tcp_compat
126
- query = Util::MysqlUtil.generate_mysql_show_grants_cmd(@db_opts)
126
+ query = Mysql::MysqlUtil.generate_mysql_show_grants_cmd(@db_opts)
127
127
 
128
128
  Open3.popen3(query) do |stdin, stdout, stderr|
129
129
  stdin.close
@@ -9,13 +9,14 @@ lib = File.expand_path(File.join(File.dirname(__FILE__), '../../'))
9
9
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
10
10
  require 'flydata'
11
11
  require 'flydata/sync_file_manager'
12
- require 'flydata/util/mysql_util'
12
+ require 'flydata/mysql/mysql_util'
13
13
  require 'flydata/fluent-plugins/preference'
14
14
  require 'flydata/fluent-plugins/mysql/binlog_position_file'
15
15
  require 'flydata/fluent-plugins/mysql/binlog_record_dispatcher'
16
16
  require 'flydata/fluent-plugins/mysql/context'
17
17
  require 'flydata/fluent-plugins/idle_event_detector'
18
18
  require 'flydata/fluent-plugins/mysql/table_meta'
19
+ require 'flydata/mysql/table_ddl'
19
20
  require 'flydata-core/fluent/config_helper'
20
21
 
21
22
  #Monkey-patch fluentd class (EngineClass) to support shutdown for input plugin.
@@ -75,11 +76,11 @@ class MysqlBinlogFlydataInput < MysqlBinlogInput
75
76
  end
76
77
 
77
78
  # Db access opts
78
- db_opts = { host: @host, port: @port, username: @username, password: @password, database: @database, ssl_ca: @ssl_ca_path }
79
+ @db_opts = { host: @host, port: @port, username: @username, password: @password, database: @database, ssl_ca: @ssl_ca_path }
79
80
 
80
81
  $log.info "mysql host:\"#{@host}\" port:\"#{@port}\" username:\"#{@username}\" database:\"#{@database}\" tables:\"#{@tables}\" tables_append_only:\"#{tables_append_only}\""
81
82
  $log.info "mysql client version: #{`mysql -V`}"
82
- server_version = `echo 'select version();' | #{Flydata::Util::MysqlUtil.generate_mysql_cmd(db_opts)} 2>/dev/null`
83
+ server_version = `echo 'select version();' | #{Flydata::Mysql::MysqlUtil.generate_mysql_cmd(@db_opts)} 2>/dev/null`
83
84
  $log.info "mysql server version: #{server_version}"
84
85
 
85
86
  @tables = @tables.split(/,\s*/)
@@ -94,7 +95,7 @@ class MysqlBinlogFlydataInput < MysqlBinlogInput
94
95
  @tables -= new_tables
95
96
  $log.info "Not watching these tables: #{new_tables.join(", ")}"
96
97
 
97
- table_meta = Mysql::TableMeta.new(db_opts.merge(tables: @tables))
98
+ table_meta = Flydata::Mysql::TableMeta.new(@db_opts.merge(tables: @tables))
98
99
 
99
100
  table_revs = tables.inject({}) do |h, table_name|
100
101
  h[table_name] = @sync_fm.table_rev(table_name)
@@ -145,6 +146,11 @@ EOS
145
146
 
146
147
  def run
147
148
  @context.table_meta.update
149
+ Flydata::Mysql::TableDdl.migrate_tables(@context.tables, @db_opts,
150
+ @context.sync_fm, @position_file,
151
+ @context) do |event|
152
+ @record_dispatcher.dispatch(event)
153
+ end
148
154
  start_kodama(mysql_url) do |c|
149
155
  c.binlog_position_file = @position_file
150
156
  if @ssl_ca_path.to_s != '' && c.respond_to?(:ssl_ca=)
@@ -167,7 +173,7 @@ EOS
167
173
  rescue => e
168
174
  # HACK: mysql-replication-listener has a network connection leak bug which doesn't release a connection
169
175
  # to MySQL. Rather than fixing the bug, restarting the fluentd process for now.
170
- $log.warn "kodama died with an error. Restart the process after #{@retry_wait} seconds. error: #{e.class.to_s} '#{e.to_s}'"
176
+ $log.warn "kodama died with an error. Restart the process after #{@retry_wait} seconds. error: #{e.class.to_s} '#{e.to_s}'\n#{e.backtrace.join("\n")}"
171
177
  sleep @retry_wait
172
178
  Process.kill(:HUP, Process.ppid) # Send SIGHUP to the supervisor to restart fluentd
173
179
  rescue SignalException
@@ -260,16 +266,15 @@ class Client
260
266
  def rows
261
267
  rs = super
262
268
  # HACK
263
- # Assuming all string values are UTF-8
264
- # To make this right, MySQL client's encoding must be set to UTF-8
265
- # But how?
269
+ # Set string encoding to binary because ruby-binlog has no knowledge
270
+ # about the encoding of strings.
266
271
  new_rs = rs.collect {|row|
267
272
  row.collect{|value|
268
273
  if (value.kind_of?(Array))
269
274
  # Update has two rows in it
270
- value.collect{|val| val.force_encoding("UTF-8") if val.respond_to?(:force_encoding); val}
275
+ value.collect{|val| val.force_encoding("binary") if val.respond_to?(:force_encoding); val}
271
276
  else
272
- value.force_encoding("UTF-8") if value.respond_to?(:force_encoding); value
277
+ value.force_encoding("binary") if value.respond_to?(:force_encoding); value
273
278
  end
274
279
  }
275
280
  }
@@ -1,6 +1,7 @@
1
1
  require 'fluent/plugin/in_mysql_binlog'
2
2
  require 'binlog'
3
- require 'flydata/fluent-plugins/mysql/binlog_position'
3
+ require 'flydata/mysql/binlog_position'
4
+ require 'flydata-core/record/record'
4
5
 
5
6
  module Mysql
6
7
  class BinlogRecordHandler
@@ -10,6 +11,7 @@ module Mysql
10
11
  RESPECT_ORDER = :respect_order
11
12
  SRC_POS = :src_pos
12
13
  TABLE_REV = :table_rev
14
+ V = :v # FlyData record format version
13
15
 
14
16
  def initialize(context)
15
17
  @context = context
@@ -21,7 +23,7 @@ module Mysql
21
23
  @context.tables.each do |table_name|
22
24
  table_binlog_content = @context.sync_fm.get_table_binlog_pos(table_name)
23
25
  if table_binlog_content
24
- @table_binlog_pos[table_name] = BinLogPosition.new(table_binlog_content)
26
+ @table_binlog_pos[table_name] = Flydata::Mysql::BinLogPosition.new(table_binlog_content)
25
27
  end
26
28
  end
27
29
  end
@@ -40,7 +42,7 @@ module Mysql
40
42
  acceptable = @context.tables.include?(table)
41
43
 
42
44
  if acceptable and @table_binlog_pos[record['table_name']]
43
- if @table_binlog_pos[record['table_name']] >= BinLogPosition.new(
45
+ if @table_binlog_pos[record['table_name']] >= Flydata::Mysql::BinLogPosition.new(
44
46
  "#{@context.current_binlog_file}\t#{record['next_position'] - record['event_length']}")
45
47
  acceptable = false
46
48
  else
@@ -84,6 +86,7 @@ module Mysql
84
86
  r[TABLE_NAME] = table
85
87
  r[SRC_POS] = "#{@context.current_binlog_file}\t#{position}"
86
88
  r[TABLE_REV] = table_rev
89
+ r[V] = FlydataCore::Record::V2
87
90
  end
88
91
 
89
92
  # Use binlog's timestamp
@@ -49,7 +49,7 @@ module Mysql
49
49
  row_values = { ROW => row }
50
50
  row_values = yield(row) if block_given? # Give the caller a chance to generate the correct row values
51
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}
52
+ row_kinds = row_types.inject({}) {|m, k| m[k] = convert_to_flydata_row_format(row_values[k]); m}
53
53
  encode_signless_integer(row_kinds, record["columns"], row_types)
54
54
  row_kinds
55
55
  end
@@ -57,22 +57,29 @@ module Mysql
57
57
  end
58
58
  end
59
59
 
60
- def convert_to_flydata_row_format(table_name, row)
60
+ def convert_to_flydata_row_format(row)
61
61
  row.each.with_index(1).inject({}) do |h, (v, i)|
62
62
  if v.kind_of?(String)
63
- v = encode_row_value(table_name, v)
63
+ v = encode_row_value(v)
64
+ if v.encoding == Encoding::BINARY
65
+ h['attrs'] ||= {}
66
+ h['attrs'][i.to_s] ||= {}
67
+ h['attrs'][i.to_s]['enc'] = 'b'
68
+ end
64
69
  end
65
70
  h[i.to_s] = v
66
71
  h
67
72
  end
68
73
  end
69
74
 
70
- def encode_row_value(table_name, value)
71
- if src_encoding = @table_meta[table_name][:encoding]
72
- value.encode('utf-8', src_encoding, :undef => :replace, :invalid => :replace)
73
- else
74
- value.encode('utf-16', :undef => :replace, :invalid => :replace).encode('utf-8')
75
+ def encode_row_value(value)
76
+ value.force_encoding('utf-8')
77
+ unless value.valid_encoding?
78
+ # value can't be treated as UTF-8. Convert to Flydata binary format.
79
+ value = "0x" + value.unpack('c*').collect{|c| "%02X" % (c < 0 ? c + 256 : c)}.join('')
80
+ value.force_encoding('binary') # setting to 'binary' to differentiate from UTF-8. Downstream code may rely on it.
75
81
  end
82
+ value
76
83
  end
77
84
 
78
85
  def encode_signless_integer(record, column_types, row_types)
@@ -1,5 +1,7 @@
1
1
  require 'mysql2'
2
+ require 'flydata-core/table_def/mysql_table_def'
2
3
 
4
+ module Flydata
3
5
  module Mysql
4
6
  class TableMeta
5
7
  MANDATORY_OPTS = [
@@ -41,45 +43,14 @@ EOT
41
43
  database: @database, tables: @tables.collect{|t| "'#{t}'"}.join(',') }
42
44
  columns = conn.query(sql)
43
45
  columns.collect do |col|
44
- @table_meta[col['table_name'].to_sym][:encoding] = get_ruby_charset_name(col['character_set_name'])
46
+ mysql_charset = col['character_set_name']
47
+ @table_meta[col['table_name'].to_sym][:encoding] = FlydataCore::TableDef::MysqlTableDef.ruby_encoding(mysql_charset)
48
+ @table_meta[col['table_name'].to_sym][:mysql_charset] = mysql_charset
45
49
  end
46
50
  ensure
47
51
  conn.close rescue nil if conn
48
52
  end
49
53
 
50
- # Charset naming conversion rule. mysql => ruby
51
- #
52
- # mysql
53
- # http://dev.mysql.com/doc/refman/5.6/en/charset-charsets.html
54
- # mysql(supported CJK character sets)
55
- # http://dev.mysql.com/doc/refman/5.6/en/faqs-cjk.html#qandaitem-A-11-1-1
56
- # For ruby, you can see encoding list with "Encoding.list"
57
- CHARSET_ENCODE_RULE = {
58
- 'ascii' => nil, # 'ASCII-8BIT', (not need to be encoded)
59
- 'utf8' => nil, # 'UTF-8', (not need to be encoded)
60
- 'utf8mb4' => nil, # 'UTF-8', (not need to be encoded)
61
- 'utf16' => 'UTF-16',
62
- 'utf32' => 'UTF-32',
63
- 'latin1' => 'ISO-8859-1',
64
- 'latin2' => 'ISO-8859-2',
65
- 'big5' => 'Big5',
66
- 'cp932' => 'CP932',
67
- 'eucjpms' => 'eucJP-ms',
68
- 'euckr' => 'EUC-KR',
69
- 'gb18030' => 'GB18030',
70
- 'gb2312' => 'GB2312',
71
- 'gbk' => 'GBK',
72
- 'sjis' => 'Shift_JIS',
73
- 'ujis' => 'EUC-JP',
74
- }
75
-
76
- def get_ruby_charset_name(mysql_charset)
77
- return nil if mysql_charset.to_s.empty?
78
- raise "Unsupported charset:#{mysql_charset}." unless CHARSET_ENCODE_RULE.has_key?(mysql_charset)
79
- charset = CHARSET_ENCODE_RULE[mysql_charset]
80
- return charset
81
- end
82
-
83
54
  # Return table meta
84
55
  # :character_set_name
85
56
  def [](table_name)
@@ -87,3 +58,4 @@ EOT
87
58
  end
88
59
  end
89
60
  end
61
+ end
@@ -1,3 +1,4 @@
1
+ module Flydata
1
2
  module Mysql
2
3
  class BinLogPosition
3
4
  include Comparable
@@ -18,3 +19,4 @@ module Mysql
18
19
  end
19
20
  end
20
21
  end
22
+ end
@@ -1,5 +1,8 @@
1
+ require 'open3'
2
+ require 'flydata-core/table_def/mysql_table_def'
3
+
1
4
  module Flydata
2
- module Util
5
+ module Mysql
3
6
  class MysqlUtil
4
7
  DEFAULT_MYSQL_CMD_OPTION = "--default-character-set=utf8 --protocol=tcp"
5
8
 
@@ -73,6 +76,36 @@ module Flydata
73
76
  generate_mysql_cmd(opt)
74
77
  end
75
78
 
79
+ def self.each_mysql_tabledef(tables, option)
80
+ command = generate_mysql_ddl_dump_cmd(option.merge(tables: tables))
81
+
82
+ create_opt = {}
83
+ if option.has_key?(:skip_primary_key_check)
84
+ create_opt[:skip_primary_key_check] = option[:skip_primary_key_check]
85
+ end
86
+
87
+ Open3.popen3(command) do |stdin, stdout, stderr|
88
+ stdin.close
89
+ stdout.set_encoding("utf-8", "utf-8") # mysqldump output must be in UTF-8
90
+ create_flydata_ctl_table = true
91
+ while !stdout.eof?
92
+ begin
93
+ mysql_tabledef = FlydataCore::TableDef::MysqlTableDef.create(stdout, create_opt)
94
+ break if mysql_tabledef.nil?
95
+ yield(mysql_tabledef, nil)
96
+ rescue FlydataCore::TableDefError=> e
97
+ yield(nil, e)
98
+ end
99
+ end
100
+ errors = ""
101
+ while !stderr.eof?
102
+ line = stderr.gets.gsub('mysqldump: ', '')
103
+ errors << line unless /Warning: Using a password on the command line interface can be insecure./ === line
104
+ end
105
+ raise errors unless errors.empty?
106
+ end
107
+ end
108
+
76
109
  private
77
110
 
78
111
  def self.convert_keys_to_sym(hash)
@@ -0,0 +1,118 @@
1
+ require 'flydata/mysql/binlog_position'
2
+ require 'flydata/mysql/mysql_util'
3
+
4
+ module Flydata
5
+ module Mysql
6
+
7
+ class TableDdl
8
+ VERSION0 = 0 # the version where no .generated_ddl file was generated.
9
+ # Therefore, this version never shows up in anywhere.
10
+ VERSION1 = 1 # the version which doesn't handle server side encoding support.
11
+ VERSION2 = 2 # the version with server side encoding support, migrated from
12
+ # the previous versions. Format/functionality-wise, it's the
13
+ # same as Version 3.
14
+ VERSION3 = 3 # the version with server side encoding support, generated by
15
+ # sync:generated_table_ddl command.
16
+ VERSION4 = 4 # the version with server side encoding support, generated by
17
+ # the auto-generated CREATE TABLE event.
18
+ VERSION = VERSION3
19
+
20
+ def self.migrate_tables(tables, mysql_opts, sync_fm, position_file, context,
21
+ &block)
22
+ migrate_to_v2(tables, mysql_opts, sync_fm, position_file, context, &block)
23
+ end
24
+
25
+ private
26
+
27
+ V2_TARGET_VERSION = VERSION2
28
+ EVENT_TYPE = 'Query'
29
+ ALTER_TABLE_CHARSET_SQL = <<EOS.strip
30
+ ALTER TABLE `%s`.`%s` CHARACTER SET = %s;
31
+ EOS
32
+ CHANGE_COLUMN_SQL = <<EOS.strip
33
+ CHANGE COLUMN `%s` %s
34
+ EOS
35
+ ALTER_TABLE_SQL = <<EOS.strip
36
+ ALTER TABLE `%s`.`%s` %s;
37
+ EOS
38
+
39
+ def self.migrate_to_v2(tables, mysql_opts, sync_fm, position_file, context)
40
+ database = mysql_opts[:database]
41
+ mysql_tabledefs = nil
42
+ original_binlog_file = nil
43
+ binlog_pos = nil
44
+ event_size = 0 # so that the next binlog position becomes the master binlog position
45
+ tables.each do |table|
46
+ # check the current ddl version
47
+ contents = sync_fm.load_generated_ddl([table])
48
+ version = contents.first.to_i
49
+ # return if no need to migrate
50
+ next if version >= V2_TARGET_VERSION
51
+
52
+ if mysql_tabledefs.nil?
53
+ MysqlUtil.each_mysql_tabledef(tables, mysql_opts) do |mysql_tabledef, error|
54
+ raise error if error
55
+
56
+ mysql_tabledefs ||= {}
57
+ mysql_tabledefs[mysql_tabledef.table_name] = mysql_tabledef
58
+ end
59
+ end
60
+ mysql_tabledef = mysql_tabledefs[table]
61
+ if binlog_pos.nil?
62
+ # get binlog position
63
+ binlog_pos = BinLogPosition.new(File.open(position_file){|f| f.read })
64
+ original_binlog_file = context.current_binlog_file
65
+ context.current_binlog_file = binlog_pos.file
66
+ end
67
+ # get charset
68
+ charset = mysql_tabledef.default_charset_mysql
69
+ # construct queries
70
+ # column charset
71
+ column_event = nil
72
+ at_subquery = mysql_tabledef.column_def.select{|col, coldef| /CHARACTER SET/.match(coldef) }.collect{|col, coldef| CHANGE_COLUMN_SQL % [col, coldef]}.join(",")
73
+ unless at_subquery.empty?
74
+ column_query = ALTER_TABLE_SQL % [database, table, at_subquery]
75
+ column_event = QueryEvent.new(EVENT_TYPE, database, table,
76
+ binlog_pos.pos, event_size, column_query,
77
+ Time.now.to_i)
78
+ yield column_event
79
+ end
80
+ # table charset
81
+ table_query = ALTER_TABLE_CHARSET_SQL % [database, table, charset]
82
+ # create events and yield
83
+ table_event = QueryEvent.new(EVENT_TYPE, database, table, binlog_pos.pos,
84
+ event_size, table_query, Time.now.to_i)
85
+ yield table_event
86
+ $log.info "migrating table `#{table}` from version #{version} to version #{V2_TARGET_VERSION}. Table event #{table_event} Column event #{column_event}"
87
+
88
+ # update generated_ddl
89
+ sync_fm.save_generated_ddl([table], V2_TARGET_VERSION.to_s)
90
+ end
91
+ context.current_binlog_file = original_binlog_file if binlog_pos
92
+ end
93
+ end
94
+
95
+ # mimics RubyBinlog::QueryEvent
96
+ class QueryEvent
97
+ def initialize(event_type, database_name, event_table_name, next_position,
98
+ event_length, query, timestamp)
99
+ @event_type = event_type
100
+ @database_name = database_name
101
+ @event_table_name = event_table_name
102
+ @next_position = next_position
103
+ @event_length = event_length
104
+ @query = query
105
+ @timestamp = timestamp
106
+ end
107
+ attr_reader :event_type, :database_name, :event_table_name, :next_position,
108
+ :event_length, :query, :timestamp
109
+
110
+ def to_s
111
+ <<EOS
112
+ event_type;#{event_type} database_name:#{database_name} event_table_name:#{event_table_name} next_position:#{next_position} event_length:#{event_length} timestamp:#{timestamp} query:#{query}
113
+ EOS
114
+ end
115
+ end
116
+
117
+ end
118
+ end
@@ -1,5 +1,5 @@
1
1
  require 'fiber'
2
- require 'flydata/util/mysql_util'
2
+ require 'flydata/mysql/mysql_util'
3
3
 
4
4
  module Flydata
5
5
  module Parser
@@ -73,16 +73,16 @@ EOS
73
73
 
74
74
  begin
75
75
  # create pipe for callback function
76
- rd_io, wr_io = IO.pipe("utf-8")
76
+ rd_io, wr_io = IO.pipe("utf-8", "utf-8")
77
77
  wr_io.sync = true
78
- wr_io.set_encoding("utf-8")
78
+ wr_io.set_encoding("utf-8", "utf-8")
79
79
  rd_io.extend(DumpStreamIO)
80
80
  binlog_pos = nil
81
81
 
82
82
  # start mysqldump
83
83
  Open3.popen3 dump_cmd do |cmd_in, cmd_out, cmd_err, wait_thr|
84
84
  cmd_in.close_write
85
- cmd_out.set_encoding("utf-8") # mysqldump output must be in UTF-8
85
+ cmd_out.set_encoding("utf-8", "utf-8") # mysqldump output must be in UTF-8
86
86
 
87
87
  first_line = cmd_out.gets # wait until first line comes
88
88
  binfile, pos = table_locker.resume
@@ -135,7 +135,7 @@ EOS
135
135
  end
136
136
 
137
137
  def generate_dump_cmd(conf, file_path = nil)
138
- Util::MysqlUtil.generate_mysqldump_without_master_data_cmd(conf.merge(result_file: file_path))
138
+ Flydata::Mysql::MysqlUtil.generate_mysqldump_without_master_data_cmd(conf.merge(result_file: file_path))
139
139
  end
140
140
 
141
141
  private