最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

PostgreSQL死鎖排查與解決指南

 更新時(shí)間:2025年11月05日 09:56:21   作者:Moshow鄭鍇  
數(shù)據(jù)庫(kù)死鎖是后端開(kāi)發(fā)者和DBA經(jīng)常遇到的棘手問(wèn)題,本文將手把手教你如何排查和解決PostgreSQL中的死鎖問(wèn)題,需要的朋友可以參考下

PostgreSQL 16默認(rèn)會(huì)記錄死鎖嗎?

答案是不會(huì)! 

雖然PostgreSQL 16具備死鎖檢測(cè)機(jī)制(在等待鎖超過(guò)deadlock_timeout后會(huì)自動(dòng)檢測(cè)并解決死鎖),但默認(rèn)不會(huì)將死鎖的詳細(xì)信息記錄到日志中。這就意味著你知道發(fā)生了死鎖,卻不知道具體原因!

如何配置死鎖日志記錄

1. 修改配置文件

找到PostgreSQL數(shù)據(jù)目錄下的postgresql.conf文件,添加以下配置:

# 記錄鎖等待信息(關(guān)鍵?。?
log_lock_waits = on
 
# 死鎖檢測(cè)超時(shí)時(shí)間(默認(rèn)1秒)
deadlock_timeout = 1s
 
# 日志級(jí)別至少設(shè)置為log
log_min_messages = log
 
# 詳細(xì)的日志前綴
log_line_prefix = '%t [%p]: db=%d,user=%u,app=%a,client=%h '

2. 重新加載配置

-- 在psql中執(zhí)行
SELECT pg_reload_conf();

或者使用命令行:

pg_ctl reload -D /path/to/your/data/directory

死鎖日志分析實(shí)例

配置完成后,當(dāng)死鎖發(fā)生時(shí),你會(huì)在日志中看到類似這樣的詳細(xì)信息:

2025-11-02 10:23:41.123 CST [12345]: LOG:  ?? Powered by Moshow 鄭鍇 | 更多技術(shù)干貨:https://zhengkai.blog.csdn.net
2025-11-02 10:23:41.123 CST [12345]: LOG:  process 12345 detected deadlock while waiting for ShareLock on transaction 123456 after 1000.123 ms
2025-11-02 10:23:41.123 CST [12345]: DETAIL:  Process holding the lock: 12346. Wait queue: .
2025-11-02 10:23:41.123 CST [12345]: PROCESS 12345: 等待事務(wù) 123456 的 ShareLock; 被進(jìn)程 12346 阻塞.
2025-11-02 10:23:41.123 CST [12345]: PROCESS 12345: 執(zhí)行語(yǔ)句: UPDATE accounts SET balance = balance - 100.00 WHERE user_id = 1;
2025-11-02 10:23:41.123 CST [12346]: PROCESS 12346: 等待事務(wù) 123457 的 ShareLock; 被進(jìn)程 12345 阻塞.
2025-11-02 10:23:41.123 CST [12346]: PROCESS 12346: 執(zhí)行語(yǔ)句: UPDATE accounts SET balance = balance + 50.00 WHERE user_id = 2;
2025-11-02 10:23:41.123 CST [12345]: ERROR:  deadlock detected

如何解讀這個(gè)日志:

  • 涉及進(jìn)程:進(jìn)程12345和12346
  • 死鎖場(chǎng)景:兩個(gè)進(jìn)程互相等待對(duì)方釋放鎖
  • 執(zhí)行的SQL:兩個(gè)UPDATE語(yǔ)句在競(jìng)爭(zhēng)相同的資源
  • 解決方案:PostgreSQL選擇中止進(jìn)程12345的事務(wù)
    • 溫和終止(優(yōu)先嘗試):     SELECT pg_terminate_backend(12345);
    • 強(qiáng)制終止(若溫和方式失敗):  SELECT pg_cancel_backend(12345);

實(shí)時(shí)監(jiān)控:系統(tǒng)視圖分析

除了查看日志,你還可以實(shí)時(shí)監(jiān)控當(dāng)前的鎖等待情況:

強(qiáng)大的鎖等待查詢語(yǔ)句

--?? Powered by Moshow 鄭鍇 | 更多技術(shù)干貨:https://zhengkai.blog.csdn.net
SELECT
    blocked_locks.pid AS blocked_pid,
    blocked_activity.usename AS blocked_user,
    blocking_locks.pid AS blocking_pid,
    blocking_activity.usename AS blocking_user,
    blocked_activity.query AS blocked_statement,
    blocking_activity.query AS current_statement_in_blocking_process,
    blocked_activity.application_name AS blocked_application,
    blocking_activity.application_name AS blocking_application
FROM pg_catalog.pg_locks blocked_locks
JOIN pg_catalog.pg_stat_activity blocked_activity 
    ON blocked_activity.pid = blocked_locks.pid
JOIN pg_catalog.pg_locks blocking_locks 
    ON blocking_locks.locktype = blocked_locks.locktype
    AND blocking_locks.DATABASE IS NOT DISTINCT FROM blocked_locks.DATABASE
    AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
    AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page
    AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple
    AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid
    AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid
    AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid
    AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid
    AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid
    AND blocking_locks.pid != blocked_locks.pid
JOIN pg_catalog.pg_stat_activity blocking_activity 
    ON blocking_activity.pid = blocking_locks.pid
WHERE NOT blocked_locks.granted;

查詢結(jié)果示例:

blocked_pidblocked_userblocking_pidblocking_userblocked_statement
12345app_user12346app_userUPDATE accounts SET balance = balance - 100 WHERE user_id = 1
12347web_user12348batch_userDELETE FROM orders WHERE status = 'cancelled'

這個(gè)查詢能幫你:

  • 實(shí)時(shí)發(fā)現(xiàn)阻塞情況
  • 識(shí)別阻塞的源頭
  • 看到具體的阻塞SQL語(yǔ)句
  • 在死鎖發(fā)生前進(jìn)行干預(yù)

最佳實(shí)踐建議

  • 生產(chǎn)環(huán)境務(wù)必配置日志:log_lock_waits = on 是你的生命線
  • 合理設(shè)置超時(shí):deadlock_timeout 保持默認(rèn)1秒即可
  • 定期檢查日志:關(guān)注 pg_stat_database 中死鎖計(jì)數(shù)器的變化
  • 代碼層面預(yù)防:確保事務(wù)中的SQL操作順序一致
  • 實(shí)時(shí)監(jiān)控:使用系統(tǒng)視圖查詢作為輔助診斷工具

預(yù)防勝于治療!通過(guò)合理的應(yīng)用設(shè)計(jì)和數(shù)據(jù)庫(kù)配置,可以大大減少死鎖的發(fā)生頻率。

以上就是PostgreSQL死鎖排查與解決指南的詳細(xì)內(nèi)容,更多關(guān)于PostgreSQL死鎖排查的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論

桂平市| 永定县| 肥西县| 兖州市| 来凤县| 壤塘县| 什邡市| 青龙| 玉龙| 曲沃县| 汾西县| 治县。| 垦利县| 昆山市| 阳曲县| 克拉玛依市| 肇东市| 阿巴嘎旗| 曲沃县| 怀来县| 汤阴县| 宁波市| 华阴市| 霍林郭勒市| 景谷| 宜黄县| 化隆| 宿迁市| 香格里拉县| 万源市| 安仁县| 缙云县| 方城县| 富裕县| 巴彦淖尔市| 夏河县| 大姚县| 沽源县| 云霄县| 荔浦县| 合水县|