mysql如何在高并发环境下备份_mysql高效备份方案

1次阅读

mysqldump 高并发下易锁表,因默认执行 flush tables with read lock,即使 –single-transaction 也仅对 innodb 有效且依赖 repeatable read 隔离级;遇 myisam、长事务或 statement 格式 binlog 会退化为全局读锁,导致写阻塞。

mysql如何在高并发环境下备份_mysql高效备份方案

mysqldump 在高并发下为什么容易锁表

默认情况下 mysqldump 执行 FLUSH TABLES WITH READ LOCK,会阻塞所有写入,哪怕加了 --single-transaction,也只对 InnoDB 有效,且要求事务隔离级别为 REPEATABLE READ;一旦遇到混合引擎(比如 MyISAM 表)、长事务未提交、或开启了 binlog_format = STATEMENT,就可能退化成全局读锁。

常见现象:SHOW PROCESSLIST 中大量线程卡在 Waiting for table flush,应用写请求超时。

  • 务必确认库中无 MyISAM 表:select TABLE_NAME, ENGINE FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'your_db' AND ENGINE = 'MyISAM';
  • 备份前检查长事务:SELECT * FROM information_schema.INNODB_TRX ORDER BY TRX_STARTED LIMIT 5;
  • 避免在业务高峰执行,或搭配 --skip-lock-tables(仅适用于全 InnoDB + --single-transaction

Percona XtraBackup 是什么,为什么它更适合高并发

innobackupex 已被弃用,现在统一用 xtrabackup(v8.0+ 支持 MySQL 8.0,需匹配版本)。它基于 InnoDB 的崩溃恢复机制,拷贝数据文件的同时记录 redo log 偏移,不锁表、不阻塞 DML,备份过程对线上影响极小。

但注意:它只支持 InnoDB 和 XtraDB,不备份 MyISAM、CSV、MEMORY 等非事务表(如有,需额外用 mysqldump --no-create-info 单独导出)。

  • 基础全量备份命令:xtrabackup --backup --target-dir=/backup/full_$(date +%F)
  • 备份后必须 --prepare 才能恢复:xtrabackup --prepare --target-dir=/backup/full_2024-06-01
  • 若启用了加密或压缩,--encrypt/--compress 会显著增加 CPU 消耗,建议在从库或低负载节点做

如何用 binlog 做增量备份并保障一致性

单纯全量备份无法满足 RPO binlog 文件名和 position(见 xtrabackup_binlog_info),后续可用 mysqlbinlog 截取增量日志。

关键点在于:增量备份不能“追着主库实时拉”,而应定期(如每 15 分钟)保存一次 SHOW MASTER STATUS,再结合 FLUSH BINARY LOGS 控制单个 binlog 文件大小,避免单文件过大导致解析慢或传输失败。

  • 获取上一次备份的位点:cat /backup/full_2024-06-01/xtrabackup_binlog_info → 输出类似 mysql-bin.000012 1987345
  • 拉取增量:mysqlbinlog --start-position=1987345 mysql-bin.000012 > incr_20240601_1500.sql
  • 恢复时先 --prepare 全量,再按顺序重放所有增量 SQL(注意跳过 SET @@session.SQL_LOG_BIN=0 这类语句,否则可能污染备份机 binlog)

备份文件校验与恢复演练常被忽略的细节

很多团队备份脚本跑通就认为万事大吉,但没验证过 tar -tzf 是否真包含 ibdata1、是否权限可读、是否跨版本兼容(例如 MySQL 5.7 备份不能直接用于 8.0 --prepare),更没人定期跑恢复测试。

最轻量的校验方式:用 xtrabackup --check-privileges 验证权限,再用 --dry-run(v8.0.30+)模拟 prepare 流程,不真正解压也不修改磁盘。

  • 恢复测试必须在独立环境(不能是生产从库),且要清空 datadir 后重新 --copy-back,再启动 mysqld 观察 Error log 是否有 InnoDB: Starting crash recovery 类提示
  • 备份路径不能放在系统盘或和 datadir 同一挂载点,防止磁盘满导致备份中断+主库宕机双重故障
  • 如果用了 LVM 快照,注意 snapshot 卷空间不足会导致备份静默失败,需监控 lvsData%
text=ZqhQzanResources