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