xtrabackup工具备份与恢复
1、xtrabackup简介
Xtrabackup是一个对InnoDB做数据备份的工具,支持在线热备份(备份时不影响数据读写),是商业备份工具InnoDB Hotbackup的一个很好的替代品。它能对InnoDB和XtraDB存储引擎的数据库非阻塞地备份(对于MyISAM的备份同样需要加表锁)。XtraBackup支持所有的Percona Server、MySQL、MariaDB和Drizzle。
xtrabackup有两个主要的工具:xtrabackup、innobackupex
- xtrabackup,只能备份InnoDB和XtraDB两种数据表
- innobackupex则封装了xtrabackup,同时可以备份MyISAM数据表
Innobackupex完整备份后生成了几个重要文件
|
1.1 xtrackup特点
- 能够对InnoDB实现热备,无需暂停数据库
- 能够对MySQL进行增量备份
- 对MySQL备份能够实现流式压缩并传输给其他服务器,--stream参数实现
- MySQL服务运行时能够在MySQL 服务器之间进行表的迁移
- 能够很容易创建一个MySQL从服务器
- 备份MySQL时不会增加服务器负担
XtraBackup能够带InnoDB引擎创建的表实现热备,对MyISAM引擎实现温备。
1.2 备份原理
在InnoDB内部会维护一个redo日志文件,我们也可以叫做事务日志文件。事务日志会存储每一个InnoDB表数据的记录修改。当InnoDB启动时,InnoDB会检查数据文件和事务日志,并执行两个步骤:它应用(前滚)已经提交的事务日志到数据文件,并将修改过但没有提交的数据进行回滚操作。
使用xtrabackup进行还原,需要xtrabackup进行”备份”和”准备”:先将文件全部复制过来,再根据事务日志对部分操作进行回滚,如下描述:
- xtrabackup的备份过程。Xtrabackup在启动时会记住log sequence number(LSN),并且复制所有的数据文件。复制过程需要一些时间,所以这期间如果数据文件有改动,那么将会使数据库处于一个不同的时间点。所以,xtrabackup会运行一个后台进程,用于监视事务日志,并从事务日志复制最新的修改。Xtrabackup持续地做这个操作,这些数据改动会写入xtrabackup_logfile文件。xtrabackup自启动开始,就不停的将事务日志中每个数据文件的修改都记录下来。
- 接下来是准备(prepare)过程。在这个过程中,xtrabackup使用之前复制的事务日志,对各个数据文件执行灾难恢复(就像mysql刚启动时要做的一样)。当这个过程结束后,数据库就可以做恢复还原了。
更详细的描述如下:
- 1. 调用xtrabackup对innodb表空间文件(这一瞬间的映像Time1)备份,而在这个innodb表备份期间数据库是不加锁的,外部可以继续往库里增减数据(这才能叫热备份)。而在Time1和Time2这两个时间点之间的改动由一个线程不断地扫innodb log获得(ChangeSet1),一旦发现redo中有新的日志写入,立刻将日志记入后台日志文件xtrabackup_log中
- 2. 锁所有库。
- 3. 以直接拷贝的方式备份frm,MYD,MYI,MRG,TRG,TRN,opt格式的文件。
- 4. 步骤3中的数据备份完毕时(Time2),停止扫innodb log的线程,把ChangeSet1的数据拷贝到备份中。
- 5. 解锁所有库。
- 6. 终止挂起,备份完毕。
注意要点
- 根据innobackupex的原理可知它不是真正的热备份,MyISAM表越少越小就越有利。要利用Xtrabackup的好处就尽量用innodb表。
- 还原备份前关闭mysql服务;还原备份后检查数据文件权限是否正确。
2、xtrabackup安装
redhat6的版本,使用2.3.4这个版本
Xtrabackup包依赖于epel源一些工具包,所以使用yum安装。
yum install percona-xtrabackup-2.3.4-1.el6.x86_64.rpm
依赖这两个包:
安装完后的目录结构如下,有4个可执行文件
usr
├── bin
│ ├── innobackupex
│ ├── xbcrypt
│ ├── xbstream
│ └── xtrabackup
其中最主要的是 innobackupex 和 xtrabackup,前者是一个 perl 脚本,后者是 C/C++ 编译的二进制。
- xtrabackup 是用来备份 InnoDB 表的,不能备份非 InnoDB 表,和 mysqld server 没有交互;innobackupex 脚本用来备份非 InnoDB 表,同时会调用 xtrabackup 命令来备份 InnoDB 表,还会和 mysqld server 发送命令进行交互,如加读锁(FTWRL)、获取位点(SHOW SLAVE STATUS)等。简单来说,innobackupex 在 xtrabackup 之上做了一层封装。
- 一般情况下,我们是希望能备份 MyISAM 表的,虽然我们可能自己不用 MyISAM表,但是 mysql 库下的系统表是 MyISAM 的(mysql自带的数据库都是什么存储引擎?经查,mysql是MyISAM,information_schema是MEMORY,performance_schema是PERFORMANCE_SCHEMA),因此备份基本都通过 innobackupex 命令进行;另外一个原因是我们可能需要保存位点信息。
- 另外2个工具相对小众些,xbcrypt 是加解密用的;xbstream 类似于tar,是 Percona 自己实现的一种支持并发写的流文件格式。两都在备份和解压时都会用到(如果备份用了加密和并发)。
3、备份
3.1 全库备份
备份场景1:备份所有数据库:备份目录里生成日期命名的文件夹
innobackupex --defaults-file=/usr/local/mysql/my.cnf --user=root --password=xxx --socket=/var/lib/mysql/mysql.sock /data/backup/
出现completed OK!表示备份完成
innobackupex会在指定存放数据的目录下用当前时间创建一个目录,所有生成的备份文件都会这个时间目录下
备份场景2:备份所有数据库,指定目录的名称
--no-timestamp参数的使用
在使用innobackupex进行备份时,还可以使用--no-timestamp选项来阻止命令自动创建一个以时间命名的目录;如此一来,innobackupex命令将会创建一个BACKUP-DIR目录来存储备份数据。
innobackupex --defaults-file=/usr/local/mysql/my.cnf --user=root --password=xxx --socket=/var/lib/mysql/mysql.sock --no-timestamp /data/backup/backup_dir
场景三:备份所有数据库,并打包
--stream=tar 参数的使用,该选项表示流式备份的格式,backup完成之后以指定格式到STDOUT,目前只支持tar和xbstream。
innobackupex --defalut-file=/usr/local/mysql/my.cnf --user=root --password=xxx --socket=/var/lib/mysql/mysql.sock --stream=tar --no-timestamp /home/data/backup 1>/home/data/backup/xtra_backup20190329.tar
1> 代表标准输出(stdout),前面不加1,只是>,一样的效果
2> 代表标准错误(stderr)
场景四:备份所有数据库,压缩打包
innobackupex --defalut-file=/usr/local/mysql/my.cnf --user=root --password=xxx --socket=/var/lib/mysql/mysql.sock --stream=tar --no-timestamp /home/data/backup |gzip >/home/data/backup/150_backup.tar.gz
注意:
Warning:
To extract Percona XtraBackup's archive you must use tar with -i option:
用tar压缩备份,在解压时必须使用 -i 参数:
可以使用如下目录解压,先创建解压的目录150_backup,解压到此目录
tar -zixvf 150_backup.tar.gz -C ./150_backup
场景5:备份到远程并压缩
innobackupex --defalut-file=/usr/local/mysql/my.cnf --user=root --password=xxx --socket=/var/lib/mysql/mysql.sock --stream=tar /home/data/backup |ssh root@192.168.2.151 "gzip >/home/data/150_backup/150_backup.tar.gz"
注意:操作此备份要在两台机器之间实现ssh免密码登录
3.2 备份指定数据库
备份场景1:备份指定数据库
备份A和B数据库,使用--databases参数指定数据库
innobackupex --defaults-file=/usr/local/mysql/my.cnf --user=root --password=xxx --socket=/var/lib/mysql/mysql.sock --databases="A B" --no-timestamp /data/backup/backup_database
3.3 备份指定表
备份场景1:备份不同库下的不同表,还是使用--databases参数,指定到表
innobackupex --defaults-file=/usr/local/mysql/my.cnf --user=root --password=xxx --socket=/var/lib/mysql/mysql.sock --databases="A.hrms_ao B.checktype" --no-timestamp /data/backup/backup_tables
备份场景2:备份一个库下的表,备份A库下h开头的表
使用--include参数,该选项表示使用正则表达式匹配表的名字
innobackupex --defaults-file=/usr/local/mysql/my.cnf --user=root --password=xxx --socket=/var/lib/mysql/mysql.sock --include="A.h" --no-timestamp /data/backup/backup_tables
3.4 增量备份
使用--incremental-basedir和--incremental参数来进行增量备份
innobackupex --defaults-file=/usr/local/mysql/my.cnf --user=root --password=xxx --socket=/var/lib/mysql/mysql.sock --no-timestamp --incremental-basedir=/data/backup/backup_dir --incremental /data/backup/increment_data/
--incremental-basedir:全量备份目录
--incremental:增量备份目录
注:全量备份的目录是:/data/backup/backup_dir
4、还原
4.1 全库还原
注:还原时,mysql服务器需要关闭,而且数据目录必须是空的,innobackupex –copy-back不会覆盖已存在的文件
- 先准备(prepare)一个完全备份
innobackupex --apply-log /data/backup/2018-11-08_09-41-06
备份完成后,数据尚且不能用于恢复操作,因为备份的数据中可能会包含尚未提交的事务或已经提交但尚未同步至数据文件中的事务。因此,此时数据文件仍处理不一致状态。“准备”的主要作用正是通过回滚未提交的事务及同步已经提交的事务至数据文件也使得数据文件处于一致性状态。
利用 --apply-log参数,此参数的作用是通过回滚未提交的事务及同步已经提交的事务至数据文件使数据文件处于一致性状态。
执行完后,xtrabackup_checkpoints文件里面的backup_type会变成full-prepared状态(之前是full-backuped的状态)
- 还原
innobackupex --defaults-file=/usr/local/mysql/my.cnf --copy-back /data/backup/2018-11-08_09-41-06/
注:
上面的命令加了--defaults-file参数,该选项指定了从哪个文件读取MySQL配置,必须放在命令行第一个选项的位置。--copy-back:做数据恢复时将备份数据文件拷贝到MySQL服务器的datadir。
另外,上面的还原都没指定还原到哪个目录,mysql怎么知道?这就需要在my.cnf加入这个参数
datadir =/data/mysql |
出现completed OK! 代表还原成功
还原完记得修改权限:
chown -R mysql:mysql /data/mysql/*
综上,总结几个注意点:
- 1.datadir目录必须为空。除非指定innobackupex --force-non-empty-directorires选项指定,否则--copy-backup选项不会覆盖
- 2.在restore之前,必须shutdown MySQL实例,你不能将一个运行中的实例restore到datadir目录中
- 3.由于文件属性会被保留,大部分情况下你需要在启动实例之前将文件的属主改为mysql,这些文件将属于创建备份的用户
4.2 增量还原
“准备”(prepare)增量备份与整理完全备份有着一些不同,尤其要注意的是:
(1)需要在每个备份(包括完全和各个增量备份)上,将已经提交的事务进行“重放”。“重放”之后,所有的备份数据将合并到完全备份上。
(2)基于所有的备份将未提交的事务进行“回滚”。
第一步:先apply-log全量备份
innobackupex --apply-log --redo-only /data/backup/backup_dir
第二步:把增量备份数据合并到全量备份数据上
innobackupex --apply-log --redo-only /data/backup/backup_dir --incremental-dir=/data/backup/increment_data
此时增量备份上的数据已经合并到全量备份上了,查看xtrabackup_checkpoints
[root@report-server backup_dir]# more xtrabackup_checkpoints backup_type = log-applied from_lsn = 0 to_lsn = 48526869189 ----------跟增量备份上的lsn一致 last_lsn = 48526869189 compact = 0 recover_binlog_info = 0 |
增量备份上的xtrabackup_checkpoints
backup_type = incremental from_lsn = 48526868973 ----------上次全量备份上的lsn to_lsn = 48526869189 ----------增量备份的截止lsn last_lsn = 48526869189 compact = 0 recover_binlog_info = 0 |
第三步:回滚完全备份
innobackupex --apply-log /data/backup/backup_dir
第四步:还原
innobackupex --defaults-file=/usr/local/mysql/my.cnf --copy-back /data/backup/backup_dir
进入到数据目录,修改权限:
chown -R mysql:mysql *
启动mysql,检查数据是否恢复成功。
4.3 xtrabackup全库还原+binlog日志还原
另外一篇日志说明
5、问题
5.1 找不到mysql.sock问题
181107 22:03:42 innobackupex: Starting the backup operation IMPORTANT: Please check that the backup run completes successfully. At the end of a successful backup run innobackupex prints "completed OK!". 181107 22:03:42 version_check Connecting to MySQL server with DSN 'dbi:mysql:;mysql_read_default_group=xtrabackup' as 'root' (using password: YES). 181107 22:03:42 version_check Connected to MySQL server 181107 22:03:42 version_check Executing a version check against the server... 181107 22:03:42 version_check Done. 181107 22:03:42 Connecting to MySQL server host: localhost, user: root, password: set, port: 0, socket: (null) Failed to connect to MySQL server: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2). |
mysql.sock有什么用?
mysql的连接方式有两种: 1、通过TCP/IP的连接 2、通过本地socket的连接,对mysql.sock来说,其作用是程序与mysqlserver处于同一台机器,发起本地连接时可用。在连接时你无须定义连接host的具体IP,只要为空或localhost就可以 在此种情况下,即使你改变mysql的外部port也是一样可能正常连接。 因为你在my.ini中或my.cnf中改变端口后,mysql.sock是随每一次 mysql server启动生成的。已经根据你在更改完my.cnf后重启mysql时重新生成了一次,信息已跟着变更。 |
那找到原因了:因为在my.cnf中没有指定mysql.sock的路径,所以默认去/tmp/目录寻找,找不到,没法链接
解决方案:找出系统的mysql.sock文件的路径,在my.cnf进行指定或者在innobackupex命令中指定sock的绝对路径
第一种方案:在my.cnf增加sock参数的设置
socket =/var/lib/mysql/mysql.sock |
命令里面指定my.cnf文件即可
innobackupex --defaults-file=/usr/local/mysql/my.cnf --user=root --password=XXX /data/backup/
第二种方案:使用find命令找出mysql.sock的路径,然后修改命令如下,加上socket参数
innobackupex --defaults-file=/usr/local/mysql/my.cnf --user=root --password=XXX --socket=/var/lib/mysql/mysql.sock /data/backup/
第三种方案:指定IP地址,通过tcp/ip方式连接
innobackupex --defaults-file=/usr/local/mysql/my.cnf --host=127.0.0.1 --user=root --password=XXX /data/backup/
5.2 安装过程出现依赖包版本过高问题
[root@report-server media]# yum install percona-xtrabackup-2.3.4-1.el6.x86_64.rpm Loaded plugins: product-id, security, subscription-manager Updating certificate-based repositories. Unable to read consumer identity Setting up Install Process Examining percona-xtrabackup-2.3.4-1.el6.x86_64.rpm: percona-xtrabackup-2.3.4-1.el6.x86_64 Marking percona-xtrabackup-2.3.4-1.el6.x86_64.rpm to be installed Resolving Dependencies --> Running transaction check ---> Package percona-xtrabackup.x86_64 0:2.3.4-1.el6 will be installed --> Processing Dependency: libz.so.1(ZLIB_1.2.0)(64bit) for package: percona-xtrabackup-2.3.4-1.el6.x86_64 --> Finished Dependency Resolution Error: Package: percona-xtrabackup-2.3.4-1.el6.x86_64 (/percona-xtrabackup-2.3.4-1.el6.x86_64) Requires: libz.so.1(ZLIB_1.2.0)(64bit) You could try using --skip-broken to work around the problem You could try running: rpm -Va --nofiles --nodigest |
查看zlib包包括的文件
rpm -ql zlib-1.2.3-27.el6.x86_64
想尝试把zlib卸载了重新安装,因为依赖太多包,卸载不了,于是使用--nodeps,不检查依赖直接卸载
rpm -e zlib --nodeps
卸载了这个以后,libz.so.1文件就没了,但是yum用不了、wget也用不了,ssh也登录不了,r很多模块都出现了问题-----经验教训,不能随便使用--nodeps参数卸载包
登录到别的机器也不行,如下提示
[root@report-server ~]# ssh patrol@192.168.241 ssh: error while loading shared libraries: libz.so.1: cannot open shared object file: No such file or directory |
本想去别的机器拷贝这个文件过来,scp也用不了,本想使用rz命令,挂载镜像找到相应的rz的rpm包进行安装,发现rpm也用不了
于是想办法去别的机器下载libz.so.1.2.3文件(因为实际的libz.so.1是一个链接文件,链接到此文件),然后制作一个iso镜像挂载上去,放到/lib64目录
做一个软连接:
ln -s libz.so.1.2.3 libz.so.1
回到开始的问题,提示“Requires: libz.so.1(ZLIB_1.2.0)(64bit)”,但是实际上已经安装了ZLIB_1.2.3版本,于是使用--nodeps参数强制安装
如下命令,安装成功。
rpm -ivh percona-xtrabackup-2.3.4-1.el6.x86_64.rpm --nodeps
--nodeps参数的意思是安装之前不检查依赖
--nodeps Don’t do a dependency check before installing or upgrading a package. |
6、其他
6.1 免密登录
原理:
操作:
环境:
主机1:192.168.161.10 linux
主机2:192.168.161.3 solaris
需求:需要从192.168.161.10登陆192.168.161.3不需要密码
- 生成公钥和私钥
ssh-keygen -t rsa
这个目录下会多两个文件,也即是生成了公钥和私钥
公共密钥是: ~/.ssh/id_rsa.pub
私有密钥是: ~/.ssh/id_rsa
把这个文件拷到对端机器
scp .shh/id_rsa.pub root@192.168.161.3:/export
然后把这个文件拷贝为authorized_keys,
注:在solaris这个文件的位置和linux是不同的
cat id_rsa.pub >/.ssh/authorized_keys
参考:
http://www.cnblogs.com/zhoujinyi/p/5893333.html