mysql 查看阻塞_MySQL8.0怎么找出阻塞源头

阻塞,MySQL中非常让人头疼的问题,因为锁资源之间的兼容关系,当一个事务需要等待另一事务所持有的锁的时候,便产生了阻塞,当数据库中存在大量阻塞的时候,导致CPU使用率飙升,整个系统的响应速度变慢。不过MySQL提供了参数innodb_lock_wait_timeout来限制锁等待时间,该参数默认值为50s,我们可以设置innodb_lock_wait_timeout为5s或者3s,这样锁等待时间不会太长。但这是治标不治本的方法,根本解决办法还是要找到产生阻塞的源头,从业务逻辑上避免产生阻塞。

在mysql5.7中,可以通过以下SQL来找出产生阻塞的语句:

select

b.trx_mysql_thread_id , – 被阻塞的会话ID

b.trx_query , – 被阻塞的SQL

c.trx_mysql_thread_id , – 造成阻塞的会话ID

c.trx_query,d.lock_mode , – 造成阻塞的SQL

lock_type, – 锁类型

lock_table , – 阻塞的表

lock_index – 阻塞的索引

from

performance_schema.innodb_lock_waits a

inner join performance_schema.innodb_trx b on a.requesting_trx_id=b.trx_id

inner join performance_schema.innodb_trx c on a.blocking_trx_id =c.trx_id

inner join performance_schema.innodb_locks d on a.blocking_lock_id=d.lock_id;

但是在mysql8.0中innodb_lock_waits,innodb_trx 这两张表被删除了,取而代之的是在performance_schema库中增加data_lock_waits,data_locks这两张表。先通过官方文档来解读一下这两张表。

data_locks:

该表显示了所有请求中和已经持有的锁。

列名

含义

ENGINE

存储引擎

ENGINE_LOCK_ID

锁的ID

ENGINE_TRANSACTION_ID

存储引擎内部ID

THREAD_ID

trx_id

EVENT_ID

会话ID

OBJECT_SCHEMA

数据库名称

OBJECT_NAME

表名称

PARTITION_NAME

分区名称

SUBPARTITION_NAME

子分区名称

INDEX_NAME

索引名称

OBJECT_INSTANCE_BEGIN

锁的内存中的地址

LOCK_TYPE

锁的类型

LOCK_MODE

如何请求锁定

LOCK_STATUS

请求状态

LOCK_DATA

锁定数据量

了解详细信息请参见官方文档:https://dev.mysql.com/doc/refman/8.0/en/performance-schema-data-locks-table.html

innodb_lock_waits:

该表显示了存在锁等待即阻塞的信息

列名

含义

ENGINE

存储引擎

REQUESTING_ENGINE_LOCK_ID

被阻塞锁的ID

REQUESTING_ENGINE_TRANSACTION_ID

被阻塞的trx_id

REQUESTING_THREAD_ID

被阻塞会话的线程ID

REQUESTING_EVENT_ID

被阻塞事件

REQUESTING_OBJECT_INSTANCE_BEGIN

内存地址

BLOCKING_ENGINE_LOCK_ID

造成阻塞锁ID

BLOCKING_ENGINE_TRANSACTION_ID

被阻塞trx_id

BLOCKING_THREAD_ID

阻塞会话的线程ID

BLOCKING_EVENT_ID

造成阻塞事件

BLOCKING_OBJECT_INSTANCE_BEGIN

内存地址

了解详细信息请参见官方文档:https://dev.mysql.com/doc/refman/8.0/en/performance-schema-data-lock-waits-table.html

现在通过锁等待信息表(innodb_lock_waits)和锁详细信息表(data_locks)以及详细事务信息的表(INNODB_TRX)查询出系统中存在阻塞的SQL和锁定的资源:

SELECT

b.trx_query,

c.trx_query,

c.OBJECT_SCHEMA,

OBJECT_NAME,

INDEX_NAME

FROM

performance_schema.data_lock_waits a

LEFT JOIN

information_schema.INNODB_TRX b ON a.REQUESTING_ENGINE_TRANSACTION_ID = b.trx_id

LEFT JOIN

information_schema.INNODB_TRX c ON a.BLOCKING_ENGINE_TRANSACTION_ID = c.trx_id

LEFT JOIN

performance_schema.data_locks c ON a.REQUESTING_ENGINE_LOCK_ID = c.ENGINE_LOCK_ID

例如:

首先将MySQL的innodb_lock_wait_timeout参数设置为600方便观察:

set global innodb_lock_wait_timeout=6000;

在session1 执行SQL:

begin:

update t_mysql_instances set f_port=3308 where f_id =1;

在session2 执行SQL:

begin:

select *from t_mysql_instances where f_id=1 for update ;

此时可以看到的现象为:

session1 :

0a057ab8eb35ada6e1504f49bdb7a9b5.png

session2:

969f146d3b6808ee49a50defb5d5c6a9.png

可以看到session执行完成,但是未提交,session2 处于执行中状态,因为session1现在仍然持有锁,所以session2被阻塞。查看阻塞:

f82e95b6690f97f73293c0adc848fb65.png

可以看到被阻塞的SQL,但是此时造成阻塞的SQL已经执行完成但是未提交,所以在information_schema.INNODB_TRX中无法查看,可以通过performance_schema.events_statements_current查询:

select *from performance_schema.events_statements_current where event_id=23;

9b9064d8e56b91b854df2100c2321265.png

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL 8.0中,sql_mode=only_full_group_by是一种SQL模式,它使得在执行GROUP BY时,SELECT列表中的非聚合列必须出现在GROUP BY子句中。这是为了确保查询结果的准确性和一致性。然而,这也可能导致一些查询出错,例如在SELECT列表中包含了非聚合列并且没有在GROUP BY子句中列出。引用 要解决这个问题,有两种方法可以尝试。首先,你可以修改全局设置,这样对于新建的数据库会有效。你可以执行以下命令:SET @@global.sql_mode ='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'; 引用 另外,如果你想对已存在的数据库生效,你需要在对应的数据库下执行以下命令:SET sql_mode ='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'; 引用 举个例子,如果你想在mt_user表中根据mobile字段进行分组,并且只显示那些mobile字段的值重复超过一次的记录,你可以执行以下查询:select id,mobile from mt_user group by mobile having count(1)>1; 但是,由于sql_mode设置为only_full_group_by,这个查询会报错,因为SELECT列表中的id字段没有在GROUP BY子句中列出。引用 因此,为了解决这个问题,你可以按照上述方法修改sql_mode设置,将only_full_group_by从中移除。这样就可以执行这个查询并得到正确的结果了。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [MySQL 8.0 修改 sql_mode=only_full_group_by](https://blog.csdn.net/qq_35349114/article/details/108277591)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值