Postgres併發處理

資料庫工作筆記發表於2024-02-20

來源:小技術君

本文,我們將深入探討併發的概念以及Postgres中是如何處理它的。讓我們開始吧!

併發及其角色

電腦科學史上最受追捧的詞彙之一是併發[1]並行[2]。如果沒有這兩者的需求,我們可以簡單地一次執行一個程式,不需要作業系統資源(RAM、CPU)在應用程式之間進行排程,從而使核心變得更簡單。核心的核心目的是排程和協調計算機資源和應用程式,使併發和並行成為可能。儘管沒有這些概念,整體複雜性可以減少95%,但顯然,95%的開發無法在沒有這些概念的情況下進行。

Postgres併發處理

併發 vs 並行

併發是處理多個任務的能力,但不一定是同時執行它們。並行涉及同時執行多個任務,通常使用多個處理單元。雖然併發和並行被認為是*不同[3]*概念,但它們實質上宣揚相同的原則,即在給定的時間內處理多個操作。我們可以堅持使用“併發”這個詞。要具體解釋併發是如何在實現它的所有領域中處理的是不可能的,因為我們處理的所有計算機系統都是以併發作為基本概念構建的。但我們可以談論最主要的領域,即資料庫系統。每個資料庫系統都採用不同的策略實現併發,但最終,我們可以將其歸結為三種策略:

1.[4] — 限制對特定資料或資源的訪問,確保只有一個使用者/程式/事務可以同時修改/檢視特定記錄或記錄集。2.多版本併發控制[5](MVCC) — 為每個使用者/程式/事務維護多個版本(下文更多介紹)。3.基於時間戳的協議[6] — 使用時間戳確定事務的序列化順序,確保事務以維護一致性的方式執行。

Postgres如何處理併發 ⛁

Postgres同時使用鎖和MVCC,但更傾向於其MVCC架構。

MVCC[7] 提供了事務之間的強大隔離[8]。這意味著每個事務都獲得其資料庫的快照或版本,其中包含有關已提交、進行中或尚未啟動的事務ID的資訊。

因此,每個快照包括:

當前事務的事務ID。活動事務ID列表 — 那些已經開始但尚未提交或回滾的事務。在拍攝快照時提交的最高事務ID。在此之後的任何ID都被視為從快照的角度來看處於“未來”。

其目的是為每個事務建立一致的檢視,以避免讀寫之間的衝突。

Postgres併發處理

MVCC事務內部流程

所有未提交的更改都在共享緩衝區快取和Write-Ahead Logging(WAL)系統中進行跟蹤,直到它們提交。一旦提交,這些更改就會被重新整理到資料庫中。為了更好地解釋MVCC的目的,考慮兩個併發事務:一個更新了行的列,另一個查詢了該行。如果第一個事務更新但尚未提交,而第二個在第一個提交之前進行查詢,可能會導致獲取未提交的更新行資料,這是不正確的,因為第一個事務有可能被中止。這種狀態稱為髒讀。Postgres如何解決這個問題呢?每個表都有帶有兩個系統列的行標頭:

xmin — 建立行的事務ID。xmax — 刪除行的事務ID。

由於MVCC快照具有事務ID(xmin)列表,因此每個事務都知道所有併發事務。在髒讀的情況下,第二個事務的快照中有第一個事務的ID在其併發事務列表中,因此Postgres會過濾該行並獲取所有其餘的符合條件的行。

Postgres併發處理

有無MVCC的區別

更詳細地說,Postgres在執行時進行了多個檢查,以確定行是否對當前事務可見。僅當滿足以下xmin條件之一時,行才可見:

xmin小於最高已提交事務ID。它是當前事務的ID。

還應遵守以下xmax條件之一:

xmax應為未設定狀態。它引用一個截至事務快照時尚未提交或啟動的事務。

這些檢查在執行時進行,但目前尚不清楚它們是如何高效地進行的,以確保不影響效能。

使用MVCC模型而不是鎖的主要優勢在於,在MVCC中,用於寫入資料的鎖不會阻塞讀取資料,反之亦然。

Postgres MVCC不能處理的事情 💔

MVCC旨在防止併發的讀/寫衝突,但它不能處理併發的寫操作,這由傳統的鎖來管理。Postgres在不同層次(行、表)上提供了各種鎖定機制,但對於同一行的寫操作,它們應該按順序進行。

雖然MySQL也透過其預設儲存引擎InnoDB提供MVCC功能,但Postgres是首個將這一概念引入資料庫世界的。這種早期採用使Postgres在讀寫負載方面比MySQL更具效能優勢,因為MySQL沒有同等最佳化。然而,在讀重型系統中,MySQL更受歡迎,因為它已被證明比Postgres更為高效。

引用連結

[1] 併發: https://www.notion.so/How-concurrency-handled-in-postgres-0d9b873c9a6e45dabfbf5d21d1947c94?pvs=4
[2] 並行: https://www.notion.so/How-concurrency-handled-in-postgres-0d9b873c9a6e45dabfbf5d21d1947c94?pvs=4
[3] 不同: https://www.google.com/search?q=concurrency+vs+parallelism&sca_esv=599372071&sxsrf=ACQVn09k-k_w7TlIT8VC8wFgW6QmAVZdDw%3A1705555740621&ei=HLeoZfjKJeiRseMP5J-K8AY&ved=0ahUKEwj4yMGgmuaDAxXoSGwGHeSPAm4Q4dUDCBA&uact=5&oq=concurrency+vs+parallelism&gs_lp=Egxnd3Mtd2l6LXNlcnAiGmNvbmN1cnJlbmN5IHZzIHBhcmFsbGVsaXNtMhEQABiABBiKBRiRAhixAxiDATILEAAYgAQYigUYkQIyCxAAGIAEGIoFGJECMgsQABiABBiKBRiRAjIFEAAYgAQyBRAAGIAEMgUQABiABDIFEAAYgAQyBRAAGIAEMgUQABiABEi5CVCJBViRB3ACeAGQAQCYAXCgAdABqgEDMS4xuAEDyAEA-AEBwgIKEAAYRxjWBBiwA8ICDRAAGIAEGIoFGEMYsAPCAg0QABiABBgNGLEDGIMBwgIGEAAYBxgewgIHEAAYgAQYDeIDBBgAIEGIBgGQBgo&sclient=gws-wiz-serp
[4] 鎖: https://blog.dbwatch.com/database-locks-how-to-monitor-and-manage-it
[5] 多版本併發控制: 
[6] 基於時間戳的協議: ~:text=Timestamp%2Dbased%20protocols%20are%20concurrency,without%20the%20need%20for%20locking.
[7] MVCC
[8] 隔離: 


來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70027826/viewspace-3006817/,如需轉載,請註明出處,否則將追究法律責任。

相關文章