Mysql增量备份与恢复
- 一、Mysql增量备份
- 1.使用mysqldump进行完全备份存在的问题
- 2.MySQL增量备份是自上一次备份后增加/变化的文件或者内容
- 3.特点
- 4.MySQL没有提供直接的增量备份方法
- 5.MySQL二进制日志对备份的意义
- 二、Mysql数据库增量恢复
- 三、增量恢复的方法
- 1、一般恢复
- 2、基于位置的恢复
- 3、基于时间点恢复
一、Mysql增量备份
1.使用mysqldump进行完全备份存在的问题
- 备份数据中有重复数据
- 备份时间与恢复时间过长
2.MySQL增量备份是自上一次备份后增加/变化的文件或者内容
3.特点
- 没有重复数据,备份量不大,时间短
- 恢复需要上次完全备份及完全备份之后所有的增量备份才能恢复,而且要对所有增量备份进行逐个反推恢复
4.MySQL没有提供直接的增量备份方法
可通过MySQL提供的二进制日志间接实现增量备份
5.MySQL二进制日志对备份的意义
- 二进制日志保存了所有更新或者可能更新数据库的操作
- 二进制日志在启动MySQL服务器后开始记录,并在文件达到max_binlog_size所设置的大小或者接收到flush logs命令后重新创建新的日志文件
- 只需定时执行flush logs方法重新创建新的日志,生成二进制文件序列,并及时把这些日志保存到安全的地方就完成了一个时间段的增量备份
二、Mysql数据库增量恢复
1.一般恢复
将所有备份的二进制日志内容全部恢复
2.断点恢复
- 基于位置恢复
数据库在某一时间点可能既有错误的操作也有正确的操作
可以基于精准的位置跳过错误的操作 - 基于时间点恢复
跳过某个发生错误的时间点实现数据恢复
三、增量恢复的方法
1、一般恢复
mysqlbinlog [–no-defaults] 增量备份文件 | mysql -u 用户名 -p
2、基于位置的恢复
恢复数据到指定位置(到错误操作前的最后一次正确操作
mysqlbinlog --stop-position=‘操作id’ 二进制日志 | mysql -u 用户名 -p密码
从指定的位置开始恢复数据(跳过错误操作后的第一次正确操作)
mysqlbinlog --start-position=‘操作id’ 二进制日志 | mysql -u 用户名 -p密码
3、基于时间点恢复
- 跳过某个发生错误的时间点实现数据恢复
- 恢复数据到指定时间(停止错误操作的时间)
mysqlbinlog --stop-datetime=‘错误时间’ 二进制日志 | mysql -u 用户名 -p密码 - 从指定的位置开始恢复数据(跳过错误操作后的第一次正确操作)
mysqlbinlog --start-datetime=‘正确操作时间’ 二进制日志 | mysql -u 用户名 -p密码
时间点恢复
mysql> create database bak;
Query OK, 1 row affected (0.01 sec)
mysql> use bak;
Database changed
mysql> create table test(id int(2),name varchar(64));
Query OK, 0 rows affected (0.01 sec)
[root@localhost ~]# mkdir /backup
[root@localhost ~]# chmod -R 777 /backup/
[root@localhost ~]# vi /etc/my.cnf
[mysqld]
log-bin = /backup/log_bin #开启增量备份
[root@localhost ~][root@localhost ~]# systemctl restart mysqld
[root@localhost ~]# mysqladmin -uroot -p flush-logs
mysql> use bak;
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> insert into test values(1,'alice'),(2,'ben');
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> delete from test where id=2;
Query OK, 1 row affected (0.00 sec) #误操作
mysql> insert into test values(3,'chalice');
Query OK, 1 row affected (0.00 sec)
mysql> select * from bak.test;
+------+---------+
| id | name |
+------+---------+
| 1 | alice |
| 3 | chalice |
+------+---------+
2 rows in set (0.00 sec)
[root@localhost ~]# mysqladmin -uroot -p flush-logs
[root@localhost ~]# mysqlbinlog --no-defaults --base64-outpu=decode-rows -v /backup/log_bin.000002
# at 290
#201030 15:12:08 server id 1 end_log_pos 339 CRC32 0x2b06bf2eTable_map: `bak`.`test` mapped to number 108
# at 339
#201030 15:12:08 server id 1 end_log_pos 394 CRC32 0x2c9d7d25Write_rows: table id 108 flags: STMT_END_F
### SET
### @1=1
### @2='alice'
### INSERT INTO `bak`.`test`
### SET
### @1=2
### @2='ben'
# at 394### INSERT INTO `bak`.`test`
# at 425 #误操作时间点
#201030 15:12:24 server id 1 end_log_pos 490 CRC32 0x68053affAnonymous_GTID last_committed=1 sequence_number=2 rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 490
#201030 15:12:24 server id 1 end_log_pos 561 CRC32 0x06f2cba2Query thread_id=4 exec_time=0 error_code=0
SET TIMESTAMP=1604041944/*!*/;
BEGIN
/*!*/;
# at 561
#201030 15:12:24 server id 1 end_log_pos 610 CRC32 0xd7d39382Table_map: `bak`.`test` mapped to number 108
# at 610
#201030 15:12:24 server id 1 end_log_pos 654 CRC32 0x9c71aaa8Delete_rows: table id 108 flags: STMT_END_F
### DELETE FROM `bak`.`test`
### WHERE
### @1=2
### @2='ben'
# at 654
#201030 15:12:24 server id 1 end_log_pos 685 CRC32 0xe407ac5fXid = 12
COMMIT/*!*/;
# at 685 #正确操作时间点
#201030 15:12:40 server id 1 end_log_pos 750 CRC32 0xc86b7911Anonymous_GTID last_committed=2 sequence_number=3 rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 750
#201030 15:12:40 server id 1 end_log_pos 821 CRC32 0x6ea8622dQuery thread_id=4 exec_time=0 error_code=0
SET TIMESTAMP=1604041960/*!*/;
BEGIN
/*!*/;
# at 821
#201030 15:12:40 server id 1 end_log_pos 870 CRC32 0xe2eb84abTable_map: `bak`.`test` mapped to number 108
# at 870
#201030 15:12:40 server id 1 end_log_pos 918 CRC32 0xbb5796a5Write_rows: table id 108 flags: STMT_END_F
### INSERT INTO `bak`.`test`
### SET
### @1=3
### @2='chalice'
# at 918
#201030 15:12:40 server id 1 end_log_pos 949 CRC32 0x424daae1Xid = 13
COMMIT/*!*/;
# at 949
#201030 15:13:09 server id 1 end_log_pos 994 CRC32 0x10fba250Rotate to log_bin.000003 pos: 4
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
mysql> drop table bak.test;
mysql> use bak;
Database changed
mysql> create table test(id int(2),name varchar(64));
[root@localhost backup]# mysqlbinlog --no-defaults --stop-datetime='2020-10-30 15:12:24' /backup/log_bin.000002 | mysql -u root -p #停止错误的时间
[root@localhost backup]# mysqlbinlog --no-defaults --start-datetime='2020-10-30 15:12:40' /backup/log_bin.000002 | mysql -u root -p #开始正确的时间
mysql> select * from bak.test;
+------+---------+
| id | name |
+------+---------+
| 1 | alice |
| 2 | ben |
| 3 | chalice |
+------+---------+
3 rows in set (0.00 sec)
位置点恢复
继续沿用上次的测试文件
mysql> drop table bak.test;
mysql> create table bak.test(id int(2),name varchar(64));
mysql> select * from bak.test;
Empty set (0.00 sec)
[root@localhost ~]# mysqlbinlog --no-defaults --base64-outpu=decode-rows -v /backup/log_bin.000002
# at 290
#201030 15:12:08 server id 1 end_log_pos 339 CRC32 0x2b06bf2eTable_map: `bak`.`test` mapped to number 108
# at 339
#201030 15:12:08 server id 1 end_log_pos 394 CRC32 0x2c9d7d25Write_rows: table id 108 flags: STMT_END_F
### INSERT INTO `bak`.`test`
### SET
### @1=1
### @2='alice'
### INSERT INTO `bak`.`test`
### SET
### @1=2
### @2='ben'
# at 394
#201030 15:12:08 server id 1 end_log_pos 425 CRC32 0x14d0edc6Xid = 11
COMMIT/*!*/;
# at 425 #误操作位置点
#201030 15:12:24 server id 1 end_log_pos 490 CRC32 0x68053affAnonymous_GTID last_committed=1 sequence_number=2 rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 490
#201030 15:12:24 server id 1 end_log_pos 561 CRC32 0x06f2cba2Query thread_id=4 exec_time=0 error_code=0
SET TIMESTAMP=1604041944/*!*/;
BEGIN
/*!*/;
# at 561
#201030 15:12:24 server id 1 end_log_pos 610 CRC32 0xd7d39382Table_map: `bak`.`test` mapped to number 108
# at 610
#201030 15:12:24 server id 1 end_log_pos 654 CRC32 0x9c71aaa8Delete_rows: table id 108 flags: STMT_END_F
### DELETE FROM `bak`.`test`
### WHERE
### @1=2
### @2='ben'
# at 654
#201030 15:12:24 server id 1 end_log_pos 685 CRC32 0xe407ac5fXid = 12
COMMIT/*!*/;
# at 685 #正确操作位置点
#201030 15:12:40 server id 1 end_log_pos 750 CRC32 0xc86b7911Anonymous_GTID last_committed=2 sequence_number=3 rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 750
#201030 15:12:40 server id 1 end_log_pos 821 CRC32 0x6ea8622dQuery thread_id=4 exec_time=0 error_code=0
SET TIMESTAMP=1604041960/*!*/;
BEGIN
/*!*/;
# at 821
#201030 15:12:40 server id 1 end_log_pos 870 CRC32 0xe2eb84abTable_map: `bak`.`test` mapped to number 108
# at 870
#201030 15:12:40 server id 1 end_log_pos 918 CRC32 0xbb5796a5Write_rows: table id 108 flags: STMT_END_F
### INSERT INTO `bak`.`test`
### SET
### @1=3
### @2='chalice'
# at 918
#201030 15:12:40 server id 1 end_log_pos 949 CRC32 0x424daae1Xid = 13
COMMIT/*!*/;
# at 949
#201030 15:13:09 server id 1 end_log_pos 994 CRC32 0x10fba250Rotate to log_bin.000003 pos: 4
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
[root@localhost ~]# mysqlbinlog --no-defaults --stop-position='425' /backup/log_bin.000002 | mysql -u root -p #停止错误的位置点
[root@localhost ~]# mysqlbinlog --no-defaults --start-position='685' /backup/log_bin.000002 | mysql -u root -p #开始正确的位置点
mysql> select * from bak.test;
+------+---------+
| id | name |
+------+---------+
| 1 | alice |
| 2 | ben |
| 3 | chalice |
+------+---------+
3 rows in set (0.00 sec)