摘要:本文主要介紹在 gaussdb(dws) 中,如何通過 sql 語句,對分布式死鎖進行檢測和恢復。
分布式數倉應用場景中,我們經常遇到資料庫系統 hang 住的問題,所謂 hang 是指雖然資料庫系統還在執行,但部分或全部業務無法正常執行。hang 問題的原因有很多,其中以分布式死鎖最為常見,本次主要分享在碰到死鎖時,如何快速地解決死鎖問題。
gaussdb(dws) 作為分布式數倉,通過鎖機制來實行併發控制,因此也存在產生分布式死鎖的可能。雖然分布式死鎖無法避免,但幸運的是其提供了多種系統檢視,能夠保證在分布式死鎖發生之後,快速地對死鎖進行定位。
收集各節點的鎖資訊。
構建等待關係。
檢測迴圈等待。
中止事務以消除死鎖。
本文介紹的方法使用簡單,門檻低,可以確保在分布式死鎖發生之後,快速解決問題,恢復業務。
通過 sql 語句進行分布式死鎖的檢測與消除
分布式死鎖和單節點死鎖的比較
單節點死鎖
單節點死鎖是指,死鎖中的所有鎖等待資訊來自同乙個節點,例如:
複製**
– 事務 transaction1
– 所在節點:cn1
begin;
truncate t1;
execute direct on(dn1) 『select * from t2』;
commit;
– 事務 transaction2
– 所在節點:cn1
begin;
truncate t2;
execute direct on(dn2) 『select * from t1』;
commit;
複製**
假設上述兩個事務的執行順序如下:
[transaction1] truncate t1
[transaction2] truncate t2
[transaction1] execute direct on(dn1) 『select * from t2』
[transaction2] execute direct on(dn2) 『select * from t1』
該執行順序會導致死鎖的產生。由於事務 transaction1 和 transaction2 都在 cn1 上執行,死鎖中的所有鎖等待資訊都在 cn1 上,因此該死鎖為單節點死鎖。
gaussdb(dws) 支援自動處理單節點死鎖。當某個節點上的多個事務陷入迴圈等待時,資料庫系統會自動將其中乙個事務中止,從而消除死鎖。
分布式死鎖
分布式死鎖是指,死鎖中的鎖等待資訊來自不同節點。例如:
複製**
– 事務 transaction1
– 所在節點:cn1
begin;
truncate t1;
execute direct on(dn1) 『select * from t2』;
commit;
– 事務 transaction2
– 所在節點:cn2
begin;
truncate t2;
execute direct on(dn2) 『select * from t1』;
commit;
複製**
本例與上一節中的例子相比,只有事務 transaction2 的所在節點從 cn1 改為了 cn2。
這就是乙個典型的分布式死鎖,單獨看 cn1 或 cn2 上的鎖等待資訊,都看不出來有死鎖,但將多個節點的鎖等待資訊放到一起看,就能找到有迴圈等待的現象。
發生分布式死鎖時,陷入死鎖的事務全部都無法繼續執行下去,只有其中乙個事務鎖等待超時,剩餘事務才能繼續執行。預設情況下,鎖等待超時時間是 20 分鐘。
分布式死鎖的檢測與消除
當我們觀察到資料庫系統出現 hang 問題時,我們需要通過 sql 語句檢測分布式死鎖,如果發現確實存在分布式死鎖,還需要對死鎖進行消除。接下來以之前的分布式死鎖為例,介紹分布式死鎖的檢測和消除的方法。
收集各節點的鎖資訊
為了檢測分布式死鎖,首先需要獲得各節點的鎖資訊。gaussdb(dws) 中可以通過 pg_locks 檢視查詢當前節點的鎖資訊,因此可以通過 execute direct 語句在所有節點查詢 pg_locks 檢視,並收集到當前節點中。
注意此處有乙個細節,pg_locks 檢視中,很多資訊是以 oid 型別給出的,例如乙個鎖加在乙個表上,pg_locks 檢視會給出表的 oid。由於同乙個表在各節點中的 oid 不一定相同,因此不能通過 oid 來標識乙個表。在收集鎖資訊時,需要先將表的 oid 轉換成 schema 名加表名。其它 oid 資訊例如分割槽 oid 等也同理,需要轉化為對應的名字。
執行附件中的示例** pgxc_locks.sql,就可以收集到各節點的鎖資訊:
複製**
複製**
構建等待關係
收集到各節點的鎖資訊之後,就可以開始構建等待關係了。
事務 a 等待事務 b,需要滿足 3 個條件:
兩個事務加鎖的資源相同(同乙個表、同乙個分割槽、同乙個頁面或同乙個元組等)。特別注意,如果事務 a 對 dn1 的 t1 表的加鎖,事務 b 對 dn2 的 t1 表的加鎖,則我們認為它們加鎖的資源不同,只有同一節點上的同一資源才被認為是相同的資源。
事務 b 已經持有鎖,而事務 a 還未持有鎖。
事務 a 和事務 b 申請的鎖的級別互斥。
通過對上一步收集到的鎖資訊進行處理,就可以構建出事務的等待關係。
執行附件中的示例** pgxc_locks_wait.sql,就可以獲得等待關係:
複製**
複製**
等待關係判環
構建出事務的等待關係之後,就可以通過檢查等待關係是否成環,來判斷當前是否有分布式死鎖。
一般情況下,等待關係不會太多,通過觀察就可以判斷出當前有無分布式死鎖。通過觀察上一節中構建的等待資訊,可以很容易地判斷出事務 transaction1 和 transaction2 發生了迴圈等待,即產生了死鎖。
消除死鎖
上一步最終可能會找到等待關係中的乙個或多個環,對於每個環,需要中止環中的乙個事務,才能消除死鎖。至於應該選擇環中的哪個事務進行中止,需要我們從事務的重要性、已執行時間等多方面進行考慮,最終選擇乙個對業務影響最小的事務進行中止。
總結通過 sql 語句,我們可以很方便地處理分布式死鎖。當我們在實際業務中遇到資料庫系統 hang 住的問題時,可以借助本文提供的方法,檢查 hang 問題是否是分布式死鎖引起的,如果問題確實是由分布式死鎖引起的,還可以通過中止某個陷入死鎖的事務,來快速恢復業務。
保護關鍵資料抵禦內部威脅 僅需5步
現在世界各地的公司都開始關注保護敏感資料抵禦高階威脅,而其中一種威脅引起最高關注 內部威脅 44.5 的攻擊來自惡意內部人員。解決內部威脅的有效方法包括兩個方面 第一,企業需要通過保護關鍵資料以及管理身份來減少內部威脅帶來的影響 其次,他們需要監控其授權使用者的行動以檢測任何異常行為。在這篇文章中,...
保護關鍵資料抵禦內部威脅 僅需5步
現在世界各地的公司都開始關注保護敏感資料抵禦高階威脅,而其中一種威脅引起最高關注 內部威脅 44.5 的攻擊來自惡意內部人員。解決內部威脅的有效方法包括兩個方面 第一,企業需要通過保護關鍵資料以及管理身份來減少內部威脅帶來的影響 其次,他們需要監控其授權使用者的行動以檢測任何異常行為。在這篇文章中,...
玩通仙4了
從福州回來以後,買了張二手破顯示卡 64m geforce4 加上郵費一共40塊錢。我終於也用上獨顯了 本來仙4想買正版來玩的,但是看我連顯示卡都沒錢買,就知道我現在是買不起正版的。但是太想玩了,就下了盜版,以後一定要把仙劍的正版都買齊。今天早上,玄霄和夙瑤也被我打敗了,通了。我沒玩之前就看過結局,...