有时难免需要恢复数据库到之前某个制定时间点(例如由于SQL误操作并且已经commit导致)。在阿里云控制台,RDS有两种恢复方法,一种是覆盖性恢复,可以为理解通过全量备份覆盖当前数据库,只能选取某个全量备份进行操作;一种是通过创建临时库,可以指定近7天内任意时间点。显然,选择后者相对能将影响降到最低。但是假如由于不靠谱的操作或者其他原因选择了前者,一旦覆盖恢复完成,则不能再创建覆盖性恢复之前时间点的临时库了。本文仅讨论操作了覆盖性恢复,如何尽量再找回一个最接近误操作时间点的数据库。
参考这个文档,首先要把最近的正常的全量备份下载下来,然后是在备份时间点之后的所有binlog增量。最后的一个binlog增量,其中会混合了正常的操作和误操作。
按照文档,先通过rds_backup_extract
解压全量备份文件。再通过innobackupex
恢复数据文件。然后修改backup-my.cnf,这个文档已经偏旧,实际上你应该只保留如下图的中间那几行就可以。
然后再根据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。
这样基本能拿到一个最接近误操作时刻的完整数据库了。
更多精彩活动:【有“福”同享.第二季】每日一分享,虚机邮箱免费用