PostgreSQL流複製之一:原理+環境搭建(轉發+整理)

資料來源:html

原理:http://www.javashuo.com/article/p-ahhfshag-br.htmlsql

原理:http://www.javashuo.com/article/p-qulzikte-dp.html數據庫

主備庫配置:https://blog.csdn.net/silenceray/article/details/54692908安全

postgres主備切換之文件觸發方式:https://blog.csdn.net/m15217321304/article/details/88850146服務器

參考:流複製延遲參數https://cloud.tencent.com/developer/article/1524114網絡

 

1、PostgreSQL經過WAL日誌構建高可靠性原理:架構

PostgrepSQL在數據目錄的子目錄pg_xlog子目錄中維護了一個WAL日誌文件,能夠把WAL日誌備份到另一臺備份服務器,經過重作WAL日誌的方式在備服務器上恢復數據(相似Oracle的redo日誌)。併發

WAL日誌複製到另一臺備份服務器能夠有兩種方式:app

一、 WAL日誌文件複製運維

此種方式是寫完一個WAL日誌後,才把WAL日誌文件拷貝到備份數據庫中。這樣一般備份會落後主庫一個WAL日誌文件,當主數據庫發生故障時,主數據庫的WAL文件並無填充完畢未傳輸(默認16MB)、或者時延等緣由致使WAL文件沒有傳輸完畢,會致使被數據庫可能存在必定的數據丟失。此種方式是postgreSQL9.0前版本主要提供的WAL日誌複製機制。

採用此方式的WAL複製,須要:

  • 主數據庫的wal_level配置爲archive或以上。
  • PostgreSQL 9.1以後提供了一個很方便的工具pg_basebackup,使用完成一次基礎備份到備數據庫。
  • 後續產生WAL文件,能夠經過archive_command參數調度命令傳輸至備機。

二、流複製(Streaming Replication)

流複製是PostgreSQL 9.0以後才提供的新的傳遞WAL日誌的方法。經過流複製,備庫不斷的從主庫同步相應的數據,並在備庫apply每一個WAL record,這裏的流複製每次傳輸單位是WAL日誌的record。它的好處是隻要主庫一產生日誌,就會立刻傳遞到備庫,同WAL日誌文件相比有更低同步延遲。

同時PostgreSQL9.0以後提供了Hot Standby能力,備庫在應用WAL record的同時也可以提供只讀服務。

PostgreSQL的流複製最多支持1主8備、支持級聯複製(主->備1,備1->備2)。

 

PostgreSQL流複製的核心部分由walsender,walreceiver和startup三個進程組成:

  1. walreceiver啓動後經過recovery.conf文件中的primary_conninfo參數信息連向主庫,主庫經過鏈接參數replication=true啓動walsender進程。
  2. walreceiver執行identify_system命令,獲取主庫systemid/timeline/xlogpos等信息,執行TIMELINE_HISTORY命令拉取history文件。
  3. 執行wal_startstreaming開始啓動流複製,經過walrcv_receive獲取WAL日誌,期間也會迴應主庫發過來的心跳信息(接收位點、flush位點、apply位點),向主庫發送feedback信息(最老的事務id),避免vacuum刪掉備庫正在使用的記錄。
  4. 執行walrcv_endstreaming結束流複製,等待startup進程更新receiveStart和receiveStartTLI,一旦更新,從新進入2/3/4步驟。

 WAL流複製支持同步、異步方式:

  •  異步流複製模式中,主庫提交的事務不會等待備庫接收WAL日誌流並返回確認信息,所以異步流複製模式下主庫與備庫的數據版本上會存在必定的處理延遲,延遲的時間主要受主庫壓力、備庫主機性能、網絡帶寬等影響,當正常狀況下,主備的延遲一般在毫秒級的範圍內,當主庫宕機,這個延遲就主要受到故障發現與切換時間的影響而拉長,不過雖然如此,這些數據延遲的問題,能夠從架構或相關自動化運維手段不斷優化設置。
  • 同步流複製模式中,要求主庫把WAL日誌寫入磁盤,同時等待WAL日誌記錄複製到備庫、而且WAL日誌記錄在任何一個備庫寫入磁盤後,才能嚮應用返回Commit結果。一旦全部備庫故障,在主庫的應用操做則會被掛起,因此此方式建議起碼是1主2備。

 

2、搭建PostgreSQL數據庫異步流複製環境

前提,數據庫安裝完畢。以主、備庫以下規劃爲例:

主庫地址/端口

10.10.10.1  /  5432

備庫地址/端口

10.10.10.2  /  5432

備主流複製用戶名/密碼

u_standby  /  standby123

數據庫用戶名

postgre

PostgreSQL主備數據庫的同步設置主要涉及以下文件:

  1. pg_hba.conf                 postgresql 主庫訪問規則文件
  2. postgresql.conf            postgresql 主庫配置文件
  3. recovery.conf               postgresql 備庫訪問主庫配置文件
  4. .pgpass                        postgresql 備庫訪問主庫的密碼文件

正常主備流複製狀況下:

  • 主庫須要pg_hba.conf、postgresql.conf
  • 備庫須要recovery.conf、.pgpass

實際操做中,建議主、備庫上都配置這四個文件,由於主、備庫角色是隨着倒換變動的。注:recovery.conf文件在備庫上是recovery.conf,在主庫上配置爲recovery.done。

 

主庫配置:

一、   配置postgresql.conf

wal_level = hot_standby  # minimal, replica, or logical   使得日誌支持Streaming Replication

max_wal_senders = 2  # max number of walsender processes   這個設置了能夠最多有幾個流複製鏈接,幾個併發的standby數據庫就設置幾個

wal_keep_segments = 256     設置流複製保留的最多的xlog數目,不要設置過小致使WAL日誌尚未來得及傳送到standby就被覆蓋。一個WAL文件默認16M

hot_standby = on  # "on" allows queries during recovery  設置爲備庫時是否支持可讀

logging_collector = on

log_directory = 'pg_log'

log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'

 

二、   配置pg_hba.conf

# TYPE  DATABASE    USER            ADDRESS              METHOD

host    all             all             127.0.0.1/32            trust

host    all             all             ::1/128                trust

host    replication      u_standby        10.10.10.0/32       trust

其中:

1) u_standby爲在主庫上建立的用於備庫鏈接主庫進行流複製的用戶,此用戶須要用戶須要有REPLICATION權限和LOGIN權限。開戶如:

create user u_standby SUPERUSER LOGIN password 'standby123';

2) 10.10.10.0/32爲備庫地址段+掩碼;也可配置爲具體的standby數據庫地址+掩碼,可配置多條。用於指定哪些地址的standby數據用哪一個用戶名/密碼到主庫獲取WAL日誌數據。使用地址段格式,則地址段內的IP均可以無密碼對此數據庫進行訪問,安全性可能會下降。所以,在生產環境中建議嚴格按照具體主機IP方式配置。

 

三、   (可選)配置recovery.done、.pgpass

同備庫recovery.conf、.pgpass配置。recovery.conf中以下IP、端口、用戶名要對應備庫信息:

primary_conninfo = 'host=10.10.10.1 port=5432 user=u_standby'   備庫鏈接主庫地址、端口、用戶名、密碼

 

四、   配置完畢需重啓數據庫

pg_ctl restart -m fast

 

進行主庫->備庫基礎備份:

一、   關閉備庫,並清空數據

  $pg_ctl stop -m fast

  rm -rf /var/lib/pgsql/data/*

 二、   進行一次主庫數據基本備份到備庫

方式一(在主庫操做):

  //開啓備份功能,pg_start_backup() 函數會在主庫上發起一個在線備份,命令執行後,將數據文件壓縮拷貝到備份節點上:

  $postgres=# select pg_start_backup('backup0001')

  //將data目錄下的數據遠程拷貝到備庫的data目錄下

  $scp -r /opt/pgsql/data/* 10.10.10.2:/opt/pgsql/data/

  //關閉備份功能

  $postgres=# select pg_stop_backup()

方式二(9.0版本後引入了pg_basebackup工具,在備庫操做):

  pg_basebackup工具支持對主庫發起一個基準備份,發起備份須要超級用戶權限或REPLICATION權限,注意max_wal_senders參數配置,由於pg_basebackup工具將消耗至少一個WAL發送進程。

  //以下IP爲主庫地址

  pg_basebackup -h 10.10.10.1 -U u_standby -F p -x -P -R -D /var/lib/pgsql/9.5/data/ -1 rep_backup   //-R 表示會在備份結束後自動生成recovery.conf文件,這樣就避免了手動建立。

 

備庫配置:

一、   修改postgresql.conf

  hot_standby = on  # "on" allows queries during recovery  設置爲備庫時是否支持可讀

二、   配置recovery.conf

  standby_mode = on

  recovery_target_timeline = 'latest'

  primary_conninfo = 'host=10.10.10.1 port=5432 user= u_standby password=standby123 '   本庫爲備庫會,鏈接主庫地址、端口、用戶名、密碼

三、   設置鏈接主庫密碼.pgpass

  10.10.10.1: 5432:replication: u_standby:standby123  //備庫都主庫同步WAL日誌使用

  10.10.10.2: 5432:replication: u_standby:standby123  //倒換後,主庫降備庫,新備庫使用

四、   配置完畢需重啓數據庫

  pg_ctl start

 

結果檢查:

一、   配置成功後,能夠查看主、備庫的walsender、walreceiver進程。

ps -ef | grep wal

主庫:

postgres 6939 6935 0 23:16 ? 00:00:00 postgres: wal writer process

postgres 6983 6935 0 23:42 ? 00:00:00 postgres: wal sender process repuser 172.17.0.5(45910) streaming 0/3000140

備庫:

postgres 26481 26479 0 23:42 ? 00:00:00 postgres: wal receiver process streaming 0/3000140

 

3、PostgreSQL的同步流複製

同步流複製配置內容相似異步流複製,差別點在於:

一、   主庫的postgresql.conf文件,增長:

  synchronous_standby_names = 'standby001'

       synchronous_standby_names是設置同步流複製的備庫的主機名,該名稱會在備庫中的參數中指定。

二、   備庫的recoveryt.conf文件

  primary_conninfo = 'host=192.168.100.32 port=5866 user=tbing application_name=standby001'

       application_name參數就是設置的同步流複製備庫的主機名,該參數值和主庫的synchronous_standby_names的參數值一致。

三、   檢查流複製狀態

  執行:

  select * from pg_stat_replication

  返回:

  sync_state       | sync     表示同步流複製

  sync_state       | async    表示異步流複製

 

4、PostgreSQL主備數據庫切換

1、識別當前庫主、備角色:

方式一:

  postgres=# select pg_is_in_recovery();   結果是f則爲主庫,t爲備庫

方式二:

  pg_controldata 結果爲cluster state是in production則爲主庫;結果爲cluster state是in archive recovery則爲備庫

方式三:

  Select pid, application_name, client_addr, client_port, state, sync_state from pg_stat_replication  查詢到結果爲主庫,查詢不到結果爲備庫。

 

2、主備倒換

在PostgreSQL如主庫出現異常時,備庫如何激活。有2種方式:

方式一:使用pg_ctl promote來激活(PostgreSQL9.1後支持)

(1)關閉主庫(模擬主庫故障):

  $ pg_ctl stop -m fast

(2)在備庫上執行pg_ctl promote命令激活備庫

  若是recovery.conf變成recovery.done表示備庫已切換成主庫

(3)原主庫變備庫

  在新備庫上建立recovery.conf、.pgpass文件,內容參考前文章節。啓動新備庫:

  $ pg_ctl start

方式二:備庫在recovery.conf文件中有個配置項trigger_file,是激活standby的觸發文件,經過檢測這個文件是否存在,存在則激活standby爲master。

(1)在recovery.conf中配置觸發器文件地址,修改本參數後須要重啓備庫:

  recovery_target_timeline = 'latest'

  standby_mode = on

  primary_conninfo = 'host=10.10.10.1 port=5432 user= u_standby password=standby123 '

  trigger_file = '/home/postgres/pg11/trigger'

(2)停掉原主庫,會發現原備庫變爲可讀寫。

  $ pg_ctl stop -m fast

(3)在備庫建立trigger_file

  $ touch /home/postgres/pg11/trigger

(4)發現原備庫變爲主庫,方法參考「識別當前庫主、備角色」。

 

3、故障的原主庫,從新做爲備庫使用

在異步流複製(async)模式下,主庫故障切換後,可能存在原主庫故障時還有數據沒來及的複製到備庫,這些數據將丟失。(注:PostgreSQL的Streaming Replication是以事務爲單位,即便數據未同步完畢,也不會出現備庫某個事務只恢復一半的狀況,所以事務一致性仍是能夠保證的。)

此種狀況下,原主庫的最後一個事務時間戳比複製到原備庫(新主庫)的事務時間戳更新。好比:倒換前最後幾個事務是100/101/102,故障前流複製到100事務,則故障切換後,原主庫中最新一個事務是102,原備庫(新主庫)中複製的最後一個事務是100,後續新主庫(原備庫)將在100的基礎上,進行新的事務操做。原主庫數據、新主庫數據出現分叉點。所以,若是但願原主庫恢復服務後做爲新備庫運行,則須要:

方式一:刪庫,重搭新備庫(詳細參考前文備庫配置過程)

  一、 關閉庫,並清空數據(清楚數據便可,不須要重裝數據庫)

    pg_ctl stop -m fast

    rm -rf /var/lib/pgsql/data/*

  二、 新備庫進行數據基本備份

    pg_basebackup  ….

  三、 啓動新備庫

    pg_ctl start

方式二:採用pg_rewind降級爲備庫,繼續服務

若是你的數據庫到達TB級別,採用方式一的全量數據基礎備份將花費數個小時。爲了解決此問題,PostgreSQL9.5引入了pg_rewind功能。原主庫(新備庫)能夠經過pg_rewind操做實現故障時間線的回退。回退後再重新主庫中獲取最新的後續數據。此時,原主庫的數據無須進行從新全量初始化就能夠繼續進行Streaming Replication,並做爲新的Slave使用。

詳見pg_rewind使用說明。

相關文章
相關標籤/搜索