mysqldump 备份时必须加 --single-transaction
吗?
不是必须,但对 InnoDB 表强烈建议加。不加会导致备份期间阻塞写入(尤其是
FLUSH TABLES WITH READ LOCK),而
--single-transaction利用 MVCC 创建一致性快照,全程不锁表。
注意它只对 InnoDB 有效;如果库中混有 MyISAM 表,仍会触发全局读锁。可通过
SELECT ENGINE, COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'your_db' GROUP BY ENGINE;检查引擎分布。 线上业务库基本都是 InnoDB,
--single-transaction是安全前提 必须搭配
--all-databases或
--databases使用,单独指定表时不生效 若备份耗时过长,事务快照可能被 purge 线程清理,导致
ERROR 1205 (HY000): Deadlock found when trying to get lock—— 此时需调大
innodb_undo_retention
如何用 mysqlbinlog
做基于时间点的异地恢复?
异地恢复依赖完整 binlog + 全量备份。关键不是“能不能”,而是“binlog 是否开启”和“是否保存了从全备时间点起的所有 binlog 文件”。
检查项:
SHOW VARIABLES LIKE 'log_bin';必须为
ON;
SHOW VARIABLES LIKE 'expire_logs_days';建议设为 7 天以上;
SHOW MASTER STATUS;记下
File和
Position,用于定位起点。 恢复前先停掉目标库的 binlog 写入:
SET sql_log_bin = 0;用
mysqlbinlog --start-datetime="2024-06-01 10:20:00" --stop-datetime="2024-06-01 10:25:00" mysql-bin.000012 | mysql -u root -p回放指定时间段 若已知误操作语句位置,用
--start-position=12345 --stop-position=12399更精准,避免跨事务截断 异地恢复时,务必确认源库与目标库的
server_id不同,否则 GTID 模式下会拒绝执行
异地恢复失败常见报错: ERROR 1840 (HY000): @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty
这是 GTID 模式下最典型的初始化冲突。本质是目标实例已执行过其他 GTID 事务,但你要导入的备份里包含
SET @@GLOBAL.GTID_PURGED语句。
解决路径分两步:先清空目标实例(仅限全新恢复场景),或跳过该语句(生产环境更稳妥)。
全新实例:执行RESET MASTER;后再导入 dump 文件 已有数据的实例:用
sed '/GTID_PURGED/d' backup.sql > clean_backup.sql删除该行,再导入 导入后手动补回 purged 集合:
SET GLOBAL GTID_PURGED='xxx-xxx-xxx:1-100';(值来自原备份文件头注释或
SHOW MASTER STATUS) 若用
mysqldump --set-gtid-purged=OFF参数重备,可彻底规避此问题
备份文件传到异地后,mysql
导入慢得离谱?
不是网络或磁盘问题,大概率是默认参数限制。MySQL 客户端在非交互模式下会逐行解析 SQL,遇到大文件极易卡住。
真正有效的提速手段只有三个:
导入前执行SET FOREIGN_KEY_CHECKS=0; SET UNIQUE_CHECKS=0; SET AUTOCOMMIT=0;,导入末尾再恢复 用
mysql --max-allowed-packet=512M -u root -p 显式调大包大小,避免因单条 INSERT 超长被截断重试若备份含大量
INSERT INTO ... VALUES (...),(...),(...),确保 mysqld 的
bulk_insert_buffer_size足够(建议 ≥ 64M)
异地恢复的核心从来不是“怎么拷贝”,而是“怎么让目标实例信任并正确解释你传过去的那堆 SQL 和 binlog”。GTID、server_id、字符集、SQL_MODE 这些看似配置项的东西,任何一个不一致,都会在最后一刻报出完全不相关的错误。
