很多小公司的因为研发流程不规范,以至于数据库甚至没有任何容灾措施,数据库服务或服务器如果出现问题,对软件对企业都将是致命打击。接下来会编(chao)辑(xi)几篇文章,实操完成一个MySQL数据库容灾备份解决方案。
需要考虑的问题有:
- 数据库怎么进行完整库的备份
- 服务器存储有限,需要进行增量备份
- 全量、增量备份的时间策略是什么样的
- 本机挂了丢失备份怎么办
- 怎么和远程服务器备份的拷贝存储
- 不可能手动备份
- 全量、增量备份的恢复
因此大致的内容会是:
- 备份工具选择和环境搭建
- 全量、增量备份的命令实操
- 全量、增量备份的恢复命令实操
- 全量、增量备份脚本编写
- 全量、增量备份恢复脚本编写
- 定时全量、增量备份的实现
- 本地与远程容灾服务器的备份通信
这些问题我认为也是测试人员在测试过程中需要和研发团队确认的问题,从基本功能和安全测试角度,测试人员都有必要关注自己公司怎么保证数据库安全的,说不定可以给你们的开发运维找点事做。
技术选型
MySQL数据库有许多备份方式,如mysqldump、mysqlhotcopy、BACKUP TABLE 、SELECT INTO OUTFILE和备份二进制日志,或者直接拷贝数据文件和相关的配置文件,MyISAM数据表是直接保存成文件的形式,备份相对简单。对于Innodb,所有的数据文件都保存在同一个文件ibdata1中,则相对不好备份,免费的方案有直接拷贝文件,备份binlog(二进制文件),或者使用mysqldump等。
大数据的备份和还原,当数据量比较大时候,mysqldump来导出比较慢,这时候可以采用采用第三方备份工具,如商业备份工具InnoDB Hotbackup和免费的Xtrabackup。下面我们采用免费的Xtrabackup来进行MySQL数据库的备份和还原。
Xtrabackup简介
Xtrabackup是一个对InnoDB做数据备份的工具,支持热备份(在线备份时不影响数据读写),是商业备份工具InnoDB Hotbackup很好的替代品。
Xtrabackup包含两个主要的工具:xtrabackup和innobackupex
- xtrabackup只能备份InnoDB和XtraDB两种数据表,而不能备份MyISAM数据表
- innobackupex是参考了InnoDB Hotbackup的innoback脚本修改而来的,innobackupex是使用perl脚本封装了xtrabackup,主要是为了方便的同时备份InnoDB和MyISAM引擎的表。
使用Xtrabackup可以做如下事情:
- 在线(热)备份整个库的InnoDB、 XtraDB表
- 在xtrabackup的上一次整库备份基础上做增量备份(innodb only)
- 以流的形式产生备份,可以直接保存到远程机器上(这对于本机硬盘空间不足或异地灾备的情况很有用)
MySQL数据库本身提供的工具并不支持真正的增量备份,二进制日志恢复是point-in-time(时间点)的恢复而不是增量备份。
Xtrabackup工作原理
Xtrabackup工具支持对InnoDB存储引擎的增量备份,工作原理如下:
- 首先需要一个完全备份,并记录下此时检查点的LSN(Log Sequence Number)。
- 在进程增量备份时,比较表空间中每个页的LSN是否大于上次备份时的LSN,如果是,则备份该页,同时记录当前检查点的LSN。
首先,在logfile中找到并记录最后一个checkpoint(“last checkpoint LSN”),然后开始从LSN的位置开始拷贝InnoDB的logfile到xtrabackup_logfile;接着,开始拷贝全部的数据文件.ibd;在拷贝全部数据文件结束之后,才停止拷贝logfile。因为logfile里面记录全部的数据修改情况,所以,即时在备份过程中数据文件被修改过了,恢复时仍然能够通过解析xtrabackup_logfile保持数据的一致。
方案实现
系统环境
环境 | 版本 | 版本说明 |
---|---|---|
操作系统 | centos | Linux iZwz98um4r4f2es3d23uz4Z 3.10.0-693.2.2.el7.x86_64 #1 SMP Tue Sep 12 22:26:13 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux |
数据库 | MySQL | 5.7.31 MySQL Community Server (GPL) |
备份工具 | xtrabackup | percona-xtrabackup-2.4.4 |
工具安装
安装依赖包
yum install cmake gcc gcc-c++ libaio libaio-devel automake autoconf bzr bison libtool ncurses-devel zlib-devel libgcrypt libgcrypt-devel perl-Time-HiRes
下载 Percona-XtraBackup
安装包
wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.4/binary/redhat/7/x86_64/percona-xtrabackup-24-2.4.4-1.el7.x86_64.rpm
安装 Percona-XtraBackup
yum localinstall percona-xtrabackup-24-2.4.4-1.el7.x86_64.rpm
全量备份
所谓全量备份,简称全备,指的全量(数据库的全部数据)把数据从一个地方拷贝到另外一个地方做一个备份。
全备份命令
innobackupex --defaults-file=/etc/my.cnf --user=root --password=YOUR_PASSWORD /home/data/backup
指定数据库备份命令(只针对MyISAM表数据库)
innobackupex --defaults-file=/etc/my.cnf --user=root --password=YOUR_PASSWORD --database=dbbackup /home/data/backup
因此特别注意,对于命令:
innobackupex --defaults-file=/etc/my.cnf --user=root --password=YOUR_PASSWORD --database=test /mysqlbackup/
其中:
- --user指定连接数据库的用户名
- --password指定连接数据库的密码
- --defaults-file指定数据库的配置文件,innobackupex要从其中获取datadir等信息
- --database指定要备份的数据库,这里指定的数据库只对MyISAM表和InnoDB表的表结构有效,对于InnoDB 数据来说都是全备(所有数据库中的InnoDB数据都进行了备份,不是只备份指定的数据库,恢复时也一样)
- /mysqlbackup是备份文件的存放位置。
当前MySQL数据库存储引擎为InnoDB,用户名root,密码为123456,执行全备命令
innobackupex --defaults-file=/etc/my.cnf --user=root --password=123456 /home/data/backup
出现如下信息时,表示完成备份
200808 16:58:37 [01] Copying ./performance_schema/events_waits_summary_global_by_event_name.frm to /home/data/backup/2020-08-08_16-58-33/performance_schema/events_waits_summary_global_by_event_name.frm
200808 16:58:37 [01] ...done
200808 16:58:37 Finished backing up non-InnoDB tables and files
200808 16:58:37 Executing FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS...
xtrabackup: The latest check point (for incremental): '43574802'
xtrabackup: Stopping log copying thread.
.200808 16:58:37 >> log scanned up to (43574811)
200808 16:58:37 Executing UNLOCK TABLES
200808 16:58:37 All tables unlocked
200808 16:58:37 [00] Copying ib_buffer_pool to /home/data/backup/2020-08-08_16-58-33/ib_buffer_pool
200808 16:58:37 [00] ...done
200808 16:58:37 Backup created in directory '/home/data/backup/2020-08-08_16-58-33'
200808 16:58:37 [00] Writing backup-my.cnf
200808 16:58:37 [00] ...done
200808 16:58:37 [00] Writing xtrabackup_info
200808 16:58:37 [00] ...done
xtrabackup: Transaction log of lsn (43574802) to (43574811) was copied.
200808 16:58:37 completed OK!
查看 /home/data/backup,确定已经备份成功
[root@iZ2zefth8eteml1eyueu1sZ ~]# cd /home/data/backup
[root@iZ2zefth8eteml1eyueu1sZ backup]# ll
drwxr-x--- 7 root root 4096 Aug 8 16:58 2020-08-08_16-58-33
[root@iZ2zefth8eteml1eyueu1sZ backup]# cd 2020-08-08_16-58-33/
[root@iZ2zefth8eteml1eyueu1sZ 2020-08-08_16-58-33]# ll
total 77872
-rw-r----- 1 root root 425 Aug 8 16:58 backup-my.cnf
drwxr-x--- 2 root root 4096 Aug 8 16:58 future
-rw-r----- 1 root root 332 Aug 8 16:58 ib_buffer_pool
-rw-r----- 1 root root 79691776 Aug 8 16:58 ibdata1
drwxr-x--- 2 root root 4096 Aug 8 16:58 lemonban
drwxr-x--- 2 root root 4096 Aug 8 16:58 mysql
drwxr-x--- 2 root root 4096 Aug 8 16:58 performance_schema
drwxr-x--- 2 root root 12288 Aug 8 16:58 sys
-rw-r----- 1 root root 115 Aug 8 16:58 xtrabackup_checkpoints
-rw-r----- 1 root root 455 Aug 8 16:58 xtrabackup_info
-rw-r----- 1 root root 2560 Aug 8 16:58 xtrabackup_logfile
压缩备份
生产环境中的备份一般不会像上面一样直接备份成一个文件夹,为了方便存储和传输,比如不仅在本机需要有备份,还需要传输到容灾服务器,这时候我们直接备份成压缩包
innobackupex --defaults-file=/etc/my.cnf --user=root --password=123456 --stream=tar /home/data/backup/ | gzip > /home/data/backup/date +%F_%H-%M-%S .tar.gz
我们看到备份成功并压缩到了指定的文件夹
[root@iZ2zefth8eteml1eyueu1sZ backup]# cd /home/data/backup/
[root@iZ2zefth8eteml1eyueu1sZ backup]# ll
total 1164
drwxr-x--- 7 root root 4096 Aug 8 17:19 2020-08-08_17-19-38
-rw-r--r-- 1 root root 1184855 Aug 8 17:19 2020-08-08_17-19-48.tar.gz
[root@iZ2zefth8eteml1eyueu1sZ backup]#
备份还原
下面是全部数据恢复的步骤:
#首先停止mysql
[root@iZ2zefth8eteml1eyueu1sZ ~]# systemctl stop mysqld
#将MySQL数据目录备份
[root@iZ2zefth8eteml1eyueu1sZ ~]# mv /var/lib/mysql /var/lib/mysql_bak
#重建数据目录
[root@iZ2zefth8eteml1eyueu1sZ ~]# mkdir -p /var/lib/mysql
#--apply-log选项的命令是准备在一个备份上启动mysql服务
[root@iZ2zefth8eteml1eyueu1sZ ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --apply-log /home/data/backup/2020-08-08_17-19-38/
#--copy-back 选项的命令从备份目录拷贝数据,索引,日志到my.cnf文件里规定的初始位置,当前数据库的数据目录为/var/lib/mysql
[root@iZ2zefth8eteml1eyueu1sZ ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --copy-back /home/data/backup/2020-08-08_17-19-38/
#改变文件所属
[root@iZ2zefth8eteml1eyueu1sZ ~]# chown -R mysql.mysql /var/lib/mysql
#启动mysql
[root@iZ2zefth8eteml1eyueu1sZ ~]# systemctl start mysqld
查看数据库状态,已经启动成功
下一篇我们讲数据库的增量备份。
欢迎来到testingpai.com!
注册 关于