什么是Mysql表元数据锁等待队列排序

时间:2018-06-06 07:11:23

标签: mysql transactions locking

我有一堆连接在事务中执行SELECT而一个执行DDL。 mysql手册非常清楚如何在事务中采用元数据锁:

  

为确保事务可序列化,服务器不得允许一个   session上执行数据定义语言(DDL)语句   在未完成的显式或隐式启动中使用的表   另一个会话中的交易。服务器通过获取实现此目的   元数据锁定事务中使用的表并推迟   在事务结束之前释放这些锁。元数据锁定   表格可防止更改表格的结构。这个锁定   方法暗示一个正在使用的表   一个会话中的事务不能在DDL语句中使用   交易结束前的其他会话。

这是有道理的,我做了这个测试:

connectionA$ begin;
connectionA$ select * from facebook_authorizations;
connectionA$ ....
connectionB$ alter table facebook_authorizations add column foo int default null;
connectionC$ begin;
connectionC$ select * from facebook_authorizations;
connectionA$ commit;

在我的系统上,当connectionA提交时,connectionC执行并且connectionB仍然挂起:它缺乏基于SELECT的转换执行。我期待元数据锁等待列表大致按FIFO顺序处理,但似乎并非如此。

是否有关于处理元数据等待队列的顺序的文档?

1 个答案:

答案 0 :(得分:0)

有关场景的详细信息:

试图重现此案,我阻止了会话B,然后阻止了会话C ... 请注意,如果会话B实际上在获取表上的元数据锁之前正在等待其他内容,则会话C没有理由等待。

现在,一般来说:

已授予的元数据锁在表performance_schema的{​​{1}}中可见,其中metadata_locksLOCK_STATUS

查看文档: https://dev.mysql.com/doc/refman/8.0/en/metadata-locks-table.html

这有助于查看哪个会话拥有哪个锁。

会话正在等待的元数据锁定在同一表中也可见,GRANTEDLOCK_STATUS一样。

这有助于查看会话正在等待什么。

(阻止的)会话等待某个内容的锁定,而该锁定又可能已被其他会话锁定(具有各种PENDINGLOCK_TYPE),但是没有直接的“会话X等待对于会话Y”的关系,则暗示已存在锁定。

当多个会话都在等待同一资源时,并且当该资源可用时(一个会话释放了元数据锁),试图预见处理顺序(在我看来)是有风险的,并且应用程序逻辑不应依赖关于这一点:据我所知,当前的实现确实是一个FIFO,但这可能随时更改,并且没有记录。

这里的合理性是服务器必须具有一定的自由度,以便例如出于性能原因而实施不同的调度策略是可行的。如果某种应用程序以某种方式“期望”给定的顺序,它将中断并阻止任何更改。