支援的版本:目前 (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它產生的記錄實際上已傳輸到磁碟之前。 這可以顯著提高小交易的吞吐量。

非同步提交會帶來資料遺失的風險。 在向客戶端報告交易完成與交易真正提交之間(即,保證如果伺服器崩潰,它不會遺失)存在一個短暫的時間窗口。 因此,如果客戶端將採取外部操作,並且依賴於交易將被記住的假設,則不應使用非同步提交。 例如,銀行當然不會對記錄 ATM 分發現金的交易使用非同步提交。 但是在許多情況下,例如事件記錄,不需要這種強有力的保證。

使用非同步提交所承擔的風險是資料遺失,而不是資料損壞。 如果資料庫崩潰,它將透過重播WAL直到最後一個被刷新的記錄來恢復。 因此,資料庫將恢復到自我一致的狀態,但是任何尚未刷新到磁碟的交易將不會反映在該狀態中。 因此,最終效果是遺失最後幾個交易。 因為交易是按照提交順序重播的,所以不會引入不一致 — 例如,如果交易 B 依賴於先前交易 A 的影響而進行了變更,則 A 的影響不可能遺失,而 B 的影響得以保留。

使用者可以選擇每個交易的提交模式,以便可以同時執行同步和非同步提交交易。 這允許在效能和交易持久性的確定性之間進行靈活的權衡。 提交模式由使用者可設定的參數 synchronous_commit 控制,可以在設定組態參數的任何方式中進行更改。 用於任何一個交易的模式取決於交易提交開始時 synchronous_commit 的值。

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

如果資料庫在非同步提交和交易之間的風險窗口期間崩潰WAL記錄,那麼在該交易期間所做的變更將會遺失。 風險窗口的持續時間是有限的,因為背景進程(WAL 寫入器)每 wal_writer_delay 毫秒將未寫入WAL記錄刷新到磁碟。 風險窗口的實際最大持續時間是 wal_writer_delay 的三倍,因為 WAL 寫入器被設計為在繁忙時段優先一次寫入整個頁面。

注意

立即模式關機等同於伺服器崩潰,因此會導致任何未刷新的非同步提交遺失。

非同步提交提供的行為不同於設定 fsync = off。 fsync 是一個伺服器範圍的設定,將更改所有交易的行為。 它停用了 PostgreSQL 中嘗試將寫入同步到資料庫不同部分的全部邏輯,因此,系統崩潰(即,硬體或作業系統崩潰,而不是 PostgreSQL 本身發生故障)可能會導致資料庫狀態的任意嚴重損壞。 在許多情況下,非同步提交提供了透過關閉 fsync 可以獲得的大部分效能提升,但沒有資料損壞的風險。

commit_delay 也聽起來與非同步提交非常相似,但它實際上是一種同步提交方法(事實上,在非同步提交期間會忽略 commit_delay)。 commit_delay 會在交易刷新之前造成延遲WAL到磁碟,希望由一個事務執行的單一刷新操作也能服務於幾乎在同一時間提交的其他事務。這種設置可以被認為是一種增加時間窗口的方式,事務可以加入一個即將參與單一刷新的群組,以便在多個事務之間分攤刷新的成本。

提交更正 (Submit correction)

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