背景:centos7.9,mysql8.0,mysqldump
1.mysqldump优势
- mysql自带,不需额外安装
- 自动记录日志position位置:
备份文件会记录当前的binlog日志点,之后恢复 备份文件配合标志点之后的binlog日志,可以恢复备份文件的数据以及灾难数据。(灾难数据是指数据备份的时间点,到故障发生的时间点,之间的不在备份里的数据变更) - 可用性,一致性
以表为单位备份数据,备份这张表时会加写锁,这张表不可写,只可读,其他表依旧可读可写,等备份完这张表后,解锁。
2. 备份数据
# 创建备份文件存放目录
mkdir -p /backup
mysqldump -uroot -p \
--all-databases \
--single-transaction \
--source-data=2 \
--flush-logs \
--column-statistics=0 > /backup/`date +%F-%H`-mysql-all.sql
--all-databases
备份所有数据库
--single-transaction
备份前创建一个数据快照,记录当前时间点每个数据库数据的版本号,备份过程中只备份这个版本号的数据,不影响用户读写
只有innodb等支持事务的引擎起作用,其他引擎的表备份时依旧会锁表
--source-data=2
将当前的二进制日志文件名和位置信息以注释形式写入备份文件,方便恢复灾难数据
备份文件里的约20-30行会有注释标记位置。方便恢复灾难数据。如果--source-data=1则不注释,直接生成change master to 语句,一般用于主从复制
旧版是--master-data,新版本后改用source-data作用不变
--flush-logs
完成备份后执行flush logs,关闭当前binlog,生成新binlog,方便管理
--column-statistics=0
mysql8.0后默认会开启column-statistics,所以要加上column-statistics=0
> /backup/
date +%F-%H-mysql-all.sql 备份文件存放位置
3. 恢复前准备
3.1 先复制备份所有的binlog日志,防止恢复出错时往binlog日志写入脏数据
mkdir -p /backup/binlogs
cp /var/lib/mysql/binlog.0* /backup/binlogs
3.2 如果是导入全量备份,建议先清空数据库,防止出现冗余数据,脏数据
方法一:库少时使用
# 找出所有非系统库
SELECT CONCAT('DROP DATABASE IF EXISTS `', SCHEMA_NAME, '`;')
FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME NOT IN ('mysql','sys','performance_schema','information_schema');
# 根据查到的非系统库一一删除,如:
DROP DATABASE IF EXISTS `shop`;
DROP DATABASE IF EXISTS `order`;
方法二:库多时,写成脚本
# 导出drop语句到sql文件
mysql -uroot -p -N -e "SELECT CONCAT('DROP DATABASE IF EXISTS \`', SCHEMA_NAME, '\`;') FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mysql','sys','performance_schema','information_schema');" > drop_all_db.sql
# 查看drop文件,核对,防止意外
cat drop_all_db.sql
# 执行删除
mysql -uroot -p < drop_all_db.sql
注:
- -N:去掉查询结构的表头
4. 恢复数据
假设数据文件意外丢失,导致数据库数据缺失时,可以恢复
4.1 查看备份文件里的binlog日志标记点
head -n 30 /backup/2026-10-31-10-mysql-all.sql
注:
- 查到标记点是binlog.000002 MASTER_LOG_POS=156,记住这个000002以及156

4.2 将标志点之后的多个binlog合并成一个文件
mysqlbinlog --start-position=156 /backup/binlog.000002 > /backup/increment.sql
mysqlbinlog /backup/binlog.000003 >> /backup/increment.sql
mysqlbinlog /backup/binlog.000004 >> /backup/increment.sql
注:
- 因为下一步使用mysqldump备份文件恢复数据时,会往binlog日志写入数据,如果直接使用/var/log/mysql下的binlog日志恢复数据时,会造成数据冗余,脏数据,所以要先存入到另外的文件不仅可以完美避免,还能方便后续审核查看sql。
- 备份文件的标记点之后有多少个binlog日志就复制多少个,如:我有1~4个,标记点是2,所以我需要用到2,3,4
- 如果是drop/delete误删数据的场景,可以配合使用--stop-position,在误操作之前停止回放binlog,如mysqlbinlog /backup/binlog.000004 --stop-position=380 >> /backup/increment.sql
4.3 恢复备份数据
# 恢复
mysql -uroot -p </backup/2026-10-31-10-mysql-all.sql
mysql -uroot -p < /backup/increment.sql
# 刷新
mysql -uroot -p -e 'flush privileges;'
注:
- 恢复备份数据,会使密码也恢复到那个备份时的密码
- 备份恢复涉及到mysql.user表时,都需要执行mysql -uroot -p -e 'flush privileges;',其他情况下不用