Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2582199
  • 博文数量: 323
  • 博客积分: 10211
  • 博客等级: 上将
  • 技术积分: 4934
  • 用 户 组: 普通用户
  • 注册时间: 2006-08-27 14:56
文章分类

全部博文(323)

文章存档

2012年(5)

2011年(3)

2010年(6)

2009年(140)

2008年(169)

分类: Oracle

2008-05-26 10:57:31

经常看到有人把这几个概念搞错。在我所处的工作环境中也听到有人老是喊死锁了赶快解锁。首先我从概念上来解释一下。什么是死锁?简单的讲就是AB两个事物,事务A锁住事务B请求的资源,事务B锁住事务A请求的资源,造成互相等待释放资源。对于死锁ORACLE会自动发现并自动回滚事物解锁,在告警日志和TRAC文件中我们可以看到DEADLOCK的信息。另外我们也可以通过V$LOCK视图去查看死锁的语句:
SELECT SID, DECODE(BLOCK, 0, 'NO', 'YES' ) BLOCKER,
DECODE(REQUEST, 0, 'NO','YES' ) WAITER
FROM V$LOCK
WHERE REQUEST > 0 OR BLOCK > 0
ORDER BY block DESC;
--这这个查询反映了哪些SESSION在等待,哪些SESSION造成了死锁。
 
什么是锁?这个ORACLE官方文档有很详细的描述,我就不细讲了。我主要来讲一下阻塞跟死锁的区别。阻塞是单方向的,死锁是双向的。假如一个SESSION正在更新一行数据,另外一个SESSION也想更新这行数据,这时这个SESSION就会发生等待。第一个SESSION造成了阻塞,第一个SESSION如果完成更新并提交,第二个SESSION就能正常进行。很多人喜欢用如下的SQL语句进行锁定对象的查询:
SELECT s.username,l.OBJECT_ID,l.SESSION_ID,s.SERIAL#,l.ORACLE_USERNAME,l.OS_USER_NAME,l.PROCESS FROM V$LOCKED_OBJECT l,V$SESSION S WHERE l.SESSION_ID=S.SID
 
这条查询语句在大型应用系统中很耗时,另外查询出来的结果也没有什么大的价值。因为这些锁定的对象对系统而言可能是很正常的,比如说一些没有提交的事务。如果这时采用KILL SESSION的方法,我估计你还没有杀完,一些新的锁定对象又出来了。怎样处理这个问题?可以参考我BLOG上的另一篇文章“ERP 死锁的解决方案”
 
造成死锁的原因到底是什么呢?按照TOM的观点他认为造成死锁的主要原因是:
a.外键未加索引
b.表上的位图索引遭到并发更新。
 
查看是不是存在未加索引的外键:
 
column columns format a30 word_wrapped
column tablename format a15 word_wrapped
column constraint_name format a15 word_wrapped
select table_name, constraint_name,
 cname1 || nvl2(cname2,','||cname2,null) ||
 nvl2(cname3,','||cname3,null) || nvl2(cname4,','||cname4,null) ||
 nvl2(cname5,','||cname5,null) || nvl2(cname6,','||cname6,null) ||
 nvl2(cname7,','||cname7,null) || nvl2(cname8,','||cname8,null)
 columns
 from ( select b.table_name,
 b.constraint_name,
 max(decode( position, 1, column_name, null )) cname1,
 max(decode( position, 2, column_name, null )) cname2,
 max(decode( position, 3, column_name, null )) cname3,
 max(decode( position, 4, column_name, null )) cname4,
 max(decode( position, 5, column_name, null )) cname5,
 max(decode( position, 6, column_name, null )) cname6,
 max(decode( position, 7, column_name, null )) cname7,
 max(decode( position, 8, column_name, null )) cname8,
 count(*) col_cnt
 from (select substr(table_name,1,30) table_name,
 substr(constraint_name,1,30) constraint_name,
 substr(column_name,1,30) column_name,
 position
 from user_cons_columns ) a,
 user_constraints b
 where a.constraint_name = b.constraint_name
 and b.constraint_type = 'R'
 group by b.table_name, b.constraint_name
 ) cons
 where col_cnt > ALL
 ( select count(*)
 from user_ind_columns i
 where i.table_name = cons.table_name
 and i.column_name in (cname1, cname2, cname3, cname4,
 cname5, cname6, cname7, cname8 )
 and i.column_position <= cons.col_cnt
 group by i.index_name
 )
 /
阅读(1653) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~