在某项目上遇到这个问题:查询一张表的sql语句一直卡住,无法返回结果,这张表的表结构也无法查看,同时所有涉及到这张表的会话全部卡住,可以说,关于这张表的所有操作都陷入了瘫痪的境地。而这张表是一张非常重要的表,很多业务都需要访问这张表,造成了很多业务都卡在这个地方。
1.在ip地址末尾为29的数据库上面执行select * from "XXX_V30"."XXX_FWFP";查询出不了结果:
2.针对这种情况,判断可能存在阻塞,于是立即用查询阻塞的sql语句进行排查:
SELECT
VTW.ID AS TRX_ID,
VS.SESS_ID,
VS.SQL_TEXT,
VS.APPNAME,
VS.CLNT_IP
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);
发现系统存在阻塞情况,这里忘记了截图,于是顺着阻塞会话往下分析。
3.从会话中可以看到:有个会话正在给这张表添加列:
/Manager//Manager/alter table "XXX_V30"."XXX_FWFP" add column("YLS_XH" INTEGER);
添加列的操作是会阻塞查询,可以解释第1步的现象,那么又是什么操作阻塞了添加列的操作呢?继续排查。
4.通过 pstack 3922425 > /home/dmdba/dmdbms/log/pstack3922425.log 命令打印当前会话线
程(添加字段的会话线程,线程号 3922425 来源于 v$sessions 的 THRD_ID 字段)的堆栈,堆
栈信息如下:
从堆栈的信息可以知道:
第一,从“dpi_link_get_tv”字样分析可能卡在dblink阶段。
第二,该问题和XXX_XX_XXX_DICOM对象有关联关系。
从XXX_XX_XXX_DICOM分析:
XXX_XX_XXX_DICOM是一个视图,而里面确实包含了主角对象"XXX_V30"."XXX_FWFP"的访问,这就说明了这个视图的访问也卡在无法访问""XXX_V30"."XXX_FWFP"这个地方,和堆栈里面所看到的信息是契合的。
5.会话分析
(1)对当前数据库会话进行分析:
select SQL_TEXT,
STATE,
CLNT_IP,
CLNT_HOST,
CLNT_TYPE,
APPNAME,
MSG_STATUS
from gv$sessions
where STATE = 'ACTIVE'
and SQL_TEXT is null;
可以看出这里存在SQL_TEXT为NULL的5个活动会话,这些会话来源于另外一台ip地址末尾为36的数据库服务器,既然前面的排查分析结果可能和dblink有关,那这里的分析就定位到dblink的源头执行服务器是36了。
(2)对36的数据库会话进行分析
36上面会话情况:
select SQL_TEXT,
STATE,
CLNT_IP,
CLNT_HOST,
CLNT_TYPE,
APPNAME,
MSG_STATUS
from gv$sessions
where STATE = 'ACTIVE' and SQL_TEXT like '%V30_XXX%';
从会话里面看出目前也刚好有5个查询的活动会话(当前会话除外)也卡住。分析查询的对象:
查询的对象V30_XXX也是一个视图,视图的定义如下:
可以看出视图里面确实用到了dblink,查看dblink的定义,dblink也刚好指向了主角机器29,那就定位到问题了,是36这个机器发往主角机器29的dblink会话阻塞了29修改表结构的操作,进而阻塞了对这张表的所有操作。
在 29 服 务 器 上 通 过 v$sessions 找 到 来 自 36 的 dblink 会 话 的 sess_id , 采 用sp_close_session(sess_id)函数关闭来自 36 的 dblink 会话,之后该表可以正常添加列,正常进行查询了,与该表关联的会话都恢复正常。
达梦数据库中,select 操作会产生共享锁,防止其他事务修改正在访问的对象。这个锁允许多个事务同时并发读取相同的资源,但是不允许任何事务修改这个资源。对于我们这个例子,也就是查询操作在未返回结果之前会阻塞对查询对象增加字段的操作。
遇到类似的问题可以往这方面的思路去排查和分析。
文章
阅读量
获赞