Oracle加索引锁表异常

项目场景:

根据现场反馈,各条产线出现设备宕机报警CIM回复超时,人工站点MES系统无响应的情况。


原因分析:

直接切入MES DB,查询发生时间点执行的SQL语句的历史记录。
SQL语句如下:

select sample_time, sql_id, event, blocking_session, blocking_session_serial#, wait_time
from gv$active_session_history 
where sample_time > TO_TIMESTAMP('2024-08-30 13:11:00.000000', 'SYYYY-MM-DD HH24:MI:SS:FF6')
and sample_time < TO_TIMESTAMP('2024-08-30 13:14:00.000000', 'SYYYY-MM-DD HH24:MI:SS:FF6')
order by sa!mple_time asc;

根据下图查询出的结果可以看出,大部分事务都被事务4264所阻塞,唯一号为61195
另外在执行dml期间,为防止对与dml相关的对象进行修改,执行dml的进程必须对该表获得TM锁,若在获得TM锁的过程中发生争用,则等待enq:TM-contention事件,与现状一致。

在这里插入图片描述

寻找根源,再用相同的方式进行二次查询,这次我们将阻塞源头加入查询条件;

select 
sample_time,sql_id,event,blocking_session,blocking_session_serial#,wait_time
from gv$active_session_history 
where session_id = '4264'
and session_serial# = '61195';

在这里插入图片描述
下一步我们根据SQL_ID看看这个SQL具体执行的是什么内容。
但是我们从gv$sql、gv$sqlarea和gv$sqltext三个视图中都查询不到这个SQL_ID对应的信息,最后在gv$sql_monitor中查出了这条SQL。这里比较奇怪,可能是因为这条SQL只执行了一次所以没有被记录在那些记录频繁执行的SQL语句的视图中。
在这里插入图片描述

到这里问题的根因就水落石出了,Oracle在给表建立索引时不使用ONLINE选项可能会导致表被锁定,在默认情况下,当你创建一个索引时,Oracle会在事务处理(DML)操作之前获取一个表的 exclusive 锁。这意味着在索引创建期间,表将被锁定,无法进行插入、更新或删除操作。
使用ONLINE选项可以避免长时间锁表,ONLINE索引建立允许在不锁定表的情况下创建索引。这是通过在创建索引期间复制表的一部分来完成的,从而减少了锁定时间,但这也要求有额外的空间来存储复制的数据。

当然我们也可以通过Oracle EM13C工具进行分析更加简单方便,在SQL监视中我们可以发现‘6xpa7j8v2b88a’这个SQL在问题发生的时间段占用了大量IO,再进行上面最后一步操作找到问题点。
在这里插入图片描述

解决方案:

解决方法是在创建索引时使用ONLINE选项。这样可以最大程度地减少对表的影响。

CREATE INDEX idx_tablename_colname ON tablename(colname) ONLINE;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值