PostgreSQL9.6主從配置


參考文檔:

  1. 備機日志傳送:https://www.postgresql.org/docs/9.6/static/warm-standby.html
  2. 英文文檔:https://www.postgresql.org/docs/current/static/index.html
  3. 中文文檔:http://www.postgres.cn/docs/9.6/
  4. pg_basebackup:https://www.postgresql.org/docs/current/static/app-pgbasebackup.html
  5. 參考1:http://blog.csdn.net/wlwlwlwl015/article/details/53287855
  6. 參考2:http://www.cnblogs.com/yjf512/p/4499547.html

 本文涉及postgresql基於異步方式的主從復制的配置驗證。 

一.主從復制簡介

1. 基於文件的日志傳送

創建一個高可用性(HA)集群配置可采用連續歸檔,集群中主服務器工作在連續歸檔模式下,備服務器工作在連續恢復模式下(1台或多台可隨時接管主服務器),備持續從主服務器讀取WAL文件。

連續歸檔不需要對數據庫表做任何改動,可有效降低管理開銷,對主服務器的性能影響也相對較低。

直接從一個數據庫服務器移動WAL記錄到另一台服務器被稱為日志傳送,PostgreSQL通過一次一文件(WAL段)的WAL記錄傳輸實現了基於文件的日志傳送。

  1. 日志傳送所需的帶寬取根據主服務器的事務率而變化;
  2. 日志傳送是異步的,即WAL記錄是在事務提交后才被傳送,那么在一個窗口期內如果主服務器發生災難性的失效則會導致數據丟失,還沒有被傳送的事務將會被丟失;
  3. 數據丟失窗口可以通過使用參數archive_timeout進行限制,可以低至數秒,但同時會增加文件傳送所需的帶寬。

2. 流復制

PostgreSQL在9.x之后引入了主從的流復制機制,所謂流復制,就是備服務器通過tcp流從主服務器中同步相應的數據,主服務器在WAL記錄產生時即將它們以流式傳送給備服務器,而不必等到WAL文件被填充。

  1. 默認情況下流復制是異步的,這種情況下主服務器上提交一個事務與該變化在備服務器上變得可見之間客觀上存在短暫的延遲,但這種延遲相比基於文件的日志傳送方式依然要小得多,在備服務器的能力滿足負載的前提下延遲通常低於一秒;
  2. 在流復制中,備服務器比使用基於文件的日志傳送具有更小的數據丟失窗口,不需要采用archive_timeout來縮減數據丟失窗口;
  3. 將一個備服務器從基於文件日志傳送轉變成基於流復制的步驟是:把recovery.conf文件中的primary_conninfo設置指向主服務器;設置主服務器配置文件的listen_addresses參數與認證文件即可。  

二.驗證環境

1. 操作系統

CentOS-7-x86_64-Everything-1511

2. PostgresSQL版本

PostgreSQL 9.6.3:https://www.postgresql.org/download/linux/redhat/

3. 主機

采用VMware ESXi虛擬出的2台服務器:

host1:psql_master,10.11.4.186

host2:psql_standby,10.11.4.187 

三.主庫配置

1. 創建復制用戶

#需要一個賬號進行主從同步
postgres=#create role repl login replication encrypted password 'repl@123';

2. 認證文件pg_hba.conf

#配置從庫可以采用repl賬號進行同步
[root@psql_master ~]# vim /var/lib/pgsql/9.6/data/pg_hba.conf 
host replication repl 10.11.4.187/32 md5

3. 主庫配置文件postgresql.conf

[root@psql_master ~]# vim /var/lib/pgsql/9.6/data/postgresql.conf
#監聽端口
listen_addresses = '*'

#主從設置為熱備模式,流復制必選參數
wal_level = hot_standby

#流復制允許的連接進程,一般同standby數量一致
max_wal_senders = 2

#流復制在沒有基於文件的連續歸檔時,主服務器可能在備機收到WAL日志前回收這些舊的WAL,此時備機需要重新從一個新的基礎備份初始化;可設置wal_keep_segments為一個足夠高的值來確保舊的WAL段不會被太早重用;1個WAL日志為16MB,所以在設置wal_keep_segments時,在滿足空間的前提下可以盡量設置大一些
wal_keep_segments = 64

#默認參數,非主從配置相關參數,表示到數據庫的連接數,一般從庫做主要的讀服務時,設置值需要高於主庫
max_connections = 100

4. 重啟服務

#同時注意打開防火牆端口打開
[root@psql_master ~]# systemctl restart postgresql-9.6

四.從庫配置

從庫安裝postgresql后,暫不初始化,如果從庫已初始化,可以清空其data目錄(默認安裝是/ /var/lib/pgsql/9.6/data/目錄)。

1. 基礎備份

[root@psql_standby ~]# pg_basebackup -h 10.11.4.186 -p 5432 -U repl -F p -P -D /var/lib/pgsql/9.6/data/
#-h,主庫主機,-p,主庫服務端口;
#-U,復制用戶;
#-F,p是默認輸出格式,輸出數據目錄和表空間相同的布局,t表示tar格式輸出;
#-P,同--progress,顯示進度;
#-D,輸出到指定目錄;
#因為主庫采用的是md5認證,這里需要密碼認證。

2. 備份目錄權限

#基於root賬號做的基礎備份,需要將相關目錄文件的權限變更
[root@psql_standby ~]# chown -R postgres:postgres /var/lib/pgsql/9.6/data/

3. 從庫配置文件postgresql.conf

#在基礎備份時,初始化文件是從主庫復制來的,所以配置文件一致,可將wal_level,max_wal_senders與wal_keep_segments等參數注釋,以下是新增或修改的參數
[root@psql_standby ~]# vim /var/lib/pgsql/9.6/data/postgresql.conf
#在備份的同時允許查詢
hot_standby = on

#可選,流復制最大延遲
max_standby_streaming_delay = 30s

#可選,從向主報告狀態的最大間隔時間
wal_receiver_status_interval = 10s

#可選,查詢沖突時向主反饋
hot_standby_feedback = on

#默認參數,非主從配置相關參數,表示到數據庫的連接數,一般從庫做主要的讀服務時,設置值需要高於主庫
max_connections = 1000

4. 恢復文件recovery.conf

#在做基礎備份時,也可通過-R參數在備份結束后自動生產一個recovery.conf文件
[root@psql_standby ~]# cp /usr/pgsql-9.6/share/recovery.conf.sample /var/lib/pgsql/9.6/data/recovery.conf

[root@psql_standby ~]# chown postgres:postgres /var/lib/pgsql/9.6/data/recovery.conf

[root@psql_standby ~]# vim /var/lib/pgsql/9.6/data/recovery.conf
#指明從庫身份
standby_mode = on

#連接到主庫信息
primary_conninfo = 'host=10.11.4.186 port=5432 user=repl password=repl@123'

#同步到最新數據
recovery_target_timeline = 'latest'

#指定觸發文件,文件存在時,將觸發從庫提升為主庫,前提是必須設置”standby_mode = on”;如果不設置此參數,也可采用”pg_ctl promote“觸發從庫切換成主庫
#trigger_file = ‘/var/lib/pgsql/9.6/data/trigger_activestandby’

5. 重啟服務

[root@psql_standby ~]# systemctl restart postgresql-9.6 

五.使用驗證

1. 查看進程 

1)主庫sender進程

[root@psql_master ~]# ps -ef | grep postgres

2)從庫receiver過程 

[root@psql_standby ~]# ps -ef | grep postgres

2. 查看復制狀態(主庫)

postgres=# \x
postgres=# select * from pg_stat_replication;
#pid,sender進程;
#usesysid,復制用戶id;
#usename,復制用戶名;
#application_name,復制進程名;
#client_addr,從庫客戶端地址;
#client_hostname,從庫客戶端名;
#client_port,從庫客戶端port;
#backend_start,主從復制開始時間;
#backend_xmin,當前后端的xmin范圍,由備機提供;
#state,同步狀態,startup:連接中;catchup:同步中;streaming:同步;
#sent_location,主傳送wal的位置;
#write_location,從接收wal的位置;
#flush_location,從刷盤的wal位置;
#replay_location,從同步到數據庫的wal位置;
#sync_priority,同步優先級,0表示異步;1~?表示同步,數字越小優先級越高;
#sync_state, async:異步;sync:同步;potential;當前是異步,但可能升級到同步模式;
#另外,”select pg_is_in_recovery();“命令也可以查看主從狀態,false是主,true為從。

3. 表復制測試 

1)建表(主庫)

postgres=# create table postgrestb(id int primary key,name VARCHAR(20),salary real);
postgres=# insert into postgrestb values(10, 'Messi', 10000.00);
postgres=# insert into postgrestb values(6, 'Xavi', 10000.00);
postgres=# select * from postgrestb;

2)查詢(從庫)

[root@psql_standby ~]# su - postgres
-bash-4.2$ psql
postgres=# \d
postgres=# select * from postgrestb;

3)從庫寫測試 

#從庫只讀,不能寫入數據
postgres=# insert into postgrestb values(8, 'Iniesta', 10000.00);

4. 主從切換 

1)切換前狀態

[root@psql_master ~]# pg_controldata /var/lib/pgsql/9.6/data/

[root@psql_standby ~]# pg_controldata /var/lib/pgsql/9.6/data/

2)主庫故障 

#以postgres賬戶停止主庫
[root@psql_master ~]# su - postgres -c "pg_ctl stop -m fast"

[root@psql_master ~]# pg_controldata /var/lib/pgsql/9.6/data/

3)創建用戶查看從庫日志 

 

#日志已經明確是不能連接到主庫
[root@psql_standby ~]# tailf /var/lib/pgsql/9.6/data/pg_log/postgresql-Tue.log

 

4)激活從庫

#采用”pg_ctl promote“切換從庫為主庫;
#切換后,從庫的recovery.conf文件名字變成了recovery.done
[root@psql_standby ~]# su - postgres -c "pg_ctl promote"

5)查看從庫日志,狀態與進程

[root@psql_standby ~]# tailf /var/lib/pgsql/9.6/data/pg_log/postgresql-Tue.log

 [root@psql_standby ~]# tailf /var/lib/pgsql/9.6/data/pg_log/postgresql-Tue.log

[root@psql_standby ~]# ps aux | grep postgres

 6)總結

  1. 配合keepalived可以做postgresql的高可用,需要寫檢測主從狀態腳本,可參考:https://github.com/francs/PostgreSQL-Keepalived-HA
  2. 檢測trigger_file存在與否也可完成從庫切換主庫;
  3. 從庫切換到主庫,故障的原主庫恢復后,可將其降為備庫,主要是設置recovery.conf文件與postgres.conf文件,最差的情況下可清空此時的備庫(原主庫)的$PGDATA,重新同步數據。  

六.同步流復制(補充)

1. 與異步流復制的區別

  1. 同步復制必須等待主庫與從庫都寫完wal后才能commit事務,在一定程度上會增加事務的響應時間;
  2. 配置同步復制步驟: 
    1. 在主庫postgresql.conf文件中設置參數synchronous_standby_names為1個字符串或"*",存在多個從庫時使用逗號分隔;
    2. 在主庫postgresql.conf文件中設置參數synchronous_commit參數設置為"on",控制是否等待wal日志buffer刷入磁盤再返回用戶事務狀態信息,同步流復制需要打開;
    3. 從庫的recovery.conf中primary_conninfo參數需要指明"application_name"。 

2. 注意事項

  1. 當只有1個從做同步流復制時,如果從庫故障,則主庫的寫也會掛起(可以看到postgres下會有數據操作的waiting進程),此時的方案建議采用1+1+n的方式,即1 master+1 slave(同步)+n slave(異步),做同步的slave故障后,可從n個異步slave中選舉1個切換成同步模式;
  2. 設置synchronous_commit = off 后,即使同步復制模式的從庫故障,主庫的事務也不會出現等待掛起的現象。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM