Class: Flydata::Mysql::MysqlDumpGeneratorNoMasterData

Inherits:
MysqlDumpGenerator show all
Defined in:
lib/flydata/command/sync.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::Mysql::MysqlDumpGenerator::MYSQL_DUMP_CMD_TEMPLATE

Instance Method Summary collapse

Methods inherited from MysqlDumpGenerator

#initialize

Constructor Details

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

Instance Method Details

#dump(file_path) ⇒ Object



907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
# File 'lib/flydata/command/sync.rb', line 907

def dump(file_path)
  # RDS doesn't allow obtaining binlog position using mysqldump.  Get it separately and insert it into the dump file.
  table_locker = Fiber.new do
    client = Mysql2::Client.new(@db_opts)
    # Lock tables
    client.query "FLUSH LOCAL TABLES;"
    q = flush_tables_with_read_lock_query(client)
    puts "FLUSH TABLES query: #{q}" if FLYDATA_DEBUG
    client.query q
    begin
      Fiber.yield  # Lock is done.  Let dump to start
      # obtain binlog pos
      result = client.query "SHOW MASTER STATUS;"
      row = result.first
      if row.nil?
        raise "MySQL DB has no replication master status.  Check if the DB is set up as a replication master.  In case of RDS, make sure that Backup Retention Period is set to more than 0."
      end
    ensure
      # unlock tables
      client.query "UNLOCK TABLES;"
      client.close
    end

    [row["File"], row['Position']]
  end

  table_locker.resume # Lock tables
  begin
    # start dump
    Open3.popen3 @dump_cmd do |cmd_in, cmd_out, cmd_err|
      cmd_in.close_write
      cmd_out.set_encoding("utf-8") # mysqldump output must be in UTF-8
      File.open(file_path, "w", encoding: "utf-8") do |f|
        find_insert_pos = :not_started
        cmd_out.each_line do |line|
          if find_insert_pos == :not_started && /^-- Server version/ === line
            find_insert_pos = :finding
          elsif find_insert_pos == :finding && /^--/ === line
            # wait before writing the first database queries
            file, pos = table_locker.resume # Get binlog pos
            # insert binlog pos
            change_master =  CHANGE_MASTER_TEMPLATE % [file, pos]
            f.print change_master

            find_insert_pos = :found
            # resume dump
          end
          f.print line
        end
      end
      cmd_err.each_line do |line|
        $stderr.print line unless /^Warning:/ === line
      end
    end
  rescue
    # Cleanup
    FileUtils.rm(file_path) if File.exists?(file_path)
    raise
  ensure
    # Let table_locker finish its task even if an exception happened
    table_locker.resume if table_locker.alive?
  end
end