当前位置: 首页 > 工具软件 > XtraBackup > 使用案例 >

Xtrabackup的备份恢复操作

戚浩淼
2023-12-01


一、下载安装Xtrabackup

  #下载安装包
  wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.10/binary/redhat/7/x86_64/percona-xtrabackup-24-2.4.10-1.el7.x86_64.rpm
  #安装依赖
  yum -y install perl-DBI libev.so.* perl perl-Digest-MD5 perl-devel libaio libaio-devel perl-Time-HiRes perl-DBD-MySQL
  #安装软件
  rpm -ivh percona-xtrabackup-24-2.4.10-1.el7.x86_64.rpm 

二、工具介绍

在这套工具集里最重要的程序有两个: innobackupexxtrabackup,前者是perl脚本,后者是C/C++编译的二进制程序。xtrabackup是用来备份InnoDB的,并不能备份非InnoDB表,它在内部实现了对InnoDB的热备份。innobackupex脚本是对xtrabackup的封装,通过调用xtrabackup命令来备份InnoDB表,同时也通过mysqldump等命令来备份非InnoDB表,并且会与MySQL数据库发送命令交互,例如获取Binlog位点、添加锁操作。
由于MySQL中的系统表(例如:mysql库)基于MyISAM存储引擎(MySQL 5.7版本之前),所以备份这部分数据一般都使用innobackupex脚本来完成。

Percona XtraBackup的优点如下。
• 无须停止数据库进行InnoDB热备。
• 增量备份MySQL。
• 流压缩传输到其他服务器。
• 在线移动表。
• 能够比较容易地创建主从同步。
• 备份MySQL时不会增大服务器负载。

三、工作流程

首先,来描述一下XtraBackup的工作流程。在工作过程中,innobackupex会和xtrabackup协同工作,共同完成备份任务。

1.innobackupex启动后,首先通过start_ibbackup()函数中的fork方式创建xtrabackup进程并且启动。然后等待xtrabackup完成InnoDB相关文件的备份。
2.innobackupex通过wait_for_ibbackup_suspend(suspend_file)检测xtrabackup_suspended_2文件是否存在,如果检测到该文件,innobackupex进程就会被唤醒。
3.xtrabackup在备份InnoDB相关文件时,会开启如下两种线程。
–ibd复制线程,负责复制ibd文件。
–redo log复制线程,负责复制redo log信息。xtrabackup首先启动redo log复制线程,从最近的checkpoint点开始顺序复制redo log;然后启动ibd复制线程,在xtrabackup复制ibd的过程中,redo log复制线程一直工作,并且innobackupex进程处于等待状态,等待被xtrabackup进程唤醒。
4.xtrabckup复制ibd完成后,通知innobackupex进程(通过创建xtrabackup_suspended_2文件方式),同时自己进入等待状态,但是redo log复制线程依然在工作。
5.innobackupex收到通知,会执行备份锁(LOCK TABLESFORBACKUP),取到一致性的位点,然后开始复制非InnoDB文件。
6.当非InnoDB文件复制完成后,innobackupex开始执行LOCKBINLOG FORBACKUP,开始通过get_mysql_master_status($con)函数来获取Binlog位置。
7.然后创建xtrabackup_binlog_info文件,通过w rite_to_backup_file(binlog_info,join("\t", @binlog_info_content)."\n")函数将Binlog的位点信息写入文件中。
8.接着发起一个通知给xtrabackup进程(通过删除xtrabackup_suspended_2的方式),同时自己进入等待状态。
9.xtrabackup收到通知后,就会停止redo log复制线程,告知innobackupex,redo log复制完成,然后通知innobackupex(通过创建xtrabackup_log_copied文件的方式)。
10.innobackupex收到通知后,就开始释放锁资源(UNLOCKBINLOG和UNLOCKTABLES)。
11.随后,innobackupex和xtrabackup进行后期工作,比如资源的释放、备份元数据信息、打印备份目录、备份Binlog的位置信息,以及写入xtrabackup_info文件信息等。
12.最后,innobackupex等待xtrabackup进程结束后退出。
 
#三点总结
1.在备份的过程中,需要复制redo log,是由于备份ibd文件的过程中该文件可能被修改,这样备份出来的文件就可能是有脏数据的。那么在恢复时,需要通过redo log进行数据恢复,即应用已经提交的事务,回滚那些未提交的事务。
2.在备份中严重依赖于xtrabackup_suspended_2和xtrabackup_log_copied文件,如果在备份过程中,人为地删除了该文件或创建了任何一个文件,都会导致备份出现错误。因为innobackupex与xtrabackup进程之间的交互是通过这两个文件进行的。
3.如果是增量复制,还存在xtrabackup_suspended_1文件,作用是一样的。

四、准备工作

Percona XtraBackup需要能够连接到数据库服务器,并在创建备份时、在某些场景下准备时以及在恢复时对服务器和 datadir 执行操作。为此必须满足对其执行的权限 。

4.1 连接参数

OptionDescription
–user用户名
–password用户密码
–port数据库端口
–socket连接本地数据库的socket文件
–host主机地址

4.2 创建用户及授权

所需的权限和特权 连接到服务器后,为了执行备份,您需要在服务器数据目录中的文件系统级别具有 READ 和 EXECUTE 权限。 数据库用户需要对要备份的表/数据库具有以下权限,具体权限的作用可查阅官网。

create user xbk_backup@'%' identified by '123';
GRANT RELOAD, LOCK TABLES, PROCESS, REPLICATION CLIENT ON *.* TO xbk_backup@'%' ;
FLUSH PRIVILEGES;

五、备份操作

5.1 全备破坏性测试(使用xtrabackup)

xtrabackup --defaults-file=/data/mysql/conf/3306/my.cnf --user=xbk_backup  --password=123 --socket=/data/mysql/data/3306/mysqld.sock --target-dir=/data/backups/ --backup    

查看

[root@node02 backups]# ls -lh /data/backups/
total 13M
-rw-r----- 1 root root  433 Aug 31 10:40 backup-my.cnf
drwxr-x--- 2 root root   98 Aug 31 10:40 gengjin
-rw-r----- 1 root root  409 Aug 31 10:40 ib_buffer_pool
-rw-r----- 1 root root  12M Aug 31 10:40 ibdata1
drwxr-x--- 2 root root 4.0K Aug 31 10:40 mysql
drwxr-x--- 2 root root 8.0K Aug 31 10:40 performance_schema
drwxr-x--- 2 root root   20 Aug 31 10:40 sbtest
drwxr-x--- 2 root root 8.0K Aug 31 10:40 sys
drwxr-x--- 2 root root   48 Aug 31 10:40 test
drwxr-x--- 2 root root  144 Aug 31 10:40 world
-rw-r----- 1 root root  101 Aug 31 10:40 xtrabackup_binlog_info
-rw-r----- 1 root root  113 Aug 31 10:40 xtrabackup_checkpoints
-rw-r----- 1 root root  693 Aug 31 10:40 xtrabackup_info
-rw-r----- 1 root root 2.5K Aug 31 10:40 xtrabackup_logfile
xtrabackup --defaults-file=/data/mysql/conf/3306/my.cnf --user=xbk_backup  --password=123 --socket=/data/mysql/data/3306/mysqld.sock --target-dir=/data/backups/ --prepare 
......
......

InnoDB: Waiting for purge to start
InnoDB: 5.7.19 started; log sequence number 5356129
xtrabackup: starting shutdown with innodb_fast_shutdown = 1
InnoDB: FTS optimize thread exiting.
InnoDB: Starting shutdown...
InnoDB: Shutdown completed; log sequence number 5356148
210831 10:47:06 completed OK!
1.删除数据目录及redolog
rm /data/mysql/data/3306/* -rf
rm /data/mysql/log/redolog/3306/* -rf
2.恢复
xtrabackup --defaults-file=/data/mysql/conf/3306/my.cnf --user=xbk_backup  --password=123 --socket=/data/mysql/data/3306/mysqld.sock --target-dir=/data/backups/ --copy-back
3.授权数据目录及redo目录
chown -R mysql.mysql /data/mysql/data/3306/*
chown -R mysql.mysql /data/mysql/log/redolog/3306/*
4.启动mysql
systemctl restart mysqld_3306
#自此数据库恢复完成

5.2 全备+增备破坏性测试(使用innobackupex)

xtrabackup 和 innobackupex 工具都支持增量备份,这意味着它们只能复制自上次备份以来发生变化的数据。
你可以在每次完整备份之间进行多次增量备份,因此您可以设置一个备份过程,例如每周一次完整备份和每天一次增量备份,或者每天一次完整备份和每小时一次增量备份。
增量备份有效,因为每个InnoDB页面都包含一个日志序列号或LSN。 LSN是整个数据库的系统版本号。每个页面的LSN显示它最近更改的时间。

1.全备份
innobackupex --defaults-file=/data/mysql/conf/3306/my.cnf --user=xbk_backup  --password=123 --socket=/data/mysql/data/3306/mysqld.sock --no-timestamp /data/backups
1.造第一次增量数据
create database kobe;
sysbench /usr/share/sysbench/oltp_read_write.lua --mysql-host=172.16.113.134 --mysql-port=3306 --mysql-user=test  --mysql-password=123 --mysql-db=kobe --table-size=100000 --tables=3 --threads=24 --report-interval=3 --time=20  prepare
2.第一次备份增量(基于上次全备)
innobackupex --defaults-file=/data/mysql/conf/3306/my.cnf --user=xbk_backup  --password=123 --socket=/data/mysql/data/3306/mysqld.sock --no-timestamp  --incremental-basedir /data/backups/  --incremental /data/backups2/
3.造第二次增量数据
create database xbk;
sysbench /usr/share/sysbench/oltp_read_write.lua --mysql-host=172.16.113.134 --mysql-port=3306 --mysql-user=test  --mysql-password=123 --mysql-db=xbk --table-size=100000 --tables=3 --threads=24 --report-interval=3 --time=20  prepare
4.第二次增备(基于第一次增备)
innobackupex --defaults-file=/data/mysql/conf/3306/my.cnf --user=xbk_backup  --password=123 --socket=/data/mysql/data/3306/mysqld.sock --no-timestamp  --incremental-basedir /data/backups2/  --incremental /data/backups3/
1.查看三次备份目录
[root@node02 ~]# ls /data/ |grep backup 
backups
backups2
backups3
2.Prepare Base Full 处理基础全备
innobackupex --defaults-file=/data/mysql/conf/3306/my.cnf --user=xbk_backup  --password=123 --socket=/data/mysql/data/3306/mysqld.sock --apply-log --redo-only  /data/backups
3.merging inc1 to BASE FULL ,合并处理backups2增量到全备
innobackupex --defaults-file=/data/mysql/conf/3306/my.cnf --user=xbk_backup  --password=123 --socket=/data/mysql/data/3306/mysqld.sock --apply-log --redo-only  --incremental-dir=/data/backups2 /data/backups
4.merging inc2 to BASE FULL,合并处理backup3增量到全备
innobackupex --defaults-file=/data/mysql/conf/3306/my.cnf --user=xbk_backup  --password=123 --socket=/data/mysql/data/3306/mysqld.sock --apply-log  --incremental-dir=/data/backups3 /data/backups
5.最后一次全备整理
 innobackupex --defaults-file=/data/mysql/conf/3306/my.cnf --user=xbk_backup  --password=123 --socket=/data/mysql/data/3306/mysqld.sock --apply-log   /data/backups
6.删除数据目录及redolog
rm /data/mysql/data/3306/* -rf
rm /data/mysql/log/redolog/3306/* -rf
7.恢复全备+增备
innobackupex --defaults-file=/data/mysql/conf/3306/my.cnf --user=xbk_backup  --password=123 --socket=/data/mysql/data/3306/mysqld.sock --copy-back  /data/backups
8.查看数据目录
[root@node02 3306]# ls
gengjin         ibdata1  mysql               sbtest  test   xbk                           xtrabackup_info
ib_buffer_pool  kobe     performance_schema  sys     world  xtrabackup_binlog_pos_innodb
9.授权数据目录及redo目录
chown -R mysql.mysql /data/mysql/data/3306/*
chown -R mysql.mysql /data/mysql/log/redolog/3306/*
10.启动mysql
systemctl restart mysqld_3306
#自此数据库恢复完成

5.3 其他备份需求

5.3.1 备份单库

innobackupex --defaults-file=/data/mysql/conf/3306/my.cnf --databases=kobe --user=xbk_backup  --password=123 --socket=/data/mysql/data/3306/mysqld.sock --no-timestamp  /data/backups_danku

5.3.2 备份单表

#方法一:
innobackupex --defaults-file=/data/mysql/conf/3306/my.cnf --databases="kobe.sbtest1"  --user=xbk_backup  --password=123 --socket=/data/mysql/data/3306/mysqld.sock --no-timestamp  /data/backups_danbiao
#方法二:
innobackupex --defaults-file=/data/mysql/conf/3306/my.cnf --include='^kobe[.]sbtest1'  --user=xbk_backup  --password=123 --socket=/data/mysql/data/3306/mysqld.sock --no-timestamp  /data/backups_danbiao

5.3.3 备份多表

1.编辑文件
cat /tmp/table.txt
kobe.sbtest1
kobe.sbtest2
xbk.sbtest3
world.city
world.country
2.备份
innobackupex --defaults-file=/data/mysql/conf/3306/my.cnf --tables-file=/tmp/table.txt  --user=xbk_backup  --password=123 --socket=/data/mysql/data/3306/mysqld.sock --no-timestamp  /data/backups_duobiao

5.4 恢复单库、单表或者多表

5.4.1 恢复单表/多表

1.拿到表结构,创建表
mysql> CREATE TABLE `sbtest1` (
    ->   `id` int(11) NOT NULL AUTO_INCREMENT,
    ->   `k` int(11) NOT NULL DEFAULT '0',
    ->   `c` char(120) NOT NULL DEFAULT '',
    ->   `pad` char(60) NOT NULL DEFAULT '',
    ->   PRIMARY KEY (`id`),
    ->   KEY `k_1` (`k`)
    -> ) ENGINE=InnoDB AUTO_INCREMENT=100001 DEFAULT CHARSET=utf8mb4;
Query OK, 0 rows affected (0.01 sec)

mysql> 
2.丢弃原来的ibd文件表空间
mysql> ALTER TABLE `sbtest1` DISCARD TABLESPACE;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> 
3.复制sbtest1表备份的ibd文件,到数据目录对应库下
cp /data/backups_danbiao/kobe/sbtest1.ibd /data/mysql/data/3306/kobe/
4.更改ibd文件的权限
chown -R mysql:mysql  sbtest1.ibd
5.导入表空间文件
mysql> ALTER TABLE `sbtest1` IMPORT TABLESPACE ;
Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> 
6.查看
mysql> select * from kobe.sbtest1 limit 2;
+----+-------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
| id | k     | c                                                                                                                       | pad                                                         |
+----+-------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
|  1 | 50095 | 33524783776-74656600149-90205850992-68486233199-38139582553-31032853662-46232099172-74461690624-87909115866-85457687836 | 61164888858-85154493460-35907316816-37705648466-22765373704 |
|  2 | 50157 | 91282821879-27789870274-87640051743-39804400153-74473090426-79246130794-92788146526-95290529525-17128128654-00698810889 | 39117864852-84907815709-14221566017-79416635061-15970385071 |
+----+-------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql> 

5.4.2 恢复单库

根据上面恢复单表的方式进行恢复,需先创建库,然后一个表一个表进行恢复。

 类似资料: