增量备份,简称增备,指的以增量(基于全量备份或增量备份新增的数据)形式把新增的数据从一个地方拷贝到另外一个地方进行的备份。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)
至此,增量的备份和恢复就完成了。
欢迎来到testingpai.com!
注册 关于