mysql备份过程中如何避免锁表_mysql无锁备份方案

5次阅读

mysqldump加–single-transaction在rr级别下对innodb表基本不锁表,但依赖无长事务;myisam仍会锁表,需配合–skip-lock-tables;物理备份更适用于大数据量场景。

mysql备份过程中如何避免锁表_mysql无锁备份方案

mysqldump 加 --single-transaction 真的不锁表吗

在可重复读(RR)隔离级别下,mysqldump --single-transaction 会发起一个一致性快照,对 InnoDB 表基本不加锁——但前提是整个 dump 过程中不能有长事务存在。一旦有活跃的长事务未提交,mysqldump 的快照会等待其结束,表现为“卡在 opening tables”或阻塞后续 DDL。

  • 必须确保备份前没有运行超时的事务:select * FROM information_schema.INNODB_TRX ORDER BY TRX_STARTED LIMIT 5;
  • 避免在备份窗口内执行 ALTER TABLEDROP INDEX 等隐式锁表操作
  • --single-transaction 对 MyISAM 表无效,仍会触发 FLUSH TABLES WITH READ LOCK(除非显式排除)
  • 建议配合 --skip-lock-tables 使用,防止 mysqldump 自动降级加锁

Percona XtraBackup 的 --no-lock 能否完全替代锁

innobackupex(现为 xtrabackup)的 --no-lock 仅跳过 FLUSH TABLES WITH READ LOCK,但它仍需在拷贝期间获取 backup_lock(MySQL 8.0+)或依赖 LOCK TABLES FOR BACKUP(5.7+)。这意味着:它不阻塞 DML,但会短暂阻塞 DDL(如 CREATE TABLETRUNCATE)。

  • MySQL 5.7+ 必须启用 lock_wait_timeout 并设为较小值(如 3),避免 DDL 被无限挂起
  • 备份开始前检查是否已开启 innodb_file_per_table=ON,否则恢复时可能失败
  • --no-lock 不适用于含非 InnoDB 表的库;混合引擎需用 --lock-ddl 或接受短时全局锁
  • 备份后务必运行 xtrabackup --prepare,否则备份集不可用——这点常被跳过导致恢复失败

逻辑备份 vs 物理备份:什么时候该放弃 mysqldump

当单表超过 10 GB 或总数据量超 100 GB 时,mysqldump 的单线程导出 + 客户端解析开销会明显拖慢备份速度,并增加主库 CPU 和网络负载。此时物理备份更稳。

  • mysqldump 导出大表容易触发 max_allowed_packet 错误,需同步调大服务端和客户端该参数
  • 若业务允许 1–2 分钟只读窗口,FLUSH TABLES WITH READ LOCK + cp/tar 原文件仍是最快方案(仅限全 InnoDB + innodb_flush_method=O_DIRECT
  • 云环境优先考虑 MySQL 官方 mysqlpump(支持并行、压缩),但注意其不兼容 MySQL 5.6 及更早版本
  • 不要在从库上无脑用 mysqldump --master-data:若从库 IO 线程延迟高,生成的 binlog 位点会不准

备份后校验 checksum 的必要性被严重低估

无论用哪种方式备份,不做校验等于没备。物理备份可能因磁盘静默错误丢失页,逻辑备份可能因字符集转换截断字段,而这些在 restore 前完全无法察觉。

  • Percona XtraBackup 备份后立即执行:xtrabackup --backup --checksum=xxhash64(8.0.26+ 支持)
  • mysqldump 导出后可用:md5sum backup.sql + 在目标机导入后执行 CHECKSUM TABLE tbl_name 对比
  • 关键业务建议在备份完成后 1 小时内完成一次最小化 restore 测试(哪怕只恢复单张小表)
  • 校验脚本必须独立于备份主机运行,避免同一块磁盘故障导致备份+校验同时失效
text=ZqhQzanResources