目录
一、前言
二、数据备份策略
2.1 全备
2.2 增量备份
2.3 差异备份
三、mysql 增量备份概述
3.1 增量备份实现原理
3.1.1 基于日志的增量备份
3.1.2 基于时间戳的增量备份
3.2 增量备份常用实现方式
3.2.1 基于mysqldump增量备份
3.2.2 基于第三方备份工具进行增量备份
四、前置准备
4.1 搭建mysql环境
4.1.1 创建映射目录
4.1.2 启动mysql
4.1.3 开启binlog
4.1.4 重启mysql实例
4.1.5 验证binlog是否开启
4.2 数据准备
4.2.1 创建数据库和表
五、mysqldump实现数据增量备份与还原
5.1 全库备份
5.2 数据库正常执行增删改查操作
5.3 模拟数据库发生故障
5.4 备份最新的二进制日志文件
5.5 全库恢复
5.6 通过binlog日志文件恢复剩下的数据
六、xtrabackup实现备份与恢复
6.1 xtrabackup简介
6.1.1 xtrabackup优缺点
6.2 xtrabackup 备份过程
6.3 xtrabackup备份与数据恢复原理
6.4 xtrabackup 安装流程
6.4.1 上传安装包
6.4.2 使用rpm安装
七、xtrabackup 模拟全库备份与恢复
7.1 实现思路
7.2 数据准备
7.3 准备一个特殊账号
7.4 全库备份操作过程
7.4.1 执行备份命令
7.4.2 预备阶段,整合日志
7.4.3 模拟数据库故障
7.4.4 执行数据库恢复
八、xtrabackup 模拟增量备份与恢复
8.1 增量备份概述
8.2 操作步骤
8.2.1 准备数据
8.2.2 执行全库备份
8.2.3 整合中间日志
8.2.4 做增量备份
8.2.5 数据文件整合
8.2.6 模拟数据库故障
8.2.7 恢复数据
8.2.8 测试数据
九、写在文末
对线上运行的mysql数据库来说,周期性做数据库备份具有重要的意义,一方面可以防止数据丢失,另一方面,备份的数据可以快速在不同的环境中使用、迁移。
结合实践经验,数据库备份通常有如下几种策略。
即备份完整的数据库,全量数据就是数据库中所有的数据(或某一个库的全部数据);
全量备份就是把数据库中所有的数据进行备份,使用mysqldump会取得一个时刻的一致性数据。
增量数据就是指上一次全量备份数据之后到下一次全备之前数据库所更新的数据,对于mysqldump、binlog就是增量数据;
备份自上一次完全备份后的全部改动和新文件,其特点有:
增量备份是指在全量备份基础上,仅备份数据发生变化的部分。相比全量备份,增量备份时间和备份文件大小都会大大减少,同时也能够更加快速地恢复数据。
增量备份的核心思想是记录每个数据块的修改情况,只备份修改过的数据块,从而实现备份效率的提升。
增量备份的实现原理主要有两种:
二进制日志(bin log)、错误日志(error log)等。其中,二进制日志记录了所有对数据库的修改操作,包括插入、更新、删除等。通过解析二进制日志,可以得到所有的修改操作,并将其应用到备份中,从而实现增量备份。
基于时间戳的增量备份是指记录每个数据块最后一次修改的时间戳,只备份时间戳发生变化的数据块。这种备份方式相对于基于日志的增量备份,实现难度较低,但在应对大量数据变化时效率较低。
实际应用中,增量备份可选择多种方案,下面介绍两种常用的方式
mysqldump是MySQL自带的备份工具,可以备份数据库的结构和数据。在备份时,可以使用--where选项指定备份数据的条件,从而实现增量备份。
比如像 XtraBackup、Mariabackup等,这些工具都支持增量备份。使用这些工具进行备份,可以更加高效地备份数据,同时也能够提高数据恢复的速度。
接下来分别利用mysqldump与XtraBackup完成mysql的增量备份的操作。
为演示方便,接下来使用docker快速搭建一个mysql,搭建方式有很多,可以结合自己的情况选择。
mkdir /usr/docker/mysql/log
mkdir /usr/docker/mysql/data
使用下面的docker命令启动mysql
docker run -p 3306:3306 --name mysql57 \
-v /usr/docker/mysql/log:/var/log/ \
-v /usr/docker/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
-d hub.c.163.com/library/mysql:5.7
使用下面的命令动态的开启上述mysql实例的binlog
docker exec mysql57 bash -c "echo 'log-bin=/var/lib/mysql/mysql-bin' >> /etc/mysql/mysql.conf.d/mysqld.cnf"
docker exec mysql57 bash -c "echo 'server-id=123454' >> /etc/mysql/mysql.conf.d/mysqld.cnf"
执行下面命令重启mysql
docker restart mysql57
通过下面的命令检查binlog是否开启
show variables like '%log_bin%';
创建数据库
create database test default charset=utf8;
创建一张表
CREATE TABLE `tb_user` (
`id` int(12) NOT NULL,
`name` varchar(32) DEFAULT NULL,
`age` int(12) DEFAULT NULL,
`subject` varchar(32) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
插入一些初始数据
insert into tb_user values (1,'liubei',33,'java');
insert into tb_user values (2,'guanyu',32,'spark');
insert into tb_user values (3,'zhangfei',30,'python');
insert into tb_user values (4,'diaochan',18,'js');
insert into tb_user values (5,'daqiao',18,'js');
执行完成后,检查一下插入的数据
mysqldump命令的介绍和使用就不再赘述了,网上资料非常多,接下来通过实际操作完整演示一下使用mysqldump完成表的增量备份与恢复的过程,整个操作流程如下:
备份二进制日志,根据其信息(导入剩余的10%的数据);
在正式使用mysqldump进行备份与还原操作之前,要确保你的mysql服务一定是开启了mysql的二进制日志,比如在上面操作完成之后,在数据目录下能看到下面的文件
使用mysqldump命令执行全库备份
#全库备份命令
mysqldump --single-transaction --flush-logs --source-data=2 --all-databases > /var/lib/mysql/sql-bk/all.sql -p
执行完成后,可以看到如下的备份sql以及产生的日志数据
假如紧接着又做了下面两步操作,新增了一条数据,删除了一条数据;
insert into tb_user values (6,'lvbu',28,'flink');
delete from tb_user where id = 3;
删除数据库
mysql -e "drop database test;" -p
找到最新的二进制日志文件,进行备份
cp /var/lib/mysql/binlog.000002 /var/lib/mysql/sql-bk
使用上面的全库sql进行数据恢复,执行下面的命令
mysql < /var/lib/mysql/sql-bk/all.sql -p
执行完成后,可以看到第一次的全量数据恢复了
使用下面的binlog命令对当前备份的binlog进行查看
#查看最后备份的那个binlog日志文件
mysqlbinlog /var/lib/mysql/sql-bk/binlog.000002#如果不方便查看,也可以输出到文件中
mysqlbinlog /var/lib/mysql/sql-bk/binlog.000002 > log.txt
但是当我们检查binlog.000002文件内容时,起始位置是4
实际会发现,这个日志文件的内容可能很多,里面有很多内容也是不需要关注的,需要重点关注的点有两个:
事实上,做增量恢复也是结合上面几个位置点为恢复依据的,然后就可以做基本的定位与恢复,所以恢复的思路就是,如果能够精确定位到增删改的位置点,从这里恢复,如果不确定,就使用最开始的位置,使用下面的命令进行恢复;
mysqlbinlog --start-position=4 --stop-position=844 /var/lib/mysql/log-bk/binlog.000002 |mysql -p
执行成功后,再次查询数据表,可以看到数据已经恢复;
xtrabackup工具是percona公司用perl语言开发的在线物理热备份工具,由于是采取物理拷贝的方式来做的备份,所以速度非常快,几十G数据也才几分钟就搞定了,而它巧妙的利用了mysql特性做到了在线热备份,不用像以前做物理备份那样关闭数据库才行,直接在线就能完成整库或者是部分库的全量备份和增量备份。
在安装Xtrabackup之前,需要先下载满足自己系统平台的安装包,下载链接:Software Downloads - Percona
优点:
备份过程快、可靠(因为是物理备份);
支持增量备份,更为灵活
备份过程不会打断正在执行的事务;
能够基于压缩等功能节约磁盘空间和流量;
自动实现备份检验;
还原速度快;
缺点:
只能对innodb表增量备份,myisam表增量备份时是全备;
innobackupex备份MyISAM表之前要对全库进行加READ LOCK,阻塞写操作,若备份是在从库上进行的话会影响主从同步,造成延迟。对InnoDB表备份不会阻塞读写。
根据上面的执行原理,其完整的流程如下图所示
在mysql中,事务日志也叫redo日志,在mysql中默认以ib_logfile0,ib_logfile1名称存在。InnoDB内部会维护一个redo日志文件,我们也可以叫做事务日志文件。事务日志会存储每一个InnoDB表数据的记录修改。当InnoDB启动时,InnoDB会检查数据文件和事务日志,并执行两个步骤:它应用(前滚)已经提交的事务日志到数据文件,并将修改过但没有提交的数据进行回滚操作。
xtrabackup内部就是利用了该日志可以完成数据的备份与恢复,具体流程如下:
结合上面的流程图,给出如下详细的说明:
Mysql5.7.3以后开启二进制日志需要加上server-id选项,不然报错
上传安装包到服务器(可在官网下载),主要包括下面两个安装包
依次执行下面的命令进行安装
yum -y install libev-4.15-3.el7.x86_64.rpm
yum -y install percona-xtrabackup-24-2.4.7-2.el7.x86_64.rpm
rpm -ql percona-xtrabackup-24
安装过程
看到上面的显示说明安装成功
以上面的图示业务场景为例,使用xtrabackup模拟全库备份与恢复过程,完整实现思路如下:
创建一个新库,创建两张表,一张引擎为innodb,另一张为myisam
mysql> create database db01 default charset=utf8;
mysql> use db01;
mysql> create table t1(id int,name varchar(10)) engine=myisam;
mysql> insert into t1 values (1,'jerry');
mysql> create table t2(id int,name varchar(10)) engine=innodb;
mysql> insert into t2 values (1,'mike');
准备一个数据库备份用的账号,开通与备份相关的权限;
mysql> grant reload,process,lock tables,replication client on *.* to 'admin'@'localhost' identified by '123';
mysql> flush privileges;
说明:
innobackupex --user=admin --password=123 /sql-backup
说明: 备份目录默认会自动创建,也可以手动创建;
第一次运行可能会报下面的错:
出现以上问题的=主要原因在于我们的mysql.sock并不在/var/lib/mysql目录下,为什么其会自动连接/var/lib/mysql目录下的mysql.sock呢?
提供两种解决方案:
方案1:把你的套接字文件创建一个软链接,放置于/var/lib/mysql/mysql.sock文件中
mkdir /var/lib/mysql
ln -s /tmp/mysql.sock /var/lib/mysql/mysql.sock
方案2:在innobackupex中添加一个-S选项,执行套接字
innobackupex -S /tmp/mysql.sock --user=admin --password=123 /sql-backup
我们使用方案2对全库进行备份命令,执行上述的命令之后,可以看到详细的备份过程
看到下面的执行结果时,说明备份完成
进入到数据备份目录下,可看到它根据时间戳生成了一个完整的备份目录
把备份这段时间内产生的日志整合到全量备份中 ,简单来说就是,在执行备份这段时间中,可能产生了其他的操作,因此需要把这部分的日志数据整合到上述备份文件中。
innobackupex --user=admin --password=123 --apply-log /sql-backup/2023-09-06_07-35-18
删除数据库 db01 或删除data数据目录
执行下面的命令进行数据恢复
innobackupex --copy-back /sql-backup/2023-09-06_07-35-18
第一次恢复报错:
出现以上问题的主要原因在于,innobackupex工具无法找到MySQL中的数据目录
解决方案:把my.cnf配置文件传递给innobackupex,让其自动识别这个文件中的datadir
innobackupex --defaults-file=/etc/my.cnf --copy-back /sql-backup/2023-09-06_07-35-18
有了全量备份的操作经验,增量备份也就是按部就班操作即可。
create database xtra_test default charset utf8;
use xtra_test;
create table M(id int,name varchar(10))engine=myisam;
create table I(id int,name varchar(10))engine=innodb;
insert into M values(1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e');
insert into I values(11,'A'),(22,'B'),(33,'C'),(44,'D'),(55,'E');
innobackupex --user=admin --password=123 /sql-back
整合全备过程中产生的日志到全备文件
innobackupex --user=admin --password=123 --apply-log --redo-only /sql-back/2023-09-07_20-09-33/
选项说明:
注意:如果已经回滚了未提交事务,那么就无法再应用增量备份。
假如全量备份之后,发生了一些增删改操作,这部分新产生的数据还需要进行备份,使用下面的命令进行增量备份
innobackupex --user=admin --password=123 --incremental /incre_backup --incremental-basedir=/sql-back/2023-09-07_20-09-33/
选项说明:
把增量备份产生的数据以及日志文件整合到全量备份中
innobackupex --user=admin --password=123 --apply-log /sql-back/2023-09-07_20-09-33 --incremental-dir=/incre_backup/2023-09-07_20-11-26
说明:
到此,增量备份就全部结束了!
删除data数据目录
关闭mysql服务
innobackupex --defaults-file=/etc/my.cnf --user=admin --password=123 --copy-back /sql-back/2023-09-07_20-09-33
恢复完成后,使用上面创建的mysq账户访问,如果无法访问,授权该账户对目录操作权限
本文通过两种方式详细总结了mysql增量备份的过程,篇幅较长,希望对你在日常的工作中有所帮助,本文到此结束,感谢观看。