Postgresql
調試掛起的會話/鎖
我們遇到了一個反復出現的情況,我們有 2 個查詢掛起,其他查詢等待那個查詢,我們的數據庫陷入停頓。我正在嘗試對此進行調試並尋求幫助。數據庫是執行 Postgres 10.6 的 RDS。
我使用 DBeaver 來監控和管理這個 DB,這裡是來自該應用程序中的 Administer -> Lock Manager 的螢幕截圖。在這種情況下,為了解決這個問題,我需要殺死其他人正在等待的一個會話,但我想了解如何更深入地調試它以找出它在等待什麼以及為什麼。
上述查詢有多個副本,因為它是由非常頻繁的 cron 作業生成的,因此至少是預期的。
根據 RDS -> 性能洞察,這個查詢和許多其他查詢在此時花費大量時間處於鎖定狀態
relation
。我希望我在這裡沒有提供足夠的資訊。讓我知道我可以添加什麼。
要調試此問題,首先要找出阻止其他會話的會話在做什麼:
SELECT state, wait_event_type, wait_event FROM pg_stat_activity WHERE pid = 29303; -- or whoever blocks the others
如果會話處於狀態
active
,則它是一個長時間執行的查詢。與查詢一起使用EXPLAIN (ANALYZE, BUFFERS)
以找出它花費時間的地方以及如何改進它。如果狀態是
idle in transactions
,您有一個忘記關閉事務的應用程序錯誤。由於所有的鎖都被持有到事務結束,這會阻塞其他事務,即使它什麼都不做。短期的解決方案是使用該
pg_cancel_backend()
功能來殺死阻塞事務。長期的解決方案是修復保持事務打開的錯誤,並通過使用越來越少的鎖來提高並發性:
EXCLUSIVE
圖像中的事務放在桌子上的鎖是嚴厲的。以我的經驗,顯式表鎖幾乎沒有必要或指示。通常它們表明程序員對數據庫事務的理解不夠好。