postgresql , pg_locks , pg_stat_activity , 鎖監控 , 誰堵塞了誰
在資料庫中,通過鎖以及多版本并發控制可以保護資料的一緻性,例如a正在查詢資料,b就無法對a通路的對象執行ddl。a正在更新某條記錄,b就不能删除或更新這條記錄。
鎖是資料庫自動管理的,同時資料庫還提供了ad lock或者lock文法,允許使用者自己控制鎖。
例如ad lock的應用可以參考如下:
<a href="https://github.com/digoal/blog/blob/master/201705/20170507_02.md">《postgresql 使用advisory lock實作行級讀寫堵塞》</a>
<a href="https://github.com/digoal/blog/blob/master/201610/20161020_02.md">《postgresql 無縫自增id的實作 - by advisory lock》</a>
<a href="https://github.com/digoal/blog/blob/master/201610/20161018_01.md">《postgresql 使用advisory lock或skip locked消除行鎖沖突, 提高幾十倍并發更新效率》</a>
<a href="https://github.com/digoal/blog/blob/master/201611/20161117_01.md">《聊一聊雙十一背後的技術 - 不一樣的秒殺技術, 裸秒》</a>
當然,如果應用程式邏輯設計不慎,就可能導緻嚴重的鎖等待,或者死鎖的産生。
如果你發現sql請求大多數時候處于等待鎖的狀态,那麼可能出現了業務邏輯的問題。
如何檢查或監控鎖等待呢?
postgresql提供了兩個視圖
1. pg_locks展示鎖資訊,每一個被鎖或者等待鎖的對象一條記錄。
2. pg_stat_activity,每個會話一條記錄,顯示會話狀态資訊。
我們通過這兩個視圖可以檢視鎖,鎖等待情況。同時可以了解發生鎖沖突的情況。
pg_stat_activity.query反映的是目前正在執行或請求的sql,而同一個事務中以前已經執行的sql不能在pg_stat_activity中顯示出來。
是以如果你發現兩個會話發生了沖突,但是他們的pg_stat_activity.query沒有沖突的話,那就有可能是他們之間的某個事務之前的sql擷取的鎖與另一個事務目前請求的query發生了鎖沖突。
如果追蹤詳細的鎖沖突資訊:
1. 可以通過lock trace跟蹤鎖等待的詳細資訊,
<a href="https://github.com/digoal/blog/blob/master/201301/20130128_01.md">《postgresql developer options (debug, trace, system table mod and so on...) 詳解》</a>
2. 通過資料庫日志(開啟lock_timeout, log_lockwait參數)(csvlog)跟蹤鎖等待資訊,
3. 或者通過資料庫日志(開啟log_statements='all',sql審計)追蹤事務中所有的sql (csvlog),分析事務之間的鎖沖突。
4. 通過sql檢視持鎖,等鎖的事務狀态。
鎖的釋放時機:
大多數鎖要等待事務結束後釋放,某些輕量級鎖(資料庫自動控制)是随用随釋放的。
這條sql非常有用,建議dba珍藏。
如果覺得寫sql麻煩,可以将它建立為視圖
1. 前面的鎖查詢sql,已經清晰的顯示了每一個發生了鎖等待的對象,按鎖的大小排序,要快速解出這種狀态,terminate最大的鎖對應的pid即可。
會話d
幹掉23043後,大家都清淨了
如果是greenplum,由于版本問題,sql語句略微不一樣,如下:
測試
關注gp_segment_id=-1的,長時間等待,殺掉procpid即可。
<a href="https://www.postgresql.org/docs/9.6/static/view-pg-locks.html">https://www.postgresql.org/docs/9.6/static/view-pg-locks.html</a>
<a href="https://www.postgresql.org/docs/9.6/static/monitoring-stats.html#pg-stat-activity-view">https://www.postgresql.org/docs/9.6/static/monitoring-stats.html#pg-stat-activity-view</a>
<a href="https://www.postgresql.org/docs/9.6/static/mvcc.html">https://www.postgresql.org/docs/9.6/static/mvcc.html</a>
<a href="https://github.com/digoal/blog/blob/master/201104/20110408_01.md">《compare postgresql and oracle dead lock detect and transaction》</a>
<a href="https://github.com/digoal/blog/blob/master/201306/20130620_01.md">《postgresql lock waiting order》</a>
<a href="https://github.com/digoal/blog/blob/master/201211/20121114_01.md">《postgresql row lock and htup.t_infomask thinking》</a>