Oracle 版本: 12.2 , RAC
OS 版本: Linux 7
問題描述:
使用者反映網頁無法正常回應,由 DB session 發現同時多個 active session 且等待事件皆為 enq: TX – row lock contention 。
問題分析:
一般來說, row lock contention 多數由於上層有尚未 commit 的 session 導致後續的 session 堵塞,由 blocking session 找到上層 sid 為 30098 為堵塞的源頭 :
30098 這個 session 並非是沒有 commit 造成堵塞,而是它本身被 gc flushed buffer 這個等待事件所影響,某個物件一直無法完成 gc flushed buffer 這個動作導致 30098 這個 session hang 住,進而影響後續 session。
解決方法:
我們必須解決 30098 卡在 gc flushed buffer 這個現象,由 incident trace 中,以 pkey 這個關鍵字找出正在 cache flushed 的 object :
得知 cache 中在 flushed 這個 pkey 0.10.157792 產生了未知的 lock 導致 flushed 無法完成,以 oradebug 命令強制解除這個 pkey 的 lock :
SQL> oradebug lkdebug -m dpkey_readmostly 157792 10 |
在解除 pkey 0.10.157792 的 lock 之後, gc flushed buffer 的等待事件消失,後續的 session 也就疏通了。
而這個 pkey flushed 的 lock 是由於 read mostly locking 的 bug 所引起的,另一種 workaround 的方法是 disable read mostly locking 這個功能 :
SQL> alter system set "_gc_persistent_read_mostly"=FALSE scope=spfile sid='*'; SQL> alter system set "_gc_read_mostly_locking"=FALSE scope=spfile sid='*';
$ srvctl stop database -d <database_name> $ srvctl start database -d <database_name> |