我正在尝试在AWS外部设置副本服务器,并且主服务器正在AWS RDS上运行.而且我不想让我的主人停机.所以我设置了我的从节点,现在我想备份我在AWS的当前数据库.
mysqldump -h RDS ENDPOINT -u root -p --skip-lock-tables --single-transaction --flush-logs --hex-blob --master-data=2 --all-databases > /root/dump.sql
我在我的VM上测试了它并且工作正常但是当它与RDS捆绑时它给了我错误
mysqldump: Couldn't execute 'FLUSH TABLES WITH READ LOCK': Access denied for user 'root'@'%' (using password: YES) (1045)
是因为我没有超级用户权限或者我如何解决这个问题?请有人建议我.
RDS甚至不允许主用户使用该SUPER
权限,这是执行所必需的FLUSH TABLES WITH READ LOCK
.(这是RDS的一个不幸的限制).
--master-data
选项会生成失败的语句,当然,如果您希望能够学习备份开始的精确binlog坐标,则必须使用该语句. FLUSH TABLES WITH READ LOCK
获取所有表的全局读锁定,允许mysqldump START TRANSACTION WITH CONSISTENT SNAPSHOT
(就像它一样--single-transaction
)然后SHOW MASTER STATUS
获取二进制日志坐标,之后它释放全局读锁定,因为它有一个事务可以将可见数据保持在一个状态与该日志位置一致.
RDS通过拒绝SUPER
权限并且没有提供明显的解决方法来打破这种机制.
有一些hacky选项可以正确地解决这个问题,其中没有一个可能特别有吸引力:
在低流量期间进行备份.如果binlog坐标在您开始备份的时间和备份开始将数据写入输出文件或目标服务器之间没有变化(假设您已使用--single-transaction
),那么这将起作用,因为您知道在过程中坐标没有改变正在运行.
在开始备份之前观察主控权上的binlog位置,并使用这些坐标CHANGE MASTER TO
.如果你的主人binlog_format
设置为ROW
那么这应该有效,尽管你可能不得不跳过几个初始错误,但不应该随后有任何错误.这是有效的,因为基于行的复制是非常确定的,如果它试图插入已存在的东西或删除已经存在的东西,它将停止.一旦超过错误,您将处于实际开始的一致快照的真实binlog坐标.
与前一项相同,但是,在恢复备份之后尝试通过使用mysqlbinlog --base64-output=decode-rows --verbose
在您获得的坐标处读取主的binlog 来确定正确的位置,检查新的从站以查看实际快照之前必须已执行的事件开始,并使用以这种方式确定的坐标CHANGE MASTER TO
.
使用外部进程获取服务器上每个表的读锁定,这将停止所有写操作; 观察到binlog位置SHOW MASTER STATUS
已停止递增,启动备份并释放这些锁.
如果您使用除最后一种方法之外的任何方法,那么进行表格比较以确保您的从站在运行后与主站相同时尤其重要.如果你遇到后续的复制错误......那就不是了.
可能最安全的选择 - 也可能是最烦人的,因为它似乎不应该是必要的 - 首先是创建RDS主机的RDS读取副本.一旦启动并与主服务器同步,您就可以通过执行RDS提供的存储过程来停止RDS只读副本上的复制,该存储过程CALL mysql.rds_stop_replication
是在RDS 5.6.13和5.5.33中引入的,不需要该SUPER
权限.
在RDS副本从站停止的情况下,将您mysqldump
从RDS读取副本中取出,该副本现在将具有一个不变的数据集,作为一组特定的主坐标.该备份还原到异地奴隶,然后使用RDS读取副本的主坐标SHOW SLAVE STATUS
Exec_Master_Log_Pos
,并Relay_Master_Log_File
为您的CHANGE MASTER TO
坐标.
Exec_Master_Log_Pos
从站上显示的值是下一个要处理的事务或事件的开始,这正是新从站需要开始在主站上读取的位置.
然后,一旦外部从站启动并运行,您就可以停用RDS只读副本.