Oracle锁阻塞是用户在操作数据库时最常遇到的一个问题,说白了就是当你或其他用户在更新某行数据时,已经锁定了该行,就会限制其他用户访问该行数据。当发生锁阻塞时,性能就会受到影响,甚至会使系统完全停止运作。
要消除Oracle锁阻塞,首先要弄清楚锁阻塞的根源,一般可以归结为以下几个原因:脏读锁定,幻象锁定,行超时锁定,列级冲突,表级冲突等。具体的原因需要分析系统的行为有关的日志文件来进一步确认,然后再采取相关的措施消除锁阻塞。
常见的消除Oracle锁阻塞的措施有:重新调整锁的类型、实施锁等待机制、增加锁的超时时间、合理调整系统的参数、禁止不必要的共享锁以及优化数据库语句等。
首先,通过调整锁的类型,将共享锁改变成排它锁,减少锁阻塞问题,如果操作是读取数据,要尽量使用可重复读模式;
其次,使用数据库本身自带的锁等待超时机制,当其他用户获取所锁定的记录时,采取等待的策略,达到超时错误意外中止的目的;
另外,也可通过增加锁的超时时间来消除锁冲突;
再者,合理调整系统的参数,如果操作锁定某一资源时长较长时,可以适当将资源池中的锁有效时长调长,以免出现用户获取锁后又释放掉了;
最后,可以合理优化数据库语句,通过合理的分段处理操作,可以降低锁有效的时间。
总的来说,解决Oracle的锁阻塞问题,要合理调整系统的参数和锁的类型,结合优化数据库语句来消除锁阻塞。当然,也可以采用DBA服务的相关技术来解决这些问题,但总的来说,从根本上解决Oracle锁阻塞的问题还是要从系统优化和程序优化上考虑,而不是依赖于简单的DBA服务。
--查看等待的session
select * from dba_waiters;
--查看锁等待情况
select distinct lk.SID,lk.ID1,lk.ID2,lk.LMODE,lk.REQUEST,lk.BLOCK,lk.TYPE,do.owner || '.' || do.object_name
from v$lock lk,
v$locked_object lo,
dba_objects do
where do.object_id = lo.OBJECT_ID
and lo.SESSION_ID = lk.SID order by sid;
--根据session的SID查看阻塞会话的详细信息
select p.SPID,
s.username,
s.machine,
s.program,
s.sid,
s.serial#,
s.status,
c.piece,
c.sql_text
from v$session s, v$process p,v$sqltext c where sid in(27,1,34) and p.addr = s.paddr and s.sql_address=c.address(+);
--杀掉阻塞的会话
alter system kill session 'sid,serial#';
批量生成杀掉session的语句:
SELECT'alter system kill session '''|| c.sid ||''||','|| c.serial# ||''';',
a.object_id, a.session_id, b.object_name, c.*
FROM v$locked_object a, dba_objects b, v$session c
WHERE a.object_id = b.object_id
AND a.SESSION_ID = c.sid(+)
ORDER BY logon_time;
发表评论