頻繁更新基礎數據表造成的數據庫死鎖

       最近,有個比較大的項目出現數據庫死鎖。經過分析數據庫trace文件,發現死鎖的是基礎數據表疾病診斷。根據對應的sql語句找到了問題所在,門診醫生錄入診斷時,程序裏面同時去更新疾病診斷基礎表,造成診斷基礎表被鎖。

        經過分析,診斷基礎表共27886條記錄,分佈在312個數據塊中,每個數據塊包含75到114條不等的記錄。由於數據庫服務器安裝的oracle rac, 共兩個節點,oracle的最小單位是數據塊,當幾百個門診大夫一起錄入診斷的時候,頻繁的更新基礎數據,造成數據塊不停的在兩個節點之間轉換,而且很多病人都同時患多種疾病,大夫錄入診斷的順序也很可能不同,造成疾病診斷表被鎖。

       另外從數據庫trace文件中發現了itl鎖,每個數據塊上面的事務槽位上限是255,通過查詢疾病診斷表,發現數據塊裏面最大的記錄數也就才114行,而程序裏面是按照值唯一的字段(無索引)去更新的記錄,理論上應該不會出現itl鎖,但是理論終歸是理論,由於數據塊裏面數據插入之後的再更新,佔用了一部分預留的10%的pctfree空間,造成了沒有足夠的可用空閒空間來支撐更多的事務併發,所以出現了itl鎖,這些鎖一起造成了部分大夫無法下診斷長達20分鐘。

        這種在併發量很高的業務流程裏面去更新常用的基礎表,可以說,從設計上就是錯誤的。如今的項目,數據量都已經達到了很高的程度了,而且併發也越來越大,性能問題應該引起所有IT人員的注意。數據量少或者併發量低的時候,一些性能低的sql語句可能發現不了問題,但是隨着系統運行時間的增長,定會有出現問題的那一天。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章