mysqldump必须加--single-transaction才安全,否则非事务表全表锁、InnoDB也可能一致性损坏;须搭配--skip-lock-tables,用subprocess.run()替代os.system(),密码走~/.my.cnf,设timeout,cron中显式PATH,备份后gzip压缩并轮转。

mysqldump 命令必须加 --single-transaction 才算真正安全
不加这个参数,mysqldump 在非事务表(如 MyISAM)上会锁全表;即使全是 InnoDB,没它也可能在备份中途被写入操作干扰,导致一致性损坏。线上库只要存在任何写入,就必须加。
-
--single-transaction仅对 InnoDB 有效,但多数现代库默认用它,所以几乎必加 - 搭配
--skip-lock-tables避免隐式锁表(mysqldump默认会尝试锁表) - 别信“我只读库所以不用”,MySQL 的 binlog、复制延迟、临时表都可能让读操作触发写行为
- 示例命令:
mysqldump --single-transaction --skip-lock-tables -u root -p mydb > backup.sql
Python 脚本里不能直接用 os.system() 调 mysqldump
它无法捕获错误码和 stderr,一旦密码错、权限不足、磁盘满,脚本就静默失败——你第二天才发现备份空了。
- 改用
subprocess.run(),显式检查returncode和stderr - 密码别拼进命令行(会留进程记录),用
~/.my.cnf配置文件更安全 - 务必设置超时:
subprocess.run(..., timeout=300),防止大库卡死整个调度 - 示例关键段:
result = subprocess.run(cmd, capture_output=True, text=True, timeout=300);之后检查if result.returncode != 0:
cron 定时执行 Python 脚本前,环境变量和路径经常不对
cron 启动的 shell 是最小化环境,PATH 里没有 mysqldump,Python 模块路径也和你终端里不一样,脚本十次有八次报 Command not found 或 ModuleNotFoundError。
- 在 crontab 里显式声明环境:
PATH=/usr/local/bin:/usr/bin:/bin - Python 脚本开头加
#!/usr/bin/env python3,且确保 cron 调用的是绝对路径:0 2 * * * /usr/bin/python3 /home/user/backup.py - 用
which mysqldump查真实路径,硬编码进脚本或环境变量 - 测试方法:手动用
env -i /bin/sh模拟 cron 环境,再跑一遍命令
备份文件没压缩 + 没轮转 = 几周后磁盘爆掉
一个 500MB 的库,每天一个 SQL 文件,两周就是 7GB;没人清理,/var 或用户家目录先扛不住。
立即学习“Python免费学习笔记(深入)”;
- dump 后立刻用
gzip压缩:mysqldump ... | gzip > backup_$(date +%F).sql.gz - 用
find /path -name "backup_*.sql.gz" -mtime +7 -delete清理 7 天前的 - 别依赖 Python 自己删文件——cron 权限、路径错误会导致删错目录,shell 命令更可控
- 压缩率看数据类型,文本类字段多的库通常能压到 1/4,别省这点 CPU
实际最难的不是写脚本,是确认每次备份真的成功了:mysqldump 退出码为 0、文件大小不为 0、gzip 解压后能 parse 出 CREATE TABLE。这些点漏掉任意一个,备份就是假的。



















