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

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

Constant Summary collapse

EXTRA_MYSQLDUMP_PARAMS =
""
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

Constants inherited from MysqlDumpGenerator

Flydata::Parser::Mysql::MysqlDumpGenerator::MYSQL_DUMP_CMD_TEMPLATE

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



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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/flydata/parser/mysql/dump_parser.rb', line 94

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

  # 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
    wr_io.sync = true
    wr_io.set_encoding("utf-8")
    rd_io.extend(DumpStreamIO)

    # 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") # mysqldump output must be in UTF-8

      first_line = cmd_out.gets # wait until first line comes
      binlog_file, binlog_pos = table_locker.resume

      threads = []

      # filter dump stream and write data to pipe
      threads << Thread.new do
        begin
          wr_io.print(first_line) # write a first line
          fileter_dump_stream(cmd_out, wr_io, binlog_file, binlog_pos)
        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)
      elsif file_path
        # store data to file
        open_file_stream(file_path) {|f| rd_io.each_line{|l| f.print(l)}}
      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
    true
  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