Waiting for table flush及Waiting for table metadata lock重现及解决

线上从库出现查询延迟,原因是大量线程等待Tableflush。问题可能源于运维在主库的Alter操作和大数据同步。解决方案是在切表前检查并结束慢查询线程,确保主从同步顺利进行。

背景:线上的从库突然查询非常慢,一直在等待,查不出来。看执行线程列表有大量的Waiting for table flush

猜测原因:

   1.运维使用alter在主库上进行大表数据的切表

   2.大数据部门在从库通过datax同步数据到数据仓库。

早上报Waiting for table flush,有可能是主库先rename成功,然后主库切表成,主从同步到从库的时候,因为从库有慢查询,所以从库报Waiting for table flush

重现步骤:

    1.先用一个线程查表然后长时间休眠,然后另一个线程rename表的时候就会报Waiting for table metadata lock

参考文档:

    https://dev.mysql.com/doc/refman/5.6/en/general-thread-states.html

该问题的解决是,在切表之前,先看下当前的线程列表,把执行慢的线程先Kill掉,然后开始切。切完,再看下线程列表,看有没有Waiting for table flush,如果没有,则本次操作成功。

Waiting for backup lock” 出现 **3个周期**,这个描述通常出现在 **MySQL 备份工具(如 Percona XtraBackup 或 MySQL Enterprise Backup)的日志中**,表示备份进程正在等待获取某种特殊锁来保证一致性。我们来详细解释这句话的含义。 --- ## 🔍 一、“Waiting for backup lock” 是什么? 这是 **Percona XtraBackup** 在执行热备时的一个阶段提示信息。 当 XtraBackup 启动后,它需要确保某些 DDL 操作不会干扰备份的一致性。为此,从 `xtrabackup 2.2+` 开始引入了 **Backup Locks** 特性(替代传统 `FLUSH TABLES WITH READ LOCK` 的一部分功能),以减少对数据库写入的影响。 > ✅ 它的目标是:**快速锁定关键元数据,而不阻塞大多数 DML 操作(INSERT/UPDATE/DELETE)** ### 日志示例: ``` [01] Waiting for backup lock (1/3) [01] Waiting for backup lock (2/3) [01] Waiting for backup lock (3/3) [01] Backup lock acquired ``` --- ## 🧩 二、“3个周期”是什么意思? 这里的“3个周期”并不是指程序只重试三次,而是一种 **轮询机制下的尝试次数记录**,意思是: > XtraBackup 每隔一段时间检查是否可以获得 backup lock,最多尝试若干次(例如每秒一次),直到成功或超时。 但实际中,“3个周期”更可能是你在日志中看到它恰好打印了三次类似的信息,并不代表硬编码为3次。这取决于当时的并发情况。 ### 实际流程如下: 1. XtraBackup 发出请求:`LOCK TABLES FOR BACKUP` - 这个锁用于阻止 DDL(如 ALTER、DROP 表等),但允许正常 DML。 2. 如果当前有长事务或 DDL 正在运行,则无法立即获得锁。 3. XtraBackup 开始轮询等待,每隔一段时间重试。 4. 每次尝试失败时可能输出一条日志:“Waiting for backup lock (n/k)” 5. 当第3次成功时,你就看到了“3个周期” 📌 所以,“3个周期”只是说明它花了 **三次尝试才拿到锁**,反映的是系统负载或并发操作的存在。 --- ## ⚠️ 三、什么时候会出现长时间等待? | 原因 | 说明 | |------|------| | 1. 长时间运行的 DDL | 如 `ALTER TABLE`, `OPTIMIZE TABLE` 等会与 backup lock 冲突 | | 2. 其他备份正在进行 | 多个 xtrabackup 同时运行会互斥 | | 3. 未提交事务持有资源 | 特别是涉及表结构变更的操作 | | 4. 使用了不支持 backup lock 的旧版本 MySQL | 回退到 FTWRL,更容易阻塞 | --- ## ✅ 四、如何排查和优化? ### 1. 查看当前阻塞源(连接谁占着不让) 登录 MySQL,运行: ```sql -- 查看是否有正在进行的 DDL SHOW PROCESSLIST; -- 更详细的等待信息(MySQL 5.7+) SELECT * FROM performance_schema.events_statements_current WHERE sql_text LIKE '%ALTER%' OR sql_text LIKE '%DROP%'; -- 查看是否有大事务未提交 SELECT * FROM information_schema.INNODB_TRX ORDER BY trx_started; ``` ### 2. 查看 backup lock 是否被其他会话占用 虽然没有直接视图,但可以通过以下方式判断: ```sql -- 查看是否有会话持有了 LOCK TABLES FOR BACKUP -- 可通过状态变量观察 SHOW STATUS LIKE 'Com_lock_tables_for_backup'; ``` 如果值 > 0 且很久没释放,说明有问题。 --- ## ✅ 五、代码示例:XtraBackup 启动命令(避免无限等待) 建议使用超时控制和日志监控: ```bash innobackupex --user=root --password=xxx \ --lock-wait-timeout=60 \ --lock-wait-query-timeout=30 \ --lock-retry=10 \ /backup/mysql/ ``` 相关参数说明: | 参数 | 含义 | |------|------| | `--lock-wait-timeout=N` | 等待 backup lock 的最大秒数(默认 70) | | `--lock-wait-query-timeout=N` | 查询是否可以加锁的超时时间 | | `--lock-retry=N` | 每次重试间隔(秒) | 设置合理值可防止备份卡死。 --- ## ✅ 六、补充:两种 Backup Lock 类型 XtraBackup 使用两个层级的锁: 1. `LOCK TABLES FOR BACKUP` - 阻止 DDL 和表级写入,不影响行级 DML。 2. `LOCK BINLOG FOR BACKUP` - 确保 binlog 位置一致,配合获取 `FLUSH LOGS` 和位点。 只有这两个锁都拿到后,备份才能进入数据拷贝阶段。 --- ## ✅ 总结 | 问题 | 解释 | |------|------| | ❓ “Waiting for backup lock 3个周期” 是什么意思? | 表示 XtraBackup 尝试了3次才成功获取 `LOCK TABLES FOR BACKUP` 锁 | | ❓ 是否正常? | 是正常的,只要最终获取成功即可 | | ❓ 时间过长怎么办? | 检查是否有长 DDL 或大事务,优化业务窗口期备份 | | ❓ 如何减少等待? | 在低峰期备份,限制 DDL 时间,配置合理的 `--lock-wait-timeout` | --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值