注册
表被锁了不要慌,动态视图来帮忙
专栏/金的探索记录/ 文章详情 /

表被锁了不要慌,动态视图来帮忙

2021/01/14 3738 10 1
摘要 本文介绍如何使用对应的动态性能视图查看阻塞以及如何解决阻塞。

大家知道,达梦数据库支持多用户并发访问、修改数据。在实际工作中,有可能出现多个事务同时访问、修改相同数据的情况,当一个事务正在占用某个资源的锁,此时另一个事务正在请求这个资源上与第一个锁相冲突的锁类型时,就会发生阻塞。此时,被阻塞的事务将一直挂起,直到持有锁的事务放弃锁定的资源为止。本文介绍如何使用对应的动态性能视图查看阻塞以及如何解决阻塞。

本文实验环境:演示环境:DM Database Server x64 V7.1.6.46-Build(2018.02.08-89107)ENT

创建测试表并插入数据

CREATE TABLE T1("ID" INT,"NAME" VARCHAR(50)) 录入实验数据: begin for i in 1..100 loop insert into t1 valuse(1,'dameng'||i); end loop; commint; end;

在 T1 上面生成 TID 锁

执行 update 操作并且不提交,具体操作如下:

update t1 set name='AAA' WHERE ID=1;

2.png

开启新会话

在新会话下执行 select 操作。

select * from t1;

3.png

可以看到,由于 MVCC 的多版本机制,写不会阻塞读,所以 select 操作可以正常进行。但是前面的事务没有提交,所以查出来的结果还是旧版本的值,也就是 update 之前的值。

在新会话下执行DML操作

DELETE FROM T1 WHERE ID=1;

4.png

此时,由于 delete 操作需要加上与之前 update 操作相同类型的锁,所以阻塞发生,当前事务被挂起。

阻塞的排查

当阻塞发生时,我们可以通过 v$lock 视图查到当前数据库中锁的状态。

SELECT * FROM V$LOCK;

5.png

结果中我们可以看到,事务 2399 被阻塞了,阻塞他的事务为 2393,同样我们也可以通过 V$TRXWAIT 视图查找谁阻塞谁。

SELECT * FROM V$TRXWAIT;

6.png

得出同样的结果,ID 为 2399 的事务正在等待 ID 为 2393 的事务,等待时间是 1071599 毫秒。接下来,通过 V$SESSIONS 视图查找两个事务对应的会话。

SELECT sess_id,sql_text,state,trx_id FROM V$SESSIONS;

7.png

可以得到两个事务对应的会话 ID 和当前执行 SQL 语句,可以知道是哪些 SQL 语句产生的阻塞。

阻塞的解决方法

根据需求,可以有两种解决方案。

  1. 提交或回滚产生阻塞的事务。

根据上文,我们可知产生阻塞的事务会话 ID 为 2410147992 。此时,我们只需要在该会话下提交或回滚事务,锁自然会被释放,阻塞解决。

  1. 关闭产生阻塞的会话

同样,我们也可以使用系统过程 SP_CLOSE_SESSION(SESS_ID) 来关闭对应的会话,具体使用方法如下。

SP_CLOSE_SESSION(2410147992);

8.png

此时,锁被释放,delete 操作也可以顺利进行下去。

DELETE FROM T1 WHERE ID=1;

9.png

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服