首页 > 数据库 >MySQL-锁等待排查

MySQL-锁等待排查

时间:2023-07-05 11:11:05浏览次数:46  
标签:lock ID 排查 MySQL mdp 锁定 等待 id SELECT

背景

最近我们的登录系统在每个钟点的 18分就会登录不进去, 排查后发现有锁等待情况 , 周期地发生那么很大几率是自动任务了, 为了找到为什么会锁等待 ,我们做了以下的排查

排查过程

-- 1.锁住的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;

-- 2.事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;

-- 3.等待的锁
SELECT * FROM information_schema.INNODB_LOCK_waits;

-- 4.当前进行的进程
SHOW FULL PROCESSLIST;

先看 1.锁住的事务 3.等待的锁


-- 1.锁住的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
+-----------------+-----------+---------+---------+--------------------+----------+----------+---------+--------+---------+
|lock_id          |lock_trx_id|lock_mode|lock_type|lock_table          |lock_index|lock_space|lock_page|lock_rec|lock_data|
+-----------------+-----------+---------+---------+--------------------+----------+----------+---------+--------+---------+
|45982383:101:7:72|45982383   |X        |RECORD   |`mdp`.`mdp_sec_user`|PRIMARY   |101       |7        |72      |1        |
|45982369:101:7:72|45982369   |S        |RECORD   |`mdp`.`mdp_sec_user`|PRIMARY   |101       |7        |72      |1        |
+-----------------+-----------+---------+---------+--------------------+----------+----------+---------+--------+---------+
           


-- 3.等待的锁
SELECT * FROM information_schema.INNODB_LOCK_waits;
+-----------------+-----------------+---------------+-----------------+
|requesting_trx_id|requested_lock_id|blocking_trx_id|blocking_lock_id |
+-----------------+-----------------+---------------+-----------------+
|45982383         |45982383:101:7:72|45982369       |45982369:101:7:72|
+-----------------+-----------------+---------------+-----------------+

图片比较好看点 :

img

可以看到 , lock_trx_id 为 45982369 , 持有的是 S锁-读锁 , 而 45982383 持有的是 X锁-写锁 , 我们知道这是冲突的, 并且从3.等待的锁可以看到 45982383 正在等待 45982369 释放锁 . 我们看一下这个 45982383 和 45982369 各是执行了什么 SQL , 导致读写锁阻塞了.

然后接着看 2.事务 4.当前进行的进程

img


img

然后我们把 SQL 复制出来

持有 S 锁 的 SQL :

INSERT INTO dataauth.ccs_data_auth_user_org (
            USER_ID,
            ORG_ID,
            ORG_CODE,
            ORG_NAME,
            SETS_OF_BOOKS_ID,
            CREATION_DATE,
            LAST_UPDATE_DATE
        ) SELECT
            u.USER_ID,
            cus.CORG_ID,
            cus.CORG_CODE,
            cus.CORG_NAME,
            u.SETS_OF_BOOKS_ID,
            now(),
            now()
        FROM
            mdp.mdp_sec_user u
        INNER JOIN mdp.mdp_sec_org_staff s ON u.USER_ID = s.USER_ID
        INNER JOIN mdp.mdp_sec_org o ON s.ORG_ID = o.ORG_ID
        INNER JOIN (
            SELECT
                c.CORG_ID,
                c.CORG_CODE,
                c.CORG_NAME,
                cl.CORG_CODE CORG_LINE_CODE,
                c.SETS_OF_BOOKS_ID
            FROM
                basedata.ccs_base_customer c,
                basedata.ccs_base_customer_line cl
            WHERE
                c.CUSTOMER_ID = cl.CUSTOMER_ID
            AND c.STORE_TYPE IN (1, 2)
            AND c.CORG_CODE IS NOT NULL
        ) cus
        WHERE
            cus.CORG_LINE_CODE LIKE concat(o.`CODE`, '%')
        AND u.SETS_OF_BOOKS_ID = cus.SETS_OF_BOOKS_ID
        ON DUPLICATE KEY UPDATE
           LAST_UPDATE_DATE = VALUES(LAST_UPDATE_DATE)

持有 X 锁 的 SQL :

update mdp.mdp_sec_user u set LAST_UPDATE_DATE = 'xx' where LOGIN_ID = 'YY' ;  

剩下的就是 SQL 优化了

SQL 字段说明

SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
  • lock_id:锁定的标识符。
  • lock_trx_id:持有锁定的事务 ID。
  • lock_mode:锁定的模式,如 SHARED、EXCLUSIVE、RECORD、TABLE 等。
  • lock_type:锁定的类型,如 RECORD、TABLE、PAGE 等。
  • lock_table:锁定的表名。
  • lock_index:锁定的索引名。
  • lock_space:锁定的表空间 ID。
  • lock_page:锁定的页码。
    需要注意的是,查询 INFORMATION_SCHEMA.INNODB_LOCKS 表需要具有相应的权限。如果您没有足够的权限,可能无法执行该查询语句。

SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
 SELECT * FROM information_schema.INNODB_LOCK_waits 
  • requesting_trx_id:正在等待锁定的事务 ID。
  • requested_lock_id:正在等待的锁定 ID。
  • blocking_trx_id:正在持有锁定的事务 ID。
  • blocking_lock_id:正在持有的锁定 ID。
  • requested_lock_type:正在等待的锁定类型,如 S、X、IS、IX 等。
  • blocking_lock_type:正在持有的锁定类型,如 S、X、IS、IX 等。
  • requested_table:正在等待锁定的表名。
  • blocking_table:正在持有锁定的表名。
  • requested_index:正在等待锁定的索引名。
  • blocking_index:正在持有锁定的索引名。

杀死阻塞进程

有时候在生产环境 ,我们不得不先杀死阻塞的线程 ,以便不阻塞生产业务.

#!/bin/bash
mysql -u root -e "show processlist" | grep -i "Locked" >> locked_log.txt

for line in `cat locked_log.txt | awk '{print $1}'`
do 
   echo "kill $line;" >> kill_thread_id.sql
done

现在kill_thread_id.sql的内容像这个样子

kill 66402982;
kill 66402983;
kill 66402986;
kill 66402991;

好了, 我们在mysql的shell中执行, 就可以把所有锁表的进程杀死了.执行上面的SQL

mysql>source kill_thread_id.sql

参考资料

  • Chatgpt

标签:lock,ID,排查,MySQL,mdp,锁定,等待,id,SELECT
From: https://www.cnblogs.com/Benjious/p/17528002.html

相关文章

  • linux问题排查方式
    1.背景有时候会遇到一些疑难杂症,并且监控插件并不能一眼立马发现问题的根源。这时候就需要登录服务器进一步深入分析问题的根源。那么分析问题需要有一定的技术经验积累,并且有些问题涉及到的领域非常广,才能定位到问题。所以,分析问题和踩坑是非常锻炼一个人的成长和提升自我能力......
  • mysql中count(*)和found_rows()的区别
    count(*)和found_rows()都可以用来求查询记录的数量而count(*)往往单独使用,found_rows()却可以跟上前面一个查询,即select*fromtablelimit10;selectfound_rows();这样的总共可分为几个区别:1.count(*)查询的无论是否为空,都会计数,而found_rows()却不是......
  • ElasticSearch - 批量更新bulk死锁问题排查
    一、问题系统介绍监听商品变更MQ消息,查询商品最新的信息,调用BulkProcessor批量更新ES集群中的商品字段信息;由于商品数据非常多,所以将商品数据存储到ES集群上,整个ES集群共划分了256个分片,并根据商品的三级类目ID进行分片路由。比如一个SKU的商品名称发生变化,我们就会收到......
  • MySQL Router 使用案例
    MySQLRouter通常会使用两个端口来处理读操作和写操作。要在Python中与MySQLRouter和MySQLReplicaSet搭配使用,并利用MySQLRouter的两个端口,您可以按照以下步骤进行配置:1.启动MySQLRouter:首先,启动MySQLRouter服务,并为读操作和写操作分别指定不同的端口。例如,您可以使用以下......
  • MySQL存储过程
    --存储过程delimiter$--声明结束符号CREATEPROCEDUREpro_test1()BEGINSELECT'HelloMySQL';END$delimiter;--声明结束符号CALLpro_test1();--调用存储过程DROPPROCEDUREpro_test1;--删除存储过程CREATEPROCEDUREpro_test1()BEGIN......
  • Nginx+Uwsgi+Django+Mysql部署项目
    第一章、准备工作第1节、创建项目目录准备好项目代码,将代码上传至myprojectmkdirmyproject第2节、安装python3cd/usr/local/mkdirPythonwgethttps://www.python.org/ftp/python/3.8.0/Python-3.8.0.tgztar-zxvfPython-3.8.0.tgzmkdir/usr/local/Python/py3_p......
  • navicat添加触发器实现禁止删除指定表的记录(mysql)
     选中指定表,右键选择设计表 在定义那儿填写语句 BEGINdeclaremsgvarchar(255);setmsg="禁止删除操作";SIGNALSQLSTATE'HY000'SETMESSAGE_TEXT=msg;END......
  • MySQL中创建触发器需要执行哪些操作?
    什么是触发器触发器,就是一种特殊的存储过程。触发器和存储过程一样是一个能够完成特定功能、存储在数据库服务器上的SQL片段,但是触发器无需调用,当对数据库表中的数据执行DML操作时自动触发这个SQL片段的执行,无需手动调用。触发器的这种特性可以协助应用在数据库端确保数据的完整......
  • 搞定MySQL,都是干货
    MySQL数据库简介MySQL近两年一直稳居第二,随时有可能超过Oracle计晋升为第一名,因为MySQL的性能一直在被优化,同时安全机制也是逐渐成熟,更重要的是开源免费的。MySQL是一种关系数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高......
  • 关于mysql存储引擎、管理和维护概述
    数据库的存储引擎是数据库的底层软件组件,数据库管理系统使用数据库引擎进行增删查改的操作。mysql的核心就是数据库引擎。mysql5.7支持的存储引擎有innoDBMyISAMMemory可以通过showengines。InnoDB存储引擎:1.InnoDB给mysql提供了具有提交,回滚,崩溃恢复的功能的事务能力的安......