目录
一:MySQL数据库备份概述
1:数据备份的重要性
2:数据库备份类型
2.1:从物理与逻辑的角度分类
(1)物理备份
(2)逻辑备份
2.2:从数据库的备份策略角度分类
3:常见的备份方法
3.1:物理冷备份
3.2:专用备份工具mysqldump和mysqlhotcopy
3.3:通过启用二进制日志进行增量备份
3.4:通过第三方工具备份
二:数据库完全备份操作
1:物理冷备份与恢复
1.1:备份数据库
1.2:恢复数据库
2:mysqldump备份与恢复
2.1:备份数据库
2.2:查看备份文件
2.3:恢复数据库
3:MySQL增量备份与恢复
3.1:MySQL增量备份概述
(1)增量备份的特点
(2)MySQL二进制日志对备份的意义
3.2:MySQL增量恢复
3.3:MySQL企业备份案例
(1)一般恢复
(2)基于位置恢复
(3)基于时间点恢复
三:制定企业备份策略的思路
四:扩展:MySQL的GTID和XtraBackup
1:MySQL的GTID
(1)配置my.cnf开启gtid
(2)创建基本测试库,表,数据
(3)全局备份
(4)插入新数据
(5)模拟数据误删除
(6)导出增量数据
(7)恢复全量
(8)恢复增量
2:XtraBackup
(1)安装XtraBackup
(2)安装qpress
(3)完整备份与恢复
(4)增量备份与恢复
保障数据安全,防止因硬件故障、人为误操作、恶意攻击或自然灾害导致数据丢失。
满足业务连续性需求,确保故障后能快速恢复服务。
合规性要求,部分行业法规强制要求数据备份。
造成数据丢失的原因:
- 程序错误
- 人为操作错误
- 运算错误
- 磁盘故障
- 灾难和盗窃
直接复制数据库的物理文件(如数据文件、日志文件),速度快,恢复简单,但可能依赖存储引擎和版本。物理备份又可以分为冷备份(脱机备份),热备份(联机备份)和温备份。
定义:
冷备份:在数据库完全关闭的状态下进行的备份。
热备份:在数据库正常运行(联机状态)时进行的备份,用户可正常访问数据库。
温备份:介于冷备份和热备份之间,数据库部分可用(如只读模式)或短暂锁定状态下的备份。
通过导出数据库逻辑结构(SQL语句),如mysqldump
生成的文本文件,兼容性好,但备份和恢复较慢。
从数据库的备份策略角度,数据库的备份可分为完全备份,增量备份和差异备份。
定义:
完全备份:备份整个数据库,占用空间大,恢复简单。
增量备份:仅备份自上次备份后的变化部分(依赖二进制日志或时间点),节省空间,但恢复需逐级合并。
差异备份:备份自上次完全备份后的所有变化,平衡存储和恢复复杂度。
操作:关闭MySQL服务后直接复制数据目录文件(如/var/lib/mysql
)。
特点:简单粗暴,适合停机维护场景,但需停服务。
mysqldump:逻辑备份工具,生成SQL脚本,支持单表、多库或全库备份,兼容性强。
mysqlhotcopy(仅限MyISAM):物理热备份工具,快速但限制较多,已逐渐被淘汰。
操作:开启
binlog
后,定期备份日志文件,通过mysqlbinlog
工具恢复至特定时间点。特点:支持时间点恢复(PITR),需结合完全备份使用。
工具举例:Percona XtraBackup(物理热备,支持InnoDB增量备份)、LVM快照、云数据库备份服务等。
优势:支持热备、高性能,适合大型生产环境。
#停止MySQL服务
systemctl stop mysqld
#创建备份文件
mkdir /backup
#打包数据库文件
tar -zcvf /backup/mysql_all-$(date +%F).tar.gz /usr/local/mysql/data/
将数据库文件/usr/local/mysql/data/转移至bak目录下,模拟故障。
mkdir bak
mv /usr/local/mysql/data/ /root/bak/
mkdir restore
tar zxf /backup/mysql_all-2025-03-22.tar.gz -C restore
mv restore/usr/local/mysql/data/ /usr/local/mysql/
systemctl start mysqld
格式一:备份指定库中的部分表
mysqldump [选项] 库名 [表名 1] [表名 2] ......> /备份路径/备份文件名
格式二:备份一个或多个完整的库(包括其中所有的表)。
mysqldump [选项] --datebases 库名1[库名 2]......>
格式三:备份MySQL服务器中的所有的库。
mysqldump [选项] --all-datebases > /备份路径/备份文件名
grep -v '^--' test.sql | grep -v '^/' | grep -v '^$'
导出sql备份脚本:
mysql [选项] [库名] [表名] < /备份路径/备份文件名
节省空间:仅备份自上次备份后发生变化的数据,减少存储占用。
时间效率高:备份速度快,适合频繁备份的场景。
依赖基础备份:需结合全量备份使用,恢复时需先还原全量备份再应用增量备份。
日志记录:通常通过二进制日志(Binary Log)实现增量备份。
记录所有数据变更:二进制日志(binlog)保存所有DML(如INSERT/UPDATE/DELETE)和DDL操作,是增量备份的核心。
支持时间点恢复:通过解析binlog可恢复到任意时间点,应对误删数据等场景。
主从复制基础:binlog是实现MySQL主从同步的关键组件。
核心步骤:
恢复最近的全量备份。
按顺序应用所有增量备份(binlog)。
工具:使用mysqlbinlog
工具解析并重放binlog文件。
场景:适用于数据误删、逻辑错误或需要回滚到特定时间点的场景。
添加数据库,表,录入信息
mysql> create database auth;
mysql> use auth;
mysql> create table user_info(user_name char(10),user_pass char(70));
mysql> insert into user_info values ('zhangsan','111');
mysql> select * from user_info ;
+-----------+-----------+
| user_name | user_pass |
+-----------+-----------+
| zhangsan | 111 |
+-----------+-----------+
1 row in set (0.00 sec)
mysql>insert into user_info values ('zhangsan',SHA2('pass',111));
mysql> select * from t1\G;
*************************** 1. row ***************************
user_name: zhangsan
user_pass: 111
*************************** 2. row ***************************
user_name: zhangsan
user_pass: NULL
2 rows in set (0.00 sec)
先进行一次完全备份
mkdir /mysql_bak
mysqldump -uroot -p auth > /mysql_bak/client_userinfo-$(date +%F).sql
ls /mysql_bak/
mysqladmin -uroot -p flush-logs
cd /usr/local/mysql/data/
ls -l binlog.*
-rw-r-----. 1 mysql mysql 1486 3月17日 15:36 binlog.000001
-rw-r-----. 1 mysql mysql 157 3月17日 15:36 binlog.000002
-rw-r-----. 1 mysql mysql 32 3月17日 15:36 binlog.index
继续录入新的数据并进行增量备份
mysql> insert into user_info values ('lisi','222');
mysql> insert into user_info values ('wangwu','222');
mysql> select * from user_info ;
+-----------+-----------+
| user_name | user_pass |
+-----------+-----------+
| zhangsan | 111 |
| zhangsan | NULL |
| lisi | 222 |
| wangswu | 222 |
+-----------+-----------+
5 rows in set (0.00 sec)
mysqladmin -uroot -p flush-logs
cd /usr/local/mysql/data/
ls -l binlog.*
/bin/cp /usr/local/mysql/data/binlog.000002 /mysql_bak/
模拟误操作删除表
mysql -uroot -p -e 'drop table auth.user_info;'
mysql -uroot -p -e 'select * from auth.user_info;'
恢复操作
mysql -uroot -p auth < /mysql_bak/client_userinfo-2025-03-17.sql
mysql -uroot -p -e 'select * from auth.user_info;'
mysqlbinlog --no-defaults /mysql_bak/binlog.000002 | mysql -uroot -p
mysql -uroot -p -e 'select * from auth.user_info;'
mysql -uroot -p -e 'drop table auth.user_info;'
mysql -uroot -p -e 'select * from auth.user_info;'
mysql -uroot -p auth < /mysql_bak/client_userinfo-2025-03-17.sql
mysqlbinlog --no-defaults /mysql_bak/binlog.000002
# 恢复从开始到最后一个事务结束(position 1003)
mysqlbinlog --no-defaults --stop-position=1003 /mysql_bak/binlog.000002 | mysql -uroot -p
或
(mysqlbinlog --no-defaults --start-position=1003 /mysql_bak/binlog.000002 | mysql -uroot -p)
mysql -uroot -p -e 'select * from auth.user_info;'
#--stop-position:恢复从 binlog 开始到位置 1003 之前的所有操作
#--start-position:恢复从位置 1003 开始到 binlog 结束的所有操作(跳过操作)
mysql -uroot -p -e 'drop table auth.user_info;'
mysql -uroot -p -e 'select * from auth.user_info;'
mysql -uroot -p auth < /mysql_bak/client_userinfo-2025-03-17.sql
mysqlbinlog --no-defaults /mysql_bak/binlog.000002
# 恢复从开始到最后一个事务结束(position 1003)
mysqlbinlog --no-defaults --stop-datatime='2025-03-17 15:48:58' /mysql_bak/binlog.000002 | mysql -uroot -p
或
(mysqlbinlog --no-defaults --start-datatime='2025-03-17 15:48:58' /mysql_bak/binlog.000002 | mysql -uroot -p)
mysql -uroot -p -e 'select * from auth.user_info;'
备份时间也要灵活调整。如:
- 数据更新频繁,则应该频繁地备份。
- 数据的重要性,在有适当更新时进行备份。
- 在数据库压力小的时间段进行备份,如一周一次完全备份,每天进行增量备份。
- 中小公司,完全备份一般一天一次即可。
- 大公司可每周进行一次完全备份,每天进行一次增量备份。
- 尽量为企业实现主从复制架构,以增加数据的可用性。
定义
GTID(全局事务标识符)是MySQL 5.6引入的特性,用于唯一标识事务。
核心特性
全局唯一性:每个事务的GTID在集群中唯一,避免主从复制中的冲突。
简化复制配置:无需依赖二进制日志文件名和位置(
binlog_file
和binlog_pos
),直接通过GTID定位同步点。一致性保障:GTID跟踪所有已执行事务,确保从库不会重复应用或遗漏事务。
vim /etc/my.cnf
[mysqld]
添加:gtid_mode=ON
enforce_gtid_consistency=ON
systemctl restart mysqld
#开启验证
mysql -uroot -ppwd123
mysql> show global variables like 'gtid_mode';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| gtid_mode | ON |
+---------------+-------+
1 row in set (0.01 sec)
mysql> reset master; #初始化master,会清除所有binlog和gtid信息
mysql> show master status;
+---------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000001 | 157 | | | |
+---------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
#创建测试库test,测试表user,并导入3条数据
mysql> create database test;
mysql> use test;
mysql> create table user(user_name char(10),user_pass char(70));
mysql> insert into user values ('zhangsan','111');
mysql> insert into user values ('lisi','222');
mysql> insert into user values ('wangwu','222');
mysql> select * from user;
+-----------+-----------+
| user_name | user_pass |
+-----------+-----------+
| zhangsan | 111 |
| lisi | 222 |
| wangwu | 222 |
+-----------+-----------+
3 rows in set (0.00 sec)
mysql> show master status;
+---------------+----------+--------------+------------------+------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+------------------------------------------+
| binlog.000001 | 1424 | | | 483ef70f-02fb-11f0-af66-000c29a96e86:1-5 |
+---------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)
mysqldump -u root -p --databases test > test.sql
grep -i gtid test.sql
mysql -uroot -p
mysql> use test;
mysql> insert into user values ('zhaoliu','3332');
mysql> insert into user values ('xiaoqi','333');
mysql> select * from test.user;
+-----------+-----------+
| user_name | user_pass |
+-----------+-----------+
| zhangsan | 111 |
| lisi | 222 |
| wangwu | 222 |
| zhaoliu | 3332 |
| xiaoqi | 333 |
+-----------+-----------+
5 rows in set (0.00 sec)
mysql> show master status;
+---------------+----------+--------------+------------------+------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+------------------------------------------+
| binlog.000001 | 2000 | | | 483ef70f-02fb-11f0-af66-000c29a96e86:1-7 |
+---------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)
mysql> drop database test;
mysql> show master status;
+---------------+----------+--------------+------------------+------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+------------------------------------------+
| binlog.000001 | 2181 | | | 483ef70f-02fb-11f0-af66-000c29a96e86:1-8 |
+---------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)
mysqlbinlog --include-gtids='483ef70f-02fb-11f0-af66-000c29a96e86:3-7' /usr/local/mysql/data/binlog.000001 > /mysqlbak.sql
mysql -u root -p -e "reset master;"
mysql -uroot -p < test.sql
mysql -uroot -p -e 'select * from test.user;'
mysql -uroot -p < mysqlbak.sql
mysql -uroot -p -e 'select * from test.user;'
定义
Percona XtraBackup是MySQL的开源热备份工具,支持InnoDB/XtraDB引擎的物理备份,备份期间不阻塞数据库读写。
核心功能
热备份:备份时允许数据库继续运行。
增量备份:仅备份自上次全量或增量备份后的变化数据。
压缩与加密:支持备份文件的压缩和加密。
流式备份:可直接备份到远程服务器或云存储。
#解压软件包
tar xzf percona-xtrabackup-8.0.35-30-Linux-x86_64.glibc2.17.tar.gz
mv percona-xtrabackup-8.0.35-30-Linux-x86_64.glibc2.17 /usr/local/xtrabackup
#修改配置文件
vim /etc/profile
export PATH=$PATH:/usr/local/xtrabackup/bin
source /etc/profile
tar xf qpress-11-linux-x64.tar
xtrabackup --defaults-file=/etc/my.cnf --user=root --password=pwd123 --backup --compress --target-dir=$bakdir
xtrabackup --defaults-file=/etc/my.cnf --user=root --password=pwd123 --decompress --target-dir=$bakdir
xtrabackup --prepare --target-dir=$bakdir
xtrabackup --defaults-file=/etc/my.cnf --user=root --password=pwd123 --copy-back --target-dir=$bakdir
chown -R mysql:mysql /usr/local/mysql/data/mysql
systemctl start mysqld
#备份
fulldir="/backup/fullbackups/$(date '+%F')"
incdir="/backup/incrementalbackups/$(date '+%F')"
mkdir -p $fulldir
mkdir -p $incdir
#准备基础数据后进行全量备份
xtrabackup --defaults-file=/etc/my.cnf --user=root --password=pwd123 --backup --compress --target-dir=$bakdir
#插入新数据后进行增量备份
xtrabackup --defaults-file=/etc/my.cnf --user=root --password=pwd123 --backup --compress --target-dir=$incdir --incremental-basedir=$fulldir
#增量恢复
#解压备份数据
xtrabackup --defaults-file=/etc/my.cnf --user=root --password= --decompress --target-dir=$fulldir
xtrabackup --defaults-file=/etc/my.cnf --user=root --password= --decompress --target-dir=$incdir
#准备数据
xtrabackup --prepare --apply-log-only --target-dir=$fulldir
#把增量备份的数据合并到完整备份里面
xtrabackup --prepare --apply-log-only --target-dir=$fulldir --incremental-dir=$incdir
#完整重放日志
xtrabackup --prepare --target-dir=$fulldir
#恢复数据
xtrabackup --defaults-file=/etc/my.cnf --user=root --password= --copy-back --target-dir=$fulldir
#修改权限,替换成自己的数据存储目录
chown -R mysql:mysql /usr/local/mysql/data
#然后启动MySQL即可
systemctl start mysqld