PostgreSQL 主從配置

什麼是流複製

  • 9.0版本開始,PG支持物理複製, 也稱爲流複製(Streaming Replication), 通過流複製技術,可以從實例級複製出一個與主庫一模一樣的從庫、備庫.
  • 與Oracle DG技術一樣, 備庫是熱備只讀的. Standby database 或 Slave

流複製的方式

同步方式有兩種:
1. 異步流複製
2. 同步流複製.

二者的區別在於: 主庫上提交事務時, 是否需要等待備庫接收WAL日誌流並寫入備庫WAL日誌文件時返回成功.

主庫備庫基本信息

角色 主機名 IP地址 操作系統 PG版本
主庫 pg01 192.168.56.101 CentOS 6.7 PG 12
備庫 pg02 192.168.56.102 CentOS 6.7 PG 12

主庫的配置及啊哦做

WAL 配置 - postgresql.conf

  • 開啓數據庫歸檔相關參數:
[postgres@pg01 data]$ vi postgresql.conf
wal_level = replica                     # minimal, replica, or logical
archive_mode = on               # enables archiving; off, on, or always
archive_command = 'test ! -f /var/lib/pgsql/12/arch/%f && cp %p /var/lib/pgsql/12/arch/%f'
## 其中: %p表示wal日誌文件的路徑,%f表示wal日誌文件名稱。
[postgres@pg01 ~]$ mkdir /var/lib/pgsql/12/arch
  • 主備庫傳輸相關參數
listen_addresses = '*' # (修改)監聽所有IP
max_connections = 100 # (修改)最大連接數,據說從機需要大於或等於該值

主庫信息配置 - pg_hba.conf

在 pg_hba.conf文件的最後加入主備庫的信息,由於主備庫身份是可以互換的所以都需要寫上:

[postgres@pg01 ~]$ cd ~/12/data
[postgres@pg01 data]$ vi pg_hba.conf 
host    replication     all       192.168.56.101/32   md5
host    replication     repuser   192.168.56.101/32   md5
host    replication     repuser   192.168.56.102/32   md5

重啓主庫使之生效

[root@pg01 ~]# service postgresql-12 stop
Stoping postgresql-12 service:                            [  OK  ]

關閉防火牆

[root@pg01 ~]# service iptables status
Table: filter
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination         
1    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED 
2    ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0           
3    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
4    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:22 
5    REJECT     all  --  0.0.0.0/0            0.0.0.0/0           reject-with icmp-host-prohibited 

Chain FORWARD (policy ACCEPT)
num  target     prot opt source               destination         
1    REJECT     all  --  0.0.0.0/0            0.0.0.0/0           reject-with icmp-host-prohibited 

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination         

[root@pg01 ~]# service iptables stop
iptables: Setting chains to policy ACCEPT: filter          [  OK  ]
iptables: Flushing firewall rules:                         [  OK  ]
iptables: Unloading modules:                               [  OK  ]

主庫創建複製用戶

建議爲流複製創建專門的複製用戶,需要具有replication和login權限:

[postgres@pg01 ~]$ psql
psql (12.0)
Type "help" for help.

postgres=# create user repuser
postgres-#   replication
postgres-#   login
postgres-#   connection limit 5
postgres-#   encrypted password 'rep123';
CREATE ROLE

備庫操作

清空所有數據目錄

備庫的數據應該是主庫一樣的。如果清理不乾淨, 下一步將會報錯,提示那裏還沒有清理乾淨。

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

從主節點獲取數據

使用repuser用戶,從主節點獲取備份數據, IP地址是主庫的。

[postgres@pg02 ~]$ pg_basebackup -h 192.168.56.101 -p 5432 -U repuser -Fp -Xs -Pv -R -D /var/lib/pgsql/12/data
Password: 
pg_basebackup: initiating base backup, waiting for checkpoint to complete
pg_basebackup: checkpoint completed
pg_basebackup: write-ahead log start point: 0/A000028 on timeline 1
pg_basebackup: starting background WAL receiver
pg_basebackup: created temporary replication slot "pg_basebackup_3162"
90235/90235 kB (100%), 2/2 tablespaces                                         
pg_basebackup: write-ahead log end point: 0/A000138
pg_basebackup: waiting for background process to finish streaming ...
pg_basebackup: syncing data to disk ...
pg_basebackup: base backup completed

-D 表示備節點用來接收主庫數據的目標路徑。

-F 指定生成的備份數據格式。p(plain)格式和t(tar)格式。
-X 設置在備份的過程中產生的WAL日誌包含在備份中的方式

如果上一步數據未清理乾淨,那麼會有如下的報錯, directory "/pgdata/tbs_dd" exists but is not empty

[postgres@pg02 ~]$ pg_basebackup -h 192.168.56.101 -p 5432 -U repuser -Fp -Xs -Pv -R -D /var/lib/pgsql/12/data
Password: 
pg_basebackup: initiating base backup, waiting for checkpoint to complete
pg_basebackup: checkpoint completed
pg_basebackup: write-ahead log start point: 0/8000028 on timeline 1
pg_basebackup: error: directory "/pgdata/tbs_dd" exists but is not empty
pg_basebackup: removing contents of data directory "/var/lib/pgsql/12/data"

如果是主庫的防火牆未關閉,那麼報錯如下:

[postgres@pg02 ~]$ pg_basebackup -h 192.168.56.101 -p 5432 -U replica -Fp -Xs -Pv -R -D /var/lib/pgsql/12/data
pg_basebackup: error: could not connect to server: could not initiate GSSAPI security context: Unspecified GSS failure.  Minor code may provide more information
could not initiate GSSAPI security context: Cannot determine realm for numeric host address
FATAL:  no pg_hba.conf entry for replication connection from host "192.168.56.102", user "replica", SSL off

編輯standby.signal文件

就在數據文件夾內,以此標識從節點,當從節點提升爲主節點後會自動刪除

[postgres@pg01 ~]$ vi ~/12/data/standby.signal
standby_mode = 'on' 

配置postgresql.conf文件

在文件的末尾添加一下內容:

[postgres@pg01 ~]$ vi ~/12/data/postgresql.conf

primary_conninfo = 'host=192.168.100.101 port=5432 user=repuser password=rep123'
recovery_target_timeline = latest 
hot_standby = on
max_standby_streaming_delay = 30s
wal_receiver_status_interval = 10s
hot_standby_feedback = on 

重啓備庫

重新啓動從節點

service postgresql-12 restart

驗證主從

方法-1

在主庫端檢查,說明102服務器是從節點,在接收流,而且是異步流複製:

[postgres@pg01 data]$ psql

postgres=# select usename , application_name , client_addr,sync_state from pg_stat_replication;
 usename | application_name |  client_addr   | sync_state 
---------+------------------+----------------+------------
 repuser | walreceiver      | 192.168.56.102 | async(1 row)

方法-2

在主、從節點分別執行如下命令:

[postgres@pg01 ~]$ ps -ef | grep postgres
  • 主節點有wal receiver進程
postgres  3252  2947  0 15:08 ?        00:00:00 postgres: walsender repuser 192.168.56.102(38410) streaming 0/B000148
  • 從節點有wal receiver進程
postgres  3004  2997  0 15:08 ?        00:00:04 postgres: walreceiver   streaming 0/B000148

方法-3

在主庫插入數據,然後在從庫查詢是否有相應結果。

  • 主庫操作
[postgres@pg01 ~]$ psql dong
psql (12.0)
Type "help" for help.

dong=# \dt
        List of relations
 Schema | Name | Type  |  Owner   
--------+------+-------+----------
 public | t1   | table | postgres
(1 row)

dong=# select count(*) from t1;
 count 
-------
     6
(6 rows)

dong=# insert into t1 select * from t1;
INSERT 0 6

dong=# select count(*) from t1;
 count 
-------
    12
(12 rows)

dong=# 
  • 備庫
[postgres@pg01 ~]$ psql dong
psql (12.0)
Type "help" for help.

dong=# \dt
        List of relations
 Schema | Name | Type  |  Owner   
--------+------+-------+----------
 public | t1   | table | postgres
(1 row)

dong=# select count(*) from t1;
 count 
-------
     6
(6 rows)

dong=# insert into t1 select * from t1;
INSERT 0 6

dong=# select count(*) from t1;
 count 
-------
    12
(12 rows)

dong=# 

參數解釋

wal_level參數控制WAL日誌信息的輸出級別

  • minimal 記錄的WAL日誌信息最少, 除了記錄數據庫異常關閉需要恢復時的WAL外, 其他操作信息都不記錄;
  • replica 記錄的WAL信息比minimal信息多, 會記錄支持WAL歸檔、複製和備庫中啓用只讀查詢等操作所需的WAL信息;
  • logical 記錄的最多, 包含了支持邏輯解析所需的WAL。 幷包含了minimal和replica記錄的信息。

archive_command

可以將WAL歸檔到本級目錄, 也可以歸檔到遠程其他主機上。

max_wal_senders

控制主庫上的最大WAL發送進程數, 通過pg_basebackup命令在主庫上做基準備份時也會消耗WAL進程。此參數不能大於max_connections, 默認值10.

wal_keep_segments

主庫pg_wal目錄保留的最小WAL日誌文件數,以便備庫落後主庫時可以通過主庫保留的WAL進行追回。默認情況下每個WAL 16MB

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章