【Postgresql】—PostgreSQL的流復制環(huán)境部署

1、介紹

PostgreSQL的主從復制有兩種方式袱衷,分別是:
一:WAL日志歸檔(base-file)
二: 流復制(streaming replication)

第一種是寫完一個WAL日志后叮称,才把WAL日志文件拷貝到standby數(shù)據(jù)庫中种玛,簡言之就是通過cp命令實現(xiàn)遠程備份藐鹤,這樣通常備庫會落后主庫一個WAL日志文件。而第二種流復制是postgresql9.x之后才提供的新的傳遞WAL日志的方法赂韵,它的好處是只要master庫一產(chǎn)生日志娱节,就會馬上傳遞到standby庫,同第一種相比有更低的同步延遲祭示,所以我們肯定也會選擇流復制的方式肄满。

流復制屬于物理層面的復制,可以從實例級復制出一個與主庫一模一樣的實例級的從庫质涛,流復制同步方式有同步稠歉、異步兩種。

異步流復制模式中蹂窖,主庫提交的事務不會等待備庫接收WAL日志流并返回確認信息轧抗,因此異步流復制模式下主庫與備庫的數(shù)據(jù)版本上會存在一定的處理延遲(毫秒級),當主庫宕機瞬测,這個延遲就主要受到故障發(fā)現(xiàn)與切換時間的影響而拉長横媚。該模式為默認模式。

同步流復制模式中月趟,要求主庫把WAL日志寫入磁盤灯蝴,同時等待WAL日志記錄復制到備庫、并且WAL日志記錄在任意一個備庫寫入磁盤后孝宗,才能向應用返回Commit結果穷躁。一旦所有備庫故障,在主庫的應用操作則會被掛起因妇,所以此方式建議起碼是1主2備问潭。

2、環(huán)境準備

拉取鏡像
docker pull postgres:12

創(chuàng)建網(wǎng)卡
docker network create --subnet=172.172.1.0/24 pg-network

創(chuàng)建容器數(shù)據(jù)庫目錄婚被,用于容器內部映射
mkdir -p /pg/pg-master/data
mkdir -p /pg/pg-standby01/data
mkdir -p /pg/pg-standby02/data

主庫
docker rm -f pg-master
rm -rf /pg/pg-master/data
rm -rf /pg/pg-master/bk

docker run -d --name pg-master -h pg-master \
   -p 54340:5432 --net=pg-network --ip 172.172.1.40 \
   -v /pg/pg-master/data:/var/lib/postgresql/data \
   -v /pg/pg-master/bk:/bk \
   -e POSTGRES_PASSWORD=lhr \
   -e TZ=Asia/Shanghai \
   postgres:12

從庫01
docker rm -f pg-standby01
rm -rf /pg/pg-master/data
rm -rf /pg/pg-master/bk

docker run -d --name pg-standby01 -h pg-standby01 \
   -p 54341:5432 --net=pg-network --ip 172.172.1.41 \
   -v /pg/pg-standby01/data:/var/lib/postgresql/data \
   -v /pg/pg-standby01/bk:/bk \
   -e POSTGRES_PASSWORD=lhr \
   -e TZ=Asia/Shanghai \
   postgres:12
  
從庫02
docker rm -f pg-standby02
rm -rf /pg/pg-master/data
rm -rf /pg/pg-master/bk
  
docker run -d --name pg-standby02 -h pg-standby02 \
   -p 54342:5432 --net=pg-network --ip 172.172.1.42 \
   -v /pg/pg-standby02/data:/var/lib/postgresql/data \
   -v /pg/pg-standby02/bk:/bk \
   -e POSTGRES_PASSWORD=lhr \
   -e TZ=Asia/Shanghai \
   postgres:12

進入容器內部
 docker exec -it pg-master bash

遠程數(shù)據(jù)庫登錄
psql -U postgres -h 172.21.209.100 -p 54340
本地登錄
psql -U postgres -h 127.0.0.1 -p 5432

配置防火墻
cat  << EOF > /pg/pg-master/data/pg_hba.conf
# TYPE  DATABASE    USER    ADDRESS       METHOD
local     all       all                    trust
host      all       all   127.0.0.1/32     trust
host      all       all    0.0.0.0/0        md5
host   replication  all    0.0.0.0/0        md5
EOF


重啟數(shù)據(jù)庫
/usr/lib/postgresql/12/bin/pg_ctl restart -D /var/lib/postgresql/data/

3狡忙、主從流復制配置

3.1、主庫配置

創(chuàng)建歸檔目錄址芯,該路徑也需要在從庫創(chuàng)建
 mkdir -p /postgresql/archive
 chown -R postgres.postgres /postgresql/archive

配置文件添加如下參數(shù)
cat >> /var/lib/postgresql/data/postgresql.conf <<"EOF"

wal_level='replica'
archive_mode='on'
archive_command='test ! -f /postgresql/archive/%f && cp %p /postgresql/archive/%f'

max_wal_senders=10
wal_keep_segments=256
wal_sender_timeout=60s

EOF

配置后重啟數(shù)據(jù)庫
root@pg-master:/var/lib/postgresql/data# su - postgres

[root@openstack ~]# docker start pg-master 
或
/usr/lib/postgresql/12/bin/pg_ctl restart -D /var/lib/postgresql/data/

登錄數(shù)據(jù)庫查看參數(shù)
psql -U postgres -h 127.0.0.1 -p 5432
select * from pg_settings where name in ('wal_level','archive_mode','archive_command');


postgres=# \x
Expanded display is on.
postgres=# select * from pg_settings where name in ('wal_level','archive_mode','archive_command');
-[ RECORD 1 ]---+------------------------------------------------------------------
name            | archive_command
setting         | test ! -f /postgresql/archive/%f && cp %p /postgresql/archive/%f
unit            | 
category        | Write-Ahead Log / Archiving
short_desc      | Sets the shell command that will be called to archive a WAL file.
extra_desc      | 
context         | sighup
vartype         | string
source          | configuration file
min_val         | 
max_val         | 
enumvals        | 
boot_val        | 
reset_val       | test ! -f /postgresql/archive/%f && cp %p /postgresql/archive/%f
sourcefile      | /var/lib/postgresql/data/postgresql.conf
sourceline      | 757
pending_restart | f
-[ RECORD 2 ]---+------------------------------------------------------------------
name            | archive_mode
setting         | on
unit            | 
category        | Write-Ahead Log / Archiving
short_desc      | Allows archiving of WAL files using archive_command.
extra_desc      | 
context         | postmaster
vartype         | enum
source          | configuration file
min_val         | 
max_val         | 
enumvals        | {always,on,off}
boot_val        | off
reset_val       | on
sourcefile      | /var/lib/postgresql/data/postgresql.conf
sourceline      | 756
pending_restart | f
-[ RECORD 3 ]---+------------------------------------------------------------------
name            | wal_level
setting         | replica
unit            | 
category        | Write-Ahead Log / Settings
short_desc      | Set the level of information written to the WAL.
extra_desc      | 
context         | postmaster
vartype         | enum
source          | configuration file
min_val         | 
max_val         | 
enumvals        | {minimal,replica,logical}
boot_val        | replica
reset_val       | replica
sourcefile      | /var/lib/postgresql/data/postgresql.conf
sourceline      | 755
pending_restart | f

postgres=# 


切換歸檔
select pg_switch_wal();
查看歸檔狀態(tài)
select * from pg_stat_get_archiver();


執(zhí)行過程:
postgres=# select * from pg_stat_get_archiver();
-[ RECORD 1 ]------+------------------------------
archived_count     | 0
last_archived_wal  | 
last_archived_time | 
failed_count       | 0
last_failed_wal    | 
last_failed_time   | 
stats_reset        | 2023-12-10 15:45:23.724072+08

postgres=# select pg_switch_wal();
-[ RECORD 1 ]-+----------
pg_switch_wal | 0/164DFE0

postgres=# 
postgres=# select * from pg_stat_get_archiver();
-[ RECORD 1 ]------+------------------------------
archived_count     | 1
last_archived_wal  | 000000010000000000000001
last_archived_time | 2023-12-10 17:21:35.079489+08
failed_count       | 0
last_failed_wal    | 
last_failed_time   | 
stats_reset        | 2023-12-10 15:45:23.724072+08

postgres=# 



主庫創(chuàng)建復制用戶
create role repluser login encrypted password 'repluser ' replication;


postgres=# create role repluser login encrypted password 'repluser ' replication;
CREATE ROLE
postgres=# \du
List of roles
-[ RECORD 1 ]----------------------------------------------------------
Role name  | postgres
Attributes | Superuser, Create role, Create DB, Replication, Bypass RLS
Member of  | {}
-[ RECORD 2 ]----------------------------------------------------------
Role name  | repluser
Attributes | Replication
Member of  | {}

postgres=# \x
Expanded display is off.
postgres=# 
postgres=# \du
                                   List of roles
 Role name |                         Attributes                         | Member of 
-----------+------------------------------------------------------------+-----------
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
 repluser  | Replication                                                | {}

postgres=# 

3.2灾茁、從庫配置

從庫對主庫進行備份,拉取主庫數(shù)據(jù)后,啟動數(shù)據(jù)庫

創(chuàng)建目錄谷炸,用于拉取主庫的數(shù)據(jù)
mkdir -p /bk
chown postgres:postgres /bk

拉取主庫數(shù)據(jù)
su - postgres
pg_basebackup -h 172.172.1.40  -p 5432 -U repluser -l bk20231210 -F p -P -R -D /bk


執(zhí)行過程:
root@pg-standby01:/# mkdir -p /bk
root@pg-standby01:/# chown postgres:postgres /bk
root@pg-standby01:/# su - postgres
postgres@pg-standby01:~$ pg_basebackup -h 172.172.1.40  -p 5432 -U repluser -l bk20231210 -F p -P -R -D /bk
24669/24669 kB (100%), 1/1 tablespace

postgres@pg-standby01:~$ cd /bk/
postgres@pg-standby01:/bk$ ls
PG_VERSION    pg_dynshmem       pg_multixact  pg_stat      pg_wal            standby.signal
backup_label  pg_hba.conf       pg_notify     pg_stat_tmp  pg_xact
base          pg_hba.conf-20231210  pg_replslot   pg_subtrans  postgresql.auto.conf
global        pg_ident.conf     pg_serial     pg_tblspc    postgresql.conf
pg_commit_ts  pg_logical        pg_snapshots  pg_twophase  postgresql.conf-20231210
postgres@pg-standby01:/bk$ 
postgres@pg-standby01:/bk$ 


從庫操作很重要北专。
關閉從庫,刪除從庫的數(shù)據(jù)文件旬陡,并且將備份文件覆蓋從庫的數(shù)據(jù)文件

這是docker環(huán)境拓颓,如果是主機環(huán)境內部操作即可。
cp -r ./pg-standby01/data ./pg-standby01/data-20231210
rm -rf /pg/pg-standby01/data/*
cp -r /pg/pg-standby01/bk/*  /pg/pg-standby01/data/

執(zhí)行過程
[root@openstack pg]# ls
pg-master  pg-standby01  pg-standby02
[root@openstack pg]# cp -r ./pg-standby01/data ./pg-standby01/data-20231210
You have new mail in /var/spool/mail/root
[root@openstack pg]# rm -rf /pg/pg-standby01/data/*
[root@openstack pg]# cp -r /pg/pg-standby01/bk/*  /pg/pg-standby01/data/


修改從庫配置文件
[root@openstack pg]# cat >> /pg/pg-standby01/data/postgresql.conf <<"EOF"
> 
> primary_conninfo = 'host=172.172.1.40 port=5432 user=repluser password=repluser'
> 
> EOF

重啟從庫
[root@openstack pg]# docker restart pg-standby01
pg-standby01

3.3描孟、查看主庫從庫的狀態(tài)

查看主庫和從庫進程
ps -ef|grep post

主庫查看wal日志發(fā)送狀態(tài)
select * from pg_stat_replication;
從庫查看wal日志接收狀態(tài)
select * from pg_stat_wal_receiver;

也可以通過該命令查看
pg_controldata  | grep state

也可以查看這個录粱,主庫是f代表false 腻格;備庫是t,代表true
select pg_is_in_recovery();


執(zhí)行過程:

主庫進程:
root@pg-master:/# ps -ef|grep post
postgres     1     0  0 17:18 ?        00:00:00 postgres
postgres    28     1  0 17:18 ?        00:00:00 postgres: checkpointer  
postgres    29     1  0 17:18 ?        00:00:00 postgres: background writer  
postgres    30     1  0 17:18 ?        00:00:00 postgres: walwriter  
postgres    31     1  0 17:18 ?        00:00:00 postgres: autovacuum launcher  
postgres    32     1  0 17:18 ?        00:00:00 postgres: archiver   last was 000000010000000000000003.00000028.backup
postgres    33     1  0 17:18 ?        00:00:00 postgres: stats collector  
postgres    34     1  0 17:18 ?        00:00:00 postgres: logical replication launcher  
postgres   113     1  0 17:34 ?        00:00:00 postgres: walsender repluser 172.172.1.41(45836) streaming 0/4000148
root       222    35  0 17:44 pts/0    00:00:00 grep post
root@pg-master:/# 


從庫備庫進程
root@pg-standby01:/# ps -ef|grep postgres
postgres     1     0  0 17:34 ?        00:00:00 postgres
postgres    26     1  0 17:34 ?        00:00:00 postgres: startup   recovering 000000010000000000000004
postgres    27     1  0 17:34 ?        00:00:00 postgres: checkpointer  
postgres    28     1  0 17:34 ?        00:00:00 postgres: background writer  
postgres    29     1  0 17:34 ?        00:00:00 postgres: stats collector  
postgres    30     1  0 17:34 ?        00:00:00 postgres: walreceiver  
root       169    31  0 17:40 pts/0    00:00:00 grep postgres

主庫查看wal日志發(fā)送狀態(tài)
postgres=# \x
Expanded display is on.
postgres=# select * from pg_stat_replication;
-[ RECORD 1 ]----+------------------------------
pid              | 113
usesysid         | 16384
usename          | repluser
application_name | walreceiver
client_addr      | 172.172.1.41
client_hostname  | 
client_port      | 45836
backend_start    | 2023-12-10 17:34:08.379909+08
backend_xmin     | 
state            | streaming
sent_lsn         | 0/4000148
write_lsn        | 0/4000148
flush_lsn        | 0/4000148
replay_lsn       | 0/4000148
write_lag        | 
flush_lag        | 
replay_lag       | 
sync_priority    | 0
sync_state       | async
reply_time       | 2023-12-10 17:44:49.38437+08

postgres=# 


從庫查看wal日志接收狀態(tài)
postgres=# select * from pg_stat_wal_receiver;
-[ RECORD 1 ]---------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
pid                   | 30
status                | streaming
receive_start_lsn     | 0/4000000
receive_start_tli     | 1
received_lsn          | 0/4000000
received_tli          | 1
last_msg_send_time    | 2023-12-10 17:47:39.657548+08
last_msg_receipt_time | 2023-12-10 17:47:39.657644+08
latest_end_lsn        | 0/4000148
latest_end_time       | 2023-12-10 17:34:08.381928+08
slot_name             | 
sender_host           | 172.172.1.40
sender_port           | 5432
conninfo              | user=repluser passfile=/var/lib/postgresql/.pgpass channel_binding=prefer dbname=replication host=172.172.1.40 port=5432 fallback_application_name=walreceiver sslmode=prefer sslcompression=0 sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=prefer krbsrvname=postgres target_session_attrs=any

postgres=# 


4菜职、測試主從復制

postgres=# \l 
                                 List of databases
   Name    |  Owner   | Encoding |  Collate   |   Ctype    |   Access privileges   
-----------+----------+----------+------------+------------+-----------------------
 postgres  | postgres | UTF8     | en_US.utf8 | en_US.utf8 | 
 template0 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
(3 rows)

postgres=# create database pgtest;
CREATE DATABASE
postgres=# \c pgtest
You are now connected to database "pgtest" as user "postgres".


pgtest=# create table t1(id int,varchar name,age int);
CREATE TABLE


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

pgtest=# 
pgtest=# INSERT INTO t1 VALUES (1, 'Xiaowang', 29);
INSERT 0 1
pgtest=# 
pgtest=# INSERT INTO t1 VALUES (2, 'Xiaoli', 18);
INSERT 0 1
pgtest=# select * from t1;
 id | varchar  | age 
----+----------+-----
  1 | Xiaowang |  29
  2 | Xiaoli   |  18
(2 rows)

pgtest=# 



主庫查詢,是否恢復旗闽,f表示否
pgtest=# select pg_is_in_recovery();
 pg_is_in_recovery 
-------------------
 f
(1 row)


從庫查詢數(shù)據(jù)同步
pgtest=# \d 
        List of relations
 Schema | Name | Type  |  Owner   
--------+------+-------+----------
 public | t1   | table | postgres
(1 row)

pgtest=# select * from t1;
 id | varchar  | age 
----+----------+-----
  1 | Xiaowang |  29
  2 | Xiaoli   |  18
(2 rows)
從庫查詢酬核,是否為恢復,t表示是恢復正常适室,表示從庫嫡意。
pgtest=# select pg_is_in_recovery();
 pg_is_in_recovery 
-------------------
 t
(1 row)


從庫創(chuàng)建數(shù)據(jù)庫失敗,因從庫是只讀的
pgtest=# create database pgtest01;
ERROR:  cannot execute CREATE DATABASE in a read-only transaction
pgtest=# 

說明主庫數(shù)據(jù)同步正常捣辆。主數(shù)據(jù)庫是讀寫的蔬螟,備數(shù)據(jù)庫是只讀的

5、主從切換

主數(shù)據(jù)庫是讀寫的汽畴,備數(shù)據(jù)庫是只讀的旧巾。當主庫出現(xiàn)故障時,我們需要將備庫提升為主庫進行讀寫操作忍些。
1)切換后鲁猩,原主庫以從庫的身份啟動:修復過程類似于重建
2)切換后,原主庫以主庫的身份啟動:
主從故障切換是在保障數(shù)據(jù)一致情況下罢坝,宕主庫宕機后廓握,從庫階梯主庫繼續(xù)提供服務。

5.1嘁酿、主庫操作

模擬主庫宕機操作隙券,并且將作為備庫繼續(xù)工作
主庫宕機
[root@openstack pg]# docker stop  pg-master
pg-master

主庫配置文件添加如下信息
cat >> /pg/pg-master/data/postgresql.conf <<"EOF"

primary_conninfo = 'host=172.172.1.41  port=5432 user=repluser password=repluser'

EOF

重啟數(shù)據(jù)庫服務
[root@openstack pg]# docker start   pg-master
pg-master

5.2、從庫操作

停止備庫
[root@openstack pg]# docker stop   pg-standby01
pg-standby01

刪除“standby.signal”噴子文件文件
mv  /pg/pg-standby01/data/standby.signal /pg/pg-standby01/data/standby.signal.bak-20231210

修改postgresql.conf
 sed -i 's/primary_conninfo/#primary_conninfo/g' /pg/pg-standby01/data/postgresql.conf

啟動數(shù)據(jù)庫服務
[root@openstack pg]# docker start    pg-standby01
pg-standby01

從庫查看是否為恢復正常
postgres=# select pg_is_in_recovery();
 pg_is_in_recovery 
-------------------
 f
(1 row)

從庫正常讀寫操作
postgres=# create database pgtest01;
CREATE DATABASE
postgres=# \l
                                 List of databases
   Name    |  Owner   | Encoding |  Collate   |   Ctype    |   Access privileges   
-----------+----------+----------+------------+------------+-----------------------
 pgtest    | postgres | UTF8     | en_US.utf8 | en_US.utf8 | 
 pgtest01  | postgres | UTF8     | en_US.utf8 | en_US.utf8 | 
 postgres  | postgres | UTF8     | en_US.utf8 | en_US.utf8 | 
 template0 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
(5 rows)

postgres=# 

5.3闹司、原主庫修復后作為從庫加入娱仔,該過程相當于重建流復制過程。

原主庫操作
創(chuàng)建目錄
mkdir -p /bk
chown postgres:postgres /bk

 su - postgres
 pg_basebackup -h 172.172.1.41  -p 5432 -U repluser -l bk20231210 -F p -P -R -D /bk


執(zhí)行過程:
root@pg-master:/# mkdir -p /bk
root@pg-master:/# chown postgres:postgres /bk
root@pg-master:/#  su - postgres
postgres@pg-master:~$  pg_basebackup -h 172.172.1.41  -p 5432 -U repluser -l bk20231210 -F p -P -R -D /bk
40632/40632 kB (100%), 1/1 tablespace
postgres@pg-master:~$ 




在pg-standby01上查看是否有復制用戶开仰,一般做了主從后是有的,如果沒有創(chuàng)建薪铜。
create role repluser login encrypted password 'repluser ' replication;

postgres=# \du
                                   List of roles
 Role name |                         Attributes                         | Member of 
-----------+------------------------------------------------------------+-----------
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
 repluser  | Replication                                                | {}

postgres=# 


關閉從庫众弓,并且將備份文件覆蓋從庫的數(shù)據(jù)文件
[root@openstack pg]# docker stop    pg-master
pg-master
You have new mail in /var/spool/mail/root
[root@openstack pg]# mv /pg/pg-master/data /pg/pg-master/data-20231210
[root@openstack pg]# mkdir -p /pg/pg-master/data/
[root@openstack pg]# cp -r /pg/pg-master/bk/* /pg/pg-master/data/


修改配置文件信息
sed -i 's/172.172.1.40 /172.172.1.41/g' /pg/pg-master/data/postgresql.conf
sed -i 's/#primary_conninfo/primary_conninfo/g' /pg/pg-master/data/postgresql.conf

啟動數(shù)據(jù)庫服務
[root@openstack data]# docker restart     pg-master
pg-master
[root@openstack data]# 


檢驗主從同步
主庫查看進程狀態(tài)
ps -ef|grep post

主庫查看wal日志發(fā)送狀態(tài)
select * from pg_stat_replication;
從庫查看wal日志接收狀態(tài)
select * from pg_stat_wal_receiver;


也可以通過該命令查看
pg_controldata  | grep state

也可以查看這個,主庫是f代表false 隔箍;備庫是t谓娃,代表true
select pg_is_in_recovery();

執(zhí)行過程:
現(xiàn)為從庫
postgres@pg-master:~$ ps -ef|grep post
postgres     1     0  0 12:07 ?        00:00:00 postgres
postgres    27     1  0 12:07 ?        00:00:00 postgres: startup   recovering 000000010000000000000007
postgres    28     1  0 12:07 ?        00:00:00 postgres: checkpointer  
postgres    29     1  0 12:07 ?        00:00:00 postgres: background writer  
postgres    30     1  0 12:07 ?        00:00:00 postgres: stats collector  
postgres    31     1  0 12:07 ?        00:00:00 postgres: walreceiver   streaming 0/7000148
root        46    40  0 12:10 pts/0    00:00:00 su - postgres
postgres    47    46  0 12:10 pts/0    00:00:00 -bash
postgres    49    47  0 12:10 pts/0    00:00:00 ps -ef
postgres    50    47  0 12:10 pts/0    00:00:00 grep post


現(xiàn)為主庫
postgres@pg-standby01:~$ ps -ef|grep post
postgres     1     0  0 11:40 ?        00:00:00 postgres
postgres    27     1  0 11:40 ?        00:00:00 postgres: checkpointer  
postgres    28     1  0 11:40 ?        00:00:00 postgres: background writer  
postgres    29     1  0 11:40 ?        00:00:00 postgres: walwriter  
postgres    30     1  0 11:40 ?        00:00:00 postgres: autovacuum launcher  
postgres    31     1  0 11:40 ?        00:00:00 postgres: archiver   last was 000000010000000000000006.00000028.backup
postgres    32     1  0 11:40 ?        00:00:00 postgres: stats collector  
postgres    33     1  0 11:40 ?        00:00:00 postgres: logical replication launcher  
root        49    34  0 11:40 pts/0    00:00:00 su - postgres
postgres    50    49  0 11:40 pts/0    00:00:00 -bash
postgres    96     1  0 12:07 ?        00:00:00 postgres: walsender repluser 172.172.1.40(33488) streaming 0/7000148
postgres   102    50  0 12:10 pts/0    00:00:00 ps -ef
postgres   103    50  0 12:10 pts/0    00:00:00 grep post
postgres@pg-standby01:~$ 


6、新增節(jié)點蜒滩,從節(jié)點2添加

6.1滨达、從庫配置

創(chuàng)建同步目錄
mkdir -p /bk
chown postgres:postgres /bk

su - postgres
pg_basebackup -h 172.172.1.41 -p 5432 -U repluser -l bk20231210 -F p -P -R -D /bk


關閉從庫奶稠,刪除從庫的數(shù)據(jù)文件,并且將備份文件覆蓋從庫的數(shù)據(jù)文件
關閉數(shù)據(jù)庫服務
docker stop    pg-standby02
mv /pg/pg-standby02/data /pg/pg-standby02/data-20231210
mkdir -p /pg/pg-standby02/data/
cp -r /pg/pg-standby02/bk/* /pg/pg-standby02/data/


添加或修改配置文件信息捡遍,如果存在則修改锌订,沒有則添加。

添加
cat >> /pg/pg-standby02/data/postgresql.conf <<"EOF"
primary_conninfo = 'host=172.172.1.41 port=5432 user=repluser password=repluser'
EOF

修改
sed -i 's/172.172.1.40 /172.172.1.41/g' /pg/pg-master/data/postgresql.conf
sed -i 's/#primary_conninfo/primary_conninfo/g' /pg/pg-master/data/postgresql.conf

啟動數(shù)據(jù)庫服務
docker restart     pg-standby02




執(zhí)行過程
root@pg-standby02:/# mkdir -p /bk
root@pg-standby02:/# chown postgres:postgres /bk
root@pg-standby02:/# su - postgres
postgres@pg-standby02:~$ pg_basebackup -h 172.172.1.41 -p 5432 -U repluser -l bk20231210 -F p -P -R -D /bk
40632/40632 kB (100%), 1/1 tablespace
postgres@pg-standby02:~$ 


[root@openstack data]# docker stop    pg-standby02
pg-standby02
You have new mail in /var/spool/mail/root
[root@openstack data]# mv /pg/pg-standby02/data /pg/pg-standby02/data-20231210
[root@openstack data]# mkdir -p /pg/pg-standby02/data/
[root@openstack data]# cp -r /pg/pg-standby02/bk/* /pg/pg-standby02/data/


[root@openstack data]# cat >> /pg/pg-standby02/data/postgresql.conf <<"EOF"
> 
> primary_conninfo = 'host=172.172.1.41 port=5432 user=repluser password=repluser'
> 
> EOF
[root@openstack data]# 

[root@openstack data]# docker restart     pg-standby02
pg-standby02

6.2画株、從庫狀態(tài)檢測

主庫從庫操作
1辆飘、查看進程
ps -ef|grep post

2、查看你日志狀態(tài)
主庫查看wal日志發(fā)送狀態(tài)
select * from pg_stat_replication;
從庫查看wal日志接收狀態(tài)
select * from pg_stat_wal_receiver;


3谓传、查看數(shù)據(jù)庫的狀態(tài)
主庫從庫都可以查看
pg_controldata  | grep state

4蜈项、查看恢復的狀態(tài),主庫是f代表false 续挟;備庫是t紧卒,代表true
select pg_is_in_recovery();

5、從庫查看數(shù)據(jù)同步的表和數(shù)據(jù)
select * from t1;

6诗祸、在主庫查看主從狀態(tài)
select * from pg_stat_replication;


主從同步的狀態(tài)查看
postgres=# select * from pg_stat_replication;
 pid | usesysid | usename  | application_name | client_addr  | client_hostname | client_port |         backend_start
         | backend_xmin |   state   | sent_lsn  | write_lsn | flush_lsn | replay_lsn | write_lag | flush_lag | repla
y_lag | sync_priority | sync_state |          reply_time           
-----+----------+----------+------------------+--------------+-----------------+-------------+----------------------
---------+--------------+-----------+-----------+-----------+-----------+------------+-----------+-----------+------
------+---------------+------------+-------------------------------
  96 |    16384 | repluser | walreceiver      | 172.172.1.40 |                 |       33488 | 2023-12-10 20:07:52.0
87953+08 |              | streaming | 0/9000148 | 0/9000148 | 0/9000148 | 0/9000148  |           |           |      
      |             0 | async      | 2023-12-10 20:37:23.120884+08
 138 |    16384 | repluser | walreceiver      | 172.172.1.42 |                 |       47518 | 2023-12-10 20:28:01.2
35939+08 |              | streaming | 0/9000148 | 0/9000148 | 0/9000148 | 0/9000148  |           |           |      
      |             0 | async      | 2023-12-10 20:37:23.120688+08
(2 rows)


postgres=# select client_addr,state,sync_state from pg_stat_replication;
 client_addr  |   state   | sync_state 
--------------+-----------+------------
 172.172.1.40 | streaming | async
 172.172.1.42 | streaming | async
(2 rows)

postgres=# 

主庫的
postgres=# select pg_is_in_recovery();
 pg_is_in_recovery 
-------------------
 f
(1 row)
從庫的
postgres=# select pg_is_in_recovery();
 pg_is_in_recovery 
-------------------
 t
(1 row)

postgres=# 


從庫查詢wal日志的狀體
postgres=# \x
Expanded display is on.
postgres=# select * from pg_stat_wal_receiver;
-[ RECORD 1 ]---------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
pid                   | 31
status                | streaming
receive_start_lsn     | 0/9000000
receive_start_tli     | 1
received_lsn          | 0/9000148
received_tli          | 1
last_msg_send_time    | 2023-12-10 20:42:13.576832+08
last_msg_receipt_time | 2023-12-10 20:42:13.576913+08
latest_end_lsn        | 0/9000148
latest_end_time       | 2023-12-10 20:31:12.534758+08
slot_name             | 
sender_host           | 172.172.1.41
sender_port           | 5432
conninfo              | user=repluser passfile=/var/lib/postgresql/.pgpass channel_binding=prefer dbname=replication host=172.172.1.41 port=5432 fallback_application_name=walreceiver sslmode=prefer sslcompression=0 sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=prefer krbsrvname=postgres target_session_attrs=any

postgres=# 

7跑芳、修改流復制為同步復制,默認為異步復制

主庫查看流復制的狀態(tài)贬媒,async為異步復制
postgres=# select client_addr,state,sync_state from pg_stat_replication;
 client_addr  |   state   | sync_state 
--------------+-----------+------------
 172.172.1.40 | streaming | async
 172.172.1.42 | streaming | async
(2 rows)

配置參數(shù)聋亡,所有節(jié)點都配置如下參數(shù)
cat >> /pg/pg-master/data/postgresql.conf <<"EOF"
synchronous_commit='on'
synchronous_standby_names='*' 
EOF

cat >> /pg/pg-standby01/data/postgresql.conf <<"EOF"
synchronous_commit='on'
synchronous_standby_names='*' 
EOF

cat >> /pg/pg-standby02/data/postgresql.conf <<"EOF"
synchronous_commit='on'
synchronous_standby_names='*' 
EOF

重啟所有節(jié)點的數(shù)據(jù)庫服務
[root@openstack data]# docker restart pg-master 
pg-master
[root@openstack data]# docker restart pg-standby01
pg-standby01
[root@openstack data]# 
[root@openstack data]# docker restart pg-standby02
pg-standby02
[root@openstack data]# 

查看同步模式
postgres=# select client_addr,state,sync_state from pg_stat_replication;
 client_addr  |   state   | sync_state 
--------------+-----------+------------
 172.172.1.42 | streaming | sync
 172.172.1.40 | streaming | potential
(2 rows)

postgres=# 



如果改為異步復制,修改如下參數(shù)际乘,然后重啟數(shù)據(jù)庫服務即可坡倔。
sed -i  's|synchronous_commit|#synchronous_commit|g'  /pg/pg-master/data/postgresql.conf
sed -i  's|synchronous_standby_names|#synchronous_standby_names|g'  /pg/pg-master/data/postgresql.conf

sed -i  's|synchronous_commit|#synchronous_commit|g'  /pg/pg-standby01/data/postgresql.conf
sed -i  's|synchronous_standby_names|#synchronous_standby_names|g'  /pg/pg-standby01/data/postgresql.conf

sed -i  's|synchronous_commit|#synchronous_commit|g'  /pg/pg-standby02/data/postgresql.conf
sed -i  's|synchronous_standby_names|#synchronous_standby_names|g'  /pg/pg-standby02/data/postgresql.conf

至此,PostgreSQL的流復制部署完畢脖含。

參考:
https://www.modb.pro/db/78858

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末罪塔,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子养葵,更是在濱河造成了極大的恐慌征堪,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件关拒,死亡現(xiàn)場離奇詭異佃蚜,居然都是意外死亡,警方通過查閱死者的電腦和手機着绊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進店門谐算,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人归露,你說我怎么就攤上這事洲脂。” “怎么了剧包?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵恐锦,是天一觀的道長往果。 經(jīng)常有香客問我,道長一铅,這世上最難降的妖魔是什么陕贮? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮馅闽,結果婚禮上飘蚯,老公的妹妹穿的比我還像新娘。我一直安慰自己福也,他們只是感情好局骤,可當我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著暴凑,像睡著了一般峦甩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上现喳,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天凯傲,我揣著相機與錄音,去河邊找鬼嗦篱。 笑死冰单,一個胖子當著我的面吹牛,可吹牛的內容都是我干的灸促。 我是一名探鬼主播诫欠,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼浴栽!你這毒婦竟也來了荒叼?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤典鸡,失蹤者是張志新(化名)和其女友劉穎被廓,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體萝玷,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡嫁乘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了球碉。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蜓斧。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖汁尺,靈堂內的尸體忽然破棺而出法精,到底是詐尸還是另有隱情多律,我是刑警寧澤痴突,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布搂蜓,位于F島的核電站,受9級特大地震影響辽装,放射性物質發(fā)生泄漏帮碰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一拾积、第九天 我趴在偏房一處隱蔽的房頂上張望殉挽。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至只酥,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背冠骄。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留加袋,地道東北人凛辣。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像职烧,于是被迫代替她去往敵國和親扁誓。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,573評論 2 353

推薦閱讀更多精彩內容