PostgreSQL做爲一個近年來纔在國內開始發展的國外的開源數據庫產品,不管是數據庫自己的問題仍是對數據庫使用不當形成的問題,在一段時間內可能不容易找到或者找不到服務提供商,所以高可用性是使用PostgreSQL的一個很是重要的問題。本節介紹PostgreSQL的高可用Synchronous Replication+HOT STANDBY單活雙機同步熱備方式,這種方式能夠保證只有在主備同時奔潰的狀況下才會丟失數據,且Standby庫能夠提供讀能力供分擔負載。數據保護模式相似Oracle Active DataGuard的最大保護模式。sql
本節僅對關鍵參數做出說明,其餘有大量PG參數配置沒法逐一解釋,閱讀前最好對PG有必定了解。數據庫
PostgreSQL數據庫自己提供三種HA模式,這裏簡單介紹:安全
1. 基於日誌文件的複製服務器
Master庫向Standby庫異步傳輸數據庫的WAL日誌,Standby解析日誌並把日誌中的操做從新執行,以實現replication功能。缺點在於Master庫必須等待每一個WAL日誌填充完整後才能發給Standby,若是在填充WAL日誌的過程當中Master庫宕機,未發送的日誌內的事務操做會所有丟失。網絡
2. 異步流複製模式app
Master庫以流模式向Standby庫異步傳輸數據庫的WAL日誌,Standby解析收到的內容並把其中的操做從新執行,以實現replication功能。這種方式和「基於日誌文件的複製」相比不須要等待整個WAL日誌填充完畢,大大下降了丟失數據的風險,但在Master庫事務提交後,Standby庫等待流數據的時刻發生Master宕機,會致使丟失最後一個事務的數據。同時備庫能夠配置成HOT Standby,能夠向外提供查詢服務,供分擔負載。dom
3. 流同步複製模式(Synchronous Replication)異步
顧名思義,是流複製模式的同步版本。向Master庫發出commit命令後,該命令會被阻塞,等待對應的WAL日誌流在全部被配置爲同步節點的數據庫上提交後,纔會真正提交。所以只有Master庫和Standby庫同時宕機纔會丟數據。多層事務嵌套時,子事務不受此保護,只有最上層事務受此保護。純讀操做和回滾不受此影響。同時備庫能夠配置成HOT Standby,能夠向外提供查詢服務,供分擔負載。採用這種模式的性能損耗依據網絡狀況和系統繁忙程度而定,網絡越差越繁忙的系統性能損耗越嚴重。socket
能夠依據實際狀況權衡以上三種數據庫複製模式的優缺點決定使用哪種數據庫高可用模式。這裏推薦使用第二種高可用方式(異步流複製模式)實現數據庫高可用。下面以異步流複製模式爲例,說明HA環境搭建:post
Master:10.19.100.2
Standby:10.19.100.3
注意:
服務器已經安裝好PG 10.3。
下面的例子裏爲了方便配置和說明,並無仔細規劃歸檔日誌的保存路徑,歸檔日誌在主備切換時用完即棄。
本節全部操做均在10.19.100.2上進行
登錄Master庫,建立具備用於傳遞數據的具備replication權限的用戶(也能夠直接用Super user看成replication用戶,但不推薦)
$ psql -U postgres -d postgres Password for user postgres: psql.bin (10.3) Type "help" for help. postgres=# CREATE ROLE replicator login replication password '123456'; CREATE ROLE
修改Master庫的pg_hba.conf,把Master庫和Standby庫的IP地址添加進Master庫網絡策略白名單中,使Standby庫能夠連上Master庫,同時便於主備切換。
$ cd /PostgreSQL/10/data/ $ vi pg_hba.conf # TYPE DATABASE USER ADDRESS METHOD # "local" is for Unix domain socket connections only local all all md5 # IPv4 local connections: host all all 127.0.0.1/32 md5 host all all 10.19.100.0/24 md5 # IPv6 local connections: host all all ::1/128 md5 # Allow replication connections from localhost, by a user with the # replication privilege. #local replication postgres md5 host replication replicator 10.19.100.2/32 md5 host replication replicator 10.19.100.3/32 md5 #host replication postgres 127.0.0.1/32 md5 #host replication postgres ::1/128 md5
修改Master庫的配置文件postgresql.conf,在原配置文件postgresql.conf的基礎上修改,修改內容以下:
$ cd /PostgreSQL/10/data/ $ mkdir arch_dir $ mkdir arch_dir_master $ vi postgresql.conf wal_level= logical max_wal_senders = 10 # at least the number of standby archive_mode = on archive_command = 'test ! -f /PostgreSQL/10/data/arch_dir/%f && cp %p /PostgreSQL/10/data/arch_dir/%f' synchronous_standby_names = '' #standby application name, in recover.conf hot_standby=on
說明:
synchronous_standby_names參數對應的參數爲同步複製保障節點,若是該參數非空,則任何一個最上層的事務都會等待被同步到該參數指明的節點後纔會在Master庫提交,若是Standby庫無響應Master庫會被hung住。若是該參數爲空,則表示採用異步複製方式。該參數能夠配置多個保障節點,以逗號分隔,PG會從第一個開始嘗試。開啓同步複製存雖然能最大限度保證數據安全,可是會影響應用可用性。同步模式下,若是Master和Standby之間的網絡情況很糟糕,那麼同步複製會極大的拉低整個系統的性能;若是Standby宕機,主庫會被hang住,雖然這裏只記錄異步複製,但具體採用何種複製請按自身業務場景選擇。
修改後的postgresql.conf配置文件既能做爲Master庫的配置文件使用,也能做爲Standby庫的配置文件使用。
建立切換爲Standby庫時的同步配置文件recovery.done
$ cd /PostgreSQL/10/data/ $ vi recovery.done standby_mode=on restore_command = 'cp /PostgreSQL/10/data/arch_dir_master/%f %p' primary_conninfo='application_name=pg2 host=10.19.100.3 port=5432 user=replicator password=123456' archive_cleanup_command ='pg_archivecleanup /PostgreSQL/10/data/arch_dir_master %r' recovery_target_timeline = 'latest'
重啓數據庫
$ pg_ctl restart -D /PostgreSQL/10/data/ -l /PostgreSQL/10/data/pglog.log
Standby庫須要以Master庫的完整備份+歸檔日誌恢復而來,若是Master庫還沒有對外提供服務,也能夠直接複製Master庫的數據文件目錄,這裏採用第一種方法,更貼近實際環境。
本節全部操做均在10.19.100.3上進行。100.3上僅安裝好數據庫軟件,沒有啓動數據庫。
使用主庫的熱備建立standby庫
$ psql -h 10.19.100.2 -p 5432 -U postgres -d postgres Password for user postgres: psql.bin (10.3) Type "help" for help. postgres=# select pg_start_Backup('backuptag',true); pg_start_backup ----------------- 0/3000060 (1 row)
複製主庫數據目錄
$ scp -r postgres@10.19.100.2:/PostgreSQL/10/data /PostgreSQL/10/data
中止主庫的熱備鎖定
$ psql -h 10.19.100.2 -p 5432 -U postgres -d postgres Password for user postgres: psql.bin (10.3) Type "help" for help. postgres=# select pg_stop_backup(); NOTICE: pg_stop_backup complete, all required WAL segments have been archived pg_stop_backup ---------------- 0/3000168 (1 row)
清理複製過來的主庫文件
$ rm -rf /PostgreSQL/10/data/pg_wal $ rm -rf /PostgreSQL/10/data/postmaster.pid $ rm –rf /PostgreSQL/10/data/arch_dir/*
修改備庫的recovery文件
$ cd /PostgreSQL/10/data/ $ mv recovery.done recovery.conf $ vi recovery.conf standby_mode=on restore_command = 'cp /PostgreSQL/10/data/arch_dir_master/%f %p' primary_conninfo='application_name=pg3 host=10.19.100.2 port=5432 user=replicator password=123456' archive_cleanup_command ='pg_archivecleanup /PostgreSQL/10/data/arch_dir_master %r' recovery_target_timeline = 'latest'
準備恢復須要的完整的歸檔文件和wal文件
$ scp -r postgres@10.19.100.2:/PostgreSQL/10/data/pg_wal /PostgreSQL/10/data/ $ scp -r 10.19.100.2:/PostgreSQL/10/data/arch_dir /PostgreSQL/10/data/arch_dir_master
啓動備庫,觀察備庫日誌
$ pg_ctl start -D /PostgreSQL/10/data -l /PostgreSQL/10/data/pglog.log waiting for server to start..... done server started $ more /PostgreSQL/10/data/log/postgresql-2018-03-08_142945.log 2018-03-08 14:29:47.685 CST [21790] LOG: started streaming WAL from primary at 0/4000000 on timeline 1
流複製搭建完成後,備庫是隻讀的,能夠利用它進行讀寫分離均衡。若是主庫失效須要提高備庫爲主庫能夠經過下面的命令。
$ pg_ctl promote -D /PostgreSQL/10/data/
觀察日誌能夠看到,數據庫結束recovery模式,開始提供服務
LOG: archive recovery complete LOG: database system is ready to accept connections LOG: autovacuum launcher started
而且能夠看到recovery.conf文件被數據庫自動改名爲recovery.done。