文章目录
- 一、 MySQL 增量备份与恢复
- 1.1 增量备份的特点
- 1.2 MySQL 二进制日志对备份的意义
- 1.3 MySQL 增量恢复
- 1.3.1 一般恢复
- 1.3.2 基于位置的恢复
- 1.3.3 基于时间点的恢复
- 二、 增量备份与还原实验
- 1. 做完整备份
- 2.开启二进制日志文件
- 3. 在数据库中插入数据,做断点恢复的条件
- 4.在上面的前提下,又做了增量备份
- 5. 对二进制日志文件进行解码
- 6. 进行断点恢复
- 根据位置点进行恢复
- 根据时间点进行恢复
一、 MySQL 增量备份与恢复
使用 mysqldump 进行完全备份,备份的数据中有重复数据,备份时间与恢复时间过长。而增量备份就是自上一次备份之后增加或改变的内容。
1.1 增量备份的特点
- 增量备份没有重复数据,备份量不大,时间短;
- 恢复麻烦,需要上次完全备份及完全备份之后所有的增量备份才能恢复,而且要对所有增量备份进行逐个反推恢复。
-MySQL 没有提供直接的增量备份办法,可以通过 MySQL 提供的二进制日志(binary logs)间接实现增量备份。
1.2 MySQL 二进制日志对备份的意义
二进制日志保存了所有更新数据库的操作。二进制日志在启动 MySQL 服务器后开始记 录,并在文件达到二进制日志所设置的最大值或者接收到 flushlogs 命令后重新创建新的日志文件,生成二进制文件序列,并及时把这些日志保存到安全的存储位置,即可完成一个时间段的增量备份。
使用 max_binlog_size 配置项可以设置二进制日志文件的最大值,达到最大值,它就会自动创建新的二进制文件。
要进行 MySQL 的增量备份,首先要开启二进制日志功能。开启 MySQL 的二进制日志功能的实现方法有很多种,最常用的是在 MySQL 配置文件的 mysqld 项下加入“log-bin=/ 文件路径/文件名”前缀,如 log-bin=/usr/local/mysql/mysql-bin,然后重启 MySQL 服务就可以在指定路径下查看二进制日志文件了。默认情况下,二进制日志文件的扩展名是一个六位的数字,如 mysql-bin.000001。
[root@localhost~]#vim/etc/my.cnf
[mysqld]
log-bin=/usr/local/mysql/data/mysql-bin
binlog_format=MIXED
[root@localhost~]#systemctlrestartmysqld
1.3 MySQL 增量恢复
常用的增量恢复的方法有三种:一般恢复、基于位置的恢复、基于时间点的恢复。
1.3.1 一般恢复
将所有备份的二进制日志内容全部恢复。
一般恢复格式
mysqlbinlog[--no-defaults] 增量备份文件 |mysql-u 用户名 -p 密码
1.3.2 基于位置的恢复
数据库管理员在操作数据库时可能在同一时间点既有错误的操作也有正确的操作,通过基于位置进行恢复可以更加精准。
基于位置的恢复格式--恢复数据到指定位置。
mysqlbinlog--stop-position='操作 id' 二进制日志 |mysql-u 用户名 -p 密码
从指定的位置开始恢复数据格式
mysqlbinlog--start-position='操作 id' 二进制日志 |mysql-u 用户名 -p 密码
1.3.3 基于时间点的恢复
跳过某个发生错误的时间点实现数据恢复,有三种方式
- 从日志开头截止到某个时间点的恢复。
mysqlbinlog[--no-defaults]--stop-datetime='年-月-日 小时:分钟:秒' 二进制日志 |mysql-u 用户名 -p 密码
- 从某个时间点到日志结尾的恢复。
mysqlbinlog[--no-defaults]--start-datetime='年-月-日 小时:分钟:秒' 二进制日志 |mysql-u 用户名 -p 密码
- 从某个时间点到某个时间点的恢复。
mysqlbinlog[--no-defaults]--start-datetime='年-月-日 小时:分钟:秒' --stop-datetime='年-月-日小时:分钟:秒' 二进制日志 |mysql-u 用户名 -p 密码
二、 增量备份与还原实验
1. 做完整备份
mysql> use company;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+-------------------+
| Tables_in_company |
+-------------------+
| info |
+-------------------+
1 row in set (0.00 sec)
mysql> select * from info;
+----+----------+---------+
| id | name | address |
+----+----------+---------+
| 1 | zhangsan | nj |
| 2 | lisi | bj |
+----+----------+---------+
2 rows in set (0.00 sec)
做完全备份
[root@localhost ~]# mysqldump -u root -pabc123 company info > /opt/company_info.sql ##将数据库company中的info表备份到/opt目录下
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@localhost ~]# ls /opt
boost_1_59_0.tar.gz mysql-5.7.17 mysql_all_2020-08-23.tar.gz rh
company_info.sql mysql-5.7.17.tar.gz mysql-boost-5.7.20.tar.gz
2.开启二进制日志文件
[root@localhost opt]# vim /etc/my.cnf
[root@localhost ~]# systemctl restart mysqld
3. 在数据库中插入数据,做断点恢复的条件
在数据库中插入数据
mysql> insert into info(name,address) values ('wangwu','nj'); ##这一步为我们想要进行的正确操作,插入一条数据
Query OK, 1 row affected (0.00 sec)
mysql> select * from info;
+----+----------+---------+
| id | name | address |
+----+----------+---------+
| 1 | zhangsan | nj |
| 2 | lisi | bj |
| 3 | wangwu | nj |
+----+----------+---------+
3 rows in set (0.00 sec)
mysql> delete from info where id=1; ##这一步为误操作,不小心删除了需要的数据
Query OK, 1 row affected (0.00 sec)
mysql> select * from info;
+----+--------+---------+
| id | name | address |
+----+--------+---------+
| 2 | lisi | bj |
| 3 | wangwu | nj |
+----+--------+---------+
2 rows in set (0.00 sec)
mysql> insert into info(name,address) values ('zhaoliu','nj'); ##在上一步的误操作之上,又做了一步正确的操作,添加了一条数据
Query OK, 1 row affected (0.01 sec)
mysql> select * from info;
+----+---------+---------+
| id | name | address |
+----+---------+---------+
| 2 | lisi | bj |
| 3 | wangwu | nj |
| 4 | zhaoliu | nj |
+----+---------+---------+
3 rows in set (0.00 sec)
4.在上面的前提下,又做了增量备份
[root@localhost data]# mysqladmin -uroot -pabc123 flush-logs ##做一个增量备份
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
[root@localhost data]# ls
auto.cnf ibdata1 mysql mysqld-bin.index
company ib_logfile0 mysql-bin.index mysql:wq.index
home ib_logfile1 mysqld-bin.000001 performance_schema
ib_buffer_pool ibtmp1 mysqld-bin.000002 sys
5. 对二进制日志文件进行解码
基于上面的情况, 就可以采用增量备份,实现断点恢复,跳过错误的操作,保留正确的操作。
查看二进制日志文件
[root@localhost data]# mysqlbinlog --no-defaults mysqld-bin.000001 > /opt/bk01.txt ##将二进制文件追加到/opt目录下
[root@localhost data]# vim /opt/bk01.txt ##查看二进制日志文件
二进制日志文件中都是如下图的格式,我们需要将二进制乱码进行解码,二进制乱码的内容就是我们在数据库中进行的sql语句。
解码查看
[root@localhost data]# mysqlbinlog --no-defaults --base64-output=decode-rows -v mysqld-bin.000001 > /opt/bk02.txt
[root@localhost data]# vim /opt/bk02.txt
6. 进行断点恢复
这时候我们需要找到我们正确操作的两个时间点,一个是错误操作之前的时间点或者位置点,还有一个是错误操作之后的时间点或者位置点,然后对这两个点进行断点恢复。
先将表删除,进行完整备份的恢复
在数据库中操作
mysql> drop table info;
Query OK, 0 rows affected (0.01 sec)
mysql> show tables;
Empty set (0.00 sec)
mysql> source /opt/company_info.sql ##恢复到完整备份时的数据库
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.01 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected, 1 warning (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.01 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected, 1 warning (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql> show tables;
+-------------------+
| Tables_in_company |
+-------------------+
| info |
+-------------------+
1 row in set (0.00 sec)
mysql> select * from info;
+----+----------+---------+
| id | name | address |
+----+----------+---------+
| 1 | zhangsan | nj |
| 2 | lisi | bj |
+----+----------+---------+
2 rows in set (0.00 sec)
根据位置点进行恢复
在Linux环境下,恢复到错误操作之前的一步
[root@localhost data]# mysqlbinlog --no-defaults --stop-position='571' /usr/local/mysql/data/mysqld-bin.000001 | mysql -uroot -pabc123
mysql: [Warning] Using a password on the command line interface can be insecure.
我们进入数据库查看,此时出现了‘wangwu’的记录
mysql> select * from info;
+----+----------+---------+
| id | name | address |
+----+----------+---------+
| 1 | zhangsan | nj |
| 2 | lisi | bj |
| 3 | wangwu | nj |
+----+----------+---------+
3 rows in set (0.00 sec)
接下来跳过错误的一步
[root@localhost data]# mysqlbinlog --no-defaults --start-position='710' /usr/local/mysql/data/mysqld-bin.000001 | mysql -uroot -pabc123
mysql: [Warning] Using a password on the command line interface can be insecure.
在数据库中查看,错误的删除被跳过,实现了断点恢复
mysql> select * from info;
+----+----------+---------+
| id | name | address |
+----+----------+---------+
| 1 | zhangsan | nj |
| 2 | lisi | bj |
| 3 | wangwu | nj |
| 4 | zhaoliu | nj |
+----+----------+---------+
4 rows in set (0.00 sec)
根据时间点进行恢复
首先恢复到完整备份时的状态
mysql> drop table info;
Query OK, 0 rows affected (0.01 sec)
mysql> show tables;
Empty set (0.00 sec)
进行完整备份恢复
mysql> source /opt/company_info.sql
Query OK, 0 rows affected (0.01 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected, 1 warning (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.01 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
Query OK, 0 rows affected (0.01 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected, 1 warning (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql> select * from info;
+----+----------+---------+
| id | name | address |
+----+----------+---------+
| 1 | zhangsan | nj |
| 2 | lisi | bj |
+----+----------+---------+
2 rows in set (0.00 sec)
然后根据时间点进行恢复
[root@localhost data]# mysqlbinlog --no-defaults --stop-datetime='2020-08-24 23:22:43' /usr/local/mysql/data/mysqld-bin.000001 | mysql -uroot -pabc123
mysql: [Warning] Using a password on the command line interface can be insecure.
在数据库中进行查看
恢复到错误之前的时间点
mysql> select * from info;
+----+----------+---------+
| id | name | address |
+----+----------+---------+
| 1 | zhangsan | nj |
| 2 | lisi | bj |
| 3 | wangwu | nj |
+----+----------+---------+
3 rows in set (0.00 sec)
跳过错误操作
[root@localhost data]# mysqlbinlog --no-defaults --start-datetime='2020-08-24 23:24:10' /usr/local/mysql/data/mysqld-bin.000001 | mysql -uroot -pabc123
mysql: [Warning] Using a password on the command line interface can be insecure.
mysql: [Warning] Using a password on the command line interface can be insecure.
mysql> select * from info;
+----+----------+---------+
| id | name | address |
+----+----------+---------+
| 1 | zhangsan | nj |
| 2 | lisi | bj |
| 3 | wangwu | nj |
| 4 | zhaoliu | nj |
+----+----------+---------+
4 rows in set (0.00 sec)