恢复操作会阻塞业务写入:因导入sql默认自动提交,insert/update/drop等语句持锁与业务dml冲突,导致响应变慢、连接堆积、lock wait timeout错误及主从延迟;myisam全程表锁,innodb大批量插入亦易引发间隙锁、自增锁争用,drop+create更致表不可读写。

恢复操作会阻塞业务写入
MySQL 恢复数据(尤其是使用 mysql 命令导入 SQL 文件)时,如果目标表正在被业务频繁写入,会出现明显锁等待甚至超时。这是因为导入过程默认以自动提交模式逐条执行语句,INSERT、UPDATE、DROP TABLE 等操作会持有表级或行级锁,与业务 DML 冲突。
常见现象包括:业务接口响应变慢、连接堆积、出现 Lock wait timeout exceeded 错误、主从延迟陡增。
- MyISAM 表恢复时全程表锁,业务写入完全阻塞
- InnoDB 表虽支持行锁,但大批量
INSERT仍可能触发间隙锁、自增锁争用,尤其在高并发插入场景下 - 若恢复中包含
DROP TABLE+CREATE TABLE,则表结构变更期间该表不可读写
mysqldump 导出的 SQL 文件恢复最危险
直接用 mysql -u user -p db_name 恢复 <code>mysqldump 输出的文件,本质是串行重放所有语句——它不区分事务边界,也不做批量优化,对大表极不友好。
例如一个 500 万行的 INSERT INTO t VALUES (...),(...),... 单条语句,MySQL 会尝试一次性解析并加锁,内存和锁开销远高于分批插入。
- 务必检查备份文件是否含
SET autocommit=0和事务包裹(BEGIN/COMMIT),没有的话恢复过程无法回滚且更易锁表 - 避免在业务高峰期执行;如必须恢复,优先改用物理备份(如
xtrabackup)+ 增量应用,耗时短、锁表时间可控 - 可先用
sed -i 's/INSERT INTO/INSERT IGNORE INTO/g'或拆分大 INSERT 为每万行一批,降低单次锁粒度
使用 LOAD DATA INFILE 恢复更快但权限受限
LOAD DATA INFILE 是 MySQL 内置的高速批量导入命令,比 mysql 命令执行 SQL 快 5–10 倍,且默认自动合并成事务、减少日志刷盘次数。但它要求文件位于数据库服务器本地(或启用 local_infile=ON 并用 LOAD DATA LOCAL INFILE)。
- 需确认 MySQL 配置中
secure_file_priv的值,否则会报错The MySQL server is running with the --secure-file-priv option - 导入前建议关闭唯一键检查:
SET unique_checks=0,导入后再开启,避免逐行校验拖慢速度 - 注意字符集匹配:文件编码需与表定义一致,否则出现乱码或
Incorrect string value报错
从 binlog 恢复需停写或过滤业务流量
用 mysqlbinlog 解析并重放 binlog 来恢复误删数据,看似“精准”,实则极易引发二次事故:只要恢复窗口内存在新写入,重放的语句就会与当前数据冲突(如重复主键、覆盖最新状态)。
典型错误操作是直接 mysqlbinlog mysql-bin.000001 | mysql -u root -p —— 这等于把过去某段时间的所有变更再跑一遍,业务根本无法感知。
- 必须用
--start-datetime/--stop-datetime或--start-position/--stop-position严格限定范围 - 推荐先将 binlog 导出为 SQL,人工审查删掉业务正常写入的语句(比如排除
INSERT INTO order_log等高频表) - 最稳妥方式:在从库上恢复验证结果,确认无误后再切流或同步到主库
SHOW PROCESSLIST 看当前活跃写入压力;恢复中监控 innodb_row_lock_waits 和 Threads_running。锁表不是能不能做的问题,而是你愿不愿意让订单创建失败五分钟。











