欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

MySQL关于table_lock_wait和table_lock_immediate_MySQL

程序员文章站 2022-04-04 14:19:52
...
bitsCN.com

MySQL关于table_lock_wait和table_lock_immediate

前记

前几天收到一位同行的一个文档,是MySQL High Performance 2的读书笔记, 97页,6w多字。在描述完知识点后,有疑问的地方列出问题,希望和我讨论。看完以后非常敬佩,自感自己无法做到这么细心。为表敬意,承诺会一一回答里面的问题。对于无法简单回复的问题,就想通过博客的方式写出来,便于讨论。

因此这个系列,就是回复这位同学的文档中的问题的。

问题

服务器变量table_locks_immediate和 table_locks_waited#?它们保持多大的比例是合适的?

背景

table_locks_immediate表示可以立即获取锁的查询次数, table_locks_waited表示不能立即获取锁的次数;

Session 1

Session 2

lock tables t1 read;

(table_locks_immediate+1)

update t1 set y=1 where id=1;

(locked并且table_locks_waited+1)

上面这个例子很简单,session 1加了表所,但是session 2要更新,获取表锁失败。

异象

Session 1

Session 2

lock tables t1 write;

(table_locks_immediate+1)

update t1 set y=1 where id=1;

(locked但table_locks_waited不变)

这个例子看上去像个bug,session 1锁表,session 2试图更新这个表,被锁住了,但是table_locks_waited没有加1,而且查看table_locks_immediate也不变。

其原因是5.5新引入的metadata lock(MDL),对表的访问都需要获取MDL。在这个例子中,session 1拥有一个排他MDL,因此Session2是被锁在获取MDL的阶段。

由于MDL是在获取表锁之前,因此在session 2被lock的时,上述两个变量都不变。

什么情况下会触发table_locks_waited

从上面这个例子看,引入MDL以后,table_locks_waited并不容易触发。除非应用主动作lock tables t read。

我们用并发压力,两个线程分别执行update t1 set y=y+1 where id=1;各5000次。

若t1为MyISAM表,MyISAM是表锁,在并发压力下,是会导致table_locks_waited急剧增加。

而在InnoDB表,由于是行锁,因此获取表锁这个逻辑都能顺利通过,因此table_locks_waited不变。

table_locks_waited多少合适

回到初始的问题,若库中都是InnoDB的表,在5.5以后,table_locks_waited这个值应该很小。在mysqldump导出表时,会执行lock table,可能导致此值增加。其他情况下,若这个值有变,说明应用端主动作了lock table,这个在InnoDB表上是不需要的,需要应用修改。

bitsCN.com