enq之TM-contention解决之道——外键无索引导致锁争用(上)
近日,开发负责人反映某生产环境业务处理缓慢,主要业务操作就是修改会员信息,登录查询后发现大量的session正在等待enq: TM - contention,且waiting的语句几乎都是update
session的即时信息没有保留,现在附上ash视图的一些统计信息,可以大概了解一下当时争用的场景
1 | SQL> @ash_wait_chains.sql username||':'||program2||event2 session_type='FOREGROUND' sysdate-6/24 sysdate-5/24 |
可以看到,TM锁的争用很多,再看一份当时awr报告的top10
虽然占DBTIME不多,但本来是很快的操作,短时间内给人的感觉就是业务处理缓慢
查一下当时等待事件的p1,p2,p3的值
1 | select ash.SAMPLE_TIME, |
下面是部分结果
1 | enq: TM - contention 1828 2401 name|mode 1414332421 object # 110417 table/partition 0 WAITING UPDATE ak25v8q8p6fzd |
可以看到p2的值为产生TM争用的对象id,经过查证,这些object均是session正在更新的表的子表,而且通过v$sql查看update语句均更改了主表的主键,问题到这里已经很明朗了,由于外键没加索引,导致了主表在更新主表主键或删除主表记录时对子表的锁定,而且这张主表被大量的子表引用,此时子表上也同时进行事务处理,所以造成了更新主表的session 不时hang住。
通过对所有子表的外键加索引,消除了争用,检测未加索引的外键语句:
1 | SELECT TABLE_NAME, |
这是摘自TOM大师的语句,外键不加索引也是导致死锁的常见原因之一,因此对于主表经常进行更新删除操作的情况,外键一定要加索引。
至于外键未加索引是如何导致锁定的,以及为何加了索引后争用就消失了? 敬请关注enq: TM - contention解决之道——外键无索引导致锁争用 (下)