本文共 1445 字,大约阅读时间需要 4 分钟。
背景
项目的快速迭代开发和在线业务需要保持持续可用的要求,导致MySQL的ddl变成了DBA很头疼的事情,而且经常导致故障发生。本篇介绍RDS分支上做的一个功能改进,DDL fast fail。主要解决:DDL操作因为无法获取MDL排它锁,进入等待队列的时候,阻塞了应用所有的读写请求问题。
MDL锁机制介绍
首先介绍一下MDL(METADATA LOCK)锁机制,MySQL为了保证表结构的完整性和一致性,对表的所有访问都需要获得相应级别的MDL锁,比如以下场景:
这种场景就是目前因为MDL锁导致的很经典的阻塞问题,如果session1长时间未提交,或者查询持续过长时间,那么后续对t1表的所有读写操作,都被阻塞。 对于在线的业务来说,很容易导致业务中断。
aliyun RDS分支改进
DDL fast fail并没有解决真正DDL过程中的阻塞问题,但避免了因为DDL操作没有获取锁,进而导致业务其他查询/更新语句阻塞的问题。
其实现方式如下:
其处理逻辑如下:
首先尝试获取t1表的MDL_EXCLUSIVE级别的MDL锁:
另外,除了alter语句以外,还支持rename,truncate,drop,optimize,create index等ddl操作。
与Oracle的比较
在Oracle 10g的时候,DDL操作经常会遇到这样的错误信息:
其实DDL获取排他锁的设计,需要考虑的就是两个问题:
在Oracle 11g的时候,引入了DDL_LOCK_TIMEOUT参数,如果你设置了这个参数,那么DDL操作将使用排队阻塞模式,可以在session和global级别设置, 给了用户更多选择。
转载地址:http://rrvwx.baihongyu.com/