不是必须,但对innodb表强烈建议加--single-transaction;它通过一致性快照避免锁表,而myisam只能用--lock-tables,默认行为。

mysqldump 备份命令必须加 --single-transaction 吗?
不是必须,但对 InnoDB 表强烈建议加。不加的话,默认会触发 --lock-tables,锁住所有表直到导出完成,主库写入会阻塞;而 --single-transaction 通过启动一个一致性快照(START TRANSACTION WITH CONSISTENT SNAPSHOT)来避免锁表,前提是数据库引擎支持事务(如 InnoDB),且没有长事务干扰。
常见错误现象:mysqldump: Got error: 1045: Access denied for user —— 密码参数格式错,-p 和密码之间不能有空格,应写成 -p'yourpass' 或交互式输入;mysqldump: Couldn't execute 'SHOW CREATE TABLE `xxx`': Table doesn't exist —— 表名大小写敏感或库名拼错。
- MyISAM 表只能用
--lock-tables(默认行为),--single-transaction无效 - 如果备份时遇到
ERROR 1205 (HY000): Deadlock found,说明有并发 DDL 操作,建议避开高峰期或加--skip-lock-tables+--flush-logs配合 binlog 恢复 - 加
--routines --triggers --events才能完整导出存储过程、触发器和事件调度器
全库、单库、单表备份怎么选参数?
参数差异直接决定恢复粒度和执行开销。不要用 --all-databases 无差别备份——它会把 mysql 系统库也导出,恢复时可能覆盖用户权限;也不推荐在生产环境直接用 mysqldump db_name > backup.sql,缺少关键元数据。
推荐组合:
- 单库备份(最常用):
mysqldump -u root -p'pass' --single-transaction --routines --triggers --databases myapp_db > myapp_db_$(date +%Y%m%d).sql - 单表备份(调试/误删恢复):
mysqldump -u root -p'pass' --single-transaction myapp_db users orders > users_orders.sql - 仅结构(不带数据):
mysqldump -u root -p'pass' --no-data myapp_db > schema_only.sql - 压缩导出(节省空间):
mysqldump -u root -p'pass' myapp_db | gzip > myapp_db.sql.gz
注意:--databases 参数会让输出包含 CREATE DATABASE IF NOT EXISTS 语句,恢复时不用提前建库;不加则只导出表结构和数据,恢复需手动 CREATE DATABASE。
备份脚本里为什么总要加 --flush-logs?
--flush-logs 的作用是:在 dump 开始前刷新 MySQL 的二进制日志(binlog),生成新编号的 binlog 文件(如从 mysql-bin.000005 切到 mysql-bin.000006)。这为后续基于 binlog 的增量恢复提供清晰起点。
不加的后果:你拿到的备份点和 binlog 位置无法精确对应,做时间点恢复(PITR)时容易跳过或重复执行部分事务。
- 必须配合
--master-data=2使用,才能在备份文件开头写入CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000006', MASTER_LOG_POS=123;这类关键信息 - 如果 MySQL 没开启 binlog(
log-bin未配置),--flush-logs会报错,先检查mysql -e "SHOW VARIABLES LIKE 'log_bin';" - 频繁执行
--flush-logs可能导致大量小 binlog 文件,需配合expire_logs_days清理
crontab 定时备份脚本最容易漏掉什么?
不是语法错误,而是环境变量缺失。crontab 默认 PATH 很窄(通常只有 /usr/bin:/bin),找不到 mysqldump 或 date 命令;同时不会加载你的 ~/.bashrc,所以 mysql 认证文件(如 ~/.my.cnf)可能不生效。
实操建议:
- 脚本开头显式声明 PATH:
PATH=/usr/local/bin:/usr/bin:/bin - 用绝对路径调用命令:
/usr/bin/mysqldump而非mysqldump - 密码别硬编码在脚本里,改用
~/.my.cnf并设权限chmod 600 ~/.my.cnf,内容:[client] user=root password=yourpass
- 每次备份后加清理逻辑,例如:
find /backup/mysql -name "*.sql" -mtime +7 -delete
真正麻烦的是备份文件权限和 SELinux 上下文——如果备份目录挂载自 NFS 或启用了 SELinux,mysqldump 可能因权限拒绝写入,得提前用 restorecon -Rv /backup 或 setsebool -P mysqld_can_network_connect 1 调整。











