Class: Flydata::Parser::Mysql::MysqlDumpGeneratorNoMasterData

Inherits:
MysqlDumpGenerator show all
Defined in:
lib/flydata/parser/mysql/dump_parser.rb

Constant Summary collapse

CHANGE_MASTER_TEMPLATE =
<<EOS
--
-- Position to start replication or point-in-time recovery from
--

-- CHANGE MASTER TO MASTER_LOG_FILE='%s', MASTER_LOG_POS=%d;

EOS

Instance Method Summary collapse

Methods inherited from MysqlDumpGenerator

#initialize

Constructor Details

This class inherits a constructor from Flydata::Parser::Mysql::MysqlDumpGenerator

Instance Method Details

#dump(file_path = nil, &block) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/flydata/parser/mysql/dump_parser.rb', line 63

def dump(file_path = nil, &block)
  unless file_path || block
    raise ArgumentError.new("file_path or block must be given.")
  end

  dump_cmd = generate_dump_cmd(@conf, file_path)

  # RDS doesn't allow obtaining binlog position using mysqldump.  Get it separately and insert it into the dump file.
  table_locker = create_table_locker
  table_locker.resume # Lock tables

  begin
    # create pipe for callback function
    rd_io, wr_io = IO.pipe("utf-8", "utf-8")
    wr_io.sync = true
    wr_io.set_encoding("utf-8", "utf-8")
    rd_io.extend(DumpStreamIO)
    binlog_pos = nil

    # start mysqldump
    Open3.popen3 dump_cmd do |cmd_in, cmd_out, cmd_err, wait_thr|
      cmd_in.close_write
      cmd_out.set_encoding("utf-8", "utf-8") # mysqldump output must be in UTF-8

      first_line = cmd_out.gets # wait until first line comes
      binfile, pos = table_locker.resume
      binlog_pos = {binfile: binfile, pos: pos}

      threads = []

      # filter dump stream and write data to pipe
      threads << Thread.new do
        begin
          wr_io.print(first_line) # write a first line
          filter_dump_stream(cmd_out, wr_io)
        ensure
          wr_io.close rescue nil
        end
      end

      # show err message
      errors = ""
      threads << Thread.new do
        cmd_err.each_line do |line|
          errors << line unless /^Warning:/ === line
        end
      end

      if block
        # call callback function with io if block is given
        block.call(rd_io, binlog_pos)
      end

      threads.each(&:join)
      unless wait_thr.value == 0
        #Raise error if the process exited with status != 0
        #(Even if there was no message on stderr stream)
        errors = "Failed to run mysqldump command." if errors.empty?
      end
      raise errors unless errors.empty?
    end
    binlog_pos
  rescue
    # Cleanup
    FileUtils.rm(file_path) if file_path && File.exists?(file_path)
    raise
  ensure
    # Let table_locker finish its task even if an exception happened
    table_locker.resume if table_locker.alive?
    rd_io.close rescue nil
    wr_io.close rescue nil
  end
end

#generate_dump_cmd(conf, file_path = nil) ⇒ Object



137
138
139
# File 'lib/flydata/parser/mysql/dump_parser.rb', line 137

def generate_dump_cmd(conf, file_path = nil)
  Flydata::Mysql::MysqlUtil.generate_mysqldump_without_master_data_cmd(conf.merge(result_file: file_path))
end