PostgreSQL中的死鎖和鎖等待

来源:https://www.cnblogs.com/wy123/archive/2020/07/23/13363767.html
-Advertisement-
Play Games

開始之前明確一下死鎖和鎖等待這兩個事件的異同相同的之處:兩者都是當前事物在試圖請求被其他事物已經占用的鎖,從而造成當前事物無法執行的現象不同的之處:死鎖是相關session雙方或者多方中必然要犧牲(回滾)至少一個事務,否則雙方(或者多方)都無法執行;鎖等待則不然,對於暫時無法申請到的鎖,嘗試持續地“ ...


 

開始之前明確一下死鎖和鎖等待這兩個事件的異同
相同的之處:兩者都是當前事物在試圖請求被其他事物已經占用的鎖,從而造成當前事物無法執行的現象
不同的之處:死鎖是相關session雙方或者多方中必然要犧牲(回滾)至少一個事務,否則雙方(或者多方)都無法執行;鎖等待則不然,對於暫時無法申請到的鎖,嘗試持續地“等待一段時間”,這個等待的時間就是“鎖等待”參數決定,超出之後就不等了。 當事物鎖等待超時後,當前事物已經持有的鎖如何處理,是一個非常考究的問題,
對於MySQL來說,可以選擇回滾整個事務,或者是僅回滾當前鎖超時的語句,具體參考這裡:https://www.cnblogs.com/wy123/p/12724252.html
下文對Postgresql中鎖超時之後當前Session中事務和語句的處理進行一個驗證。

Postgresql的死鎖檢測機制

鎖等待有可能是發展成死鎖,也有可能不是死鎖,可能繼續等待一段時間之後就可以正常申請到所需要的鎖了。
發生死鎖的情況下,一定會產生鎖等待,因為此時的鎖等待繼續下去沒有任何意義,所以必須(立刻)犧牲其中一個事務,MSSQL和MySQL都是類似的處理機制。
沒有死鎖等待時間一說,因為一旦死鎖的條件生成,則沒有任何緩衝的餘地,必須至少犧牲(回滾)其中一個事物,釋放其占用的鎖,來打斷這個死鎖的閉環。
但在MySQ中有一個死鎖自動檢測開關,可以打開或者關閉這個自動的死鎖檢測與解除機制,預設是打開的。
但是在Postgresql中,有一個死鎖等待事件的參數,預設是1s中,也就是是說Postgresql後臺進程會以1s的頻率來檢測是否存在死鎖。

換句話說就是,在Postgresql的死鎖檢測機制中,不是以MySQL中那種實時監測方式來處理死鎖的。為什麼postgresql中對於死鎖要以類似於定時輪訓的方式來實現死鎖檢測而不是實時監測?

回答這個問題之前,先回到MySQL中:
上面提到MySQL中的死鎖自動檢測機制是有一個開關的,當然這個開關是可以關閉的,也就是系統不檢測死鎖信息,那麼在死鎖發生後也就無法自動犧牲其中一個事務。
那為什麼還要允許這個開關設置為關閉呢?其實死鎖檢測也是需要代價的,尤其是實時監測,參考這裡:https://mp.weixin.qq.com/s/Lc_tQEK55r_syapebSu0Cg,提到過通過關閉死鎖檢測來提升性能的最佳實踐。

然後回到Postgresql中:
在Postgresql中,deadlock_timeout是進行死鎖檢測之前在一個鎖上等待的總時間(以毫秒計)。Postgresql的理念中認為死鎖檢測代價是比較高的,因此伺服器不會在每次等待鎖時都判斷有沒有形成死鎖。我們樂觀地假設在生產應用中死鎖是不常出現的,並且只在開始檢測死鎖之前等待一會兒。增加這個值就減少了浪費在無用的死鎖檢測上的時間(頻率),但是降低了報告真正死鎖錯誤的速度。預設是 1 秒(1s),這可能是實際中你想要的最小值。在一個高負載的伺服器上,你可能需要增大它。這個值的理想設置應該超過你通常的事務時間,這樣就可以減少在鎖釋放之前就開始死鎖檢查的機會。同理,對於高併發小事務處理系統上,預設的1秒已經足夠了。只有超級用戶可以更改這個設置。
參考:https://postgresqlco.nf/zh/doc/param/deadlock_timeout/

Postgresql鎖超時

Postgresql中同樣可以設置所等待的超時時間,意味著當前事務在請求一個鎖的時候,一旦等待時長超出指定的時間,當前語句被中止。
該參數的預設值為0,意味著發生鎖等待的時候永遠不超時,一直等待下去。

與statement_timeout不同,這個超時只在等待鎖時發生。註意如果statement_timeout為非零,設置lock_timeout為相同或更大的值沒有意義,因為事務超時將總是先與鎖超時觸發。 官網說不推薦在postgresql.conf中設置lock_timeout,因為它會影響所有會話。
實際這個建議值得商榷,如果不設置lock_timeout,一個Session的鎖等待將無限拉長(如果statement_timeout不限制的話),一旦大量的連接涌入進來等待一個短時間內無法釋放的不相容鎖,那麼資料庫的連接數可能在短時間內被打爆,影響一些正常的連接。這裡認為應該根據系統中事務輕重程度,設置成超過deadlock_timeout且小於statement_timeout的一個值,強制一些超鎖等待超時的Session自動終止,不要無限期等待而占用資料庫連接,引發系統級的異常。

Postgresql中的鎖超時後事務的處理

相比MySQL給予了用戶充分的自由,在超等待超時後,可以選擇設置回滾當前語句,或者回滾整個事務(參數innodb_rollback_on_timeout決定),Postgresql中是如何處理的呢? 可以創建一個死鎖Session,當前事務作為犧牲品犧牲之後,出現current transaction is aborted, commands ignored until end of transaction block
當前Session作為犧牲品之後,回滾的是整個事務,這個容易理解

對於鎖超時之後當前Session的情況呢,設置一個鎖超時的時間

製造一個鎖超時的場景,鎖超時之後,當前Session的任何語句都會被回滾,即便是執行一個commit,當前Session鎖超時後的Session狀態,雖然還是一個活動事務,但能且只能回滾。

鎖超時之後的Session狀態

可見,預設情況下,Postgresql在當前Session鎖超時之後,會回滾整個事務,而不是當前語句,這樣其實更加的科學合理,MySQL也是這麼建議的。

最後,Postgresql中的deadlock_timeout,設置成不同的值,一方面取決於業務,另外一方面,對系統整體的性能影響,該如何科學地衡量?
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在vmware虛擬機環境下: 實驗環境: 1,CentOS7伺服器,ip地址192.168.118.10/24 2,win7客戶端,ip地址192.168.118.100/24 一,搭建伺服器 1,配置本地yum源 [root@localhost ~]# cd /etc/yum.repos.d [r ...
  • session複製集群的原理就是通過多播通信的方式,把節點的session信息發送給集群其他節點;這種session複製集群有一個缺陷,如果後端tomcat server 一旦增多,那麼對於後端用於發送session信息的網路會非常擁擠,到達一定的量以後,後端網路就可能癱瘓,這樣一來session... ...
  • 安裝自動補齊需要依賴工具 yum install -y bash-completion docker命令補齊: 執行下列命令 sh /usr/share/bash-completion/bash_completion sh /usr/share/bash-completion/completions ...
  • 我對ubuntu的紫色不太喜歡,我比較喜歡黑色;雖然20.04版本換成了黑色,登錄界面也很好看;但是我用的是舊版本ubuntu,所以只能動手改了; grub界面顏色設置: vim /usr/share/plymouth/themes/ubuntu-logo/ubuntu-logo.grub; 結束後 ...
  • 近期,重新玩了玩kali下的airmon-ng等一套工具“破解”自家wifi密碼。 首先,有關處理2.4Ghz的wifi,在網上講解詳細且含圖文搭配的教程有許多,所以在這裡就不多贅述了。 這裡,主要說明一下處理5Ghz的wifi,在鎖定目標wifi後使用aireplay-ng指令抓取握手包時在確定無 ...
  • 普通的存儲器器件為單埠,也就是數據的輸入輸出只利用一個埠,設計了兩個輸入輸出埠的就是雙埠sram。雖然還具有擴展系列的4埠sram,但雙埠sram已經非常不錯了。雙埠sram經常應用於cpu與其周邊控制器等類似需要直接訪問存儲器或者需要隨機訪問緩衝器之類的器件之間進行通信的情況。從存儲 ...
  • 在Zabbix Server伺服器上安裝oracle-instantclient11.2後,結果使用sqlplus命令時遇到“sqlplus: error while loading shared libraries: libnsl.so.1: cannot open shared object f... ...
  • 本文更新於2020-05-03,使用MySQL 5.7,操作系統為Deepin 15.4。 許可權 許可權存取需要用到mysql庫中user、db、host、tables_priv、columns_prvi這幾個許可權表。列分為4個部分:用戶列、許可權列、安全列、資源控制列。許可權列又分為普通許可權和管理許可權。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...