MySQL增量备份和还原
文章目录
1. MySQL增量备份
(1) 使用mysqldump进行完全备份存在的问题
- 备份数据中有重复数据
- 备份时间与恢复时间过长
- 是自上一次备份后增加/变化的文件或者内容
特点
- 没有重复数据,备份量不大,时间短
- 需要恢复上次完全备份及完全备份之后所有的增量备份才能恢复,而且要
对所有增量备份进行逐个反推恢复
(2) MySQL没有提供直接的增量备份方法
- 可通过MySQL提供的二进制日志间接实现增量备份
(3) MySQL二进制日志对备份的意义
- 二进制日志保存了所有更新或者可能更新数据库的操作
- 二进制日志在启动MySQL服务器后开始记录,并在文件达到
- max_binlog_size所设置的大小或者接收到flush logs命令后重新创建新的日志文件
- 只需定时执行flush logs方法重新创建新的日志,生成二进制文件序列,并及时把这些日志保存到安全的地方就完成了一个时间段的增量备份
2. 增量恢复的方法
(1)一般恢复
- 将所有备份的二进制日志内容全部恢复
- 一般恢复格式
mysqlbinlog [--no-defaults] 增量备份文件 | mysql -u 用户名 -p
案例
- 开启二进制日志功能在数据库的配置文件my.cnf 中添加log-bin=mysql-bin
- 之后产出mysql-bin.000001二进制日志文件
- 先进行完全备份数据库,因为增量备份文件都是基于完全备份文件的基础上然后通过二进制日志文件的记录进行还原
- 在未进行flush logs 产生新的增量备份文件之前,下面的操作是记录到上一次的二进制日志文件中mysql-bin.000001
- 还原增量备份文件之前,需要先还原完全备份文件然后指定增量备份文件的具体操作位置和时间点进行还原,也可以一般增量备份还原。
[root@promote opt]# vim /etc/my.cnf
log-bin=mysql-bin ##添加该语句
[root@promote opt]# systemctl restart mysqld
[root@promote opt]# cd /usr/local/mysql/data/
[root@promote data]# ll
-rw-r-----. 1 mysql mysql 48 8月 22 14:11 master.info
drwxr-x---. 2 mysql mysql 4096 8月 15 12:58 mysql
-rw-r-----. 1 mysql mysql 1303 8月 21 17:04 mysql-bin.000001
[root@promote opt]# mysqldump -u root -p123 auth info > /opt/info.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@promote opt]# ll
总用量 135740
-rw-r--r--. 1 root root 83709983 6月 24 2018 boost_1_59_0.tar.gz
-rw-r--r--. 1 root root 787762 8月 19 15:47 enough.sql
-rw-r--r--. 1 root root 2228 8月 22 14:20 info.sql
drwxr-xr-x. 37 7161 31415 4096 8月 15 12:49 mysql-5.7.17
-rw-r--r--. 1 root root 51433090 6月 24 2018 mysql-5.7.17.tar.gz
-rw-r--r--. 1 root root 1515870 8月 19 13:11 mysql_all-2020-08-19.tar.gz
-rw-r--r--. 1 root root 1515822 8月 19 13:00 mysql_.tar.gz
drwxr-xr-x. 2 root root 6 10月 31 2018 rh
-rw-r--r--. 1 root root 3951 8月 19 15:41 taobao.sql
-rw-r--r--. 1 root root 4231 8月 19 15:45 taobao_user.sql
############ 做增量备份恢复之前需要做完全备份还原#################
[root@promote opt]#mysql -u root -p123 < /opt/info.sql
[root@promote opt]# mysqlbinlog --no-defaults mysql-bin.000001 | mysql -u root -p
(2)基于位置恢复
- 数据库在某一时间点可能既有错误的操作也有正确的操作
- 可以基于精准的位置跳过错误的操作
格式
恢复数据到指定位置
mysqlbinlog --no-defaults --stop-position=’操作 id’ 二进制日志 |mysql -u 用户名 -p 密码
从指定的位置开始恢复数据
mysqlbinlog --no-defaults --start-position=’操作 id’ 二进制日志 |mysql -u 用户名 -p 密码
(3)基于时间点恢复
从日志开头截止到某个时间点的恢复
格式
mysqlbinlog [--no-defaults] --stop-datetime=’年-月-日 小时:分钟:秒’ 二进制日志 | mysql -u 用户名 -p 密码
从某个时间点到日志结尾的恢复
格式
扫描二维码关注公众号,回复:
11629656 查看本文章
mysqlbinlog [--no-defaults] --start-datetime=’年-月-日 小时:分钟:秒’ 二进制日志 | mysql -u 用户名 -p 密码
从某个时间点到某个时间点的恢复
格式
mysqlbinlog [--no-defaults] --start-datetime=’年-月-日 小时:分钟:秒’ --stop-datetime=’年-月-日小时:分钟:秒’ 二进制日志 | mysql -u 用户名 -p 密码
3.查看二进制日志文件
== 注意事项==
假设如下是停止的位置,那么看位置at 之后,第一个at 1203 是插入info06 表的操作位置,at 1257 不是。时间点是2020-08-23 16:26:02 注意时间格式
想要停止某个操作,查找这个操作的位置进行–stop-position =‘位置’ 即可,是指操作到这个位置就停止不执行这个记录的操作
# at 1203
#200823 16:26:02 server id 1 end_log_pos 1257 CRC32 0x20b403ae Table_map: `auth`.`info06` mapped to number 232
# at 1257
#200823 16:26:02 server id 1 end_log_pos 1356 CRC32 0xe5ad7721 Write_rows: table id 232 flags: STMT_END_F
### INSERT INTO `auth`.`info06`
### SET
### @1=1
### @2='qq'
### @3=8
方法一 直接解码查看
[root@localhost data]#/usr/local/mysql/bin/mysqlbinlog --no-defaults --base64-output=DECODE-ROWS -v mysql-bin.000001
方法二:导入到TXT文本中查看
[root@localhost data]#/usr/local/mysql/bin/mysqlbinlog --no-defaults --base64-output=DECODE-ROWS -v mysql-bin.000001 > /opt/bk01.txt
[root@localhost data]#cat /opt/bk01.txt
4. 案例:企业数据恢复
(1)需求描述
- 北京移电通信公司的用户信息数据库为client,用户资费数据表为user_info
- 为该公司每周进行完全备份每天为该公司进行增量备份
用户信息
- 初始数据记录添加
- 开启MySQL的二进制日志功能
- 方法1:MySQL的配置文件的 [mysqld]
项中加入log-bin=filepath项,如log-bin=mysql-bin,然后重启mysqld服务 - 二进制日志的默认路径/usr/local/mysql/data/
- 方法2:启动MySQL时增加–log-bin=filepath参数
- 其中 filepath要改为实际的二进制文件的路径
- 执行后,/usr/local/mysql/data/中会生成mysql-bin.000001日志文件
[root@promote opt]# vim /etc/my.cnf
log-bin=mysql-bin ##添加该语句
[root@promote opt]# cd /usr/local/mysql/data
[root@promote data]# ll
-rw-r-----. 1 mysql mysql 154 8月 23 12:10 mysql-bin.000001
-rw-r-----. 1 mysql mysql 19 8月 23 12:10 mysql-bin.index
- 使用mysqldump命令进行完整备份,可对数据库或表进行备份
[root@localhost ~]# mysqldump -u root -p client user_info > client-userinfo.sql
- 生成新的二进制日志
[root@localhost ~]# mysqladmin -uroot -p flush-logs
Enter password: //输入数据库密码
- 插入新的数据,并进行增量备份
- 2020-01-02 16:41:16 插入赵六
- 2020-01-02 16:41:24 插入孙七
MySQL [(none)]> use client;
Database changed
MySQL [client]> insert into user_info values('000009','赵六','男','019','37');
Query OK, 1 row affected (0.00 sec)
MySQL [client]> insert into user_info values('000010','孙七','男','020','36');
Query OK, 1 row affected (0.00 sec)
MySQL [client]>
[root@localhost ~]# mysqladmin -uroot -p flush-logs
Enter password: //输入数据库密码
- 模拟误操作,删除user_info表
[root@localhost ~]# mysql -u root -p -e 'drop table client.user_info;'
- 执行完全恢复
[root@localhost ~]# mysql -u root -p client < client-userinfo.sql
[root@localhost ~]# mysql -u root -p
MySQL [(none)]> use client
Database changed
MySQL [client]> select * from user_info;
+--------------+--------+--------+--------+----------+
| IdentityCard | name | gender | UserID | expenses |
+--------------+--------+--------+--------+----------+
| 000006 | 张三 | 男 | 016 | 10 |
| 000007 | 李四 | 女 | 017 | 91 |
| 000008 | 王五 | 女 | 018 | 23 |
+--------------+--------+--------+--------+----------+
5 rows in set (0.00 sec)
- 一般恢复(增量部分)
[root@localhost ~]# mysqlbinlog --no-defaults /mysql_bak/mysql-bin.000002| mysql -u root -p
Enter password:
[root@Mysql1 ~]# mysql -u root -p
Enter password:
MySQL [(none)]> use client;
Database changed
MySQL [client]> select * from user_info;
| IdentityCard | name | gender | UserID | expenses |
+----------+-------+-------+-----------+-------+
| 000006 | 张三 | 男 | 016 | 10 |
| 000007 | 李四 | 女 | 017 | 91 |
| 000008 | 王五 | 女 | 018 | 23 |
| 000009 | 赵六 | 男 | 019 | 37 |
| 000010 | 孙七 | 男 | 020 | 36 |
+----------+-------+-------+-----------+-------+
6 rows in set (0.00 sec)
- 基于位置恢复到添加孙七之前的数据记录
- 先查看二进制日志的文件,找到具体基于某个位置或者时间点进行恢复
[root@localhost data]#/usr/local/mysql/bin/mysqlbinlog --no-defaults --base64-output=DECODE-ROWS -v mysql-bin.000001
[root@localhost ~]# mysqlbinlog --stop-position='623' /mysql_bak/data/mysql-bin.000002 | mysql -uroot -p
Enter password:
[root@Mysql1 ~]# mysql -u root -p
Enter password:
MySQL [(none)]> use client;
Database changed
MySQL [client]> select * from user_info;
+-----------+--------+--------+-------------+--------+
| IdentityCard | name | gender | UserID | expenses |
+-----------+--------+--------+-------------+--------+
| 000006 | 张三 | 男 | 016 | 10 |
| 000007 | 李四 | 女 | 017 | 91 |
| 000008 | 王五 | 女 | 018 | 23 |
| 000009 | 赵六 | 男 | 019 | 37 |
+-----------+--------+--------+-------------+--------+
5 rows in set (0.00 sec)
- 基于时间恢复赵六的数据记录
[root@localhost ~]# mysqlbinlog --stop-datetime='2020-01-02 16:41:24' /mysql_bak/data/mysql-bin.000002 | mysql -u root -p
Enter password:
[root@Mysql1 ~]# mysql -u root -p
Enter password:
MySQL [(none)]> use client;
Database changed
MySQL [client]> select * from user_info;
+----------+-------+------+------------+--------+
| IdentityCard | name | gender | UserID | expenses |
+----------+-------+------+------------+--------+
| 000006 | 张三 | 男 | 016 | 10 |
| 000007 | 李四 | 女 | 017 | 91 |
| 000008 | 王五 | 女 | 018 | 23 |
| 000009 | 赵六 | 男 | 019 | 37 |
+----------+-------+------+------------+--------+
6 rows in set (0.00 sec)
6. 总结
- 在flush-logs 设置增量备份之前,必须先进行完全备份。MySQLdump
- 当前对数据库表格的操作是记录在上一次二进制日志记录文件中。所以想要实现记录,先执行flush-logs 生成增量记录日志文件。
- 在做任何增量备份还原的时候,需要执行完全备份恢复。MySQL或者source