推荐 --single-transaction(仅InnoDB有效),混用引擎或需强一致性时改用 --lock-all-tables;备份前查引擎、加 --databases 和权限导出;设超时与包大小防中断;binlog可恢复删库但须ROW格式且日志未过期。
mysqldump 备份时加 --single-transaction 还是 --lock-all-tables
对正在写入的业务库,--single-transaction 是默认推荐,但它只对 innodb 有效;myisam 表会自动退化成全局锁,导致备份期间写入阻塞。如果库混用引擎,或不确定表类型,--lock-all-tables 更稳妥——但意味着整个备份过程所有写操作暂停。
常见错误现象:mysqldump: Got error: 1146: Table 'xxx' doesn't exist,其实是备份中途被 DDL(如 DROP TABLE)干扰,--single-transaction 无法隔离 DDL。
- 线上 OLTP 环境且全为 InnoDB → 用
--single-transaction+--routines+--triggers - 含 MyISAM 或需强一致性快照 → 改用
--lock-all-tables,并尽量选低峰期执行 - 备份前先查引擎:
SELECT table_name, engine FROM information_schema.tables WHERE table_schema = 'your_db';
备份文件里没包含 CREATE DATABASE 和权限语句怎么办
mysqldump 默认不导出 CREATE DATABASE,也不导出用户、权限等元数据,还原时容易因库不存在或权限缺失失败。
- 加
--databases参数(注意是复数):mysqldump --databases mydb > backup.sql,它会在 SQL 开头插入CREATE DATABASE IF NOT EXISTS `mydb`; - 权限要单独导出:
mysqldump -u root -p --no-data --no-create-info mysql user db tables_priv > grants.sql - 还原顺序必须是:先执行
grants.sql(需 root 权限),再执行backup.sql
遇到 ERROR 2013 (HY000) 或备份中断后文件不完整
这是网络抖动、超时或大表导出时连接断开的典型表现,生成的 SQL 文件末尾常缺 ; 或直接截断,强行还原会报语法错误。
- 加
--max-allowed-packet=512M(根据最大 BLOB 字段调整),避免 packet 被截断 - 设长超时:
--connect-timeout=3600 --net-read-timeout=3600 --net-write-timeout=3600 - 关键备份务必校验完整性:还原前用
tail -n 20 backup.sql | grep "^-- Dump completed"确认结尾标记存在 - 别依赖单次 dump:对 TB 级库,改用
--tables分表导出,按表名并行+校验,失败只重跑单表
勒索场景下,mysqlbinlog 日志能否救回被删库的数据
能,但前提是:binlog 必须开启(log_bin=ON)、格式为 ROW、且备份时刻起的日志未被覆盖或删除。一旦 DROP DATABASE 执行,binlog 里只有事件,没有“反向语句”,得靠解析定位到删库前最后位置点。
- 查当前 binlog 状态:
SHOW MASTER STATUS;,确认File和Position - 定位删库时间点:
mysqlbinlog --base64-output=DECODE-ROWS -v mysql-bin.000001 | grep -A5 -B5 "DROP DATABASE" - 恢复时用
--stop-position截断到删库前,再导入全量备份 + 增量日志 - 注意:
mysqlbinlog解析大日志极慢,建议提前把 binlog 拷贝到离线机处理,别在生产库上跑
最易被忽略的一点:很多 DBA 开了 binlog,但没配 expire_logs_days,结果磁盘满后 MySQL 自动 purge 了旧日志——备份再全,没日志也回滚不了误操作。

















