达梦数据库-学习-12-锁等待排查

目录

一、环境信息

二、介绍

三、数据字典表

1、V$SESSIONS

2、V$LOCK

四、系统存储过程

1、SP_CLOSE_SESSION

(1)声明

(2)说明

五、定位锁SQL

六、锁类型

七、锁模式

1. X 锁(排他锁,Exclusive Lock)

2. IX 锁(意向排他锁,Intent Exclusive Lock)

3. S 锁(共享锁,Shared Lock)

4. IS 锁(意向共享锁,Intent Shared Lock)

5. 锁的兼容性

八、小实验

1、会话一执行SQL正常

2、会话二执行SQL卡住

3、会话三查询锁

4、会话三杀死持锁会话

5、会话二执行SQL正常

6、会话一断开连接

7、查看锁


一、环境信息

名称
CPU12th Gen Intel(R) Core(TM) i7-12700H
操作系统CentOS Linux release 7.9.2009 (Core)
内存2G
逻辑核数2
DM版本1          DM Database Server 64 V8
2          DB Version: 0x7000c
3          03134284194-20240703-234060-20108
4          Msg Version: 12
5          Gsu level(5) cnt: 0

二、介绍

在工作中我们经常会遇到锁等待导致的生产问题,例如:并发度低、应用执行SQL卡住等等,如何快速定位锁成了我们解决问题的关键。

三、数据字典表

1、V$SESSIONS

显示当前会话的具体信息,如执行的 sql 语句、主库名、当前会话状态、用户名等等。
字段名描述
SESS_ID会话 ID,系统内部标识
SESS_SEQ会话序列号,每创建一个会话,系统自动为其生成一个全局递增的序列号
SQL_TEXT取 sql 的头 1000 个字符
STATE会话状态。

CREATE 创建,表示会话对象已创建,但还不能使用;

STARTUP 启动,表示会话正在启动中;

IDLE 空闲,表示会话当前没有执行操作;

ACTIVE 活动,表示会话当前正在执行操作;

PENDING 限流等待,当 INI 参数MAX_CONCURRENT_TRX>0 时,会话可能会因为并行事务限流而处于此状态;

FREEING 正在释放,表示会话正在被释放;
N_STMTSTMT 的容量
N_USED_STMT已使用的 STMT 数量
SEQ_NO会话上语句的序列号
CURR_SCH当前模式
USER_NAME当前用户
TRX_ID事务 id,为 0 表示事务未开始或事务已结束
CREATE_TIME会话创建时间
CLNT_TYPE客户端类型(4 种)
TIME_ZONE时区
CHK_CONS是否忽略约束检查
CHK_IDENT是否忽略自增列指定列表检查
RDONLY是否是只读会话
INS_NULL列不存在 default 选项,是否插入空值
COMPILE_FLAG是否忽略编译选项,用于 view,procedure,trigger……的编译
AUTO_CMT是否自动提交
DDL_AUTOCMTDdl 语句是否自动提交
RS_FOR_QRY非查询语句生成结果集标记
CHK_NET是否检查网络
ISO_LEVEL隔离级。

0:读未提交;

1:读提交;

2:可重复读;

3:串行化
CLNT_HOST客户端主机名
APPNAME应用程序名
CLNT_IP客户端 IP
OSNAME客户端操作系统名
CONN_TYPE连接类型
VPOOLADDR内存池的首地址
RUN_STATUS记录运行状态,可能值为“IDLE”与“RUNNING”
MSG_STATUS记录消息处理状态,可能值为“RECEIVE”(已接受)与“SEND”(已发送)
LAST_RECV_TIME记录最近接收的消息时间
LAST_SEND_TIME记录最近发送的消息时间
DCP_FLAG1) 是否是通过 DCP_PORT登录 DCP 服务器的会话,Y 表示是,N 表示否

2) 是否是通过 DCP 代理连接到 MPP 的会话,Y 表示是,N 表示否
THRD_ID线程 ID
CONNECTED连接是否正常:

1 表示连接正常,

0 表示连接已经关闭
PORT_TYPE连接端口类型:

2 表示 TCP 连接

12 表示端口已经关闭

13 表示 UDP 连接
SRC_SITE源节点,65535 表示本地 SESSION,其他值代表 MPP集群用户直接登录的节点号
MAL_ID邮箱 ID
CONCURRENT_FLAG是否占用了限流资源
CUR_LINENO存储过程执行时记录当前的行号
CUR_MTDNAME存储过程执行时记录当前的方法名
CUR_SQLSTR存储过程执行时记录当前执行的 SQL 的前 100 个字符
CLNT_VER登记登录接口程序的版本号
SQL_ID对应的语句 ID,为-1 表示会话当前没有执行 SQL,显示的 SQL 为上次执行的 SQL 信息
EIDDPC 环境下会话的全局 ID
CLIENT_INFO显示通过系统包方法dbms_application_info.set_client_info('当前会话的客户端信息')设置的当前会话的客户端信息
CLIENT_IDENTIFIER显示通过系统包方法 dbms_session.set_identifier('
当前会话 ID')设置的当前会话 ID
MODULE显示通过系统包方法
dbms_application_info.set_module('当前会话运行的模块名称')设置的当前会话运行的模块名称
ACTION显示通过系统包方法
dbms_application_info.set_action('当前模块正
在执行的事务名称')设置的当前模块正在执行的事务名称
HEART_BEAT_INTERVAL心跳间隔时间
HEART_BEAT_TIMEOUT心跳超时时间
TMP_USED_TYPE显示会话中使用的临时表空间的类型(如 BTR、BLOB、MTAB、BACKUP 等),存在多个类型时,不同类型用“/”隔开(如BTR/BLOB)
TMP_USED_EXTENT_NUM显示会话中使用的临时表空间所占用的总簇数

2、V$LOCK

显示活动的事务锁信息。
字段名描述
ADDR锁地址
TRX_ID所属事务 ID
LTYPE锁类型:TID 锁、对象锁
LMODE锁模式:S 锁、X 锁、IX 锁、IS 锁
BLOCKED是否阻塞。0 表示已上锁成功,非阻塞;1 表示处于上锁等待状态,阻塞
TABLE_ID对于对象锁,表示表对象或字典对象的 ID;对于 TID 锁,表示封锁记录对应的表 ID。-1 表示事务启动封锁自身的 TID
ROW_IDXTID 锁封锁记录行信息。-1 表示事务启动封锁自身的 TID
TIDTID 锁对象事务 ID
IGN_FLAG锁对象的 IGNORABLE 标记,INI 参数 LOCK_DICT_OPT 开启时有效。

取值 0:表示锁正在使用中,IGN_FLAG 最低位置为 0;

取值 1:表示事务 TRX1 已经提交,但是锁资源未释放,TRX1 重新封锁时可以直接使用,此时 IGN_FLAG 最低位置为 1;

取值 2:为 0+2 的组合值。当锁正被使用时,另一事务要封锁同一对象,将当前正被使用的锁的 IGN_FLAG 次低位置为 1;

取值 3:为 1+2 的组合值。当 TRX1 已提交,但锁未释放时,另一事务TRX2 要封锁同一对象,此时 TRX2 可以忽略此IGN_FLAG=1 的锁,但是要将此锁的 IGN_FLAG 次低位置为 1
HLCK_EP关联对象 HLCK 所属节点号。DSC 集群环境标识创建 HLCK 对象的节点号,缺省为 255,单机无效
SPT_NO关联的保存点序号
THRD_ID线程号

四、系统存储过程

1、SP_CLOSE_SESSION

(1)声明

SP_CLOSE_SESSION(INT SESSION_ID);

(2)说明

根据SESSION_ID杀死对应会话。

五、定位锁SQL

SELECT
A.*,
B.SESS_ID,B.SQL_TEXT,B.USER_NAME,B.CLNT_IP,
C.SESS_ID,C.SQL_TEXT,C.USER_NAME,C.CLNT_IP
FROM (SELECT TRX_ID,LTYPE,LMODE,TID FROM V$LOCK WHERE BLOCKED = 1) A 
JOIN V$SESSIONS B ON A.TRX_ID = B.TRX_ID
JOIN V$SESSIONS C ON A.TID    = C.TRX_ID;
别名描述
A锁信息
B等待锁的会话信息
C持有锁的会话信息

六、锁类型

特性TID 锁(事务锁)对象锁
锁定对象单行数据整个数据库对象(如表、索引、分区等)
粒度行级锁对象级锁
作用范围控制事务对单行数据的并发访问控制事务对数据库对象的并发访问
使用场景UPDATEDELETESELECT FOR UPDATEDDL 操作(如 ALTER TABLEDROP TABLE
并发度
生命周期与事务生命周期一致与操作生命周期一致

七、锁模式

1. X 锁(排他锁,Exclusive Lock)

  • 定义
    X 锁是排他锁,表示事务对资源(如表、行、块等)拥有独占访问权限。

  • 作用
    当一个事务对资源加 X 锁后,其他事务不能对该资源加任何类型的锁(包括 S 锁、X 锁、IX 锁等),直到该事务释放锁。

  • 使用场景

    • 对数据进行修改操作时(如 UPDATEDELETEINSERT)。

    • 对表结构进行修改时(如 ALTER TABLE)。

  • 特点

    • 排他性强,确保事务对资源的独占访问。

    • 锁的粒度可以是行级、表级,具体取决于操作和锁模式。


2. IX 锁(意向排他锁,Intent Exclusive Lock)

  • 定义
    IX 锁是意向排他锁,表示事务有意向在更细粒度的资源上加 X 锁。

  • 作用
    IX 锁是一种表级锁,用于通知其他事务:当前事务可能会对表中的某些行或块加 X 锁。

  • 使用场景

    • 当事务需要对表中的某些行或块加 X 锁时,会先对表加 IX 锁。

    • 用于提高锁管理的效率,避免其他事务对整个表加不兼容的锁。

  • 特点

    • 是一种表级锁,表示事务的“意向”。

    • 不直接锁定数据,而是为后续的 X 锁做铺垫。


3. S 锁(共享锁,Shared Lock)

  • 定义
    S 锁是共享锁,允许多个事务同时读取资源,但不允许修改。

  • 作用
    当一个事务对资源加 S 锁后,其他事务可以对该资源加 S 锁,但不能加 X 锁。

  • 使用场景

    • 对数据进行只读操作时(如 SELECT)。

    • 允许多个事务同时读取同一资源。

  • 特点

    • 允许多个事务共享读取权限。

    • 与 X 锁不兼容,与 S 锁和 IS 锁兼容。


4. IS 锁(意向共享锁,Intent Shared Lock)

  • 定义
    IS 锁是意向共享锁,表示事务有意向在更细粒度的资源上加 S 锁。

  • 作用
    IS 锁是一种表级锁,用于通知其他事务:当前事务可能会对表中的某些行或块加 S 锁。

  • 使用场景

    • 当事务需要对表中的某些行或块加 S 锁时,会先对表加 IS 锁。

    • 用于提高锁管理的效率,避免其他事务对整个表加不兼容的锁。

  • 特点

    • 是一种表级锁,表示事务的“意向”。

    • 不直接锁定数据,而是为后续的 S 锁做铺垫。


5. 锁的兼容性

以下是 X 锁、IX 锁、S 锁和 IS 锁之间的兼容性:

请求锁 \ 现有锁ISIXSX
IS兼容兼容兼容不兼容
IX兼容兼容不兼容不兼容
S兼容不兼容兼容不兼容
X不兼容不兼容不兼容不兼容
  • IS 锁 和 IX 锁 是意向锁,用于表示事务的意向,不直接锁定数据。

  • S 锁 和 X 锁 是实际锁定数据的锁。

八、小实验

1、会话一执行SQL正常

SQL> UPDATE ZXJ.TEST SET A = 10 WHERE A = 8;
影响行数 1

已用时间: 2.664(毫秒). 执行号:1203.

我们没有提交数据,所以数据库在TEST表的A=8这一行上加了行排他锁。

2、会话二执行SQL卡住

SQL> UPDATE ZXJ.TEST SET A = 1 WHERE A = 8;

因为会话二也想更新A=8这一行数据,也需要加行排他锁,因为行排他锁是互斥的,所以会话二进行等待。

3、会话三查询锁

SQL>
SELECT 
A.*,
B.SESS_ID,B.SQL_TEXT,B.USER_NAME,B.CLNT_IP,
C.SESS_ID,C.SQL_TEXT,C.USER_NAME,C.CLNT_IP
FROM (SELECT TRX_ID,LTYPE,LMODE,TID FROM V$LOCK WHERE BLOCKED = 1) A 
JOIN V$SESSIONS B ON A.TRX_ID = B.TRX_ID
2   3   4   5   6   7   JOIN V$SESSIONS C ON A.TID    = C.TRX_ID;

行号     TRX_ID               LTYPE LMODE TID                  SESS_ID              SQL_TEXT                               USER_NAME
---------- -------------------- ----- ----- -------------------- -------------------- -------------------------------------- ---------
           CLNT_IP   SESS_ID              SQL_TEXT                                USER_NAME CLNT_IP                    
           --------- -------------------- --------------------------------------- --------- ---------------------------
1          32070                TID   X     32069                140544886022640      UPDATE ZXJ.TEST SET A = 1 WHERE A = 8; SYSDBA
           ::1:43834 153575616            UPDATE ZXJ.TEST SET A = 10 WHERE A = 8; SYSDBA    ::ffff:192.168.217.66:47334


已用时间: 1.976(毫秒). 执行号:1032.
名字会话IDSQL
持锁会话153575616UPDATE ZXJ.TEST SET A = 10 WHERE A = 8;行排他锁
等锁会话140544886022640UPDATE ZXJ.TEST SET A = 1 WHERE A = 8;

4、会话三杀死持锁会话

因为会话一持锁,执行SQL不提交数据,所以我们选择杀死会话一。

SQL> SP_CLOSE_SESSION(153575616);
DMSQL 过程已成功完成
已用时间: 0.804(毫秒). 执行号:1033.

5、会话二执行SQL正常

SQL> UPDATE ZXJ.TEST SET A = 1 WHERE A = 8;
影响行数 1

已用时间: 00:03:40.118. 执行号:803.

6、会话一断开连接

SQL> SELECT * FROM V$LOCK LIMIT 10;

服务器[192.168.217.66:5238]:处于普通打开状态
已连接

7、查看锁

锁消失,那这个锁等待的问题我们就已经解决啦,但这只是一个治标不治本的的问题,根本的原因还是为什么会话一(或者说应用)为什么长期持有锁不释放,是业务逻辑需要还是逻辑漏洞,需要和应用研发沟通此事。

SQL> 
SELECT
A.*,
B.SESS_ID,B.SQL_TEXT,B.USER_NAME,B.CLNT_IP,
C.SESS_ID,C.SQL_TEXT,C.USER_NAME,C.CLNT_IP
FROM (SELECT TRX_ID,LTYPE,LMODE,TID FROM V$LOCK WHERE BLOCKED = 1) A 
JOIN V$SESSIONS B ON A.TRX_ID = B.TRX_ID
2   3   4   5   6   7   JOIN V$SESSIONS C ON A.TID    = C.TRX_ID;
未选定行

已用时间: 0.479(毫秒). 执行号:1037.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值