1. 程式人生 > >頻繁更新基礎資料表造成的資料庫死鎖

頻繁更新基礎資料表造成的資料庫死鎖

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

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

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

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