物理备份缺点
跨平台性差(跨文件系统可能不能恢复) 备份时间长,冗余备份,浪费存储空间
mysqldump备份缺点
效率较低,备份和还原速度慢,锁表 备份过程中,数据插入和更新操作被阻塞
XtraBackup
工具什么是XtraBackup
工具
一款强大的在线热备工具 - 备份过程中不锁库表,适合生产环境 - 由专业组织Percona提供(改进MuSQL分支) 主要含两个组件 - xtrabackup: C程序,支持InnoDB/XtraDB - innobackupex: 以Perl脚本封装xtrabackup,还支持MyISAM
安装软件包
# 依赖libev包,本机没有,需要从网上下载,yum会自动解决 # 安装包在package目录下 # yum安装自动解决依赖(将本地包拷贝到主机上);两台机子都装 [root@admin ~]# yum -y install percona-xtrabackup-24-2.4.7-1.el7.x86_64.rpm
[root@admin ~]# rpm -qa | grep percona percona-xtrabackup-24-2.4.7-1.el7.x86_64 [root@admin ~]# rpm -ql percona-xtrabackup-24 [root@admin ~]# man innobackupex
innobackupex
命令命令格式
innobackupex 选项 # 完全备份(不需要自己创建目录名,会自动创建) innobackupex --user 用户名 --password 密码 备份目录名 --no-timestamp # 完全恢复 innobackupex --apply-log 目录名 # 准备恢复数据 innobackupex --copy-back 目录名 # 恢复数据 innobackupex在备份的过程中不会锁表,如果遇到数据插入,会将新加入的数据备份到其他文件中,准备恢复时,再恢复
常用选项
常用选项 | 含义 |
---|---|
--host |
主机口(默认是localhost ) |
--user |
用户名 |
--port |
端口号(默认是3306 ) |
--password |
密码 |
--databases |
数据库名 |
--no-timestamp |
不用日期名备份文件存储的子目录名 |
--redo-only |
日志合并 |
--apply-log |
准备恢复数据 |
--copy-back |
拷贝数据 |
--incremental 目录名 |
增量备份 |
--incremental-basedir=目录名 |
增量备份时,指定上一次备份数据存储的目录名 |
--incremental-dir=目录名 |
准备恢复数据时,指定增量备份数据存储的目录名 |
--export |
导出表信息 |
import |
导入表空间 |
--databases="库名" # 一个库 --databases="库1 库2" # 多个库 --databases="库1.表" # 一张表 # 不加入该字段,指所有库
[root@admin ~]# innobackupex --user root --password 123456 /allbak # 这里没有指定库,所以备份所有库 # 这里没有加"no-timestamp",生成的文件则是"/allbak"目录下日期为名 [root@admin ~]# ls /allbak/ 2021-11-19_00-43-17 [root@admin ~]# ls /allbak/2021-11-19_00-43-17/
数据的完全备份
[root@admin ~]# innobackupex --user root --password 123456 /allbak --no-timestamp [root@admin ~]# scp -r /allbak root@192.168.4.11:/root/
数据恢复的步骤
# 数据恢复 步骤如下 1. 停止数据库服务 2. 清空数据库目录 3. 准备恢复数据 4. 拷贝数据到数据库目录下 5. 修改数据库目录的所有者和所有组用户为mysql 6. 启动服务 7. 管理员登陆查看数据
完全恢复数据
[root@node1 ~]# systemctl stop mysqld [root@node1 ~]# rm -rf /var/lib/mysql/* [root@node1 ~]# innobackupex --apply-log /root/allbak/ [root@node1 ~]# innobackupex --copy-back /root/allbak/ [root@node1 ~]# chown -R mysql:mysql /var/lib/mysql [root@node1 ~]# systemctl start mysqld [root@node1 ~]# ss -utnlp | grep :3306 [root@node1 ~]# mysql -uroot -p123456 -e "select * from db2.user"
模拟表数据丢失
mysql> delete from db2.user mysql> select * from db2.user
具体操作如下:
1. 删除表空间 - mysql> alter table 库名.表名 discard tablespace; 2. 导出表信息 - ~]# innobackupex --apply-log -export 数据完全备份目录 3. 拷贝表信息文件到数据库目录底下 - ~]# cp 数据完全备份目录/数据库名/表名.(ibd,cfg,exp) 数据库名/库名目录/ 4. 修改表信息文件的所有者目录及组用户为MySQL - ~]# chown mysql:mysql 数据库目录/库名 5. 导入表空间 - mysql> alter table 库名.表名 import tablespace; 6. 删除数据库目录下的表信息文件 - ~]# rm -rf 数据库目录/库名/表名.{cfg,exp} 7. 查看表记录 - mysql> select * from 库名.表名; # 扩展内容:对数据库表文件的说明 [root@admin ~]# ls /var/lib/mysql/db2/ db.opt user.frm user.ibd 表名.frm # 表信息文件,存储表结构相关 表名.ibd # 表空间文件,存放数据相关 # 恢复单张表本质上就是删掉原有的表空间文件,替换成有数据的空间文件
mysql> alter table db2.user discard tablespace; [root@node1 ~]# innobackupex --apply-log --export /root/allbak/ [root@node1 ~]# cp /root/allbak/db2/user.{ibd,cfg,exp} /var/lib/mysql/db2/ [root@node1 ~]# ls /var/lib/mysql/db2/ db.opt user.cfg user.exp user.frm user.ibd [root@node1 ~]# chown mysql:mysql /var/lib/mysql/db2/user.* mysql> alter table db2.user import tablespace; [root@node1 ~]# rm -rf /var/lib/mysql/db2/user.{cfg,exp} mysql> select * from user;
增量备份
增量备份: 备份上次备份后,所有新产生的数据 # 信息文件 备份文件/xtrabackup_checkpoints [root@admin ~]# cat /allbak/xtrabackup_checkpoints backup_type = full-backuped # 查看备份数据的类型
增量备份命令格式
innobackupex --user 用户名 --password 密码 --incremental 增量目录 --incremental-basedir=目录名 --no-timestamp --incremental # 增量备份的文件目录 --incremental-basedir # 上次备份的文件目录(数据库与该文件对比,备份不同的数据)
增量备份示例
[root@admin ~]# innobackupex --user root --password 123456 --incremental /new1dir --incremental-basedir=/allbak --no-timestamp # 对比文件使用上次完全备份的"/allbak" mysql> insert into user(username) values("lisk"); # 数据库插入几条数据模拟增量备份条件 mysql> insert into user(username) values("zhuangba"); [root@admin ~]# innobackupex --user root --password 123456 --incremental /new2dir --incremental-basedir=/new1dir --no-timestamp # 这个时候,上次备份的文件就变成了"/new1dir"
增量恢复
# 准备恢复数据 innobackupex --apply-log --redo-only 目录名 --incremental-dir=目录名 # 恢复数据 ps:恢复前清空数据库目录并停止服务 innobackupex --copy-back 目录名 # 准备恢复数据的过程,也是日志(数据)合并的过程
# 将备份数据拷贝到目标服务器(admin服务器操作) [root@admin ~]# scp -r /allbak root@192.168.4.11:/opt [root@admin ~]# scp -r /new1dir root@192.168.4.11:/opt [root@admin ~]# scp -r /new2dir root@192.168.4.11:/opt # 准备恢复数据(node1服务器操作) # 每个步骤注意观察初始备份文件日志序列号(lsn)的变化 [root@node1 ~]# innobackupex --apply-log --redo-only /opt/allbak/ # 这个时候xtrabackup_checkpoints类型已经变为log-applied,可以追加日志 [root@node1 ~]# innobackupex --apply-log --redo-only /opt/allbak/ --incremental-dir=/opt/new1dir [root@node1 ~]# innobackupex --apply-log --redo-only /opt/allbak/ --incremental-dir=/opt/new2dir # 准备合并步骤 1. 将最初备份文件修改为可追加模式 2. 将增量备份文件(new1dir)的数据合并到最初备份的文件(allbak) 3. 将增量备份文件(new2dir)的数据合并到最初备份的文件(allbak) 注:每次合并时,合并的不只是数据,日志序列号(lsn)也会发生改变 [root@node1 ~]# rm -rf /opt/new1dir/ /opt/new2dir/ # 当数据合并到初始备份文件后,增量备份文件就可以删除了 [root@node1 ~]# systemctl stop mysqld [root@node1 ~]# rm -rf /var/lib/mysql/* [root@node1 ~]# innobackupex --copy-back /opt/allbak/ # 恢复数据 [root@node1 ~]# chown -R mysql:mysql /var/lib/mysql [root@node1 ~]# systemctl start mysqld [root@node1 ~]# ss -utnlp | grep :3306 # 验证数据恢复效果 [root@node1 ~]# mysql -uroot -p123456 -e "select count(*) from db2.user"