学术能力的缺乏并不意味着你就擅长混社会,说不定还不如在学校的表现

发掘积累过程的快感

首页 » BIBLE模型 » 数据库技术 » MySQL增量备份与恢复实例

MySQL增量备份与恢复实例


小量的数据库可以每天进行完整备份,因为这也用不了多少时间,但当数据库很大时,就不太可能每天进行一次完整备份了,这时候就可以使用增量备份。增量备份的原理就是使用了 mysql 的 binlog 日志。
本次操作的 MySQL 版本为 5.5.40 for Linux (x86_64)

增量备份要确保打开了二进制日志。

mysql> show variables like '%log_bin%';

首先对 pak 数据库做一个完整备份:

$ mysqldump -h localhost -upak -ppwd -P3306 --master-data=2 --single-transaction --opt pak > pak_bak_full.sql

这时候就会得到一个全备文件 pak_bak_full.sqlmysqldump 操作会导致滚动一次 log,假设新的 binlog 文件是 mysql-bin.000002。

1. 模拟插入数据和误操作

a. 在 pak 库的某个表插入一些数据,然后执行 flush logs 命令。这时将会产生一个新的二进制日志文件 mysql-bin.000003,mysql-bin.000002 则保存了全备过后的所有更改,既增加记录的操作也保存在了 mysql-bin.00002 中。

b. 再在 pak 库中的 t_user 表中增加两条记录,然后误删除 t_user 表。t_user 中增加记录的操作和删除表的操作都记录在 mysql-bin.000003 中。

2. 开始恢复

恢复过程不要记录日志:

mysql > set global sql_log_bin=0;

3. 首先导入全备数据

$ mysql -h localhost -upak -ppwd < pak_bak_full.sql
或
mysql> source /path/backup/pak_bak_full.sql

我们也可以看到全备时的 binlog 位置:

head -50 backup-file.sql |grep 'CHANGE MASTER'
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=4321;

查看当前所在二进制日志中的位置:

mysql> show master status;

根据上面两个 position 能大概确定需要完整恢复哪几个 binlog 文件。

在待恢复的 position 或时间点以前、全备以后的 binlog 需要全部恢复,多个文件以空格隔开

$ mysqlbinlog /var/lib/mysql/mysql-bin.000002 | mysql -uroot -p

此时查询可以得到前两条数据。

5. 恢复部分 mysql-bin.000003

这个日志中包括了新增记录和误删表两个部分,我们需要恢复到新增记录之后、误删操作以前的位置。

如果知道误操作的命令如 DROP TABLE,则可以通过下面的方法在 binlog 文件中找到误操作之前的那个 position:
(如下面的信息显示,误操作 DROP TABLE 之前的 pos 是 775,在 datetime 141204 15:08:04 或 pos 882 时完成 DROP TABLE 操作)

$ mysqlbinlog /var/lib/mysql/mysql-bin.000003 |grep -C 5 'DROP TABLE'
#141204 15:07:05 server id 1  end_log_pos 775     Xid = 376
COMMIT/*!*/;
# at 775
#141204 15:08:04 server id 1  end_log_pos 882     Query    thread_id=10    exec_time=0    error_code=0
SET TIMESTAMP=1417676884/*!*/;
DROP TABLE `t_user` /* generated by server */
/*!*/;
# at 882

恢复命令:

$ mysqlbinlog /var/lib/mysql/mysql-bin.000003 --stop-position=775 | mysql -h localhost -uroot -p

如果 position 难以确定,但知道需要恢复到的确切(服务器)时间,也可以使用 datetime:

$ mysqlbinlog /var/lib/mysql/mysql-bin.000003 --stop-datetime="2014-12-04 15:08:00" | mysql -uroot -p

如果不是误操作导致的,而是迁移数据库,那么不需要 position 或 datetime,使用所有 binlog 文件增量恢复即可。

确定恢复成功后记得打开日志记录:

mysql > set global sql_log_bin=1;

报错

  1. unknown variable ‘default-character-set=utf8’
    在使用 mysqlbinlog 查看二进制日志的时候,提示下面的错误:

    /usr/local/mysql/bin/mysqlbinlog: unknown variable ‘default-character-set=utf8’

    原因是在我为了统一 mysql 客户端到服务端的的字符编码,在 /etc/my.cnf 文件的 [client][mysqld] 等节加入了 default-character-set = utf8mysqlbinlog 会从 my.cnf 中的 [client] 读取配置,但奈何 mysqlbinlog 并不认识这个选项(据说是个 bug)导致的。
    应对这个 bug 的方法有两个:
    第一,自然是注释到 [client] 中的这个字符集配置;
    第二,改用 loose-default-character-set = utf8。在选项前加了 loose-,表示当程序不认识此选项时会略过此选项,并给出一个警告。

互联网信息太多太杂,各互联网公司不断推送娱乐花边新闻,SNS,微博不断转移我们的注意力。但是,我们的时间和精力却是有限的。这里是互联网浩瀚的海洋中的一座宁静与美丽的小岛,供开发者歇息与静心潜心修炼。 “Bible”是圣经,有权威的书,我们的本意就是为开发者提供真正有用的的资料。 我的电子邮件 1217179982@qq.com,您在开发过程中遇到任何问题,欢迎与我联系。
Copyright © 2024. All rights reserved. 本站由 Helay 纯手工打造. 蜀ICP备15017444号