手动恢复RDS MySQL数据库

有时难免需要恢复数据库到之前某个制定时间点(例如由于SQL误操作并且已经commit导致)。在阿里云控制台,RDS有两种恢复方法,一种是覆盖性恢复,可以为理解通过全量备份覆盖当前数据库,只能选取某个全量备份进行操作;一种是通过创建临时库,可以指定近7天内任意时间点。显然,选择后者相对能将影响降到最低。但是假如由于不靠谱的操作或者其他原因选择了前者,一旦覆盖恢复完成,则不能再创建覆盖性恢复之前时间点的临时库了。本文仅讨论操作了覆盖性恢复,如何尽量再找回一个最接近误操作时间点的数据库。

参考这个文档,首先要把最近的正常的全量备份下载下来,然后是在备份时间点之后的所有binlog增量。最后的一个binlog增量,其中会混合了正常的操作和误操作。

按照文档,先通过rds_backup_extract解压全量备份文件。再通过innobackupex恢复数据文件。然后修改backup-my.cnf,这个文档已经偏旧,实际上你应该只保留如下图的中间那几行就可以。

手动恢复RDS MySQL数据库

然后再根据RDS控制台显示的数据库版本,去下载一个版本号大于等于该版本的MySQL。可以从国内开源镜像下载,不然会比较尴尬。由于是临时使用,随便指向一个目录用完可以删了。

$ mkdir build && cd build
$ cmake .. -DCMAKE_INSTALL_PREFIX=/path/to/tmp/mysql
$ make && make install

之后把/path/to/tmp/mysql/bin临时加到PATH环境变量,放在最前面。

然后就可以启动这个数据库了。

$ mysqld_safe --defaults-file=/path/to/mysqldata/backup-my.cnf --datadir=/path/to/mysqldata

先用客户端连接看看是否正常。如果启动之后异常推出,看看错误日志,一般都能解决。

然后就可以挨个执行那些binlog文件了,当然前面说到的那个混合了正常的操作和误操作的binlog除外。

$ mysqlbinlog mysql-bin.xxxxxx | mysql -uroot --force

如果是5.6开启了GTID,可能会遇到关于GTID的报错。有两个解决办法:

  • 1 修改启动参数,改为如下:
$ mysqld_safe --defaults-file=/path/to/mysqldata/backup-my.cnf --datadir=/path/to/mysqldata --log-bin --log-slave-updates --gtid-mode=ON --enforce-gtid-consistency --binlog_format=row
  • 2 mysqlbinlog加上--skip-gtids参数。

最后,针对那个混合了正常的操作和误操作,先用mysqlbinlog将其转换成文本文件,找到最后的正常事务的时间点,可以通过head -c把正常的部分切割出来,然后手工编辑下,使其格式完整,再重放执行这个binlog。

这样基本能拿到一个最接近误操作时刻的完整数据库了。

更多精彩活动:【有“福”同享.第二季】每日一分享,虚机邮箱免费用

上一篇:scrollHeight的分析


下一篇:为什么说优秀架构师往往是一个悲观主义者?