2025年9月25日: PostgreSQL 18 釋出!
支援的版本: 當前 (18) / 17 / 16 / 15 / 14 / 13
開發版本: devel
不支援的版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3

28.4. 非同步提交 #

非同步提交 是一種允許事務更快完成的選項,但代價是資料庫崩潰時可能丟失最新的事務。在許多應用程式中,這是一個可接受的權衡。

如前一節所述,事務提交通常是 同步 的:伺服器在向客戶端返回成功指示之前,會等待事務的WAL記錄被重新整理到永久儲存。因此,客戶端可以保證報告已提交的事務將被保留,即使伺服器在之後立即崩潰。然而,對於短事務來說,這種延遲是總事務時間的主要組成部分。選擇非同步提交模式意味著伺服器在事務邏輯上完成後立即返回成功,而在它生成的WAL記錄實際寫入磁碟之前。這可以為小型事務提供顯著的吞吐量提升。

非同步提交引入了資料丟失的風險。在向客戶端報告事務完成與事務真正提交(即保證在伺服器崩潰時不會丟失)之間有一個短暫的時間視窗。因此,如果不應使用非同步提交,客戶端將採取外部操作,依賴於事務將被記住的假設。例如,銀行絕對不會使用非同步提交來記錄自動取款機吐出現金的事務。但在許多場景中,例如事件日誌記錄,就不需要這種強有力的保證。

使用非同步提交的風險是資料丟失,而不是資料損壞。如果資料庫崩潰,它將透過重放WAL到最後一個已重新整理記錄來恢復。因此,資料庫將恢復到一致的狀態,但尚未重新整理到磁碟的任何事務將不會反映在該狀態中。最終效果是丟失最後幾個事務。因為事務是按提交順序重放的,所以不會引入不一致——例如,如果事務 B 進行了依賴於先前事務 A 的效果的更改,那麼 A 的效果不可能在 B 的效果被保留的同時丟失。

使用者可以選擇每個事務的提交模式,因此可以同時運行同步和非同步提交的事務。這允許在效能和事務永續性保證之間進行靈活的權衡。提交模式由使用者可設定的引數 synchronous_commit 控制,該引數可以透過任何設定配置引數的方式進行更改。任何一個事務使用的模式取決於事務提交開始時 synchronous_commit 的值。

某些實用命令,例如 DROP TABLE,無論 synchronous_commit 的設定如何,都會強制同步提交。這是為了確保伺服器檔案系統與資料庫的邏輯狀態之間的一致性。支援兩階段提交的命令(如 PREPARE TRANSACTION)也始終是同步的。

如果在非同步提交和事務WAL記錄寫入之間的風險視窗期間資料庫崩潰,那麼該事務所做的更改 會丟失。風險視窗的持續時間是有限的,因為後臺程序(WAL writer)每 wal_writer_delay 毫秒將未寫入的WAL記錄重新整理到磁碟。風險視窗的實際最長持續時間是 wal_writer_delay 的三倍,因為 WAL writer 的設計是在繁忙時段優先寫入整個頁面。

注意

立即模式關機等同於伺服器崩潰,因此將導致任何未重新整理的非同步提交丟失。

非同步提交提供的行為不同於設定 fsync = off。 fsync 是一個伺服器範圍的設定,它會改變所有事務的行為。它停用了 PostgreSQL 中試圖將寫操作同步到資料庫不同部分的所有邏輯,因此係統崩潰(即硬體或作業系統崩潰,而不是 PostgreSQL 本身失敗)可能導致資料庫狀態任意嚴重損壞。在許多場景中,非同步提交提供了透過關閉 fsync 所能獲得的大部分效能提升,而沒有資料損壞的風險。

commit_delay 聽起來也非常類似於非同步提交,但它實際上是一種同步提交方法(事實上,在非同步提交期間會忽略 commit_delay)。 commit_delay 會在事務重新整理WAL到磁碟之前延遲一段時間,希望能有一個事務執行的單個重新整理也可以服務於大約同時提交的其他事務。該設定可以被認為是增加事務可以加入即將參與單個重新整理的組的時間視窗的一種方式,以分攤多個事務的重新整理成本。

提交更正

如果您在文件中發現任何不正確、與您在使用特定功能時的體驗不符或需要進一步澄清的內容,請使用 此表單 報告文件問題。