異步流複製模式如何保證不丟數據?
標簽
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與LSN柵欄
兩階段提交(2PC),在很多分布式數據庫中,被用於確保分布式事務的一致性。
在單個數據庫中,也可以被業務用於多個事務之間的依賴保證。
實際上,如果你要保證事務提交後,在異步的備庫也提交,也可以使用2PC來實現。
備庫延遲的判斷
首先我們要了解如何判斷備庫的延遲.
查看當前數據庫的LSN位置。
# select pg_current_xlog_insert_location();
pg_current_xlog_insert_location
---------------------------------
3F7/517DE940
(1 row)
查看備庫接收並持久化的WAL LSN位置。
# select flush_location from pg_stat_replication ;
flush_location
----------------
3F7/51EAE058
(1 row)
當 "備庫的LSN >= 當前主庫的LSN" 時,說明你前麵提交的事務都已經同步到備庫了。
例子
主庫
產生一個2PC事務
postgres=# create table test(id int);
CREATE TABLE
postgres=# begin;
BEGIN
postgres=# insert into test values (1);
INSERT 0 1
postgres=# prepare transaction '2pctest';
PREPARE TRANSACTION
查看備庫LSN是否大於等於主庫當前的LSN
postgres=# select flush_location from pg_stat_replication ;
flush_location
----------------
81/A601E170
(1 row)
postgres=# select pg_current_xlog_insert_location();
pg_current_xlog_insert_location
---------------------------------
81/A601E170
(1 row)
確保 備庫LSN是否大於等於主庫當前的LSN 後,關閉主庫(模擬主庫DOWN機)
pg_ctl stop -m fast
waiting for server to shut down.... done
server stopped
查看備庫現在有沒有未結束的2pc事務,當前還沒有激活,所以看不到
postgres=# select * from pg_prepared_xacts ;
transaction | gid | prepared | owner | database
-------------+-----+----------+-------+----------
(0 rows)
激活備庫
pg_ctl promote
server promoting
再次查看備庫,未提交的2PC出現了。
psql
psql (9.4.1)
Type "help" for help.
postgres=# select * from pg_prepared_xacts ;
transaction | gid | prepared | owner | database
-------------+---------+------------------------------+----------+----------
115258352 | 2pctest | 2017-05-04 19:42:51.32323+08 | postgres | postgres
(1 row)
你要做的是提交或回滾這些2PC事務即可。
使用這種方式,我們在異步的流複製節點中,也可以做到不丟事務。(雖然這麼做比較繁瑣。)
對於非常關鍵的事務,你可以通過以上方式來實現異步複製也不丟數據。
事務級同步級別
實際上PostgreSQL的同步級別(synchronous_commit)可以配置在事務中,也就是說,可以對可靠性要求高的事務,設置為同步模式。
對於可靠性要求低的事務,設置為異步模式。
例子,設置事務為同步模式。
begin;
set local synchronous_commit=on; -- 同步模式
....
end;
例子,設置事務為異步模式。
begin;
set local synchronous_commit=local; -- 異步模式
....
end;
參考
《PostgreSQL 10.0 preview 功能增強 - slave支持WAITLSN 'lsn', time;用於設置安全replay柵欄》
https://www.postgresql.org/docs/9.6/static/sql-prepare-transaction.html
https://www.postgresql.org/docs/9.6/static/sql-commit-prepared.html
https://www.postgresql.org/docs/9.6/static/sql-rollback-prepared.html
https://www.postgresql.org/docs/9.6/static/view-pg-prepared-xacts.html
最後更新:2017-05-04 21:01:14