推荐用脚本+定时任务自动清理MySQL历史备份,按时间戳命名(如db_20240520_1230.sql.gz),用find按修改时间(-mtime +7)或文件名日期精准删除过期文件,执行前先用-print预览;InnoDB备份必须加--single-transaction,MyISAM则用--lock-all-tables;需显式添加--routines、--triggers、--events才能导出视图、存储过程等对象。

如何自动清理过期的 MySQL 历史备份文件
手动删备份迟早出错,推荐用脚本+定时任务自动管理。核心思路是:按时间戳命名备份文件(如 backup_20240520.sql.gz),再用 find 按修改时间或文件名匹配规则清理。
常见错误是直接 rm -f *.sql.gz —— 一不小心删掉最新备份。务必加时间过滤条件。
- 推荐备份命名格式:
mysqldump -u root -p database_name | gzip > /backup/db_$(date +\%Y\%m\%d_\%H\%M).sql.gz - 保留最近 7 天的备份:
find /backup -name "db_*.sql.gz" -mtime +7 -delete - 若按文件名中的日期判断(更精准):
find /backup -name "db_????????.sql.gz" -exec sh -c '[[ $(basename "$1") =~ db_([0-9]{8})_ ]] && [[ ${BASH_REMATCH[1]} -lt $(date -d "7 days ago" +\%Y\%m\%d) ]] && rm "$1"' _ {} \; - 执行前先用
-print替代-delete预览将删哪些文件
mysqldump 备份时要不要加 --single-transaction
对 InnoDB 表必须加,否则可能拿到不一致快照;对 MyISAM 表无效,且会隐式加全局读锁,导致写入阻塞。
典型误用场景:混合引擎库没区分表类型,盲目加该参数,结果 MyISAM 表锁住业务写入。
- 只备份 InnoDB 库:
mysqldump --single-transaction --routines --triggers db_name - 含 MyISAM 表:改用
--lock-all-tables(锁全库,一致性好但停写久),或分表导出 -
--single-transaction不影响 binlog 位置,适合搭配--master-data=2做主从同步起点
备份文件压缩率与恢复速度怎么平衡
gzip 默认压缩级别(-6)在体积和耗时间较均衡;zstd 或 pigz 可显著提速,但需额外安装。
线上库超 50GB 后,单纯 gzip -9 会让备份窗口拉长、IO 压力陡增,反而增加失败风险。
- 常规大小(mysqldump ... | gzip -6 > backup.sql.gz
- 大库(>20GB):
mysqldump ... | pigz -p 4 > backup.sql.gz(需yum install pigz) - 追求极致压缩(归档用):
mysqldump ... | zstd -T4 -19 > backup.sql.zst,但恢复时需zstd -d backup.sql.zst | mysql - 别用
gzip -9—— 压缩时间翻倍,体积只省 3%~5%
为什么 mysqldump 备份后恢复不了视图或存储过程
默认不导出函数、存储过程、事件、触发器,只导表结构和数据。这是最常被忽略的兼容性断点。
现象是:恢复后 SHOW CREATE VIEW xxx 报错,或调用存储过程提示不存在。
- 必须显式加参数:
--routines(含 function + procedure)、--triggers、--events - 注意权限:
SELECT权限不够,还需SHOW VIEW、EXECUTE、EVENT等权限才能完整导出 - 跨版本恢复时,低版本 dump 文件含高版本语法(如 JSON 函数),需加
--compatible=mysql40兼容处理










