mysql备份时如何避免锁表_mysql并发安全措施

7次阅读

mysqldump加–single-transaction可避免锁表但仅对InnoDB有效,利用MVCC快照实现无锁备份;mysqlpump支持线程并行备份;Percona XtraBackup提供真正零锁物理备份。

mysql备份时如何避免锁表_mysql并发安全措施

mysqldump 加 --single-transaction 能避免锁表,但仅对 InnoDB 有效

MySQL 默认的 mysqldump 在备份时会执行 FLUSH tableS WITH READ LOCK(除非显式禁用),导致整个实例只读,业务写入阻塞。对 InnoDB 表,加 --single-transaction 可绕过全局锁:它利用 MVCC 在事务快照中读取数据,全程不阻塞 DML。

  • 必须确保所有待备份表都是 InnoDB 引擎,MyISAM 表仍会被锁(哪怕加了该参数)
  • 备份开始前需确认 autocommit=1,否则事务不会自动开启,快照无法建立
  • 大表或长事务会导致快照一致性窗口拉长,可能引发 Error 1205 (HY000): Deadlock found 或备份超时
  • 不适用于有 DDL 操作的场景——ALTER TABLE 等会中断一致性快照,报错 Cannot execute statement in a READ ONLY transaction

mysqlpump 替代 mysqldump 提升并发备份能力

mysqlpump 是 MySQL 5.7+ 提供的并行逻辑备份工具,原生支持多线程导出、按库/表粒度分片、自动跳过锁表操作,比 mysqldump 更适合高并发环境。

  • 默认启用 --single-transaction,且对每个数据库单独启事务,降低长事务影响
  • --default-parallelism=N 控制线程数(如 N=4),但注意不要超过服务器 CPU 核心数 × 2
  • 不支持 MyISAM 表的无锁备份,遇到时会自动退化为表级 LOCK TABLES,需提前检查引擎类型
  • 导出的 SQL 中包含 SET session binlog_format=ROW,若目标环境禁用 row 格式会报错,需提前清理或加 --skip-binlog

物理备份(Percona XtraBackup)是真正零锁的方案

逻辑备份本质是查数据再拼 SQL,I/O 和 CPU 压力大,且无法做到严格时间点一致;而 Percona XtraBackup 直接拷贝 InnoDB 数据文件,通过 replay redo log 实现最终一致性,全程不锁表、不阻塞业务。

  • 备份时主库持续接受写入,xtrabackup 仅在最后几秒做 FLUSH TABLES WITH READ LOCK 获取 binlog 位点,锁时极短
  • 要求 MySQL 开启 innodb_file_per_table=ON,否则无法精确备份单表
  • 恢复前必须执行 xtrabackup --prepare,否则启动 MySQL 会报错 InnoDB: database page corruption on disk
  • 不兼容 MySQL 8.0 的数据字典表(mysql.ibd),8.0+ 需用 mysqlbackupxbstream 流式备份

备份期间的并发安全关键配置项

无论选哪种备份方式,以下配置直接影响并发表现和数据一致性:

  • innodb_lock_wait_timeout:建议设为 600(默认 50),避免备份脚本因锁等待被 kill
  • max_connections:备份进程本身占连接,需预留足够余量,否则业务连接会报 ERROR 1040 (HY000): Too many connections
  • innodb_log_file_size:过小会导致频繁 checkpoint,拖慢备份速度;过大则 --prepare 时间变长
  • 备份命令中务必加 --set-gtid-purged=OFF(GTID 环境下),否则可能触发 ERROR 1236 (HY000): The slave is connecting using CHANGE MASTER TO

备份不是“跑完命令就完事”,InnoDB 引擎、事务隔离级别、binlog 格式、甚至备份时刻是否有长事务运行,都会让同一套命令在不同环境表现迥异。最容易被忽略的是:没验证备份文件能否真正恢复——导出 SQL 是否语法完整,xtrabackup 备份后是否成功 prepare,这些步骤缺一不可。

text=ZqhQzanResources