- 阻塞发生条件
在程序运行时,如果有异常长时间执行等待无结果,可以排查是否有阻塞的情况。
在 DM 数据库中, INSERT、 UPDATE、 DELETE 是最常见的会产生阻塞和死锁的语句。
INSERT 发生阻塞的唯一情况是, 当多个事务同时试图向有主键或 UNIQUE 约束的表中插入相同的数据时,其中的一个事务将被阻塞,直到另外一个事务提交或回滚。一个事务提交时,另一个事务将收到唯一性冲突的错误;一个事务回滚时,被阻塞的事物可以继续执行。
当 UPDATE 和 DELETE 修改的记录,已经被另外的事务修改过, 将会发生阻塞,直到另一个事务提交或回滚。
2.排查阻塞
–dm7中可以使用下面的sql语句查询阻塞信息
WITH TRX_TAB AS
(SELECT DISTINCT O1.NAME,L1.TRX_ID FROM V$LOCK L1,SYSOBJECTS O1 WHERE L1.TABLE_ID=O1.ID AND O1.ID<>0),
TRX_SESS AS (
SELECT L.TRX_ID WT_TRXID, L.ROW_IDX BLK_TRXID,L.BLOCKED,(SELECT NAME TABLE_NAME FROM TRX_TAB A WHERE A.TRX_ID=L.TRX_ID) WT_TABLE,
S1.SESS_ID WT_SESS,S2.SESS_ID BLK_SESS,
S1.USER_NAME WT_USER_NAME,S2.USER_NAME BLK_USER_NAME,S1.SQL_TEXT,S1.CLNT_IP,DATEDIFF(SS, S1.LAST_SEND_TIME, SYSDATE) SS
FROM V$LOCK L,V$SESSIONS S1,V$SESSIONS S2
WHERE L.TRX_ID=S1.TRX_ID AND L.ROW_IDX=S2.TRX_ID)
SELECT SYSDATE STATTIME,* FROM TRX_SESS where BLOCKED=1;
查询通过WT_TRXID为等待的事务号,BLK_TRXID为阻塞的事务号,BLK_SESS为阻塞的会话号。例如,图中220134、220135被220133的事务阻塞。
通过上面的阻塞事务号BLK_TRXID或者阻塞会话号BLK_SESS,关联到会话视图v$sessions中的SESS_ID或者TRX_ID。例如,通过上面的BLK_SESS 1162268952查询到阻塞会话。
3. 排查记录日志
通过上面的sql语句都能通过sql_text字段查到阻塞会话最后执行的sql,但要具体看到整个会话的事务,以及程序绑定的具体参数,可以通过提前打开达梦的日志记录。
执行:sp_set_para_value(1,‘SVR_LOG’,1),然后日志生成在达梦安装目录下log目录dmsql开头的日志文件。可以通过上面查询到的事务号找到具体执行内容。
例如:通过上面查询的阻塞事务号220133,可以查看到这个阻塞会话执行过insert跟update操作,220134和220135执行分别是同一个主键的insert和update语句就被阻塞了。如果是程序执行,会单独显示的绑定参数值。
生产环境下,找到记录日志结果后,建议及时关闭记录日志功能,执行:sp_set_para_value(1,‘SVR_LOG’,0)。
4.解除阻塞
通过上面的分析,如果想要快速处理阻塞,根据查找到的阻塞会话sess_id,通过执行函数sp_close_session(sess_id),可以强行结束阻塞的会话。如果经常出现此类阻塞,就因根据业务需求,修改业务逻辑。