postgresql , 流複制 , 異步 , 2pc , 3pc
postgresql支援多種事務commit模式,以一主多備的同步流複制為例,事務的redo資訊持久化是怎樣的呢?
配置synchronous_commit參數如下,以及對應的含義:
local:表示redo本地持久化。
on:表示本地持久化,以及一個備庫持久化。
remote_write:表示本地持久化,以及備庫異步write完成。
off:表示本地寫wal buffer完成。
quorum:表示本地持久化,同時加上備庫已持久化的個數,需要超過半數節點。
很顯然,如果隻有一個備庫,并且synchronous_commit使用local模式的話,在發生ha時,不能保證不丢資料。
但是有什麼方法能做到隻有一個備庫,并且synchronous_commit使用local模式,還能不丢資料呢?
兩階段送出(2pc),在很多分布式資料庫中,被用于確定分布式事務的一緻性。
在單個資料庫中,也可以被業務用于多個事務之間的依賴保證。
實際上,如果你要保證事務送出後,在異步的備庫也送出,也可以使用2pc來實作。
首先我們要了解如何判斷備庫的延遲.
檢視目前資料庫的lsn位置。
檢視備庫接收并持久化的wal lsn位置。
當 "備庫的lsn >= 目前主庫的lsn" 時,說明你前面送出的事務都已經同步到備庫了。
主庫
産生一個2pc事務
檢視備庫lsn是否大于等于主庫目前的lsn
確定 備庫lsn是否大于等于主庫目前的lsn 後,關閉主庫(模拟主庫down機)
檢視備庫現在有沒有未結束的2pc事務,目前還沒有激活,是以看不到
激活備庫
再次檢視備庫,未送出的2pc出現了。
你要做的是送出或復原這些2pc事務即可。
使用這種方式,我們在異步的流複制節點中,也可以做到不丢事務。(雖然這麼做比較繁瑣。)
對于非常關鍵的事務,你可以通過以上方式來實作異步複制也不丢資料。
實際上postgresql的同步級别(synchronous_commit)可以配置在事務中,也就是說,可以對可靠性要求高的事務,設定為同步模式。
對于可靠性要求低的事務,設定為異步模式。
例子,設定事務為同步模式。
例子,設定事務為異步模式。
<a href="https://github.com/digoal/blog/blob/master/201703/20170312_18.md">《postgresql 10.0 preview 功能增強 - slave支援waitlsn 'lsn', time;用于設定安全replay栅欄》</a>
<a href="https://www.postgresql.org/docs/9.6/static/sql-prepare-transaction.html">https://www.postgresql.org/docs/9.6/static/sql-prepare-transaction.html</a>
<a href="https://www.postgresql.org/docs/9.6/static/sql-commit-prepared.html">https://www.postgresql.org/docs/9.6/static/sql-commit-prepared.html</a>
<a href="https://www.postgresql.org/docs/9.6/static/sql-rollback-prepared.html">https://www.postgresql.org/docs/9.6/static/sql-rollback-prepared.html</a>
<a href="https://www.postgresql.org/docs/9.6/static/view-pg-prepared-xacts.html">https://www.postgresql.org/docs/9.6/static/view-pg-prepared-xacts.html</a>