注册
DM数据库中的锁超时和锁等待
专栏/培训园地/ 文章详情 /

DM数据库中的锁超时和锁等待

LEO(ಡωಡ) 2023/10/09 4019 3 0
摘要

锁超时

DM数据库对于DDL操作引起的锁的解决方案分为两种方法,方法一:是在业务低峰期延长锁超时时间,以及开启快速加列、修改列、删除列提高DDL操作的成功率;方法二:是在无业务情况下,清理干扰会话,进行DDL操作维护。

1、模拟锁超时的情况

会话一:向表TEST插入一条语句,INSERT操作成功,但未提交,此刻模拟业务表上DML操作频繁,这是一个长事务语句
SQL> insert into TEST values(3,'AAA');

会话二:向表TEST添加一个字段,此时会报“[-6407]:Lock timeout”的错误,即锁超时错误,添加字段的擦着不会成功
SQL> alter table TEST add column address varchar(100);
alter table TEST add column address varchar(100);
[-6407]:Lock timeout.

2、提高DDL操作的成功率

在日常工作中,一般不会允许停业务来进行DDL维护操作,因为停止业务的代价会比较高,对于复杂的系统,停机维护更是充满了不可控的隐患和危险。DM数据库可以采用延长锁超时的时间,以及开启快速加列、修改列、删除列提高DDL操作的成功率。DM数据库的DDL操作的锁超时时间缺省为10秒,手动进行动态调整,延长至60秒,以期尽可能的获取业务表的锁,具体操作如下:

参数名 缺省值 属性 说明
DDL_WAIT_TIME 10 动态,会话级 DDL操作的锁超时时间,以秒为单位。有效值围(0~60)

除此之外还可配合ALTER_TABLE_OPT参数共同使用,尤其在面对大表的时候,效果会出奇的好。参数ALTER_TABLE_OPT可以对加列、修改列、删除列操作进行优化,如下:

参数名 缺省值 属性 说明
ALTER_TABLE_OPT 0 动态,会话级 是否对加列、修改列、删除列操作进行优化, 0:全部不优化; 1:全部优化; 2: 打开快速加列,对于删除列和修改列与1等效; 3: 打开快速加列,允许指定快速列默认值,其他功能与2时相同

动态参数,可以在数据库中实时设置和实时生效,不需要重启数据库:会话级参数,仅仅在当前会话有效,不会影响到其他会话。延长达梦数据库的DDL操作的锁超时时间至60秒,并开启快速加列、修改列、删除列:

在会话一的窗口内,延长达梦数据库的DDL操作的锁超时时间至60秒,再次回到会话二,争取在锁超时的60秒时间内获取到业务表的锁,就可以进行快速DDL维护操作:
会话1:
SQL> SP_SET_PARA_VALUE (1, 'DDL_WAIT_TIME', 60); 
DMSQL executed successfully 
used time: 8.970(ms). Execute id is 4101. 

SQL> SP_SET_PARA_VALUE (1, 'ALTER_TABLE_OPT', 2); 
DMSQL executed successfully 
used time: 8.316(ms). Execute id is 4102. 

会话2:
SQL> alter table TEST add column address varchar(100); 
executed successfully 
used time: 00:00:04.420. Execute id is 4103.

3、清理干扰的会话

对于业务侧已确认某时间段无业务访问,可以直接进行DDL操作,但有时依旧报锁等待超时的错误,对此可以使用上述的方式提高我们的操作效率,同时对干扰我们维护的会话进行清理。

我们直接从v$sessions动态视图中可找到会话中关于该表所涉及到的会话,并手动关闭会话,可借助存储语句完成: 
SQL> SET SERVEROUT ON # 在块中有打印信息时,默认不会打印,需要手动开启 
SQL> declare 
session_id bigint;  
begin 
select sess_id into session_id from v$sessions where sess_id<>sessid and UCASE(sql_text) like '%TEST%';  
print session_id; 
sp_close_session(session_id); 
end  
/ 

锁等待

达梦数据库中,DML操作是常见的会导致锁等待的语句,DDL操作频繁虽然低,操作不当也会导致锁等待。运维一旦发现锁等待问题,需要配合业务侧及时处理掉,以免锁等待累积造成更严重的现网故障。

1、模拟锁等待的现象

模拟达梦数据库DML操作可能会出现的行锁等待,同时打开两个会话窗口,就是在未执行SQL前打开两个会话窗口。

1、会话一:更新表TEST中id=2的(id字段为主键字段)数据,更新成功,但不要提交:
SQL> update TEST set name='BBB' where id=2; 

2、会话二:继续更新表TEST中id=2的这行数据,就会出现未更新成功,处于等待状态: 
SQL> update TEST set name='CCC' where id=2;

此时会话二处于挂起状态,因为会话二在等待会话一持有的资源,仅当会话一提交或回滚后才能执行成功。已经模拟出锁等待问题,这里需要处理一下锁等待:
1、首先查看被挂起的事务,即找到被挂起事务ID(TRX_ID)
SQL> SELECT VTW.ID AS TRX_ID, VS.SESS_ID ,VS.SQL_TEXT FROM V$TRXWAIT VTW LEFT JOIN 
V$TRX VT ON (VTW.ID=VT.ID) LEFT JOIN V$SESSIONS VS ON (VT.SESS_ID=VS.SESS_ID); 
LINEID   TRX_ID   SESS_ID          SQL_TEXT 
------   ------   --------------   --------------------- 
1        6158   139808835965528    update TEST set name='CCC' where id=2;

2、通过挂起事务ID(TRX_ID)找到等待的事务(WAIT_FOR_ID)
SQL> SELECT WAIT_FOR_ID,WAIT_TIME FROM V$TRXWAIT WHERE ID=6158; 
LINEID     WAIT_FOR_ID          WAIT_TIME 
---------- -------------------- -----------
1          6157                108572

2、通过等待事务ID(WAIT_FOR_ID)定位到正在执行的语句
SQL> SELECT VT.ID AS TRX_ID,VS.SESS_ID,VS.SQL_TEXT ,VS.APPNAME,VS.CLNT_IP FROM 
V$TRX VT LEFT JOIN V$SESSIONS VS ON (VT.SESS_ID=VS.SESS_ID) WHERE VT.ID = 6157;
LINEID   TRX_ID   SESS_ID           SQL_TEXT
-------- -------- -----------------  ------------------------------------- 
1        6157     139809037292120   update TEST set name='CCC' where id=2;

2、处理引起锁等待的语句

这种对于引起锁等待的语句,优先kill掉引起锁等待的语句,保障系统稳定运行。后续再对抓取到的语句进行分析和定位。

1、建议先系统自带的函数kill掉引起锁等待的语句: 
SQL> SP_CLOSE_SESSION(139809037292120); 

2、再查看会话二,就发现update操作已经执行成功: 
SQL> update TEST set name='CCC' where id=2;

在DM数据库中,INSERT、UPDATE、DELETE更新操作是最常见的会产生阻塞和死锁的语句。INSERT发生阻塞的唯一情况是, 当多个事务同时试图向有主键或UNIQUE约束的表中插入相同的数据时,其中的一个事务将被阻塞,直到另外一个事务提交或回滚。一个事务提交时,另一个事务将收到唯一性冲突的错误;一个事务回滚时,被阻塞的事务可以继续执行下去。而当UPDATE和DELETE修改的记录,已经被另外的事务修改过,将会发生阻塞的情况,直到另一个事务提交或回滚。

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服