云贝教育 |【技术文章】PG的流复制搭建

一 主备机器规划主机名

主:192.168.2.103 db1 
备:192.168.2.104 db2 

二 创建流复制

2.1 修改主机配置(两台主机都修改)

$ cat /etc/hosts 
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 
192.168.2.103 db1 
192.168.2.104 db2 

2.2 在主库设置

1) 初始化新数据库

pg_ctl init -D /pgdata/data 

2) 启动数据库

pg_ctl -D /pgdata/data start 

3)建立同步用户

postgres=# create role repl login replication encrypted password 'repl'; 
CREATE ROLE 

4)配置$PGDATA/data/pg_hba.conf

host replication repl db2 trust 
host replication repl 192.168.2.0/24 trust 
host all all 192.168.2.0/24 trust 

注意:备库也做同样的配置(注意修改主机名),为了后面的主备切换

5)配置$PGDATA/data/postgres.conf

listen_addresses = '*' 
wal_level = replica 
max_wal_senders=10 
archive_mode = on 
archive_command = 'cp %p /home/postgres/arch/%f' 
restore_command = 'cp /home/postgres/arch/%f %p' 
recovery_target_timeline = 'latest' 
full_page_writes = on 
wal_log_hints = on logging_collector = on 
log_directory = 'pg_log'13 log_filename = 'postgresql-%Y-%m-%d.log' 

6)重启让配置生效

pg_ctl -D /pgdata/data restart 

2.3 在备库设置

1)不需要初始化,直接从主库备份就行

pg_basebackup -h db1 -p 5432 -U repl -R -F p -P -D /pgdata/data 

2)备库修改配置文件

listen_addresses = '*' 
wal_level = replica 
max_wal_senders=10 
archive_mode = on 
archive_command = 'cp %p /home/postgres/arch1/%f' --设置归档 cp 命令 
restore_command = 'cp /home/postgres/arch1/%f %p' 
recovery_target_timeline = 'latest' 
full_page_writes = on 
wal_log_hints = on logging_collector = on 
log_directory = 'pg_log' 
log_filename = 'postgresql-%Y-%m-%d.log' 
--以下参数因为使用pg_basebackup不需要重复设置 hot_standby = on #在备份的同时允许查询,默认值
max_standby_streaming_delay = 30s #可选,流复制最大延迟 
wal_receiver_status_interval = 10s #可选,从向主报告状态的最大间隔时间 
hot_standby_feedback = on #可选,查询冲突时向主反馈 

3)配置$PGDATA/data/pg_hba.conf

host replication repl db1 trust #这里修改主机名为主机的 
host replication repl 192.168.2.0/24 trust 
host all all 192.168.2.0/24 trust 

4)创建备库文件 standby.signal

touch standby.signal

#连接到主库信息 
primary_conninfo = 'host=db1 port=5433 user=repl password=repl options=''-c wal_sender_timeout=5000''' 
#将来变成主库时需要用到的参数。 
restore_command = 'cp /home/postgres/arch1/%f %p' 
#变成主库后需要清空的归档日志 
archive_cleanup_command = 'pg_archivecleanup /home/postgres/arch1 %r' 
#把备库变成 read-only transaction 模式 
standby_mode = on 

5)重启让配置生效

pg_ctl -D /pgdata/data restart

三、验证

3.1 查看主备进程

[postgres@db1 pg_wal]$ ps -ef|grep wal 
postgres 58923 58918 0 02:46 ? 00:00:00 postgres: walwriter 
postgres 59341 58918 0 02:52 ? 00:00:00 postgres: walsender repl 192.168.2.104(60618) streaming 0/5000060 

[postgres@db2 pg_wal]$ ps -ef|grep wal 
postgres 69657 69648 0 02:52 ? 00:00:00 postgres: walreceiver streaming 0/5000060 

3.2 主库切换日志

postgres=# select pg_switch_wal(); 
pg_switch_wal 
--------------- 
0/4000160 
(1 row) 

查看备库WAL日志同步情况

3.3 查看当前备库状态:

select pg_is_in_recovery(); 
t :true,意味着处于 recovery 状态 
f :false,意味着处于正常服务状态 

3.4 主库查询

postgres=# \x 
Expanded display is on. 
postgres=# select * from pg_stat_replication; 
-[ RECORD 1 ]----+------------------------------ 
pid              | 59341 
usesysid         | 16388 
usename          | repl 
application_name | walreceiver 
client_addr      | 192.168.2.104 
client_hostname  | db2 
client_port      | 60618 
backend_start    | 2023-12-10 02:52:19.435147+08 
backend_xmin     | 
state            | streaming 
sent_lsn         | 0/7000148 
write_lsn        | 0/7000148 
flush_lsn        | 0/7000148 
replay_lsn       | 0/7000148 
write_lag        | 
flush_lag        | 
replay_lag       | 
sync_priority    | 0 
sync_state       | async 
reply_time       | 2023-12-10 02:59:39.394891+08 

sync_state表示同步模式

sent_lsn表示发送日志的起点

reply_time表示应用日志的起点

3.5 备库数据库日志内容

2023-12-10 02:52:19.437 CST [69657] LOG: started streaming WAL from primary at 0/4000000 on timeline 1 
2023-12-10 02:57:19.469 CST [69650] LOG: restartpoint starting: time 
2023-12-10 02:57:19.476 CST [69650] LOG: restartpoint complete: wrote 1 buffer s (0.0%); 0 WAL file(s) added, 0 removed, 4 recycled; write=0.001 s, sync=0.001 s, total=0.007 s; sync files=0, longest=0.000 s, average=0.000 s; distance=6553 6 kB, estimate=65536 kB 
2023-12-10 02:57:19.476 CST [69650] LOG: recovery restart point at 0/7000060 

四、主从切换

这里建议把wal保留参数调大,保证切换过程中,原备库的日志和原主库的日志LSN同步

▪ min_wal_size

▪ wal_keep_size

4.1 停止主库

pg_ctl -D /pgdata/data stop 

4.2 备库上执行命令,提升为主备

执行以下命令进行主从切换,把备库改成主库,执行之后发现 standby.signal 被删除了 
pg_ctl promote 查看最新状态: 
pg_controldata | grep cluster 
Database cluster state: in production 

4.3 修改postgresql.auto.conf

primary_conninfo = 'user=repl passfile=''/home/postgres/.pgpass'' host=pg1 port=1922 sslmode=disable 
sslcompression=0 gssencmode=disable krbsrvname=postgres target_session_attrs=any' 

重启数据库,查看后台进程,此时未发现walsender进程

ps -ef|grep postgres 

4.4 在新备库上(原主库)创建一个 standby.signal文件,添加如下内容:

primary_conninfo = 'host=db2 port=5433 user=repl password=repl options=''-c wal _sender_timeout=5000''' 
restore_command = 'cp /home/postgres/arch1/%f %p' 
archive_cleanup_command = 'pg_archivecleanup /home/postgres/arch1 %r' 
standby_mode = on

4.5 在新备库的 postgresql.auto.conf 文件中添加

如下内容:

primary_conninfo = 'user=repl passfile=''/home/postgres/.pgpass'' channel_bindi ng=prefer host=db2 port=5433 sslmode=prefer sslcompression=0 sslsni=1 ssl_min_p rotocol_version=TLSv1.2 gssencmode=prefer krbsrvname=postgres target_session_attrs=any' 

注意/home/postgres/.pgpass 其实没有没有这个文件,不需要创建。

4.6 启动新备库:

pg_ctl start 

4.7 验证主备库是否能够同步

在主库进行 dml 操作,发现备库能够正常同步,切换成功。

五、实时同步

上面的配置是异步同步,对于主库的性能影响是最小的,但是会丢数据,我们可以把复制配置成

实时同步。

当设置同步复制时:

• 最小化延迟

• 确保您有冗余延迟

• 同步复制比异步复制代价更高同步时是通过一个关键的参数 application_name 来实现的。

5.1 配置主库 postgres.conf,添加如下内容:

synchronous_standby_names = 'standby_pg2' 
synchronous_commit = on 

5.2 重启主库

pg_ctl restart 

5.3 修改备库 standby.signal 配置文件

在原来的内容中添加 application_name 内容

primary_conninfo = 'host=pg1 application_name=standby_pg2 port=1922 user=repl password=oracle options=''-c wal_sender_timeout=5000''' 
restore_command = 'cp /home/postgres/arch/%f %p' 
archive_cleanup_command = 'pg_archivecleanup /home/postgres/arch %r' 
standby_mode = on 

5.4 修改备库 postgresql.auto.conf

添加 application_name 内容,实际上备库是以这个文件为主,上面修改的 standby.signal 并不生效:

primary_conninfo = 'user=repl passfile=''/home/postgres/.pgpass'' channel_binding=prefer host=db2 application_name=standby_pg2 port=5433 sslmode=prefer sslcom pression=0 sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=prefer krbsrvna me=postgres target_session_attrs=any' 

5.5 重启备库,查看后台日志信息:

consistent recovery state reached at 0/21000188

5.6、在主库查看同步状态:

postgres=# \x 
Expanded display is on. 
postgres=# SELECT * FROM pg_stat_replication; 
-[ RECORD 1 ]----+------------------------------ 
pid              | 75433 
usesysid         | 16388 
usename          | repl 
application_name | standby_pg2 
client_addr      | 192.168.2.103 
client_hostname  | db1 
client_port      | 57420 
backend_start    | 2023-12-10 04:17:12.048633+08 
backend_xmin     | 
state            | streaming 
sent_lsn         | 0/110000D8 
write_lsn        | 0/110000D8 
flush_lsn        | 0/110000D8 
replay_lsn       | 0/110000D8 
write_lag        | 
flush_lag        | 
replay_lag       |22 sync_priority | 1 
sync_state       | sync 
reply_time       | 2023-12-10 04:17:22.111778+08 

状态显示为实时同步。

5.7 验证备库关闭

#备库 
[postgres@db1 data]$ pg_ctl -D /pgdata/data/ stop 
waiting for server to shut down.... done 
server stopped #主备 
postgres=# create table t1 as select * from pg_class; 
。。。。。等待中 

备库关闭之后,主库执行DML操作HANG住。

5.8 多个从库的配置

如果我们配置了多个备库,而且进行实时同步,假如只要保证前面的备库能够实时就可以,那么

可以进行如下设置:

synchronous_standby_names = 'FIRST 2 (s1, s2, s3)' 

如果只要保证其中任何的备库同步成功,可以进行如下设置:

synchronous_standby_names = 'ANY 2 (s1, s2, s3)'

六、添加节点

6.1 修改 standby.signal 和postgres.auto.conf 文 件

1)三节点还原主备 
pg_basebackup -h db2 -p 5433 -U repl -R -F p -P -D /pgdata/data2 2)修改三节点端口号 
port=5433 3)修改三节点postgres.auto.conf 
primary_conninfo = 'user=repl passfile=''/home/postgres/.pgpass'' channel_bindi ng=prefer host=db2 application_name=standby_pg2 port=5433 sslmode=prefer sslcom pression=0 sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=prefer krbsrvna me=postgres target_session_attrs=any' 

6.2 修改主库的 postgres.conf,添加如下一行:

synchronous_standby_names = 'standby_pg3' 
synchronous_commit = on synchronous_standby_names = 'FIRST 2 (standby_pg2,standby_pg3)' 

6.3 重启主库,查看复制状态:

pg_ctl restart testdb=# \x 
Expanded display is on. 
testdb=# select * from pg_stat_replication 

6.4 验证同步

主要备库的任何一个节点无法同步,都会影响主库的事务操作。但是发现正常的一个备库节点能够同步,即使主库处于停留状态,由此证明主库已经把事务传递到备库了,只是有备库没有同步,所以处于等待状态。

6.5 如果把主库的参数修改如下:

synchronous_standby_names = 'FIRST 1 (standby_pg2,standby_pg3)' 

实验证明,如果第二个备库节点发生故障无法同步,不会影响主库事务操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/224882.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

spring-cloud-stream-kafka生产速度慢

包版本spring-cloud-starter-stream-kafka:3.1.0 修改yaml配置 添加poller配置

Python多态原理及实现

对于弱类型的语言来说,变量并没有声明类型,因此同一个变量完全可以在不同的时间引用不同的对象。当同一个变量在调用同一个方法时,完全可能呈现出多种行为(具体呈现出哪种行为由该变量所引用的对象来决定),…

人工智能与低代码:前端技术的双重变革

随着科技的飞速发展,人工智能(AI)和低代码开发平台已经成为当下热门的话题。在前端技术领域,这两大技术的崛起正在悄然改变开发模式,提高开发效率,降低技术门槛。本文将从以下几个方面,详细探讨…

Netty介绍

1. Netty介绍 是一个异步的、基于事件驱动的网络应用框架,用以开发高性能,高可靠性的网络io程序。Netty主要针对在TCP协议下,面向clients端的高并发应用,或者peer-to-peer场景下大量数据持续传输的应用。Netty本质上是一个NIO框架…

12.15每日一题(备战蓝桥杯摘花生)

12.15每日一题(备战蓝桥杯摘花生) 题目 摘花生 Hello Kitty想摘点花生送给她喜欢的米老鼠。 她来到一片有网格状道路的矩形花生地(如下图),从西北角进去,东南角出来。 地里每个道路的交叉点上都有种着一株花生苗,上…

都有哪些大厂开始适配鸿蒙原生应用呢

12月8日,随着支付宝宣布启动鸿蒙原生应用开发以来,国内宣布接入鸿蒙原生应用开发的公司越来越多。事实上,自9月华为宣布鸿蒙原生应用全面启动以来,已有金融、旅行、社交等多个领域的企业和开发者陆续宣布加入鸿蒙生态,…

配电房智能运维工具-电易云

配电房智能运维是将云计算、物联网、大数据与“互联网”服务理念相结合,采用“线上线下”的服务模式,为电力终端用户提供托管式配电智能运维服务。电易云智慧电力物联网是以提高电力运行安全,降低运维成本为目标,采用物联网、云计…

Linux-CentOS7(无图形界面版)部署stable-diffusion-webui 全过程

Linux-CentOS7(无图形界面版)部署Stable Diffusion webui 全过程 前置要求 git的版本不能是CentOS默认的版本(1.8),版本太老,在后面安装过程会失败。去github上下载最新的git源码包 安装成功显示版本号 …

ElasticSearch与HBase的分布式存储设计

本文内容覆盖如今两大非结构化数据库之间的区别 详情介绍 从各个角度详细对比 1. 官方定位 HBase 是 Hadoop 数据库,是一个分布式、可扩展的大数据存储。 当您需要对大数据进行随机、实时的读/写访问时,请使用 Apache HBase™。 这个项目的目标是在商用硬件集群上托管非常大…

github 学习番外篇

我们可以按照仓库开始的提示提交仓库 不知道为什么 出现了 我用 git branch 查看了一下,竟然没发现分支 后来发现是只有commit以后才会显示这个分支 后来显示 这是因为本地和远程仓库不同步的原因 这时候我们就需要git pull 一下 发现两个仓库由于不关联不能git…

电商项目高并发缓存实践

大部分面向公众的互联网系统,其并发请求数量与在线用户数量都是正相关的,而 MySQL 能够承担的并发读写量是有一定上限的,当系统的访问量超过一定程度的时候,纯 MySQL 就很难应付了。绝大多数互联网系统都是采用 MySQLRedis 这对经…

衡兰芷若成绝响,人间不见周海媚(4k修复基于PaddleGan)

一代人有一代人的经典回忆,1994年由周海媚、马景涛、叶童主演的《神雕侠侣》曾经风靡一时,周海媚所诠释的周芷若凝聚了汉水之钟灵,峨嵋之毓秀,遇雪尤清,经霜更艳,俘获万千观众,成为了一代人的共…

Gartner发布2024年网络安全预测 :IAM 和数据安全相结合,解决长期存在的挑战

安全和风险管理领导者需要采用可组合的数据安全视图。这项研究预测,将数据安全创新应用于痛点和高级用例将有助于组织将其数据用于几乎任何用例。 主要发现 在所有云服务模型中,数据安全以及身份和访问管理 (IAM) 的责任均由最终客户承担。 由于这两个学…

Python等比例缩放图片并修改对应的Labelme标注文件(v2.0)

Python等比例缩放图片并修改对应的Labelme标注文件(v2.0) 前言前提条件相关介绍实验环境Python等比例缩放图片并修改对应的Labelme标注文件Json文件代码实现输出结果 前言 此版代码,相较于Python等比例缩放图片并修改对应的Labelme标注文件&a…

seleniumwire获取页面接口数据

selenium并不支持获取响应的数据,我们可以使用selenium-wire库,selenium-wire扩展了 Selenium 的 Python 绑定,可以访问浏览器发出的底层请求。 编写的代码与 Selenium 的方式相同。 1. 先安装seleniumwire的插件 pip install selenium-wir…

CSS基础面试题

介绍一下标准css盒子模型与低版本IE的盒子模型? 标准盒子模型:宽度内容的宽度(content) border padding margin 低版本IE盒子模型:宽度内容宽度(contentborderpadding) margin box-sizing 属性…

Kafka Avro序列化之二:使用Twitter的Bijection 类库实现

Kafka Avro序列化之一:使用自定义序列化 比较麻烦,需要根据 schema 生成实体类,需要调用 avro 的 API 实现 对象到 byte[]的序列化 和 byte[] 到对象的反序列化转化,而那些方法看上去比较繁琐,幸运的是,Twitter 开源的类库 Bijection 对传统的 Avro API 进行了封装了和优…

python实现切割mp4视频,按照指定要求截取视频

方法一: 该python代码用以将一长段视频,分割成自己需要的时长段的视频 import cv2START_HOUR 0 START_MIN 0 START_SECOND 0 START_TIME START_HOUR * 3600 START_MIN * 60 START_SECOND # 设置开始时间(单位秒) END_HOUR 0 END_MIN 0 END_SE…

ElasticSearch指南 - Mapping - Metadata fields

Metadatas - fields 每份doc都有关联它的metadata数据, 例如_index 和 _id字段. 这些metadatas字段的一些行为能在创建mapping的时候被定制化. 表示唯一性的metadatas字段 _index 表示doc属于哪个index _id doc的id 源doc的metadatas字段 _source doc的原始json字符串 _s…

shell脚本中调用python脚本的函数并获取python脚本函数的return值

1. 编写Python脚本 假设你有一个Python脚本example.py,其中包含一个名为my_function的函数,并且你希望在Shell脚本中调用这个函数并获取其返回值。示例Python脚本如下: # example.pydef my_function():return "Hello from Python"…