PostgreSQL-流复制集群搭建

流复制分为异步和同步复制,异步:故名意思主库不会管从库是否落盘,应用完成,主库也会提交事务。而同步复制:主库会等待从库,数据回放是否完成,或者是否落盘等,在流复制强同步的情况下,主库可能会陷入等待,无法提交事务。

环境介绍

角色IP服务
leader172.22.138.218/20postgresql v14
standby1172.22.138.219/20postgresql v14
standby2172.22.138.220/20postgresql v14

异步流复制

Leader节点的配置

首先在三个节点上搭建好PostgreSQL。
如果不知道怎么搭建的可以查看我另一篇文章《PostgreSQL-Linux环境源码编译安装》

https://blog.csdn.net/h_3369/article/details/141358564?spm=1001.2014.3001.5502

1.在172.22.138.218要做主库的节点创建复制用户

root # su - postgres
postgres # psql
...
postgres=# create user replica with password 'replica';
postgres=# alter user replica replication;

2.编辑172.22.138.218节点的访问控制文件,在pg_hba.conf中增加复制用户的访问权限。

postgres # cd /data/pgsql/data
postgres # vim pg_hba.conf

# 注意!下方IP地址的子网掩码根据实际情况配置
...
host    replication     all             172.22.138.219/20               trust
host    replication     all             172.22.138.220/20               trust
...

3.修改172.22.138.218的postgresql.conf配置文件,请确保配置文件中的目录都正确或都存在,并确保属主属组的权限为postgres。

postgres # vim postgresql.conf
...
port = '5432'
listen_addresses = '*
max_connections = '1000'
max_locks_per_transaction = '64'
max_prepared_transactions = '0'
max_replication_slots = '10'
max_wal_senders = '10'
max_worker_processes = '8'
track_commit_timestamp = 'off'
wal_sender_timeout = 60s
wal_keep_size = '1600MB'
wal_level = 'replica'
wal_log_hints = 'on'
hot_standby = 'on'
archive_mode=on
archive_command='cp %p //data/pgsql/archive/%f'
archive_timeout=1800
hba_file = '/data/pgsql/data/pg_hba.conf'
ident_file = '/data/pgsql/data/pg_ident.conf'
logging_collector = on
log_directory = '/data/pgsql/log' 

4.重启postgresql,使配置文件生效。

root # systemctl restart postgresql

Standby节点的配置

1.停止所有standby节点的postgresql进程

root # systemctl stop postgresql

2.清理standby的pgsql数据目录

postgres # mkdir /tmp/data
postgres # mv /data/pgsql/data/* /tmp/data

3.在standby节点通过物理备份工具pg_basebackup,将leader节点的数据copy到standby节点

postgres # pg_basebackup -D /data/pgsql/data/ -h 172.22.138.218 -p 5432 -U replica -X stream -Pv -R

4.修改standby节点的postgresql.conf文件,在primary_conninfo选项加入节点标识application_name。

postgres # vim postgresql.conf
...

primary_conninfo = '... application_name=standby1 ....'
primary_conninfo = '... application_name=standby2 ....'

5.启动standby节点的postgresql

root # systemctl start postgresql

6.查看leader节点和standby节点的复制状态

# leader
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 | replay_lag | sync_priority | sync_state |          reply_time           |
+-------+----------+---------+------------------+----------------+-----------------+-------------+-------------------------------+--------------+-----------+------------+------------+------------+------------+-----------+-----------+------------+---------------+------------+-------------------------------+
| 12368 |    16384 | replica | standby1         | 172.22.138.219 |                 |       47170 | 2024-08-15 10:23:36.860733+08 |              | streaming | 0/DC000000 | 0/DC000000 | 0/DC000000 | 0/DC000000 |           |           |            |             0 | async      | 2024-08-15 11:10:18.855529+08 |
| 11101 |    16384 | replica | standby2         | 172.22.138.218 |                 |       55800 | 2024-08-15 09:57:31.073827+08 |              | streaming | 0/DC000000 | 0/DC000000 | 0/DC000000 | 0/DC000000 |           |           |            |             0 | async      | 2024-08-15 11:10:19.992588+08 |
+-------+----------+---------+------------------+----------------+-----------------+-------------+-------------------------------+--------------+-----------+------------+------------+------------+------------+-----------+-----------+------------+---------------+------------+-------------------------------+

# standby
postgres=# select * from pg_stat_wal_receiver;
-[ RECORD 1 ]---------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
pid                   | 18720
status                | streaming
receive_start_lsn     | 0/DB000000
receive_start_tli     | 3
written_lsn           | 0/DC000000
flushed_lsn           | 0/DC000000
received_tli          | 3
last_msg_send_time    | 2024-08-15 11:11:08.623733+08
last_msg_receipt_time | 2024-08-15 11:11:08.623328+08
latest_end_lsn        | 0/DC000000
latest_end_time       | 2024-08-15 11:09:52.14472+08
slot_name             | pa_pg_2
sender_host           | 172.22.138.218
sender_port           | 5432
conninfo              | user=replica dbname=replication host=172.22.138.218 port=5432 application_name=standby1 ....

同步流复制

同步流复制,相较于异步,只需要在搭建流复制的时候,在本文档的第一阶段的Leader节点配置环节的第三步,修改leader节点postgresql.conf文件的时候加入两个参数。synchronous_commit和synchronous_standby_names。
synchronous_commit这个参数主要是为了控制,当一个事务写入后,判断一个事务是否已经正确提交,在什么状态下提交的
synchronous_standby_names这个参数,主要是在同步复制配置过程中,比较重要的一个参数,前面提到了当synchronous_commit,配置不同的值,需要等待从库刷盘、接收wal log等几种情况,而相关需要它等待的从库就在这里配置。配置方式也是多种方式。

synchronous_commit

  • off:当pgsql事务提交的时候,不需要等待wal buffer中的数据,是否已经刷盘到wal log,立即返回给客户端,事务提交成功。这种情况数据库因为不需要等待事务是否落盘,所以性能最佳,但相对会有数据丢失的风险。如果在数据提交后,wal buffer没有刷盘完成到wal log,数据库此时崩溃,可能会丢失数据。

  • local:当事务提交时,确认数据落盘,写入到了本地主库的数据文件,本地持久化成功,返回客户端已提交,但是不会管备库是否接收和落盘。此种情况相较于off,要安全一些,保证了主库数据安全的情况下,还能保留一定的性能。

  • remote_write:对于安全和性能,相对来说比较平衡,它保证了事务在主库实现持久化后,至少有一个同步的从库,接收并且写入了wal log到文件系统当中,当时不保证从库wal log是否刷盘和应用。随后对客户端返回已提交。

  • remote_apply:较高的安全性,较低的性能,它保证了事务在主库实现持久化后,至少有一个同步的从库,接收并且写入了wal log到文件系统,并且回放完成,应用到了数据库中,但是没有保证数据是否刷盘。

  • on:最高级别的数据持久性保障,较差的性能,不但保证了主库本地数据的持久性,如果是在一主两从的流复制中,还需要至少一个从库已经持久化刷盘完成(这个需要配置synchronous_standby_names),最后才可以返回给客户端已提交。这就是我们前面说到的,强同步流复制,当然如果从库一直没有提交,主库就会夯住,处于一直等待。

synchronous_standby_names

  • synchronous_standby_names = ‘standby1’:配置一个表示,只需要等待standby1这一个从库,等待到哪个地步由synchronous_commit的具体参数控制。

  • synchronous_standby_names = ‘FIRST 1 (standby1,standby2)’:FIRST 1表示最多等待几个从库,这里表示最多等待一个,优先级最高的为standby1,表示优先等待standby1这一个从库,如果standby1不可用了,那系统将自动降级等待standby2。

  • synchronous_standby_names = ‘ANY 1 (standby1,standby2)’:ANY 1表示从standby1和standby2两个节点,等待任意一个即可,没有所谓的优先级,任何一个等待完成都算成功。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值