2013-12-17 210 views
15

我正在尝试在AWS外部设置副本,并且主服务器正在AWS RDS上运行。我不想让我的主人有任何停机时间。所以我设置了我的从节点,现在我想备份当前在AWS的数据库。备份MySQL亚马逊RDS

mysqldump -h RDS ENDPOINT -u root -p --skip-lock-tables --single-transaction --flush-logs --hex-blob --master-data=2 --all-databases > /root/dump.sql

我测试我的虚拟机和它的工作很好,但与RDS搭售时,它给了我错误

mysqldump: Couldn't execute 'FLUSH TABLES WITH READ LOCK': Access denied for user 'root'@'%' (using password: YES) (1045)

是不是因为我不具备超级用户权限或如何我解决了这个问题?请有人建议我。

+0

看起来像一个权限问题。最有可能的是,root用户没有被授予来自您要发送请求的任何ip的权限。你可以尝试SHOW GRANTS FOR'root'@'%';确认。另外假设你删除了该帖子的密码。 –

+0

谢谢埃文。这些是我对用户root的权限“SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,RELOAD,PROCESS,REFERENCES,INDEX,ALTER,SHOW DATABASES,CREATE TEMPORARY TABLES,LOCK TABLES,EXECUTE,REPLICATION SLAVE,REPLICATION CLIENT,CREATE VIEW,SHOW VIEW,CREATE ROUTINE,ALTER ROUTINE,CREATE USER,EVENT''我缺少什么权限?有什么想法吗。 – JavaGuy

+0

而这些权限是'root'@'%'正确的吗? MySQL GRANTS是基于'ip'的'用户'。它实际上是非默认的(我相信)为一个root授予所有权限*。* TO'root'@'%' –

回答

45

RDS甚至不允许主用户使用SUPER权限,并且这是执行FLUSH TABLES WITH READ LOCK所必需的。 (这是RDS的一个不幸的限制)。

失败语句由--master-data选项生成,当然,如果您想要了解备份开始时的精确二进制日志坐标,这当然是必需的。 FLUSH TABLES WITH READ LOCK获得关于所有表全局读锁定,允许的mysqldump来START TRANSACTION WITH CONSISTENT SNAPSHOT(因为它与--single-transaction一样),然后SHOW MASTER STATUS获得二进制日志坐标后,它释放全局读锁定,因为它有将保持可见交易数据处于与日志位置一致的状态。

RDS打破了这种机制,通过拒绝SUPER特权,并提供没有明显的解决方法。

有可正常工作一些解决这个哈克选项,其中没有一个是特别有吸引力:

  • 期间低流量做备份。如果binlog坐标在开始备份和备份开始将数据写入输出文件或目标服务器(假设您使用的是--single-transaction)之间没有发生变化,那么这将起作用,因为您知道坐标没有改变进程正在运行。

  • 观察主服务器上的二进制日志位置右侧开始备份之前,并使用这些坐标与CHANGE MASTER TO。如果您的主人的binlog_format设置为ROW那么这应该起作用,尽管您可能不得不跳过一些初始错误,但不应该随后出现任何错误。这是有效的,因为基于行的复制是非常确定性的,如果它试图插入已经存在的东西或删除已经消失的东西,它将停止。一旦过去了错误,你将会处在实际开始的一致快照所在的真正的二进制日志坐标中。

  • 如前面的项目,但是,恢复备份后尝试通过mysqlbinlog --base64-output=decode-rows --verbose你获得的坐标读大师的二进制日志,检查你的新奴隶,看看哪些事件必须已经确定正确的位置在快照实际开始之前已经被执行,并且使用以这种方式确定的坐标为CHANGE MASTER TO

  • 使用外部处理,以获得在每个读锁和服务器,该服务器将停止所有的写操作在每个表;观察到SHOW MASTER STATUS的binlog位置已停止递增,启动备份并释放这些锁。

如果你使用任何比也许是最后一个其他的这些方法,这是特别重要的,你做表的比较是一定的,一旦它运行你的奴隶是相同的主。如果你遇到后续的复制错误......那么它不是。

可能是最安全的选择 - 也可能是最烦人的,因为它似乎不应该是必要的 - 首先创建RDS主设备的RDS只读副本。一旦启动并同步到主设备,您可以通过执行RDS提供的存储过程CALL mysql.rds_stop_replicationwhich was introduced in RDS 5.6.13 and 5.5.33停止RDS只读副本上的复制,该过程不需要SUPER权限。

在RDS副本从站停止的情况下,从RDS只读副本取出您的mysqldump,该副本现在将具有不变的数据集,并作为特定的一组主坐标。将此备份还原到您的异地从属设备,然后使用SHOW SLAVE STATUSExec_Master_Log_PosRelay_Master_Log_File的RDS只读副本的主坐标作为您的CHANGE MASTER TO坐标。

从站上的Exec_Master_Log_Pos中显示的值为the start of the next transaction or event to be processed,这就是您的新从站需要在主站上开始读取的确切位置。

然后,只要外部从站启动并运行,就可以停用RDS只读副本。

+0

你可以把它翻译成非mysql专家吗?我不明白'Exec_Master_Log_Pos','Relay_Master_Log_File'等。每个命令在哪里执行? – dieend

+2

@dieend这些是您将在查询'SHOW SLAVE STATUS;'的输出中看到的列。 http://dev.mysql.com/doc/refman/5.6/en/show-slave-status.html –

+0

如何“将此备份还原到您的场外奴隶”以及如何设置奴隶“这正是您的位置新的奴隶需要开始阅读主人。“? – dieend

-3

无论事情已经改变,因为@迈克尔 - sqlbot的反应,或存在一个误区,这里发生了(可能是我的一部分),

您可以使用COPY导入CSV文件导入到RDS,至少在Postgres的版本,你只需要使用FROM STDIN,而不是直接命名的文件,
这意味着你最终管道之类的东西:

cat data.csv | psql postgresql://server:5432/mydb -U user -c "COPY \"mytable\" FROM STDIN DELIMITER ',' " 
+0

我想你可能误解了这个问题。它涉及MySQL的RDS,并在RDS外部的MySQL服务器上设置实时读取副本。设置副本需要一个备份,在一个精确的时间点快照服务器,将该快照恢复到另一台计算机,然后指示第二台服务器开始在执行备份的精确位置从主服务器执行复制事件。对RDS的限制禁止在该流程开始时获得简短的全局锁定的能力。 –

1

迈克尔的回答是非常有益的,重点是主要症结:你根本无法GRANT所需SUPER权限在RDS上,因此你不能使用--master-data标志来让事情变得更容易。

我读过,有可能通过API创建或修改数据库参数组来解决这个问题,但我认为使用RDS过程是一个更好的选择。

虽然多层复制方法运行良好,并且可以包含RDS/VPC之外的层,因此可以使用此方法从“Classic”EC2复制到VPC。

许多必需的功能只在MySQL 5.5和5.6的后续版本中有效,我强烈建议您在复制堆栈中涉及的所有数据库上运行相同的版本,因此您可能必须升级之前的所有这些,这意味着更乏味和复制等等。

3

的RDS二进制日志位置可以使用mydumper--lock-all-tables,它将使用LOCK TABLES ... READ只是为了让二进制日志坐标,然后realease它,而不是FTWRL

2

感谢Michael,我认为最正确的解决方案和AWS推荐的方法是使用只读副本作为源进行复制,如解释here所述。

拥有一个RDS高手,RDS读取副本,与MySQL实例准备,步骤获得外部从有:

  1. 在主,增加二进制日志保留期。

mysql> CALL mysql.rds_set_configuration('binlog retention hours', 12);

  • 在读复制品停止复制,以避免在备份过程中的变化。
  • mysql> CALL mysql.rds_stop_replication;

  • 在读复制品注释的binlog状态(MASTER_LOG_FILE和Read_Master_Log_Pos)
  • mysql> SHOW SLAVE STATUS;

  • 在服务器实例上执行备份并导入它(使用Max建议的mydumper可以加快此过程)。
  • mysqldump -h RDS_READ_REPLICA_IP -u root -p YOUR_DATABASE > backup.sql

    mysql -u root -p YOUR_DATABASE < backup.sql

  • 在服务器实例设置为RDS主从设备。
  • mysql> CHANGE MASTER TO MASTER_HOST='RDS_MASTER_IP',MASTER_USER='myrepladmin', MASTER_PASSWORD='pass', MASTER_LOG_FILE='mysql-bin-changelog.313534', MASTER_LOG_POS=1097;

    Relace MASTER_LOG_FILE和MASTER_LOG_POS到MASTER_LOG_FILE Read_Master_Log_Pos的值,您之前保存的,你也需要在RDS主的用户通过从复制使用。

    mysql> START SLAVE;

  • 在服务器实例检查是否复制了成功。
  • mysql> SHOW SLAVE STATUS;

  • 在RDS读副本恢复复制。 mysql> CALL mysql.rds_start_replication;
  • +0

    这工作就像一个魅力!谢谢! – Tsojcanth