MySQL 全量增量备份方案 -2

本贴最后更新于 1354 天前,其中的信息可能已经时过境迁

增量备份,简称增备,指的以增量(基于全量备份或增量备份新增的数据)形式把新增的数据从一个地方拷贝到另外一个地方进行的备份。MySQL全量备份可以参考上一篇帖子MySQL 备份方案 1- 全量备份

在InnoDB中,每个page中都记录LSN信息,每当相关数据发生改变,page的LSN就会自动增加,xtrabackup的增量备份就是依据这一原理进行的。xtrabackup将上次备份(完全备份集或者也是一个增量备份集)以来LSN改变的page进行备份。

所以,要做增量备份第一次就要做一个完全备份(就是将MySQL实例或者说要备份的数据库表做一个完全复制,同时记录LSN),之后可以基于此进行增量备份以及恢复。

增量备份的优点有:

数据库太大没有足够的空间全量备份,增量备份能有效节省空间,并且效率高;

支持热备份,备份过程不锁表(针对InnoDB而言),不阻塞数据库的读写;

每日备份只产生少量数据,也可采用远程备份,节省本地空间;

备份恢复基于文件操作,降低直接对数据库操作风险;

备份效率更高,恢复效率更高

全备基础上增量备份

增量备份仍然需要基于全备。我们有有一个全备:/home/data/backup/2020-08-08_17-19-38(在全备文章中创建的),在该全备的基础上做增量备份。

首先创建数据库demo、数据库表backup,并插入一条数据

mysql> create database demo;
Query OK, 1 row affected (0.01 sec)

mysql> use demo;
Database changed
mysql> create table backup(id int(11) not null auto_increment,name varchar(255) not null,primary key(id)); 
Query OK, 0 rows affected (0.01 sec)

mysql> insert into backup (name) values(1);  
Query OK, 1 row affected (0.01 sec)

执行增量备份命令,其中--incremental-basedir指向全备目录,--incremental指向增量备份存储目录

[root@iZ2zefth8eteml1eyueu1sZ ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=123456 --incremental-basedir=/home/data/backup/2020-08-08_17-19-38 --incremental /home/data/backup

执行结果

200809 11:39:15 >> log scanned up to (43580195)

200809 11:39:15 Executing UNLOCK TABLES
200809 11:39:15 All tables unlocked
200809 11:39:15 [00] Copying ib_buffer_pool to /home/data/backup/2020-08-09_11-39-11/ib_buffer_pool
200809 11:39:15 [00]        ...done
200809 11:39:15 Backup created in directory '/home/data/backup/2020-08-09_11-39-11'
200809 11:39:15 [00] Writing backup-my.cnf
200809 11:39:15 [00]        ...done
200809 11:39:15 [00] Writing xtrabackup_info
200809 11:39:15 [00]        ...done
xtrabackup: Transaction log of lsn (43580186) to (43580195) was copied.
200809 11:39:16 completed OK!

上面语句执行成功之后,会在--incremental执行的目录下创建一个时间戳子目录(本例中为:/home/data/backup/2020-08-09_11-39-11),在该目录下存放着增量备份的所有文件。

[root@iZ2zefth8eteml1eyueu1sZ ~]# cd /home/data/backup/
[root@iZ2zefth8eteml1eyueu1sZ backup]# ll
total 1168
drwxr-x--- 7 root root    4096 Aug  8 18:00 2020-08-08_17-19-38
-rw-r--r-- 1 root root 1184855 Aug  8 17:19 2020-08-08_17-19-48.tar.gz
drwxr-x--- 8 root root    4096 Aug  9 11:39 2020-08-09_11-39-11
[root@iZ2zefth8eteml1eyueu1sZ backup]# cd 2020-08-09_11-39-11/
[root@iZ2zefth8eteml1eyueu1sZ 2020-08-09_11-39-11]# ls
backup-my.cnf   ibdata1.delta  performance_schema      xtrabackup_logfile
demo            ibdata1.meta   sys
future          lemonban       xtrabackup_checkpoints
ib_buffer_pool  mysql          xtrabackup_info
[root@iZ2zefth8eteml1eyueu1sZ 2020-08-09_11-39-11]#

在备份目录下,有一个文件xtrabackup_checkpoints记录着备份信息,全备与增备下xtrabackup_checkpoints文件的信息如下

全备的信息如下
backup_type = full-prepared
from_lsn = 0
to_lsn = 43574802
last_lsn = 43574811
compact = 0
recover_binlog_info = 0

基于该全备的增量备份的信息如下
backup_type = incremental
from_lsn = 43574802
to_lsn = 43580186
last_lsn = 43580195
compact = 0
recover_binlog_info = 0

从上面可以看出,增量备份的from_lsn等于全量备份的to_lsn,均为43574802

增量备份基础上进行增量备份

首先插入一条数据

mysql> insert into backup(name) values('testingpai.com'); 
Query OK, 1 row affected (0.00 sec)

mysql> select * from backup;
+----+----------------+
| id | name           |
+----+----------------+
|  1 | 1              |
|  2 | testingpai.com |
+----+----------------+
2 rows in set (0.00 sec)

mysql>  

增量备份:在之前增量备份/home/data/backup/2020-08-09_11-39-11 的基础上进行备份

[root@fenwoo backup]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=123456 --incremental-basedir=/home/data/backup/2020-08-09_11-39-11 --incremental /home/data/backup

备份完毕,可以看到,该增量备份的xtrabackup_checkpoints记录着备份信息如下:

backup_type = incremental
from_lsn = 43580186
to_lsn = 43580368
last_lsn = 43580377
compact = 0
recover_binlog_info = 0

其中from_lsn等于上一次增量备份(/home/data/backup/2020-08-09_11-39-11)的to_lsn:值均为43580186

增备数据恢复

增量备份的恢复比全备要复杂很多,第一步是在所有备份目录下重做已提交的日志。

第一步:

innobackupex --apply-log --redo-only BASE-DIR
innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR-1
innobackupex --apply-log BASE-DIR --incremental-dir=INCREMENTAL-DIR-2

其中BASE-DIR是指某个全备目录,INCREMENTAL-DIR-1是指第一次的增量备份,INCREMENTAL-DIR-2是指第二次的增量备份(即基于INCREMENTAL-DIR-1的增量),以此类推。

这里要注意的是:最后一步的增量备份并没有--redo-only选项!还有,可以使用--use_memory提高性能。

接下来我们来实操增量备份的恢复,首先执行如下命令,模拟需要数据恢复的场景

[root@iZ2zefth8eteml1eyueu1sZ ~]# systemctl stop mysqld //停止mysql 
[root@iZ2zefth8eteml1eyueu1sZ ~]# mv /var/lib/mysql /var/lib/mysql_bak //数据目录备份
[root@iZ2zefth8eteml1eyueu1sZ ~]# mkdir -p /var/lib/mysql  //重建数据目录

然后执行第一步,进行备份日志的重做:

[root@lemon backup]# innobackupex --apply-log --redo-only /home/data/backup/2020-08-08_17-19-38 [root@lemon backup]# innobackupex --apply-log --redo-only /home/data/backup/2020-08-08_17-19-38 --incremental-dir=/home/data/backup/2020-08-09_11-39-11 [root@lemon backup]# innobackupex --apply-log /home/data/backup/2020-08-08_17-19-38 --incremental-dir=/home/data/backup/2020-08-09_11-50-08

以上语句执行成功之后,最终数据在BASE-DIR(即全备目录/home/data/backup/2020-08-08_17-19-38)下。

第一步完成之后,我们开始第二步:回滚未完成的日志:

innobackupex --apply-log BASE-DIR

上面执行完之后,BASE-DIR里的备份文件已完全准备就绪,最后一步是拷贝:

innobackupex --copy-back BASE-DIR

具体命令如下:

[root@fenwoo backup]# innobackupex --apply-log /home/data/backup/2020-08-08_17-19-38
[root@fenwoo backup]# innobackupex --copy-back /home/data/backup/2020-08-08_17-19-38

同样地,拷贝结束之后,记得检查下数据目录的权限是否正确。然后重启数据库:

[root@iZ2zefth8eteml1eyueu1sZ mysql]# chown -R mysql.mysql /var/lib/mysql
[root@iZ2zefth8eteml1eyueu1sZ mysql]# systemctl start mysqld
[root@iZ2zefth8eteml1eyueu1sZ mysql]# systemctl status mysqld
● mysqld.service - MySQL Server
   Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
   Active: active (running) since Sun 2020-08-09 15:57:55 CST; 6s ago
     Docs: man:mysqld(8)
           http://dev.mysql.com/doc/refman/en/using-systemd.html
  Process: 19388 ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid $MYSQLD_OPTS (code=exited, status=0/SUCCESS)
  Process: 19371 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS)
 Main PID: 19393 (mysqld)
   CGroup: /system.slice/mysqld.service
           └─19393 /usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid

Aug 09 15:57:53 iZ2zefth8eteml1eyueu1sZ systemd[1]: Starting MySQL Server...
Aug 09 15:57:55 iZ2zefth8eteml1eyueu1sZ systemd[1]: Started MySQL Server.
[root@iZ2zefth8eteml1eyueu1sZ mysql]# mysql -uroot -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.31 MySQL Community Server (GPL)

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

可以看到,数据库正常启动成功!查询数据,两次增量的数据也恢复了

mysql> use demo;
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> select * from backup;
+----+----------------+
| id | name           |
+----+----------------+
|  1 | 1              |
|  2 | testingpai.com |
+----+----------------+
2 rows in set (0.00 sec)

至此,增量的备份和恢复就完成了。

2 操作
happy 在 2020-08-09 16:53:50 更新了该帖
happy 在 2020-08-09 16:53:30 更新了该帖
1 回帖
请输入回帖内容 ...