deadlock引起数据库挂死

某天,应用程序突然挂了,程序中报错连不上数据库。登录数据库主机后,发现sqlplus也登录不了,登录时,sqlplus长时间没有响应,检查alertlog只是发现半小时前检测到一个deadlock,没有其他的报错信息。心想oracle检测到deadlock能自动解锁,因此一开始没怀疑到是因为deadlock的原因,由于登录不上数据库,为了尽快的回复业务,停掉应用程序,杀掉ps -ef |grep LOCAL=N的进程后,再次能登录数据库,重启了数据库,再次启动应用,回复正常。

追溯原因时,一开始是怀疑系统的内核参数设置不正确,导致主机资源耗尽,因此无法sqlplus登录。但是检查了一遍主机的内核参数,发现均正常。主机的syslog同样也没发现异常。奇怪,为什么会出现挂死的现象?请教了老网虫白鳝后,才明白了某些版本的oracle检查到deadlock后会触发一个关于deadlock的bug,导致enqueue hash chain的parent latch被hold住,然后在做SYSTEM DUMP的时候可能产生LATCH死锁,这个时候可能hang住,时间可能是在几秒钟,也有可能是几小时。

进一步检查这个deadlock的trace文件:

检查addr为c0000001c1a4d458的latch:

确实我们看到了enqueue hash chain。enqueue hash chain是用于保护每一个library cache中的hash bucket。
(这里借用一下eygle的图说明一下library cache的结构)

由于parent latch被HOLD了,所有对数据库library cache加锁的操作都无法进行,而sqlplus登录的时候要申请AUDSES$的SEQUENCE,因此sqlplus无法登录,同理所有的应用程序也无法登录——应用程序挂死。

在metalink上也确认了这个bug:2530125

可是,在第二天下午,再次出现的由于deadlock导致数据库挂死的问题,检查alertlog发现在很早之前已经有deadlock的现象,为何系统会频繁的出现deadlock?

根据deadlock的trace文件,根据deadlock graph的wait的模式是SSX,这就很有可能是外键没加索引造成。检查相关语句中的外键,靠!确实是外键没加索引。

对外键增加索引后,系统正常运行一周,不再发生死锁,也不再发生挂死现象。至此问题解决。回顾问题:由于外键没加索引–引起死锁–触发bug2530125–enqueue hash latch–无法登录–程序挂死。

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注