MYSQL 8 从锁开始 监控你的锁,死锁,死锁的详细信息

本文介绍如何利用MySQL的performance_schema来分析锁的竞争情况,包括如何查询当前的锁状态及锁定中的语句,以及如何深入分析死锁的原因。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1fdf161b9f49352006561eb7da63035f.png

MYSQL 中有一个重要的特性就是锁,如何认识到锁的概念对于使用MYSQL有着重要的意义,针对与锁的认识,以及发现我们需要通过MYSQL本身的performance_schema  中的表来了解,不熟悉这一个系列的同学可以去从之前的performance_schema 系列里面去了解performance_schema的日常使用。MYSQL的锁可以从 metadata 和 表锁开始。

下面的这个查询就对

select ss.thd_id,ss.conn_id,ss.user,ss.statement_latency,ss.lock_latency,ss.full_scan,
ss.current_memory,ss.trx_autocommit,ss.program_name,ml.object_name,ml.object_schema,
ml.lock_type,ml.lock_status,ss.current_statement
from performance_schema.metadata_locks as ml
left join sys.session as  ss on ml.owner_thread_id = ss.thd_id
where ml.object_type = 'table' and ml.object_name in  ('session');

733db0c219ddce026b6e6296c1a7c364.png

上面的查询可以获得当前查询中的查询语句中正在获得的锁的形式以及内存消耗等。

下面的语句可以从performance_schema 中获得当前的查询中因为锁而正在锁定中的语句中所需的表,分为正在等待的访问的线程和正在阻挡这个线程运作的线程,当然可以稍微的在变化一下,就可以获得两个操作的语句,这里就不在网下扩展了。

SELECT OBJECT_TYPE, OBJECT_SCHEMA, OBJECT_NAME,
w.OWNER_THREAD_ID AS WAITING_THREAD_ID,
b.OWNER_THREAD_ID AS BLOCKING_THREAD_ID
FROM performance_schema.metadata_locks w
INNER JOIN performance_schema.metadata_locks b
USING (OBJECT_TYPE, OBJECT_SCHEMA, OBJECT_NAME)
WHERE w.LOCK_STATUS = 'PENDING'
AND b.LOCK_STATUS = 'GRANTED';SELECT OBJECT_TYPE, OBJECT_SCHEMA, OBJECT_NAME,
w.OWNER_THREAD_ID AS WAITING_THREAD_ID,
b.OWNER_THREAD_ID AS BLOCKING_THREAD_ID
FROM performance_schema.metadata_locks w
INNER JOIN performance_schema.metadata_locks b
USING (OBJECT_TYPE, OBJECT_SCHEMA, OBJECT_NAME)
WHERE w.LOCK_STATUS = 'PENDING'
AND b.LOCK_STATUS = 'GRANTED';

基于上面的查询,实际上我们可以获得数据库中你想查看的当前查询语句的锁的问题,以及当前如果有语句之间产生BLOCK 的成因在哪里。

那么除此以外,我们在MYSQL的操作中的死锁的问题,怎么分析在MYSQL8 中祭出了表

1 data_lock_waits

2 data_locks

两个表

查询当前表中是否有死锁或锁的block,需要从data_lock_waits中获取信息,我们模拟一个死锁的场景,下面可以直接通过data_lock_waits 来获取到当时的一个信息,这个信息就是被最后被KILL掉的那个查询的信息。

主要就是两个点

1   requesting_thread_id

2   blocking_thread_id

我们即添加一些东西,就可以直接展示出死锁当时的情况。

f1ca2313b2f808d14abd25414e06fcc3.png

select  dlw.REQUESTING_ENGINE_LOCK_ID,ss.thd_id,ss.current_statement,ss.last_statement,'killed_statement'
from  performance_schema.data_lock_waits as dlw
left join sys.session as ss on ss.thd_id = REQUESTING_THREAD_ID
union all
select  dlw.REQUESTING_ENGINE_LOCK_ID,ss.thd_id,ss.current_statement,ss.last_statement,'kill_statement'
from  performance_schema.data_lock_waits as dlw
left join sys.session as ss on ss.thd_id = BLOCKING_THREAD_ID;

79d8c97d25dc5f10d83bac3d910e40c5.png

从截图上看我们可以在死锁发生的瞬间,执行这个语句,并抓到当时死锁时的一刻发生了什么并且将那个语句将那个语句killed 看的一清二楚。

当然如果对此还不满足的情况下,那么我们可以在通过 data_locks 进行更深度的分析。

select  dlw.REQUESTING_ENGINE_LOCK_ID,ss.thd_id,ss.current_statement,ss.last_statement,'killed_statement',dl.index_name,dl.lock_type,dl.lock_mode
from  performance_schema.data_lock_waits as dlw
left join sys.session as ss on ss.thd_id = REQUESTING_THREAD_ID
left join performance_schema.data_locks as dl on ss.thd_id = dl.thread_id
union all
select  dlw.REQUESTING_ENGINE_LOCK_ID,ss.thd_id,ss.current_statement,ss.last_statement,'kill_statement',dl.index_name,dl.lock_type,dl.lock_mode
from  performance_schema.data_lock_waits as dlw
left join sys.session as ss on ss.thd_id = BLOCKING_THREAD_ID
left join performance_schema.data_locks as dl on ss.thd_id = dl.thread_id;

fab6987685eb47eb6c409963745c48ab.png

从图中看到,我们在操作同一个表,并且我们在操作同一个记录,此时我们的死锁发证在行锁,在同一个行中发生了互斥,导致上面的93号的线程中的信息被KILLED 。

锁的信息标注了,产生的是X行锁。 

以上的查询对于我们的分析死锁,以及成因有着很大的帮助。

e1549285dfc5885512a9ffaabd0a9703.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值