使用Percona xtrabackup对已在使用的MySQL做主从备份

主库配置

首先要配置主库服务器的相关主从备份的配置,比如配置启用binlog日志等,涉及到配置修改如下,修改my.conf文件

COPY
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[mysqld]
## 设置server_id,一般设置为IP,注意要唯一
server_id=100
## 复制过滤:也就是指定哪个数据库不用同步(mysql库一般不同步)
binlog-ignore-db=mysql
## 开启二进制日志功能,可以随便取,最好有含义(关键就是这里了)
log-bin=mysql-bin
## 为每个session 分配的内存,在事务过程中用来存储二进制日志的缓存
binlog_cache_size=1M
## 主从复制的格式(mixed,statement,row,默认格式是statement)
binlog_format=mixed
## 二进制日志自动删除/过期的天数。默认值为0,表示不自动删除。
expire_logs_days=7
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062

以上是主库做主从备份需要的一些配置,每个配置的已有详细说明,关于MySQL主从备份的一些基础概念和配置方法,详细可以参考**MySQL主从复制搭建,基于日志(binlog)**

初识Percona xtrabackup

Xtrabackup是由percona开源的免费数据库热备份软件,它能对InnoDB数据库和XtraDB存储引擎的数据库非阻塞地备份(对于MyISAM的备份同样需要加表锁)。

为什么要用Xtrabackup?因为传统的mysqldump备份方式是采用的逻辑备份,其最大的缺陷是备份和恢复速度较慢,如果数据库很大,mysqldump备份就不太适合,并且mysqldump备份时会对数据库运行造成一定的影响,并且xtrabackup还可以进行增量备份,可以降低备份数据大小和每日备份时间。

(就算做了增量备份,也一定要定时全量备份)

安装Percona xtrabackup

进入官网下载页面,选择Percona XtraBackup,根据自己的os选择对应的版本下载,如我是centos7

COPY
1
wget https://downloads.percona.com/downloads/Percona-XtraBackup-2.4/Percona-XtraBackup-2.4.22/binary/redhat/7/x86_64/percona-xtrabackup-24-2.4.22-1.el7.x86_64.rpm

下载完成后使用rpm命令安装,可能会出现缺少依赖无法安装的情况,需要安装相关依赖,如我安装时提示缺少依赖

COPY
1
2
3
4
libev.so.4
perl(DBD::mysql)
perl(Digest::MD5)
rsync

于是首先安装Libev.so依赖,去http://rpm.pbone.net/index.php3/stat/3/srodzaj/1/search/libev.so.4 下载对应系统的安装包,并安装

COPY
1
wget ftp://ftp.pbone.net/mirror/ftp5.gwdg.de/pub/opensuse/repositories/home:/rudi_m/CentOS_7/x86_64/libev4-4.24-8.1.x86_64.rpm

然后安装,perl相关依赖,以下命令是从网上找的,我也不清楚是不是要安装这么多

COPY
1
yum -y install perl perl-devel libaio libaio-devel perl-Time-HiRes perl-DBD-MySQL rsync perl l perl-Digest-MD5

安装完成之后运行安装Percona xtrabackup命令,安装成功

COPY
1
rpm -ivh percona-xtrabackup-24-2.4.22-1.el7.x86_64.rpm

备份

执行命令

COPY
1
innobackupex --defaults-file=/etc/my.cnf --socket=/var/lib/mysql/mysql.sock --user=数据库用户名 --password=用户密码 --parallel=4 /usr/local/mysql_back

其中/etc/my.cnf为当前数据库配置文件地址,/var/lib/mysql/mysql.sock  为当前数据库sock文件地址,需要根据其实情况配置,/usr/local/mysql_back为备份文件存放目录,–parallel=4为开启4个子进程并发备份多个数据文件(一个数据文件只有一个进程进行备份)

通过innobackupex备份MySQL,本质是通过文件复制实现的,但是复制过程中,可能会有事物未提交,所以备份完成之后需要再次将尚未提交的事务或已经提交但尚未同步至数据文件中的事务进行相关处理,执行命令

COPY
1
innobackupex --defaults-file=/etc/my.cnf --socket=/var/lib/mysql/mysql.sock --user=数据库用户名 --password=用户密码 --apply-log /usr/local/mysql_back/2021-06-24_13-59-56

其中后面的2021-06-24_13-59-56是指上个命名备份出来的目录,要根据实际备份出来的文件夹名称修改

复制备份文件夹

备份完成之后,需要将备份文件夹复制到从库服务器,使用scp命令可以直接传到从库服务器

COPY
1
scp -r /usr/local/mysql_back/2021-06-24_13-59-56 ip:目录

其中/usr/local/mysql_back/2021-06-24_13-59-56是本地目录地址,需要根据实际情况配置,ip是指从库的IP地址,这里用内网和外网IP都可以,目录为从库服务的目录,根据实际情况选择即可

如果从库没有固定IP或者觉得这一步比较麻烦,可以采用远程备份的方式,直接再从库服务器上面使用innobackupex备份,但是innobackupex不能直接采用异地备份,只能采取ssh密匙认证传输,因为有点麻烦,所以我就直接在主库备份然后传到从库了,有兴趣的同学可以自己研究一下

恢复备份到从库

备份文件夹复制完成之后,需要先恢复到从库,首先再从库服务器上面安装好跟主库同版本的MySQL(最好版本一致,防止出现问题),安装完成之后再安装Percona xtrabackup,步骤跟主库上面的步骤一致,从库的MySQL先不启动,直接执行恢复命令

COPY
1
innobackupex --defaults-file=/etc/my.cnf --copy-back /备份文件夹目录

恢复的同时可以去修改从库MySQL的配置文件,尤其是当数据量比较大的时候,恢复也是需要一定时间的,首先在从库my.conf配置以下内容

COPY
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[mysqld]
## 设置server_id,一般设置为IP,注意要唯一
server_id=101
## 复制过滤:也就是指定哪个数据库不用同步(mysql库一般不同步)
binlog-ignore-db=mysql
## 开启二进制日志功能,以备Slave作为其它Slave的Master时使用
log-bin=edu-mysql-slave1-bin
## 为每个session 分配的内存,在事务过程中用来存储二进制日志的缓存
binlog_cache_size=1M
## 主从复制的格式(mixed,statement,row,默认格式是statement)
binlog_format=mixed
## 二进制日志自动删除/过期的天数。默认值为0,表示不自动删除。
expire_logs_days=7
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062
## relay_log配置中继日志
relay_log=edu-mysql-relay-bin
## log_slave_updates表示slave将复制事件写进自己的二进制日志
log_slave_updates=1
## 防止改变数据(除了特殊的线程)
read_only=1

恢复后重启MySQL,注意先检查MySQL的文件目录权限问题,因为我是用的root用户恢复,所以文件夹里面的文件都归属root,导致MySQL启动失败失败,需要先把MySQL的数据目录所属分组分配给MySQL用户,执行命令

COPY
1
chown -R mysql:mysql MySQL数据目录

创建主库复制账号

需要先再主库上面创建一个从库用来复制数据的账号

COPY
1
2
grant replication slave,replication client on *.* to slaveuser@'从库IP' identified by '密码';
flush privileges;

这里我们创建的用户名是slaveuser,指定了只有从库能链接,如果多个从库,并且从库在同一个网段,可以IP最后一个.后面跟%分号,如果不是同一网段,可以针对每个从库创建一个同用户名但是不用Host的用户,建议密码都一直方便维护,不建议用%,测试环境和自己做测试用%没有关系,但是生产环境最好别用%来授权,防止数据泄露

开启主从复制

首先去备份文件去看当前的备份的日志偏移量,复制需要根据偏移量来复制,常规情况下(从数据库还未正式使用的情况下),我们会从主库去获取这个偏移量,但是由于我们现在是主库还是一直在运行这,业务也一直在正常的写入和更新,所以主库的偏移量已经不适用我们的从库,所以要从备份文件里面去看,进入到备份文件夹目录(有年月日那个),执行命令

COPY
1
more xtrabackup_binlog_info

会返回日志名字和偏移量类似于下面这种

COPY
1
mysql-bin.xxxx        411xxxx

其中mysql-bin.xxxx是日志文件的名字,411xxxx是我们偏移量

有了日志文件名字和偏移量之后,再从库MySQL里面执行

COPY
1
change master to master_host='主库ip', master_user='复制用户', master_password='复制密码', master_port=3306, master_log_file='mysql-bin.xxxx', master_log_pos=411xxxx, master_connect_retry=30;

上面执行的命令的解释:

master_host=’主库ip’                  ## Master的IP地址

master_user=’复制用户’                             ## 用于同步数据的用户(在Master中授权的用户)

master_password=’复制密码’     ## 同步数据用户的密码

master_port=3306                              ## Master数据库服务的端口

master_log_file=’mysql-bin.xxxx’        ##指定Slave从哪个日志文件开始读复制数据(Master上执行命令的结果的File字段)

master_log_pos=411xxxx                         ## 从哪个POSITION号开始读(Master上执行命令的结果的Position字段)

master_connect_retry=30  ##当重新建立主从连接时,如果连接建立失败,间隔多久后重试。单位为秒,默认设置为60秒,同步延迟调优参数。

成功之后继续执行

COPY
1
start slave;

成功之后可以执行

COPY
1
show slave status;

查看当前复制状态,也可以查询不同表的数据对比复制是否正常,如果数据库较大,做从库时间过长,那么需要等一段时间才能做对比,因为一般数据库很大的情况下,数据写入也非常大,从库要同步过来本来也就需要不少时间,尤其是一般从库性能跟主库还差了几个量级的情况下,会造成一定的延迟,可以通过查看复制状态返回的Relay_Master_Log_File和Exec_Master_Log_Pos来判断当前复制到了那里,以及估算复制速度

Authorship: 作者
Article Link: https://raye.wang/2021/06/24/%E4%BD%BF%E7%94%A8Percona-xtrabackup%E5%AF%B9%E5%B7%B2%E5%9C%A8%E4%BD%BF%E7%94%A8%E7%9A%84MySQL%E5%81%9A%E4%B8%BB%E4%BB%8E%E5%A4%87%E4%BB%BD/
Copyright: All posts on this blog are licensed under the CC BY-NC-SA 4.0 license unless otherwise stated. Please cite Raye Blog !