达梦数据库死锁与阻塞分析解决

一、阻塞与死锁的简单定义:

1、什么是死锁?

死锁:是两个事务都在等待对方持有的资源锁,要等待对方释放有的资源锁之后才能继续工作,两者互不想让,坚持到底,都在等待彼此完成才继续工作,就是这样的状态,双方都完成不了,从而陷入死循环。

遇到死锁解决策略:

1、数据库中的机制是当发生死锁时会牺牲其中的一个进程来让其继续执行下去。

2、那种情况是应用程序BUG产生的,需要调整程序的逻辑结构,在对多表进行操作时,尽量按照相同的顺序执行,避免同时锁定两个资源,必须同时锁定两个资源的时候,要保证在任何时候都要按照相同顺序来锁定资源。

2、什么是阻塞?

阻塞:是第一个事务占有资源没有释放,而第二个事务需要获取这个资源,如果第一个事务没有提交或者回滚,第二个事务会一直等待下去,直到第一个事务释放该资源为止

遇到阻塞解决策略:

1、被阻塞的事务会一直挂起、直到持有锁的事务放弃锁定的资源为止(提交/回滚)

2、程序应用bug产生,需要调整程序的逻辑结构,尽量形成短事务,快速提交,避免阻塞时间过长,不要将其他无关操作放到容易引起阻塞的模块。

二、达梦数据库死锁与阻塞解释

       阻塞和死锁是会与并发事务一起发生的两个事件,它们都与锁相关。当一个事务正在占用某个资源的锁,此时另一个事务正在请求这个资源上与第一个锁相冲突的锁类型时,就会发生阻塞。被阻塞的事务将一直挂起,直到持有锁的事务放弃锁定的资源为止。死锁与阻塞的不同之处在于死锁包括两个或者多个已阻塞事务,它们之间形成了等待环,每个都等待其他事务释放锁。例如事务1给表 T1 上了排他锁,第二个事务给表 T2 上了排他锁,此时事务 1请求 T2 的排他锁,就会处于等待状态,被阻塞。若此时 T2 再请求表 T1 的排他锁则T2 也处于阻塞状态。此时这两个事务发生死锁,DM 数据库会选择牺牲掉其中一个事务

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

三、如何排查死锁与阻塞

A、排查死锁方式:

1、使用系统视图查看死锁:

SELECT * FROM  V$DEADLOCK_HISTORY;

select dh.trx_id,sh.sess_id,wm_concat(top_sql_text) 
from V$DEADLOCK_HISTORY dh,V$SQL_HISTORY sh 
where dh.trx_id=sh.trx_id 
and dh.sess_id=sh.sess_id 
group by dh.trx_id,sh.sess_id;

查询结果:

       由于死锁会被数据库系统自动识别并终止,所以从会话视图中是感受不到的,程序会反馈一个死锁错误,通过死锁历史动态视图V$DEADLOCK_HISTORY,可以查询到发生过的死锁信息。

2、通过事务ID(trx_id)去sql日志中查找对应的事务确定完整的事务信息。根据完整的事务信息和死锁规则,去找其他影响的事务操作确定业务功能设计从而优化处理逻辑消除或者降低死锁频率。

ps:sql日志在数据库安装目录的log文件夹里

B、排查阻塞方式

1、使用系统视图查询

SELECT SYSDATE AS STATTIME,
       DATEDIFF(SS,S1.LAST_SEND_TIME,SYSDATE) AS SS,
       '被阻塞的信息' AS WT,
	   S1.SESS_ID AS WT_SESS_ID,
	   S1.SQL_TEXT AS WT_SQL_TEXT,
       S1.STATE AS WT_STATE,
	   S1.TRX_ID AS WT_TRX_ID,
	   S1.USER_NAME AS WT_USER_NAME, 
       S1.CLNT_IP AS WT_CLNT_IP,
	   S1.APPNAME AS WT_APPNAME,
	   S1.LAST_SEND_TIME AS WT_LAST_SEND_TIME,
	   '引起阻塞的信息' AS FM,
	   S2.SESS_ID AS FM_SESS_ID,
	   S2.SQL_TEXT AS FM_SQL_TEXT,
	   S2.STATE AS FM_STATE,
	   S2.TRX_ID AS FM_TRX_ID,
	   S2.USER_NAME AS FM_USER_NAME,
	   S2.CLNT_IP AS FM_CLNT_IP,
	   S2.APPNAME AS FM_APPNAME,
       S2.LAST_SEND_TIME AS FM_LAST_SEND_TIME
FROM V$SESSIONS S1,
V$SESSIONS S2 ,V$TRXWAIT W
WHERE S1.TRX_ID = W.ID
AND S2.TRX_ID = W.WAIT_FOR_ID;

SELECT timestampdiff(ss,LAST_RECV_TIME,SYSDATE) AS SS,
SF_GET_SESSION_SQL(SESS_ID) AS SESS_ID , * 
FROM SYS."V$SESSIONS"
where SESS_ID <> SESSID
ORDER BY 1 DESC;

2、通过事务ID(trx_id)去sql日志中查找对应的事务确定完整的事务信,和查询中被阻塞的事务sql进行对照确认。

ps:sql日志在数据库安装目录的log文件夹里

四、怎样解锁死锁与阻塞

       死锁不用人工干涉,数据库系统自动识别并解除。但是死锁是非正常情况,需要找到死锁原因后,从应用逻辑层解决。
      阻塞 可能是应用流程涉及提交慢导致,但是最终也会提交或者回滚,所以一般情况下也会自动消除。如果阻塞很长时间没有消除,在数据库层可以通过 SP_CLOSE_SESSION(SESSID);来强制终阻塞源头的会话使其回滚,来解除阻塞,但是这个需要用户确认,不能私自操作。

1、从系统时间中可以查看锁等待事件和地锁事件发生的次数和时间来评估是否存在死锁和阻塞

查询语句:

SELECT * FROM V$SYSTEM_EVENT ORDER BY TIME_WAITED DESC;

2、可以通过辅助表跟踪阻塞

STEP1:创建辅助记录表:

CREATE TABLE TRX_WAIT(
"STATTIME" TIMESTAMP,
"SS" INTEGER,
"WT" VARCHAR2(30),
"WT_SESS_ID" BIGINT,
"WT_SQL_TEXT" VARCHAR(1000),
"WT_STATE" VARCHAR(10),
"WT_TRX_ID" BIGINT,
"WT_USER_NAME" VARCHAR(128),
"WT_CLNT_IP" VARCHAR(128),
"WT_APPNAME" VARCHAR(128),
"WT_LAST_SEND_TIME" DATETIME(6),

"FM" VARCHAR2(30),
"FM_SESS_ID" BIGINT ,
"FM_SQL_TEXT" VARCHAR(1000),
"FM_STATE" VARCHAR(10),
"FM_TRX_ID" BIGINT,
"FM_USER_NAME" VARCHAR(128),
"FM_CLNT_IP" VARCHAR(128),
"FM APPNAME" VARCHAR(128),
"FM LAST SEND TIME"DATETIME(6)
);

STEP2:创建辅助存储过程GET_TX_WAIT

CREATE PROCEDURE GET_TX_WAIT AS
BEGIN
INSERT INTO TRX_WAIT
SELECT SYSDATE AS STATTIME,
       DATEDIFF(SS,S1.LAST_SEND_TIME,SYSDATE) AS SS,
       '被阻塞的信息' AS WT,
	   S1.SESS_ID AS WT_SESS_ID,
	   S1.SQL_TEXT AS WT_SQL_TEXT,
       S1.STATE AS WT_STATE,
	   S1.TRX_ID AS WT_TRX_ID,
	   S1.USER_NAME AS WT_USER_NAME, 
       S1.CLNT_IP AS WT_CLNT_IP,
	   S1.APPNAME AS WT_APPNAME,
	   S1.LAST_SEND_TIME AS WT_LAST_SEND_TIME,
	   '引起阻塞的信息' AS FM,
	   S2.SESS_ID AS FM_SESS_ID,
	   S2.SQL_TEXT AS FM_SQL_TEXT,
	   S2.STATE AS FM_STATE,
	   S2.TRX_ID AS FM_TRX_ID,
	   S2.USER_NAME AS FM_USER_NAME,
	   S2.CLNT_IP AS FM_CLNT_IP,
	   S2.APPNAME AS FM_APPNAME,
       S2.LAST_SEND_TIME AS FM_LAST_SEND_TIME
FROM V$SESSIONS S1,
V$SESSIONS S2 ,V$TRXWAIT W
WHERE S1.TRX_ID = W.ID
AND S2.TRX_ID = W.WAIT_FOR_ID;
COMMIT;
END;

STEP3:创建作业定时收集阻塞数据:

想要了解更多:达梦数据库 - 新一代大型通用关系型数据库 | 达梦在线服务平台

  • 26
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
达梦数据库常⽤系统视图及查询语句 ⼀、常⽤的系统视图: dba_objects:显⽰数据库中所有的对象,例如想查询数据库中有没有某个对象 v$sessions:显⽰会话的具体信息,如执⾏的 sql 语句、主库名、当前会话状态、⽤户名等等 v$lock:查看当前数据库中锁的信息 v$mem_pool:显⽰所有的内存池信息 V$deadlock_histor::记录死锁的历史信息 V$TABLESPACE:显⽰表空间信息,不包括回滚表空间信息 V$TRX:显⽰所有活动事务的信息。通过该视图可以查看所有系统中所有的事务以及相关信息,如锁信息等。 ⼆、常⽤查询语句 1、查询数据库在线实例信息 select distinct NAME, HOST_NAME, SVR_VERSION, DB_VERSION, START_TIME, STATUS$, MODE$ from V$INSTANCE; 2、查看数据库常⽤参数值 select PARA_NAME,PARA_VALUE FROM V$DM_INI WHERE PARA_NAME IN('MEMORY_POOL','BUFFER','PORT_NUM','MAX_SESSIONS','MAX_SESS ION_STATEMENT','INSTANCE_NAME','BAK_PATH','SYSTEM_PATH','ARCH_INI'); 3、查询数据库初始化配置 select SF_GET_PAGE_SIZE() page_size, SF_GET_EXTENT_SIZE() extent_size, SF_GET_UNICODE_FLAG() unicode_flag, SF_GET_CASE_SENSITIVE _FLAG() case_sensitive_flag, SF_GET_SYSTEM_PATH() system_path; 4、查询数据库名称、数据库总⼤⼩、数据库是否启⽤归档 select NAME,STATUS$,ARCH_MODE, TOTAL_SIZE from SYS.V$DATABASE; 5、查询数据库连续运⾏时间 select (SYSDATE-START_TIME)*24 FROM V$INSTANCE; 6、查询数据库管理⽤户状态,默认表空间,是否存在被锁定 select D.USERNAME,A.CREATED,D.ACCOUNT_STATUS,D.DEFAULT_TABLESPACE,D.EXPIRY_DATE,D.LOCK_DATE FROM DBA_USERS D,ALL_USE RS A; 7、查询当前数据库的⽇志分组情况 select GROUP_ID,FILE_ID,PATH,CLIENT_PATH,RLOG_SIZE FROM SYS.V$RLOGFILE; 8、查询表空间信息 select T.NAME 表空间名称, D.PATH 表空⽂件路径, T.TYPE$ 表空间类型, T.STATUS$ 表空间状态, T. FILE_NUM 包含的⽂件数, D.TOTAL_SIZE*16/1024 总⼤⼩, D.FREE_SIZE*16/1024 空闲⼤⼩, TRUNC((TRUNC(D.TOTAL_SIZE-D.FREE_SIZE, 4)/D.TOTAL_SIZE)*100, 2) 使⽤率 FROM V$TABLESPACE T, V$DATAFILE D WHERE "GROUP_ID"=T.ID; 9、查询数据表所分配的空间⼤⼩,辅助查询表⽤户使⽤情况 select OWNER,TABLESPACE_NAME,SEGMENT_TYPE,SEGMENT_NAME,BLOCKS,BYTES/1024/1024 FROM DBA_SEGMENTS ORDER BY OWNER,SE GMENT_NAME; 10、查询表索引状态,便于确认表索引是否可⽤ select I.TABLE_OWNER,I.TABLE_NAME,O.OBJECT_NAME,O.OBJECT_TYPE,O.STATUS FROM USER_INDEXES I,USER_OBJECTS O WHERE O.OBJE CT_NAME=I.INDEX_NAME AND O.STATUS='INVALID'; 11、查询数据库归档信息 select ARCH_TYPE,ARCH_DEST FROM V$DM_ARCH_INI; select ARCH_NAME, ARCH_TYPE, ARCH_DEST, ARCH_FILE_SIZE, ARCH_SPACE_LIMIT, ARCH_TIMER_NAME, ARCH_IS_VALID from SYS.V$DM_AR CH_IN

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值