1 Xtrabackup介绍
Xtrabackup是Percona公司针对MySQL数据库开发的一款开源物理备份工具,可以对InnoDB和XtraDB等事务引擎的数据库实现非阻塞备份,也可以对MyISAM等非事务引擎实现锁表方式备份。Xtrabackup特点如下
- 复制物理文件,备份和恢复数据的速度非常快,安全可靠
- 备份期间执行的事务不中断,备份InnoDB数据不影响业务连续性
- 备份期间不会增加数据库性能压力
- 自动校验备份数据
- 全量、增量、压缩及流备份
- 在线迁移数据表、快速创建从库
- 版本兼容性好,支持全系列的MySQL和MariaDB
2 Xtrabackup安装步骤
2.1 系统环境说明
--- 查看系统版本
cat /etc/redhat-release
--- 查看内核版本
uname -r
--- 查看系统位数
uname -m
2.2 安装Xtrabackup
--- 安装基础环境包
yum install perl perl-devel libaio libaio-devel perl-Time-HiRes perl-DBD-MySQL
--- 下载Xtrabackup
wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.4/binary/redhat/7/x86_64/percona-xtrabackup-24-2.4.13-1.el7.x86_64.rpm
--- 安装Xtrabackup
yum install percona-xtrabackup-24-2.4.13-1.el7.x86_64.rpm
--- 查看安装结果
ls -l `which xtrabackup innobackupex`
3 Xtrabackup备份与恢复
3.1 Xtrabackup命令说明
- Xtrabackup用于InnoDB和XtraDB等事务引擎的数据库的热备份工具,不能用于备份MyISAM引擎数据
- Innobackupex是Xtrabackup命令基于perl语言进行二次封装的工具,支持Xtrabackup功能,还可以备份MyISAM及多种引擎混合使用的场景
3.2 创建数据库用户
CREATE USER 'backup'@'localhost' IDENTIFIED BY 'backup123';
GRANT RELOAD,LOCK TABLES,PROCESS,REPLICATION CLIENT ON *.* TO 'backup'@'localhost';
GRANT BACKUP_ADMIN,SELECT ON *.* TO 'backup'@'localhost';
FLUSH PRIVILEGES;
3.3 Innobackupex介绍
语法如下
innobackupex [--user=username] [--host=hostname] [--password=WORD] [--port=PORT] [--socket=SOCKET] [--defaults-file=my.cnf] PATH
Innobackupex参数说明
参数 | 说明 |
--user=USERNAME | 用于备份数据的用户 |
--password=PASSWORD | 用于备份数据的用户密码 |
--port=PORT | 数据库服务端口 |
--host=HOSTNAME | 备份数据库的主机名 |
--defaults-file | MySQL的配置文件备份 |
--defaults-group=GROUP-NAME | 多实例环境 |
--databases | 备份的数据库,多数据库使用'空格"分隔 |
--incremental | 增量备份,后跟增量备份路径 |
--incremental-basedir=DIRECTORY | 增量备份使用,增量备份的路径 |
--incremental-dir=DIRECTORY | 增量备份恢复时,合并增量备份到全备份,指定增量备份路径 |
--no-timestamp | 生成的备份文件不以时间戳为目录 |
--slave-info | 记录主库binlog位置点,保存在xtrabackup_slave_info文件,用于主从复制 |
--safe-slave-backup | 暂停slave库的SQL线程,备份结束后自动开启SQL线程,确保数据一致性,类似锁表 |
--stream=tar | 备份结果以tar的文件输出 |
--include=ocean | 备份包含的库表 |
--throttle=500 | 限定I/O |
--apply-log | 回滚未提交数据,应用redo日志 |
--use-memory | 恢复时使用内存量(需与--apply-log一起使用) |
--copy-back | 备份数据复制回原始位置 |
--redo-only | 合并多份增量备份,只应用redo日志数据,而不应用undo日志回滚数据 |
--rsync | 加速本地文件传输,适用于non-innodb引擎 |
--parallel=N | 增加多线程备份 |
3.4 全量备份与恢复
--- 创建备份目录
mkdir -p /bak/ocean
--- 全量备份
innobackupex --defaults-file=/etc/my.cnf --user=backup --password=backup123 --socket=/app/mysql5.7/tmp/mysql.sock --no-timestamp /bak/ocean/full
--- 查看binlog信息
cat /bak/ocean/full/xtrabackup_binlog_info
--- 查看备份检查点
cat /bak/ocean/full/xtrabackup_checkpoints
--- 应用日志,回滚未提交事务,确保数据一致性
innobackupex --apply-log --use-memory=64m /bak/ocean/full
--- 恢复数据
/etc/init.d/mysqld stop
ss -lnt | grep 3306
mv /app/mysql5.7/data /app/mysql5.7/data_ss
mkdir /app/mysql5.7/data
innobackupex --defaults-file=/etc/my.cnf --copy-backup --rsync /bak/ocean/full
chown -R mysql.mysql /app/mysql5.7/data
/etc/init.d/mysqld start
3.5 增量备份与恢复
增量备份是以一次全量备份做基准进行增量备份的,之后的每次增量备份都是基于前一次增量备份的数据来实现
--- 全量备份
innobackupex --defaults-file=/etc/my.cnf --user=backup --password=backup123 --socket=/app/mysql5.7/tmp/mysql.sock --no-timestamp /bak/ocean/base_full
--- 第一次增量备份
innobackupex --defaults-file=/etc/my.cnf --user=backup --password=backup123 --socket=/app/mysql5.7/tmp/mysql.sock --no-timestamp --incremental-basedir=/bak/ocean/base_full --incremental /bak/ocean/1st_incr
--- 第二次增量备份
innobackupex --defaults-file=/etc/my.cnf --user=backup --password=backup123 --socket=/app/mysql5.7/tmp/mysql.sock --no-timestamp --parallel=4 --incremental-basedir=/bak/ocean/1st_incr --incremental /bak/ocean/2nd_incr
--- 应用日志,回滚未提交事务,确保数据一致性
innobackupex --apply-log --use-memory=64m --redo-only /bak/ocean/base_full
innobackupex --apply-log --use-memory=64m --redo-only --incremental-dir=/bak/ocean/1st_incr /bak/ocean/base_full
innobackupex --apply-log --use-memory=64m --redo-only --incremental-dir=/bak/ocean/2nd_incr /bak/ocean/base_full
innobackupex --apply-log --use-memory=64m /bak/ocean/base_full
--- 恢复数据
/etc/init.d/mysqld stop
ss -lnt | grep 3306
mv /app/mysql5.7/data /app/mysql5.7/data_ss
mkdir /app/mysql5.7/data
innobackupex --defaults-file=/etc/my.cnf --copy-back --rsync /bak/ocean/base_full
chown -R mysql.mysql /app/mysql5.7/data
/etc/init.d/mysqld start
注:增量备份合并过程中,--redo-only参数是只应用redo日志恢复数据,不执行undo未提交数据,待最后增量数据合并完成一起应用undo日志回滚数据。
4 Xtrabackup分库、分表备份与恢复
4.1 分库、分表备份
Xtrabackup分库、分表备份数据,需开启独立表空间模式,innodb_file_per_table=ON
--- 备份单库ocean
innobackupex --defaults-file=/etc/my.cnf --user=backup --password=backup123 --socket=/app/mysql5.7/tmp/mysql.sock --no-timestamp --databases="ocean" /bak/ocean/single_db
--- 备份多库
innobackupex --defaults-file=/etc/my.cnf --user=backup --password=backup123 --socket=/app/mysql5.7/tmp/mysql.sock --no-timestamp --databases="ocean bob" /bak/ocean/multi_db
--- 备份单表
innobackupex --defaults-file=/etc/my.cnf --user=backup --password=backup123 --socket=/app/mysql5.7/tmp/mysql.sock --no-timestamp --databases="ocean.sales" /bak/ocean/single_tab
--- 备份多表
innobackupex --defaults-file=/etc/my.cnf --user=backup --password=backup123 --socket=/app/mysql5.7/tmp/mysql.sock --no-timestamp --databases="ocean.sales ocean.depts mysql.user" /bak/ocean/multi_tab
4.2 分库、分表恢复
分库、分表恢复数据时,使用"--export"参数,需初始化一个纯净的mysql数据库
--- 在纯净的mysql环境执行
innobackupex --apply-log --export /bak/ocean/single_tab
--- 初始化数据库
/app/mysql/bin/mysqld --no-defaults --initialize --basedir=/app/mysql --datadir=/app/mysql/data --user=mysql
--- 恢复数据
cp /bak/ocean/ocean_sales/* /app/mysql5.7/data
chown -R mysql.mysql /app/mysql5.7/data
--- 启动数据库,查看表数据
/etc/init.d/mysqld start
select * from ocean.sales;
--- mysqldump工具导出表数据,恢复到生产数据库
mysqldump -uroot -p'root1234' ocean sales > single_tab.sql
mysql ocean < single_tab.sql
--- source 恢复数据
mysqldump -uroot -p'root1234' ocean sales > single_tab.sql
mysql -uroot -p'root1234' -S /app/mysql5.7/tmp/mysql.sock
use ocean
source single_tab.sql
--- SQL语句导出、导入数据
mysql -uroot -p'root1234' -S /app/mysql5.7/tmp/mysql.sock
use ocean
select * from sales into outfile /bak/ocean/single_tab.txt" character set utf8;
mysql -uroot -p'root1234' -S /app/mysql5.7/tmp/mysql.sock
use ocean
delete from sales;
load data infile '/bak/ocean/single_tab.txt' into table sales;
5 企业案例
系统开发工程师测试功能脚本时,误操作执行在生产环境数据库中,导致生产数据异常。幸运的是专业的DBA团队配置了日常数据备份策略,通过备份恢复了受损的数据,最大限度的降低了企业的损失。下面我们来看一下恢复过程
--- 周日凌晨1:00的全量备份
innobackupex --defaults-file=/etc/my.cnf --user=backup --password=backup1234 --socket=/app/mysql5.7/tmp/mysql.sock --no-timestamp /bak/ocean/base_full
--- 周一凌晨1:00的增量备份
innobackupex --defaults-file=/etc/my.cnf --user=backup --password=backup1234 --sock=/app/mysql5.7/tmp/mysql.sock --no-timestamp --incremental-basedir=/bak/ocean/base_full --incremental /bak/ocean/1st_incr
--- 周一上午10:00,开发顾问误操作
drop database ocean
--- 周一上午10:03,前端应用无法访问,业务中断。DBA查看日志,发现业务数据库不存在,查看系统审计日志发现数据库丢失原因
--- 备份binlog
cp -a /app/mysql5.7/log /bak/ocean/binlog
--- 应用日志,回滚未提交事务,确保数据一致性
innobackupex --apply-log --use-memory=64m --redo-only /bak/ocean/base_full
innobackupex --apply-log --use-memory=64m --redo-only --incremental-dir=/bak/ocean/1st_incr /bak/ocean/base_full
innobackupex --apply-log --use-memory=64m /bak/ocean/base_full
--- 恢复binlog日志数据
cat /bak/ocean/1st_incr/xtrabackup_binlog_info
ocean-bin.000008 668
mysqlbinlog -d ocean ocean-bin.000008 ocean-bin.000009 --start-position=668 -r bin.sql
grep -w drop bin.sql
sed -i '/drop database ocean/d' bin.sql
--- 确保恢复过程中数据一致性,关闭数据库服务端口
iptables -I INPUT -p tcp --dport 3306 ! -s 10.6.0.243 -j DROP
--- 恢复数据
/etc/init.d/mysqld stop
ss -lnt | grep 3306
mv /app/mysql5.7/data /app/mysql5.7/data_ss
mkdir /app/mysql5.7/data
#innobackupex --defaults-file=/etc/my.cnf --copy-back --rsync /bak/ocean/base_full
mv /bak/ocean/base_full/* /app/mysql5.7/data
chown -R mysql.mysql /app/mysql5.7/data
/etc/init.d/mysqld start
--- 应用binlog恢复数据
mysql ocean < bin.sql
相关链接