首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >MySQL 5.7:如何有效规避 MDL 元数据锁阻塞?

MySQL 5.7:如何有效规避 MDL 元数据锁阻塞?

原创
作者头像
贺春旸的技术博客
发布2025-02-17 10:41:32
发布2025-02-17 10:41:32
3820
举报
文章被收录于专栏:DBA 平台和工具DBA 平台和工具

在 MySQL 5.7 中,元数据锁(MDL, Metadata Lock) 机制用于确保数据一致性,但如果处理不当,可能会导致长时间阻塞,影响数据库的并发性能。

MDL 锁的影响

任何 读取写入 操作都会获取 MDL 锁,以防止表结构在操作过程中发生变更。例如,在 SELECT 查询执行时,不能对表进行 ALTER 操作,否则会出现等待现象。

假设以下事务按顺序执行:

  1. 事务 A 执行:
代码语言:sql
复制
SELECT SLEEP(3600), id FROM sbtest1 LIMIT 10;

由于 SLEEP(3600) 使查询持续 1 小时,MDL 读锁 也会保持 1 小时。

2. 事务 B 试图修改表结构:

代码语言:sql
复制
ALTER TABLE sbtest1 ADD COLUMN age INT;

由于 ALTER TABLE 需要 获取 MDL 写锁,但事务 A 未释放 MDL 读锁,事务 B 只能进入 Waiting for table metadata lock 状态,一直等待事务 A 结束。

3. 事务 C 执行普通查询:

代码语言:sql
复制
SELECT * FROM sbtest1 LIMIT 10;

由于事务 B 未能获取 MDL 写锁,事务 C 也会等待事务 B 释放锁,进入 Waiting for table metadata lock 状态,造成 连锁阻塞

优化方案:调整 lock_wait_timeout

MySQL 提供了 lock_wait_timeout 参数,控制 MDL 锁的等待时间。默认值可能长达 1 年,容易导致长时间阻塞。 建议调整此参数,例如设置为 3~10 秒,让超时的 DDL 语句自动终止,避免影响后续事务:

代码语言:sql
复制
SET GLOBAL lock_wait_timeout = 5;

这样,当事务 B 在 5 秒内无法获取 MDL 锁,会直接报错(ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction)而 不会一直等待,从而防止事务 C 也陷入等待状态,提高数据库的可用性。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • MDL 锁的影响
  • 优化方案:调整 lock_wait_timeout
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档