Percona XtraBackup主要是有两个工具,其中一个是xtrabackup,一个是innobackupex,后者是前者封装后的一个脚本。
在针对MySQL的物理备份工具中,大概是最流行也是最强大的工具了,此外著名的物理备份工具还有官方的mysqlbackup。
xtrabackup只可备份事务表,不能用于备份非事务表,而innobackupex不仅可用于备份事务表,也可以备份非事务表如MyISAM
〇 实验
接下来就是实验……
先建个备份用的用户,给个权限。
- mysql> CREATE USER xbackup@localhost IDENTIFIED BY 'back123';
- mysql> GRANT RELOAD, PROCESS, LOCK TABLES, REPLICATION CLIENT ON *.* TO xbackup@localhost;
〇 完全备份&恢复
在test.tb里加入测试数据
- mysql> CREATE TABLE test.tb(id int primary key, name varchar(16));
- Query OK, 0 rows affected (0.07 sec)
- mysql> INSERT INTO test.tb VALUES(1,'zhou'),(2,'430'),(3,'YYF'),(4,'ChuaN'),(5,'Faith');
- Query OK, 5 rows affected (0.02 sec)
- Records: 5 Duplicates: 0 Warnings: 0
创建备份存放目录
$ mkdir -p /data/backup/
指定备份存放位置,开始备份
$ innobackupex -uxbackup -pbackup123 --no-timestamp /data/backup/backup
此处的/data/backup/backup就是全备的目录了。
…………(省略刷屏输出)
xtrabackup: Transaction log of lsn (304289583) to (304290858) was copied.
170321 16:06:11 completed OK!
看到completed OK,表明就真的ok了。
可以看一下这个目录中的内容:
一部分是MySQL下datadir的内容,如库目录,redolog,系统表空间。
一部分是之前也有介绍过的,由备份工具生成的东西:
backup-my.cnf
ibdata1
ib_logfile0
ib_logfile1
mysql
performance_schema
test
xtrabackup_binlog_info
xtrabackup_binlog_pos_innodb
xtrabackup_checkpoints
xtrabackup_info
xtrabackup_logfile
进行prepare
$ innobackupex --apply-log /data/backup/backup
关闭mysqld
$ mysqladmin -uroot -p shutdown
Enter password:
$ ps -ef|grep mysql
root 2991 2438 1 11:08 pts/0 00:00:00 grep mysql
移除datadir:
$ mv /data/mysql_data /data/mysql_data.bk
恢复数据
$ innobackupex --copy-back /data/backup/backup/
修改新datadir的权限
$ chown mysql:mysql -R /data/mysql_data
启动数据库
$ mysqld &
$ ps -ef|grep mysql
root 2712 2438 86 16:35 pts/0 00:00:02 mysqld
root 2714 2438 0 16:35 pts/0 00:00:00 grep mysql
检查test.tb中的内容
- $ mysql -e "SELECT * FROM test.tb;"
- +----+-------+
- | id | name |
- +----+-------+
- | 1 | zhou |
- | 2 | 430 |
- | 3 | YYF |
- | 4 | ChuaN |
- | 5 | Faith |
- +----+-------+
至此,完全备份&恢复完成
〇 增量备份&恢复
先来一次全备:
$ innobackupex -uxbackup -pbackup123 --no-timestamp /data/backup/all_backup
修改测试表及数据:(加个字段,改两条数据)
- mysql> ALTER TABLE test.tb ADD COLUMN picked varchar(16);
- Query OK, 0 rows affected (0.06 sec)
- Records: 0 Duplicates: 0 Warnings: 0
- mysql> UPDATE test.tb SET picked='naga' WHERE id=1;
- Query OK, 1 row affected (0.04 sec)
- Rows matched: 1 Changed: 1 Warnings: 0
- mysql> UPDATE test.tb SET picked='TA' WHERE id=2;
- Query OK, 1 row affected (0.00 sec)
- Rows matched: 1 Changed: 1 Warnings: 0
执行第一次增量备份:
$ innobackupex -uxbackup -pbackup123 --no-timestamp --incremental /data/backup/incremental-dir-1 --incremental-basedir=/data/backup/all_backup/
可以再做一次增量备份:
此时有两种增量备份方法:
第一种,总是针对basedir做增量,这个方式恢复起来就特别简单了,只需要将最后一次的增量备份合并到全量备份里,就可以恢复了。
第二种,总是针对上一次的增量,做增量备份。这个方式的恢复,就要逐一合并了,也就是我上述所说看起来有点复杂的增备思路。
反正我是喜欢第一种的,感觉也可以适应绝大多数场景。
我拿word涂了两张图,帮助理解。
第一种:
总是将1月1日的全备作为basedir,所以FROM_LSN号总是5000。
第二种:
总是把上一次(最近一次)的备份作为basedir。
此处介绍第二种:
多次增量备份的方法依旧,只需要修改--incremental-basedir即可:
继续对test.tb做一些修改:
- mysql> UPDATE test.tb SET picked='DS' WHERE id=3;
- Query OK, 1 row affected (0.04 sec)
- Rows matched: 1 Changed: 1 Warnings: 0
- mysql> SELECT * FROM test.tb;
- +----+-------+--------+
- | id | name | picked |
- +----+-------+--------+
- | 1 | zhou | naga |
- | 2 | 430 | TA |
- | 3 | YYF | DS |
- | 4 | ChuaN | NULL |
- | 5 | Faith | NULL |
- +----+-------+--------+
- 5 rows in set (0.01 sec)
针对第一次增量备份/data/backup/incremental-dir-1,做第二次增量备份,将第二次的增量备份放到/data/backup/incremental-dir-2/
$ innobackupex -uxbackup -pbackup123 --no-timestamp --incremental /data/backup/incremental-dir-2/ --incremental-basedir=/data/backup/incremental-dir-1
prepare过程,这个也是增量备份里最蛋疼的过程:
因为总共做了三次备份,所以先做三次prepare:
先对全备做prepare:
$ innobackupex --apply-log --redo-only /data/backup/all_backup/
然后接下来做第一次增量备份的prepare:
$ innobackupex --apply-log --redo-only /data/backup/all_backup/ --incremental-dir=/data/backup/incremental-dir-1
再对第二次的增量备份prepare,注意,第二次的增备是最后一次,所以不需要加上--redo-only参数:
$ innobackupex --apply-log /data/backup/all_backup/ --incremental-dir=/data/backup/incremental-dir-2
最后将两次增量备份和全备做一次合并:
$ innobackupex --apply-log /data/backup/all_backup/
恢复过程,这个和全量恢复没有区别:
停掉mysqld
$ mysqladmin -uroot -p shutdown
$ ps -ef|grep mysql
root 3533 3081 0 17:05 pts/1 00:00:00 grep mysql
移除datadir
$ mv /data/mysql_data /data/mysql_data.bk2
恢复数据
$ innobackupex --copy-back /data/backup/all_backup/
修改新datadir的权限
$ chown mysql:mysql -R /data/mysql_data
启动
$ mysqld &
检查一下,全备和两次增备的内容都已经被恢复回来了,也就是最后一次数据的状态:
- $ mysql -uroot -p -e "SELECT * FROM test.tb;"
- +----+-------+--------+
- | id | name | picked |
- +----+-------+--------+
- | 1 | zhou | naga |
- | 2 | 430 | TA |
- | 3 | YYF | DS |
- | 4 | ChuaN | NULL |
- | 5 | Faith | NULL |
- +----+-------+--------+
至此,增量备份&恢复完成。
〇 总结一下xtrabackup备份及恢复全过程:
1、备份操作,需要提供具有足够权限的MySQL用户,并且mysqld启动用户需要对datadir有rwx的权限。
2、prepare,将未提交的事务回滚,将已提交的事务写入数据文件。
3、停止mysqld服务
4、mv data/ data_bak_.../
5、copyback回去
6、修改权限新的datadir权限
7、启动服务
当然,上述所有的备份对象,都是针对整个MySQL实例。
〇 参考资料:
官方手册:
https://www.percona.com/doc/percona-xtrabackup/2.3/index.html
更多XtraBackup相关教程见以下内容: