物理备份之Xtrabackup
介绍
Xtrabackup是由percona提供的mysql数据库备份工具,据官方介绍,这也是世界上惟一一款开源的能够对innodb和xtradb数据库进行热备的工具。特点:
- 备份过程快速、可靠;
- 备份过程不会打断正在执行的事务;
- 能够基于压缩等功能节约磁盘空间和流量;
- 自动实现备份检验;
- 还原速度快;
使用xtrabackup使用InnoDB能够发挥其最大功效, 并且InnoDB的每一张表必须使用单独的表空间, 我们需要在配置文件中添加 innodb_file_per_table = ON 来开启
XtraBackup的全备份+XtraBackup增量备份+binlog日志进行恢复最新数据。也可以恢复误操作。
刚开始用mysqldump,备份100G+的数据库,再加上服务器繁忙,备份速度像蜗牛似的,于是寻找更高效的备份方法。
Xtrabackup备份原理:
物理备份,不锁表,那么怎么保证现有的数据(备份过程中有尚未提交或已经提交但未同步事务)与复制出来的数据一致呢?
我们知道MySQL修改操作都会先记录在ib_logfile日志文件,再同步到磁盘,这个文件并重复使用。在复制期间会开启一个线程用来监控ib_logfile日志文件,如果有修改就从上次记录的日志序列号(checkpoins)开始复制新增内容到Logfile文件。复制结束后,把logfile事务日志进行回滚,把未完成的事务同步到ibdata1和ibd里面,来保证数据一致性。这与Mysql崩溃后恢复基本操作一样
1.1 了解备份方式
热备份:读写不受影响(mysqldump-->innodb)
温备份:仅可以执行读操作(mysqldump-->myisam)
冷备份:离线备份,读写都不可用
逻辑备份:将数据导出文本文件中(mysqldump)
物理备份:将数据文件拷贝(xtrabackup、mysqlhotcopy)
完整备份:备份所有数据
增量备份:仅备份上次完整备份或增量备份以来变化的数据
差异备份:仅备份上次完整备份以来变化的数据
1.3 安装方式
CentOS:
rpm -ivh www.percona.com/downloads/p…
yum install percona-xtrabackup #xtrabackup2.2不支持MySQL5.1的Innodb引擎,如需要可安装2.0版本(www.percona.com/downloads/X…
1.4 了解常用参数
- --user= #指定数据库备份用户
- --password= #指定数据库备份用户密码
- --port= #指定数据库端口
- --host= #指定备份主机
- --socket= #指定socket文件路径
- --databases= #备份指定数据库,多个空格隔开,如--databases="dbname1 dbname2",不加备份所有库
- --defaults-file= #指定my.cnf配置文件
- --apply-log #日志回滚
- --incremental= #增量备份,后跟增量备份路径
- --incremental-basedir= #增量备份,指上次增量备份路径
- --redo-only #合并全备和增量备份数据文件
- --copy-back #将备份数据复制到数据库,数据库目录要为空
- --no-timestamp #生成备份文件不以时间戳为目录名
- --stream= #指定流的格式做备份,--stream=tar,将备份文件归档
- --remote-host=user@ip DST_DIR #备份到远程主机
使用xtrabackup进行MySQL数据库备份
前面介绍mysqldump备份方式是采用逻辑备份,其最大的缺陷就是备份和恢复速度都慢,对于一个小于50G的数据库而言,这个速度还是能接受的,但如果数据库非常大,那再使用mysqldump备份就不太适合了。而使用lvm快照功能对数据库进行备份,可以实现几乎热备的功能,但备份过程较为复杂,不过现在倒是有个工具mylvmbackup可以实现自动化备份。
前面我们也说道,使用物理备份时最快的,那有没有办法实现物理热备呢?
目前主流的有两个工具可以实现热备:ibbackup和xtrabackup;ibbackup是商业软件,没服务器授权为5000美元,非常昂贵。而xtrabackup功能比ibbackup还要强大,但却是开源的。因此我们这里就来介绍xtrabackup的使用。
Xtrabackup是由percona提供的mysql数据库备份工具,据官方介绍,这也是世界上惟一一款开源的能够对innodb和xtradb数据库进行热备的工具。特点:
- (1)备份过程快速、可靠;
- (2)备份过程不会打断正在执行的事务;
- (3)能够基于压缩等功能节约磁盘空间和流量;
- (4)自动实现备份检验;
- (5)还原速度快;
Xtrabackup中主要包含两个工具:
xtrabackup:是用于热备份innodb, xtradb表中数据的工具,不能备份其他类型的表,也不能备份数据表结构,xtrabackup命令只备份数据文件,并不备份数据表结构(.frm),所以使用xtrabackup恢复的时候必须有对应表结构文件(.frm)。用innobackupex命令,此命令相当于冷备份,复制数据目录的索引,数据,结构文件,但会有短暂的锁表(时间依赖于MyISAM大小)。;
innobackupex:是将xtrabackup进行封装的perl脚本,提供了备份myisam表的能力。
Xtrabackup中主要包含两个工具:
xtrabackup:是用于热备innodb,xtradb表中数据的工具,不能备份其他类型的表,也不能备份数据表结构;
innobackupex:是将xtrabackup进行封装的perl脚本,提供了备份myisam表的能力。
常用选项:
| --host | 指定主机 |
|---|---|
| --user | 指定用户名 |
| --password | 指定密码 |
| --port | 指定端口 |
| --databases | 指定数据库 |
| --incremental | 创建增量备份 |
| --incremental-basedir | 指定包含完全备份的目录 |
| --incremental-dir | 指定包含增量备份的目录 |
| --apply-log | 对备份进行预处理操作 |
一般情况下,在备份完成后,数据尚且不能用于恢复操作,因为备份的数据中可能会包含尚未提交的事务或已经提交但尚未同步至数据文件中的事务。因此,此时数据文件仍处理不一致状态。“准备”的主要作用正是通过回滚未提交的事务及同步已经提交的事务至数据文件也使得数据文件处于一致性状态。
- --redo-only 不回滚未提交事务
- --copy-back 恢复备份目录
使用innobackupex备份时,其会调用xtrabackup备份所有的InnoDB表,复制所有关于表结构定义的相关文件(.frm)、以及MyISAM、MERGE、CSV和ARCHIVE表的相关文件,同时还会备份触发器和数据库配置信息相关的文件,这些文件会被保存到一个以时间命名的目录当中。在备份的同时,innobackupex还会在备份目录中创建如下文件:
(1)xtrabackup_checkpoints -- 备份类型(如完全或增量)、备份状态(如是否已经为prepared状态)和LSN(日志序列号)范围信息:
每个InnoDB页(通常为16k大小)
都会包含一个日志序列号,即LSN,LSN是整个数据库系统的系统版本号,每个页面相关的LSN能够表明此页面最近是如何发生改变的。
(2)xtrabackup_binlog_info -- mysql服务器当前正在使用的二进制日志文件及备份这一刻位置二进制日志时间的位置。
(3)xtrabackup_binlog_pos_innodb -- 二进制日志文件及用于InnoDB或XtraDB表的二进制日志文件的当前position。
(4)xtrabackup_binary -- 备份中用到的xtrabackup的可执行文件;
(5)backup-my.cnf -- 备份命令用到的配置选项信息:
在使用innobackupex进行备份时,还可以使用--no-timestamp选项来阻止命令自动创建一个以时间命名的目录:如此一来,innobackupex命令将会创建一个BACKUP-DIR目录来存储备份数据。
如果要使用一个最小权限的用户进行备份,则可基于如下命令创建此类用户:如果要使用一个最小权限的用户进行备份,则可基于如下命令创建此类用户:
mysql> CREATE USER 'bkpuser'@'localhost' IDENTIFIED BY '123456'; #创建用户
mysql> REVOKE ALL PRIVILEGES,GRANT OPTION FROM 'bkpuser'; #回收此用户所有权限
mysql> GRANT RELOAD,LOCK TABLES,RELICATION CLIENT ON *.* TO 'bkpuser'@'localhost'; #授权刷新、锁定表、用户查看服务器状态
mysql> FLUSH PRIVILEGES; #刷新授权表
*注意:备份时需启动MySQL,恢复时需关闭MySQL,清空mysql数据目录且不能重新初始化,恢复数据后应该立即进行一次完全备份*
Xtrabackup备份原理
Xtrabackup备份流程图:
(1)innobackupex启动后,会先fork一个进程,用于启动xtrabackup,然后等待xtrabackup备份ibd数据文件;
(2)xtrabackup在备份innoDB数据是,有2种线程:redo拷贝线程和ibd数据拷贝线程。xtrabackup进程开始执行后,会启动一个redo拷贝的线程,用于从最新的checkpoint点开始顺序拷贝redo.log;再启动ibd数据拷贝线程,进行拷贝ibd数据。这里是先启动redo拷贝线程的。在此阶段,innobackupex进行处于等待状态(等待文件被创建)
(4)xtrabackup拷贝完成ibd数据文件后,会通知innobackupex(通过创建文件),同时xtrabackup进入等待状态(redo线程依旧在拷贝redo.log)
(5)innobackupex收到xtrabackup通知后哦,执行FLUSH TABLES WITH READ LOCK(FTWRL),取得一致性位点,然后开始备份非InnoDB文件(如frm、MYD、MYI、CSV、opt、par等格式的文件),在拷贝非InnoDB文件的过程当中,数据库处于全局只读状态。
(6)当innobackup拷贝完所有的非InnoDB文件后,会通知xtrabackup,通知完成后,进入等待状态;
(7)xtrabackup收到innobackupex备份完成的通知后,会停止redo拷贝线程,然后通知innobackupex,redo.log文件拷贝完成;
(8)innobackupex收到redo.log备份完成后,就进行解锁操作,执行:UNLOCK TABLES;
(9)最后innbackupex和xtrabackup进程各自释放资源,写备份元数据信息等,innobackupex等xtrabackup子进程结束后退出。
安装
版本选择
mysql 5.7以下版本,可以采用percona xtrabackup 2.4版本
mysql 8.0以上版本,可以采用percona xtrabackup 8.0版本,xtrabackup8.0也只支持mysql8.0以上的版本
比如,接触过一些金融行业,mysql版本还是多采用mysql 5.7,当然oracle官方对于mysql 8.0的开发支持力度日益加大,新功能新特性迭代不止。生产环境采用mysql 8.0的版本比例会日益增加。
安装方式一
# 安装yum仓库
yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm -y
# 安装XtraBackup命令
yum install percona-xtrabackup-24 -y
安装方式二
#下载epel源
wget -O /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo
#安装依赖
yum -y install perl perl-devel libaio libaio-devel perl-Time-HiRes perl-DBD-MySQL
#下载Xtrabackup
wget https://downloads.percona.com/downloads/Percona-XtraBackup-2.4/Percona-XtraBackup-2.4.23/binary/redhat/7/x86_64/percona-xtrabackup-24-2.4.23-1.el7.x86_64.rpm
# 安装
yum localinstall -y percona-xtrabackup-24-2.4.4-1.el6.x86_64.rpm
安装完后会生成命令
xtrabackup 以前使用该命令
innobackupex 现在使用该命令
innobackupex是xtrabackup的前端配置工具,使用innobackupex备份时, 会调用xtrabackup备份所有的InnoDB表, 复制所有关于表结构定义的相关文件(.frm)、以及MyISAM、MERGE、CSV和ARCHIVE表的相关文件, 同时还会备份触发器和数据库配置文件信息相关的文件, 这些文件会被保存至一个以时间命名的目录.
Xtrabackup 备份方式(物理备份)
1.对于非innodb表(比如myisam)是直接锁表cp数据文件,属于一种温备。
2.对于innodb的表(支持事务),不锁表,cp数据页最终以数据文件方式保存下来,并且把redo和undo一并备走,属于热备方式。
3.备份时读取配置文件/etc/my.cnf
Xtrabackup全量备份
#1、创建备份目录,会把mysql的datadir中的内容备份到改目录中
mkdir /backup
#2、全备
#2.1 在本地执行下述命令,输入登录数据的本地账号与密码
#2.2 指定备份目录为/backup下的full目录
innobackupex --user=root --password=123 /backup/full
#3、查看:默认会在备份目录下生成一个以时间戳命名的文件夹
[root@localhost ~]# cd /backup/full/
[root@localhost full]# ls
2021-07-16_16-09-47
[root@localhost full]# ls 2021-07-16_16-09-47/ #备份目录
。。。
[root@localhost full]# ls /var/lib/mysql # 数据目录
。。。
# 4、去掉时间戳,让备份数据直接放在备份目录下
我们在写备份脚本和恢复脚本,恢复的时候必须指定上一次备份的目录,如果备份目录带着时间戳,该时间戳我们很难在脚本中确定,无为了让脚本编写更加方便,我们可以使用选项--no-timestamp去掉时间戳,让备份内容直接放置于我们指定的目录下(ps:金融公司喜欢每天全备,每小时增备,如果备份目录带着时间戳,看似合理,但确实会很让头疼)
[root@localhost full]# rm -rf 2021-07-16_17-45-53/
[root@localhost full]# innobackupex --user=root --password=123 --no-timestamp /backup/full
# 补充:关于备份目录下新增的文件说明,可用cat命令查看
xtrabackup_checkpoints 存储系统版本号,增备的时候会用到
xtrabackup_info 存储UUID,数据库是由自己的UUID的,如果相同,做主从会有问题
xtrabackup_logfile 就是redo
xtrabackup全量备份与恢复
备份:
innobackupex --user=DBUSER --password=DBUSERPASS --defaults-file=/etc/my.cnf /path/to/BACKUP-DIR/
恢复:
innobackupex --apply-log /backups/2000-07-39_11-04-55/
innobackupex --copy-back --defaults-file=/etc/my.cnf /backups/2000-07-30_11-04-55/
(1)准备(prepare)一个完全备份
一般情况下,在备份完成后,数据尚且不能用于恢复操作,因为备份的数据中可能会包含尚未提交的事务或者已经提交但尚未同步至数据文件中的事务。因此,此时数据文件仍处于不一致状态。"准备"的主要作用正是通过回滚未提交的事务及同步已经提交的事务至数据文件也使用得数据文件处于一致性状态。
innobackupex命令的--apply-log选项可用于实现上述功能,如下面的命令:
#innobackupex --apply-log /path/to/BACKUP-DIR
如果执行正确,其最后输出的几行信息通常如下:
120407 09:01:04 innobackupex: completed OK!
在实现"准备"的过程中,innobackupex通常还可以使用--user-memory选项来指定其可以使用的内存的大小,默认为100M.如果有足够的内存空间可用,可以多划分一些内存给prepare的过程,以提高其完成备份的速度。
(2)从一个完全备份中恢复数据
注意:恢复不用启动MySQL
innobackupex命令的--copy-back选项用于恢复操作,其通过复制所有数据相关的文件至mysql服务器DATADIR目录中来执行恢复过程。innobackupex通过backup-my.cnf来获取DATADIR目录的相关信息。
innobackupex --copy-back /path/to/BACKUP-DIR
当数据恢复至DATADIR目录以后,还需要确保所有的数据文件的属主和属组均为正确的用户,如mysql,否则,在启动mysqld之前还需要事先修改数据文件的属主和属组。如:
chown -R mysql.mysql /mydata/data/
(3)实战练习
- 全量备份
[root@master backups]# innobackupex --user=root --password=123456 --host=127.0.0.1 /backups/ #在master上进行全库备份#语法解释说明:#--user=root 指定备份用户#--password=123456 指定备份用户密码#--host 指定主机#/backups 指定备份目录
[root@master backups]# ll
total 0
drwxr-x--- 7 root root 232 Jul 30 11:01 2000-07-30_11-01-37
[root@master backups]# ll 2000-07-30_11-01-37/ #查看备份数据
total 77856
-rw-r----- 1 root root 418 Jul 30 11:01 backup-my.cnf #备份用到的配置选项信息文件
-rw-r----- 1 root root 79691776 Jul 30 11:01 ibdata1 #数据文件
drwxr-x--- 2 root root 20 Jul 30 11:01 kim
drwxr-x--- 2 root root 4096 Jul 30 11:01 mysql
drwxr-x--- 2 root root 4096 Jul 30 11:01 performance_schema
drwxr-x--- 2 root root 20 Jul 30 11:01 repppp
drwxr-x--- 2 root root 4096 Jul 30 11:01 wordpress
-rw-r----- 1 root root 21 Jul 30 11:01 xtrabackup_binlog_info #mysql服务器当前正在使用的二进制日志文件和此时二进制日志时间的位置信息文件
-rw-r----- 1 root root 113 Jul 30 11:01 xtrabackup_checkpoints #备份的类型、状态和LSN状态信息文件
-rw-r----- 1 root root 482 Jul 30 11:01 xtrabackup_info
-rw-r----- 1 root root 2560 Jul 30 11:01 xtrabackup_logfile #备份的日志文件
- 恢复
[root@slave ~]# /etc/init.d/mysqld stop #停止slave上的mysql
Shutting down MySQL.. SUCCESS!
[root@slave tools]# yum install -y percona-xtrabackup-24-2.4.9-1.el7.x86_64.rpm #安装xtrabackup
[root@master backups]# scp -r 2000-07-30_11-01-37/ root@192.168.56.12:/backups/ #从master上拷贝备份数据
[root@slave tools]# innobackupex --apply-log /backups/2000-07-30_11-01-37/ #合并数据,使数据文件处于一致性的状态
000729 23:18:23 innobackupex: Starting the apply-log operation
IMPORTANT: Please check that the apply-log run completes successfully.
At the end of a successful apply-log run innobackupex
prints "completed OK!".
innobackupex version 2.4.9 based on MySQL server 5.7.13 Linux (x86_64) (revision id: a467167cdd4)
xtrabackup: cd to /backups/2000-07-30_11-01-37/
xtrabackup: This target seems to be not prepared yet.
InnoDB: Number of pools: 1
xtrabackup: xtrabackup_logfile detected: size=8388608, start_lsn=(3127097)
......
InnoDB: FTS optimize thread exiting.
InnoDB: Starting shutdown...
InnoDB: Shutdown completed; log sequence number 3129915
000729 23:18:30 completed OK!
[root@slave ~]# rm -rf /usr/local/mysql/data/ #在slave上删除原有的数据
[root@slave ~]# vim /etc/my.cnf #配置my.cnf的数据目录路径,否则会报错,要和master一致
datadir=/usr/local/mysql/data
[root@slave ~]# innobackupex --copy-back /backups/2000-07-30_11-01-37/ #在slave上数据恢复
180729 23:32:03 innobackupex: Starting the copy-back operation
IMPORTANT: Please check that the copy-back run completes successfully.
At the end of a successful copy-back run innobackupex
prints "completed OK!".
......
000729 23:32:08 completed OK! #看到completed OK就是恢复正常了
[root@slave ~]# ll /usr/local/mysql/data/ #slave上查看数据目录,可以看到数据已经恢复,但是属主会有问题,需要进行修改,所以一般使用mysql的运行用户进行恢复,否则需要进行修改属主和属组信息
total 188432
-rw-r----- 1 root root 79691776 Jul 29 23:32 ibdata1
-rw-r----- 1 root root 50331648 Jul 29 23:32 ib_logfile0
-rw-r----- 1 root root 50331648 Jul 29 23:32 ib_logfile1
-rw-r----- 1 root root 12582912 Jul 29 23:32 ibtmp1
drwxr-x--- 2 root root 20 Jul 29 23:32 kim
drwxr-x--- 2 root root 4096 Jul 29 23:32 mysql
drwxr-x--- 2 root root 4096 Jul 29 23:32 performance_schema
drwxr-x--- 2 root root 20 Jul 29 23:32 repppp
drwxr-x--- 2 root root 4096 Jul 29 23:32 wordpress
-rw-r----- 1 root root 482 Jul 29 23:32 xtrabackup_info
[root@slave ~]# chown -R mysql.mysql /usr/local/mysql/data/ #修改属主属组
[root@slave ~]# /etc/init.d/mysqld start #启动mysql
Starting MySQL. SUCCESS!
[root@slave ~]# mysql -uroot -p -e "show databases;" #查看数据,是否恢复
Enter password:
+--------------------+
| Database |
+--------------------+
| information_schema |
| kim |
| mysql |
| performance_schema |
| repppp |
| wordpress |
+--------------------+
总结全库备份与恢复三步曲:
a. innobackupex全量备份,并指定备份目录路径;
b. 在恢复前,需要使用--apply-log参数先进行合并数据文件,确保数据的一致性要求;
c. 恢复时,直接使用--copy-back参数进行恢复,需要注意的是,在my.cnf中要指定数据文件目录的路径。
Xtrabackup增量备份
#一 基于上一次备份进行增量,参数说明:
--incremental:开启增量备份功能
--incremental-basedir:上一次备份的路径
#二 加上上一次命令
innobackupex --user=root --password=123 --no-timestamp --incremental --incremental-basedir=/backup/full/ /backup/xtra
#三 判断数据备份是否衔接
cat /backup/full/xtrabackup_checkpoints
backup_type = full-backuped
from_lsn = 0
to_lsn = 1808756
last_lsn = 1808756
compact = 0
recover_binlog_info = 0
flushed_lsn = 1808756
cat /backup/xtra/xtrabackup_checkpoints
backup_type = incremental
from_lsn = 0008756 # 值应该与全被的to_lsn一致
to_lsn = 0008756
last_lsn = 0008756
compact = 0
recover_binlog_info = 0
flushed_lsn = 0008756
xtrabackup增量备份与恢复
使用innobackupex进行增量备份,每个InnoDB的页面都会包含一个LSN信息,每当相关的数据发生改变,相关的页面的LSN就会自动增长。这正是InnoDB表可以进行增量备份的基础,即innobackupex通过备份上次完全备份之后发生改变的页面来实现。在进行增量备份时,首先要进行一次全量备份,第一次增量备份是基于全备的,之后的增量备份都是基于上一次的增量备份的,以此类推。
要实现第一次增量备份,可以使用下面的命令进行:
基于全量备份的增量备份与恢复 做一次增量备份(基于当前最新的全量备份)
innobackupex --user=root --password=root --defaults-file=/etc/my.cnf --incremental /backups/ --incremental-basedir=/backups/2000-07-30_11-01-37
- 准备基于全量
innobackupex --user=root --password=root --defaults-file=/etc/my.cnf --apply-log --redo-only /backups/2000-07-30_11-01-37
- 准备基于增量
innobackupex --user=root --password=root --defaults-file=/etc/my.cnf --apply-log --redo-only /backups/2018-07-30_11-01-37 --incremental-dir=/backups/2018-07-30_13-51-47/3. 恢复
innobackupex --copy-back --defaults-file=/etc/my.cnf /opt/2017-01-05_11-04-55/
解释:
2000-07-30_11-01-37指的是完全备份所在的目录。
2000-07-30_13-51-47指定是第一次基于2000-07-30_11-01-37增量备份的目录,其他类似以此类推,即如果有多次增量备份。每一次都要执行如上操作。
需要注意的是,增量备份仅能应用于InnoDB或XtraDB表,对于MyISAM表而言,执行增量备份时其实进行的是完全备份。
"准备"(prepare)增量备份与整理完全备份有着一些不同,尤其要注意的是: ①需要在每个备份 (包括完全和各个增量备份)上,将已经提交的事务进行"重放"。"重放"之后,所有的备份数据将合并到完全备份上。 ②基于所有的备份将未提交的事务进行"回滚"
(1)增量备份演示
[root@master backups]# innobackupex --user=root --password=123456 --host=127.0.0.1 /backups/ #全备数据[root@master ~]# mysql -uroot -p #在master上创建student库并创建testtb表插入若干数据Enter password:
mysql> create database student;
Query OK, 1 row affected (0.03 sec)
mysql> use student;
Database changed
mysql> create table testtb(id int);
Query OK, 0 rows affected (0.07 sec)
mysql> insert into testtb values(1),(10),(99);
Query OK, 3 rows affected (0.04 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from testtb;
+------+
| id |
+------+
| 1 |
| 10 |
| 99 |
+------+
3 rows in set (0.00 sec)
mysql> quit;
Bye
#使用innobackupex进行增量备份[root@master backups]# innobackupex --user=root --password=123456 --host=127.0.0.1 --incremental /backups/ --incremental-basedir=/backups/2000-07-30_11-01-37/
......
000730 13:51:50 Executing UNLOCK TABLES
000730 13:51:50 All tables unlocked
000730 13:51:50 Backup created in directory '/backups/2000-07-30_13-51-47/'
MySQL binlog position: filename 'mysql-bin.000005', position '664'
000730 13:51:50 [00] Writing /backups/2000-07-30_13-51-47/backup-my.cnf
000730 13:51:50 [00] ...done
000730 13:51:50 [00] Writing /backups/2000-07-30_13-51-47/xtrabackup_info
000730 13:51:50 [00] ...done
xtrabackup: Transaction log of lsn (3158741) to (3158741) was copied.
000730 13:51:50 completed OK!
[root@master backups]# ll #查看备份数据
total 0
drwxr-x--- 7 root root 232 Jul 30 11:01 2000-07-30_11-01-37 #全量备份数据目录
drwxr-x--- 8 root root 273 Jul 30 13:51 2000-07-30_13-51-47 #增量备份数据目录
[root@master 2000-07-30_11-01-37]# cat xtrabackup_checkpoints #查看全量备份的xtrabackup_checkpoints
backup_type = full-backuped #备份类型为全量备份
from_lsn = 0 #lsn从0开始
to_lsn = 3127097 #lsn到3127097结束
last_lsn = 3127097
compact = 0
recover_binlog_info = 0
[root@master 2018-07-30_13-51-47]# cat xtrabackup_checkpoints #查看增量备份的xtrabackup_checkpoints
backup_type = incremental #备份类型为增量备份
from_lsn = 3127097 #lsn从3127097开始
to_lsn = 3158741 #lsn到啊3158741结束
last_lsn = 3158741
compact = 0
recover_binlog_info = 0
(2)增量备份后数据恢复演示
(1)模拟mysql故障,删除数据目录所有数据[root@master ~]# /etc/init.d/mysqld stop #模拟mysql故障,停止mysql
Shutting down MySQL.. SUCCESS!
[root@master ~]# rm -rf /usr/local/mysql/data/* #删除数据目录中的所有数据(2)合并全备数据目录,确保数据的一致性
[root@master ~]# innobackupex --apply-log --redo-only /backups/2018-07-30_11-01-37/
180730 14:05:27 innobackupex: Starting the apply-log operation
IMPORTANT: Please check that the apply-log run completes successfully.
At the end of a successful apply-log run innobackupex
prints "completed OK!".
innobackupex version 2.4.9 based on MySQL server 5.7.13 Linux (x86_64) (revision id: a467167cdd4)
xtrabackup: cd to /backups/2018-07-30_11-01-37/
......
......
xtrabackup: starting shutdown with innodb_fast_shutdown = 1
InnoDB: Starting shutdown...
InnoDB: Shutdown completed; log sequence number 3127106
InnoDB: Number of pools: 1
180730 14:05:29 completed OK!(3)将增量备份数据合并到全备数据目录当中
[root@master ~]# innobackupex --apply-log --redo-only /backups/2018-07-30_11-01-37/ --incremental-dir=/backups/2018-07-30_13-51-47/
180730 14:06:42 innobackupex: Starting the apply-log operation
IMPORTANT: Please check that the apply-log run completes successfully.
At the end of a successful apply-log run innobackupex
prints "completed OK!".
......
......
180730 14:06:44 [00] ...done
180730 14:06:44 completed OK!
[root@master ~]# cat /backups/2018-07-30_11-01-37/xtrabackup_checkpoints
backup_type = log-applied #查看到数据备份类型是增加
from_lsn = 0 #lsn从0开始
to_lsn = 3158741 #lsn结束号为最新的lsn
last_lsn = 3158741
compact = 0
recover_binlog_info = 0(4)恢复数据
[root@master ~]# innobackupex --copy-back /backups/2018-07-30_11-01-37/
180730 14:07:51 innobackupex: Starting the copy-back operation
IMPORTANT: Please check that the copy-back run completes successfully.
At the end of a successful copy-back run innobackupex
prints "completed OK!".
.......
.......
180730 14:08:17 [01] ...done
180730 14:08:17 completed OK!
[root@master ~]# ll /usr/local/mysql/data/
total 77844
-rw-r----- 1 root root 79691776 Jul 30 14:08 ibdata1
drwxr-x--- 2 root root 20 Jul 30 14:08 kim
drwxr-x--- 2 root root 4096 Jul 30 14:08 mysql
drwxr-x--- 2 root root 4096 Jul 30 14:08 performance_schema
drwxr-x--- 2 root root 20 Jul 30 14:08 repppp
drwxr-x--- 2 root root 56 Jul 30 14:08 student
drwxr-x--- 2 root root 4096 Jul 30 14:08 wordpress
-rw-r----- 1 root root 21 Jul 30 14:08 xtrabackup_binlog_pos_innodb
-rw-r----- 1 root root 554 Jul 30 14:08 xtrabackup_info
[root@master ~]# chown -R mysql.mysql /usr/local/mysql/data #更改数据的属主属组
[root@master ~]# /etc/init.d/mysqld start #启动mysql
Starting MySQL.Logging to '/usr/local/mysql/data/master.err'.
.. SUCCESS!
[root@master ~]# mysql -uroot -p -e "show databases;" #查看数据是否恢复
Enter password:
+--------------------+
| Database |
+--------------------+
| information_schema |
| kim |
| mysql |
| performance_schema |
| repppp |
| student |
| wordpress |
+--------------------+
总结:
(1)增量备份需要使用参数--incremental指定需要备份到哪个目录,使用incremental-dir指定全备目录;
(2)进行数据备份时,需要使用参数--apply-log redo-only先合并全备数据目录数据,确保全备数据目录数据的一致性;
(3)再将增量备份数据使用参数--incremental-dir合并到全备数据当中;
(4)最后通过最后的全备数据进行恢复数据,注意,如果有多个增量备份,需要逐一合并到全备数据当中,再进行恢复。
#1. --user=root 指定备份的用户
#2. --password=root指定备份用户的密码
#3. --defaults-file=/etc/my.cnf 指定的备份数据的配置文件
#4. /opt/ 指定备份后的数据保存路径
更多参数详见:www.cnblogs.com/linhaifeng/…
企业实战:Xtrabackup + Binlog恢复
mysql配置文件:数据目录与binlog放在不同的文件夹下
[mysqld]
datadir=/var/lib/mysql
default-storage-engine=innodb
innodb_file_per_table=1
server_id=1
log-bin=/data/binlog/mybinlog
binlog_format='row' #(row,statement,mixed)
binlog_rows_query_log_events=on
max_binlog_size=100M
为binlog日志创建目录
mkdir -p /data/binlog/
chown -R mysql.mysql /data/
启动mysql
systemctl restart mysql
模拟数据
create database full charset utf8mb4;
use full;
create table t1 (id int);
insert into t1 values(1),(2),(3);
commit;
进行周日的全备
# 1、事先创建好备份目录
[root@db01 backup]# rm -rf /backup
[root@db01 backup]# mkdir /backup
# 2、全备
[root@db01 backup]# innobackupex --user=root --password=123 --no-timestamp --parallel=5 /backup/full
模拟周一的数据变化
create database inc1 charset utf8mb4;
use inc1;
create table t1 (id int);
insert into t1 values(1),(2),(3);
commit;
进行周一的增量备份
innobackupex --user=root --password=123 --no-timestamp --incremental --incremental-basedir=/backup/full /backup/inc1
检查本次备份的LSN
[root@localhost backup]# cat /backup/full/xtrabackup_checkpoints
backup_type = full-backuped
from_lsn = 0
to_lsn = 1817002
last_lsn = 1817002
compact = 0
recover_binlog_info = 0
flushed_lsn = 1817002
[root@localhost backup]# cat /backup/inc1/xtrabackup_checkpoints
backup_type = incremental
from_lsn = 1817002
to_lsn = 1825905
last_lsn = 1825905
compact = 0
recover_binlog_info = 0
flushed_lsn = 1825905
[root@localhost backup]#
模拟周二数据变化
create database inc2 charset utf8mb4;
use inc2;
create table t1 (id int);
insert into t1 values(1),(2),(3);
commit;
周二的增量
innobackupex --user=root --password=123 --no-timestamp --incremental --incremental-basedir=/backup/inc1 /backup/inc2
周三的数据变化
create database inc3 charset utf8mb4;
use inc3;
create table t1 (id int);
insert into t1 values(1),(2),(3);
commit;
模拟上午10点数据库崩溃
systemctl stop mysql # pkill -9 mysqld
\rm -rf /var/lib/mysql/*
恢复思路
1. 停业务,挂维护页
2. 查找可用备份并处理备份:full+inc1+inc2
3. 找到binlog中: inc2 到 故障时间点的binlog
4. 恢复全备+增量+binlog
5. 验证数据
6. 起业务,撤维护页
恢复前的准备 [rml_read_more]:
所有增量必须要按顺序合并到全备当中才能用于恢复
#(1) 整理full,--use-memory越大效率越高,但是不要超过内存大小,超过则报错
innobackupex --apply-log --use-memory=3G --redo-only /backup/full
--apply-log:该选项表示同xtrabackup的--prepare参数,一般情况下,在备份完成后,数据尚且不能用于恢复操作,因为备份的数据中可能会包含尚未提交的事务或已经提交但尚未同步至数据文件中的事务。因此,此时数据 文件仍处理不一致状态。--apply-log的作用是通过回滚未提交的事务及同步已经提交的事务至数据文件使数据文件处于一致性状态。
#(2) 合并inc1到full,并整理备份
innobackupex --apply-log --use-memory=3G --redo-only --incremental-dir=/backup/inc1 /backup/full
#(3) 合并后对比inc1与full的LSN号:last_lsn保持一致
cat /backup/full/xtrabackup_checkpoints
cat /backup/inc1/xtrabackup_checkpoints
#(4) 合并inc2到full,并整理备份 (合并最后一个增量备份时不要加--redo-only)
innobackupex --apply-log --use-memory=3G --incremental-dir=/backup/inc2 /backup/full
#(5) 合并后对比inc2与full的LSN号:last_lsn保持一致
cat /backup/full/xtrabackup_checkpoints
cat /backup/inc2/xtrabackup_checkpoints
#(6) 最后一次整理ful
innobackupex --use-memory=3G --apply-log /backup/full
#(7) 截取二进制日志
# 起点
cat /backup/inc2/xtrabackup_binlog_info
输出内容如下
mysql-bin.000031 1997 aa648280-a6a6-11e9-949f-000c294a1b3b:1-17,
e16db3fd-a6e8-11e9-aee9-000c294a1b3b:1-9
# 终点:
mysqlbinlog /data/binlog/mysql-bin.000031 |grep 'SET'
SET @@SESSION.GTID_NEXT= 'e16db3fd-a6e8-11e9-aee9-000c294a1b3b:12'/*!*/;
# 导出:
mysqlbinlog --skip-gtids --include-gtids='e16db3fd-a6e8-11e9-aee9-000c294a1b3b:10-12' /data/binlog/mysql-bin.000031>/backup/binlog.sql
或:
mysqlbinlog /data/binlog/mybinlog.000003 --start-position=1648 > /backup/binlog.sql恢复备份的数据
cp -a /backup/full/* /var/lib/mysql
chown -R mysql.mysql /var/lib/mysql
systemctl start mysql
mysql -uroot -p123
> set sql_log_bin=0;
> source /backup/binlog.sql
验证
select * from full.t1;
select * from inc1.t1;
select * from inc2.t1;
select * from inc3.t1;
恢复
XTRABACKUP参数说明
具体使用方法可以参考:Percona XtraBackup使用说明
通用选项:
-u, --user=name
-p, --password[=name]
-P, --port=#
-H, --host=name
-S, --socket=name
备份选项:
--backup #创建备份并且放入--target-dir目录中
--target-dir #指定backup的目的地,如果目录不存在,xtrabakcup会创建。如果目录存在且为空则成功。不会覆盖已存在的文件。
示例:$ xtrabackup --backup --target-dir=/data/backups/
增量选项:
--incremental-basedir
示例:$ xtrabackup --backup --target-dir=/data/backups/inc1 --incremental-basedir=/data/backups/base
压缩解压选项:
--compress #压缩
--compress-threads=n #启用n个线程进行压缩
--decompress #准备数据之前先解压
加密解密选项:
--encrypt=AES128|AES192|AES256
--encrypt-key=ENCRYPTION_KEY #使用适当长度的加密密钥。不建议在通过命令行访问机器的情况下使用此选项,因此可以将该密钥视为过程信息的一部分
--encrypt-key-file=KEYFILE #可从中读取适当长度的原始密钥的文件的名称。该文件必须是一个简单的二进制(或文本)文件,其中包含准确使用的密钥
--encrypt-threads #可以指定多个线程并行地进行加密
--encrypt-chunk-size #可用于指定每个加密线程的工作加密缓冲区的大小(以字节为单位)(默认值为64K)
--decrypt #解密
准备选项:
--prepare #实现通过回滚未提交的事务及同步已经提交的事务至数据文件使数据文件处于一致性状态
--apply-log-only #prepare备份的时候只执行redo阶段,用于增量备份(最后一次增量备份的准备不需要此选项)。
恢复选项:
--copy-back:做数据恢复时将备份数据文件拷贝到MySQL服务器的datadir。
--move-back:这个选项与--copy-back相似,唯一的区别是它不拷贝文件,而是移动文件到目的地。这个选项移除backup文件,用时候必须小心。
还可以通过rsync或cp来恢复文件
示例:$ rsync -avrP /data/backup/ /var/lib/mysql/
参数说明:
--apply-log-only:prepare备份的时候只执行redo阶段,用于增量备份。
--backup:创建备份并且放入--target-dir目录中
--close-files:不保持文件打开状态,xtrabackup打开表空间的时候通常不会关闭文件句柄,目的是为了正确处理DDL操作。如果表空间数量非常巨大并且不适合任何限制,一旦文件不在被访问的时候这个选项可以关闭文件句柄.打开这个选项会产生不一致的备份。
--compact:创建一份没有辅助索引的紧凑备份
--compress:压缩所有输出数据,包括事务日志文件和元数据文件,通过指定的压缩算法,目前唯一支持的算法是quicklz.结果文件是qpress归档格式,每个xtrabackup创建的*.qp文件都可以通过qpress程序提取或者解压缩
--compress-chunk-size=#:压缩线程工作buffer的字节大小,默认是64K
--compress-threads=#:xtrabackup进行并行数据压缩时的worker线程的数量,该选项默认值是1,并行压缩('compress-threads')可以和并行文件拷贝('parallel')一起使用。例如:'--parallel=4 --compress --compress-threads=2'会创建4个IO线程读取数据并通过管道传送给2个压缩线程。
--create-ib-logfile:这个选项目前还没有实现,目前创建Innodb事务日志,你还是需要prepare两次。
--datadir=DIRECTORY:backup的源目录,mysql实例的数据目录。从my.cnf中读取,或者命令行指定。
--defaults-extra-file=[MY.CNF]:在global files文件之后读取,必须在命令行的第一选项位置指定。
--defaults-file=[MY.CNF]:唯一从给定文件读取默认选项,必须是个真实文件,必须在命令行第一个选项位置指定。
--defaults-group=GROUP-NAME:从配置文件读取的组,innobakcupex多个实例部署时使用。
--export:为导出的表创建必要的文件
--extra-lsndir=DIRECTORY:(for --bakcup):在指定目录创建一份xtrabakcup_checkpoints文件的额外的备份。
--incremental-basedir=DIRECTORY:创建一份增量备份时,这个目录是增量别分的一份包含了full bakcup的Base数据集。
--incremental-dir=DIRECTORY:prepare增量备份的时候,增量备份在DIRECTORY结合full backup创建出一份新的full backup。
--incremental-force-scan:创建一份增量备份时,强制扫描所有增在备份中的数据页即使完全改变的page bitmap数据可用。
--incremetal-lsn=LSN:创建增量备份的时候指定lsn。
--innodb-log-arch-dir:指定包含归档日志的目录。只能和xtrabackup --prepare选项一起使用。
--innodb-miscellaneous:从My.cnf文件读取的一组Innodb选项。以便xtrabackup以同样的配置启动内置的Innodb。通常不需要显示指定。
--log-copy-interval=#:这个选项指定了log拷贝线程check的时间间隔(默认1秒)。
--log-stream:xtrabakcup不拷贝数据文件,将事务日志内容重定向到标准输出直到--suspend-at-end文件被删除。这个选项自动开启--suspend-at-end。
--no-defaults:不从任何选项文件中读取任何默认选项,必须在命令行第一个选项。
--databases=#:指定了需要备份的数据库和表。
--database-file=#:指定包含数据库和表的文件格式为databasename1.tablename1为一个元素,一个元素一行。
--parallel=#:指定备份时拷贝多个数据文件并发的进程数,默认值为1。
--prepare:xtrabackup在一份通过--backup生成的备份执行还原操作,以便准备使用。
--print-default:打印程序参数列表并退出,必须放在命令行首位。
--print-param:使xtrabackup打印参数用来将数据文件拷贝到datadir并还原它们。
--rebuild_indexes:在apply事务日志之后重建innodb辅助索引,只有和--prepare一起才生效。
--rebuild_threads=#:在紧凑备份重建辅助索引的线程数,只有和--prepare和rebuild-index一起才生效。
--stats:xtrabakcup扫描指定数据文件并打印出索引统计。
--stream=name:将所有备份文件以指定格式流向标准输出,目前支持的格式有xbstream和tar。
--suspend-at-end:使xtrabackup在--target-dir目录中生成xtrabakcup_suspended文件。在拷贝数据文件之后xtrabackup不是退出而是继续拷贝日志文件并且等待知道xtrabakcup_suspended文件被删除。这项可以使xtrabackup和其他程序协同工作。
--tables=name:正则表达式匹配database.tablename。备份匹配的表。
--tables-file=name:指定文件,一个表名一行。
--target-dir=DIRECTORY:指定backup的目的地,如果目录不存在,xtrabakcup会创建。如果目录存在且为空则成功。不会覆盖已存在的文件。
--throttle=#:指定每秒操作读写对的数量。
--tmpdir=name:当使用--print-param指定的时候打印出正确的tmpdir参数。
--to-archived-lsn=LSN:指定prepare备份时apply事务日志的LSN,只能和xtarbackup --prepare选项一起用。
--user-memory = #:通过--prepare prepare备份时候分配多大内存,目的像innodb_buffer_pool_size。默认值100M如果你有足够大的内存。1-2G是推荐值,支持各种单位(1MB,1M,1GB,1G)。
--version:打印xtrabackup版本并退出。
--xbstream:支持同时压缩和流式化。需要客服传统归档tar,cpio和其他不允许动态streaming生成的文件的限制,例如动态压缩文件,xbstream超越其他传统流式/归档格式的的优点是,并发stream多个文件并且更紧凑的数据存储(所以可以和--parallel选项选项一起使用xbstream格式进行streaming)。
使用lvm2快照备份数据
部署lvm环境
# 1、添加硬盘; 这里我们直接实现SCSI硬盘的热插拔, 首先在虚拟机中添加一块硬盘, 无需重启
echo '- - -' > /sys/class/scsi_host/host0/scan
echo '- - -' > /sys/class/scsi_host/host1/scan
echo '- - -' > /sys/class/scsi_host/host2/scan
# 2、创建逻辑卷
pvcreate /dev/sdb
vgcreate vg1 /dev/sdb
lvcreate -n lv1 -L 5G vg1
# 3、格式化制作文件系统并挂载
mkfs.xfs /dev/mapper/vg1-lv1
mkdir /lv1
mount /dev/mapper/vg1-lv1 /var/lib/mysql
chown -R mysql.mysql /var/lib/mysql
# 4、修改mysql配置文件的datadir如下
[root@node1 ~]# rm -rf /var/lib/mysql/* # 删除原数据
[root@node1 ~]# vim /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
# 5、重启MySQL、完成初始化
[root@node1 ~]# systemctl restart mysqld
# 6、往数据库内插入测试数据
create database db3;
use db3;
create table t1(id int);
insert t1 values(1),(2),(3);
创建快照卷并备份
mysql> FLUSH TABLES WITH READ LOCK; #锁定所有表
Query OK, 0 rows affected (0.00 sec)
[root@node1 lvm_data]# lvcreate -L 1G -s -n lv1_from_vg1_snap /dev/vg1/lv1 #创建快照卷
mysql> UNLOCK TABLES; #解锁所有表
Query OK, 0 rows affected (0.00 sec)
[root@node1 lvm_data]# mkdir /snap1 #创建文件夹
[root@node1 lvm_data]# mount -o nouuid /dev/vg1/lv1_from_vg1_snap /snap1
[root@localhost snap1]# cd /snap1/
[root@localhost snap1]# tar cf /tmp/mysqlback.tar *
[root@localhost snap1]# umount /snap1/ -l
[root@localhost snap1]# lvremove vg1/lv1_from_vg1_snap
恢复数据
rm -rf /var/lib/mysql/*
# 恢复
tar xf /tmp/mysqlback.tar -C /var/lib/mysql/