热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PostgreSQL14.5复制流(同步复制)

1介绍    PostgresSQL在9.0版本实现的复制功能只能进行异步复制,在PostgreSQL9.1版本中可以支持同步复制。    PostgreSQL流复制是基于WA

1 介绍

        PostgresSQL在9.0版本实现的复制功能只能进行异步复制,在PostgreSQL 9.1版本中可以支持同步复制

        PostgreSQL流复制是基于WAL日志传输实现的:主库发送WAL日志,备库接收WAL日志并进行回放。

 

流复制的3个主要进程:



  • 主库的walsender进程:负责发送WAL日志给备库。

  • 备库的walreceiver进程:负责主库发送的WAL日志。

  • 备库的startup进程:重放接收的WAL日志。

 

主从之间是怎么通信的?

(1)primary端 后端进程通过执行函数XLogInsert()和XLogFlush(),将WAL数据写入并刷新到WAL段文件中。

(2)primary端 WAL发送器进程将写入WAL段文件的WAL数据发送到WAL接收器进程。

(3)primary端 在发送WAL数据之后,后端进程继续等待来自备库的ACK响应。更确切地说,后端进程通过执行内部函数SyncRepWaitForLSN()来获取锁存器,并等待它被释放。

(4)standby端 上的WAL接收器通过write()系统函数调用,将接收到的WAL数据写入备库的WAL段,并向WAL发送器返回ACK响应。

(5)standby端 WAL接收器通过调用(如fsync()函数)将WAL数据刷新到WAL段中,向WAL发送器返回另一个ACK响应,并通知启动进程相关WAL数据已更新。

(6)standby端 启动进程重放已写入WAL段的WAL数据。

(7)primary端 WAL发送器在收到来自WAL接收器的ACK响应后释放后端进程的锁存器,然后后端进程完成commit或abort动作。锁存器释放的时间取决于参数synchronous_commit。如果它是‘on’(默认),那么当接收到步骤(5)的ACK时,锁存器被释放;如果它是'remote_write',当接收到步骤(4)的ACK时,其被释放。

 

每个ACK响应将备库的内部信息通知给主库,包含以下4个项目:



  • 已写入最新WAL数据的LSN位置。

  • 已刷新最新WAL数据的LSN位置。

  • 启动进程已经重放最新的WAL数据的LSN。

  • 发送此响应的时间戳。


2 安装PostgreSQL 14.5

CentOS 7.6

PostgreSQL 14.5

 

安装步骤请参考:PostgreSQL 14.5 for CentOS安装


3 配置复制流(同步复制)

同步流复制primary数据库要求wal日志写入standby数据库commit后才会返回成功,所以当standby与primary断开时,primary端会hang住。为了解决这个问题需要与primary配置至少两个standby,确保primary数据库的wal日志写入任意一个standby数据库并commit。


3.1 配置“复制槽”

        standby端如果长时间停机,重启后standby可能因缺少相应的WAL日志无法连接primary。此时可以通过启用max_replication_slots参数启用复制槽来解决此问题。

        primary端实例会一直保留预写日志(WAL)文件,直到所有备库所需的插槽都确认已接收到特定段为止。只有完成此操作后,主库实例才会移除相应的WAL文件。

 

Primary端创建复制槽

SELECT * FROM pg_create_physical_replication_slot('pg_primary');

 

查看复制槽

postgres=# select * from pg_replication_slots;
slot_name | plugin | slot_type | datoid | database | active | active_pid | xmin | catalog_xmin | restart_lsn | confirmed_flush_lsn
------------+--------+-----------+--------+----------+--------+------------+------+--------------+-------------+---------------------
pg_primary | | physical | | | t | 116077 | | | 89/A40003E0 |

3.2 开启归档

开启归档模式

创建归档目录

[postgres]# mkdir $PGDATA/arch_log

配置归档脚本

[postgres]# vi $PGDATA/archive.sh
cp --preserve=timestamps $1 $PGDATA/arch_log/$2 ; find $PGDATA/arch_log -type f -mtime +30 | xargs rm -fr;

修改归档相关参数

[postgres]# vi $PGDATA/postgresql.conf
archive_mode = on
archive_command = '/bin/bash archive.sh %p %f'
archive_timeout = 1800

重启postgres使归档参数生效

[postgres]# pg_ctl restart

查看参数是否已经生效

postgres=# select name,setting from pg_settings where name in ('archive_mode','archive_command','archive_timeout');
name | setting
-----------------+----------------------------
archive_command | /bin/bash archive.sh %p %f
archive_mode | on
archive_timeout | 1800

手动归档

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

查看归档目录是否已存在归档文件

[postgres]# ls $PGDATA/arch_log
000000010000000000000004

3.3 primary端配置

 创建复制用户

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

配置权限配置文件

[postgres]# vi pg_hba.conf
添加如下:
host replication repl 0.0.0.0/0 md5

 配置参数(这个必须配置)

[postgres]# vi postgresql.conf
listen_addresses = '*'
wal_level = replica
hot_standby = on #指定备库可读模式
synchronous_commit = on #配置同步模式
synchronous_standby_names = 'host72,host73' #只要primary端wal传到任意一台standby并commit就OK(此处是application_name)

重启PG使参数生效

[postgres]# pg_ctl restart

 3.4 配置standby端

 删除standby端数据

[postgres]# pg_ctl stop
[postgres]# rm -fr $PGDATA/*

复制primary端到standby端,在$PGDATA路径下会生成standby.signal文件

[postgres]# pg_basebackup -h 192.168.2.221 -U repl -D $PGDATA -X stream -P -R

 

配置主从参数

[postgres]# vi $PGDATA/standby.signal
primary_cOnninfo= 'application_name=host72 user=repl password=Your_passwd channel_binding=disable host=192.168.1.71 port=5432 sslmode=disable sslcompression=0 sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=disable krbsrvname=postgres target_session_attrs=any'
[postgres]# vi $PGDATA/postgresql.conf
#primary_cOnninfo= 'host=192.168.1.71 port=5432 user=repl password=Your_passwd' #配置standby.signal此处可不用配置
recovery_target_timeline = 'latest'
primary_slot_name = 'pg_primary'
hot_standby = on #配置standby端可读

3.5 启动流复制

standby端启动postgres

[postgres]# pg_ctl start

 

primary端查看流复制详情

postgres=# select * from pg_stat_replication;
-[ RECORD 1 ]----+------------------------------
pid | 22930
usesysid | 16384
usename | repl
application_name | host72
client_addr | 192.168.1.72
client_hostname |
client_port | 54718
backend_start | 2022-09-22 21:42:14.120187+08
backend_xmin |
state | streaming
sent_lsn | 0/6F0003B8
write_lsn | 0/6F0003B8
flush_lsn | 0/6F0003B8
replay_lsn | 0/6F0003B8
write_lag | 00:00:00.000336
flush_lag | 00:00:00.000336
replay_lag | 00:00:00.000336
sync_priority | 1
sync_state | sync
reply_time | 2022-09-22 21:42:14.229005+08
-[ RECORD 1 ]----+------------------------------
pid | 22930
usesysid | 16384
usename | repl
application_name | host72
client_addr | 192.168.1.73
client_hostname |
client_port | 54718
backend_start | 2022-09-22 21:42:14.120187+08
backend_xmin |
state | streaming
sent_lsn | 0/6F0003B8
write_lsn | 0/6F0003B8
flush_lsn | 0/6F0003B8
replay_lsn | 0/6F0003B8
write_lag | 00:00:00.000336
flush_lag | 00:00:00.000336
replay_lag | 00:00:00.000336
sync_priority | 1
sync_state | sync
reply_time | 2022-09-22 21:42:14.229005+08

4 监控复制流

Primary端查看已连接的Standby端信息,如果为空说明复制流异常

postgres=# \x on;
Expanded display is on.
postgres=# select * from pg_stat_replication;
-[ RECORD 1 ]----+------------------------------
pid | 4007
usesysid | 16384
usename | repl
application_name | walreceiver
client_addr | 192.168.1.72
client_hostname | host72
client_port | 34596
backend_start | 2022-09-21 17:47:09.629914+08
backend_xmin |
state | streaming
sent_location | 1/F4000060
write_location | 1/F4000060
flush_location | 1/F4000060
replay_location | 1/F4000060
sync_priority | 0
sync_state | sync
----+------------------------------
pid | 116097
usesysid | 16385
usename | repl
application_name | walreceiver
client_addr | 192.168.1.73
client_hostname |
client_port | 45984
backend_start | 2021-12-20 16:17:58.493769+08
backend_xmin |
state | streaming
sent_location | 89/A2BE8E10
write_location | 89/A2BE8E10
flush_location | 89/A2BE8E10
replay_location | 89/A2BE8E10
sync_priority | 0
sync_state | sync

 

Standby端查看是否处于recovery状态,值为“t”说明是当前数据库是备库,值为“f”说明当前数据库是主库(也可能复制流出现异常出现双主)

postgres=# select pg_is_in_recovery();
pg_is_in_recovery
-------------------
t

 

通过pg_controldata命令查看Database cluster state,值为“in archive recovery”说明是当前数据库是备库,值为“in production”说明当前数据库是主库

[postgres@host72 postgres]$ pg_controldata $DATA
pg_control version number: 960
Catalog version number: 201608131
Database system identifier: 7122063347532860770
Database cluster state: in archive recovery
pg_control last modified: Wed 21 Sep 2022 05:52:09 PM CST
Latest checkpoint location: 1/F4000098
Prior checkpoint location: 1/F0000060
Latest checkpoint's REDO location: 1/F4000060
Latest checkpoint's REDO WAL file: 00000001000000010000003D
Latest checkpoint's TimeLineID: 1
Latest checkpoint's PrevTimeLineID: 1
Latest checkpoint's full_page_writes: on
Latest checkpoint's NextXID: 0:1762
Latest checkpoint's NextOID: 24576
Latest checkpoint's NextMultiXactId: 1
Latest checkpoint's NextMultiOffset: 0
Latest checkpoint's oldestXID: 1753
Latest checkpoint's oldestXID's DB: 1
Latest checkpoint's oldestActiveXID: 1762
Latest checkpoint's oldestMultiXid: 1
Latest checkpoint's oldestMulti's DB: 1
Latest checkpoint's oldestCommitTsXid:0
Latest checkpoint's newestCommitTsXid:0
Time of latest checkpoint: Wed 21 Sep 2022 05:51:43 PM CST
Fake LSN counter for unlogged rels: 0/1
Minimum recovery ending location: 1/F4000108
Min recovery ending loc's timeline: 1
Backup start location: 0/0
Backup end location: 0/0
End-of-backup record required: no
wal_level setting: replica
wal_log_hints setting: on
max_connections setting: 500
max_worker_processes setting: 8
max_prepared_xacts setting: 0
max_locks_per_xact setting: 64
track_commit_timestamp setting: off
Maximum data alignment: 8
Database block size: 8192
Blocks per segment of large relation: 131072
WAL block size: 8192
Bytes per WAL segment: 67108864
Maximum length of identifiers: 64
Maximum columns in an index: 32
Maximum size of a TOAST chunk: 1996
Size of a large-object chunk: 2048
Date/time type storage: 64-bit integers
Float4 argument passing: by value
Float8 argument passing: by value
Data page checksum version: 0

 

在standby查看wal接收情况

postgres=# \x on;
Expanded display is on.
postgres=# select * from pg_stat_wal_receiver;
-[ RECORD 1 ]---------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
pid | 34474
status | streaming
receive_start_lsn | 0/70000000
receive_start_tli | 2
written_lsn | 0/70000250
flushed_lsn | 0/70000250
received_tli | 2
last_msg_send_time | 2022-09-22 21:55:55.905271+08
last_msg_receipt_time | 2022-09-22 21:55:55.904179+08
latest_end_lsn | 0/70000250
latest_end_time | 2022-09-22 21:55:25.866616+08
slot_name | pg_primary
sender_host | 192.168.1.71
sender_port | 5432
conninfo | user=repl password=******** channel_binding=disable dbname=replication host=192.168.1.71 port=5432 application_name=host72 fallback_application_name=walreceiver sslmode=disable sslcompression=0 sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=disable krbsrvname=postgres target_session_attrs=any

 

作者:高&玉,博客园链接:https://www.cnblogs.com/haha029/p/16721007.html



推荐阅读
  • Oracle Database 10g许可授予信息及高级功能详解
    本文介绍了Oracle Database 10g许可授予信息及其中的高级功能,包括数据库优化数据包、SQL访问指导、SQL优化指导、SQL优化集和重组对象。同时提供了详细说明,指导用户在Oracle Database 10g中如何使用这些功能。 ... [详细]
  • 本文介绍了如何在MySQL中将零值替换为先前的非零值的方法,包括使用内联查询和更新查询。同时还提供了选择正确值的方法。 ... [详细]
  • 在数据分析工作中,我们通常会遇到这样的问题,一个业务部门由若干业务组构成,需要筛选出每个业务组里业绩前N名的业务员。这其实是一个分组排序的 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文介绍了adg架构设置在企业数据治理中的应用。随着信息技术的发展,企业IT系统的快速发展使得数据成为企业业务增长的新动力,但同时也带来了数据冗余、数据难发现、效率低下、资源消耗等问题。本文讨论了企业面临的几类尖锐问题,并提出了解决方案,包括确保库表结构与系统测试版本一致、避免数据冗余、快速定位问题等。此外,本文还探讨了adg架构在大版本升级、上云服务和微服务治理方面的应用。通过本文的介绍,读者可以了解到adg架构设置的重要性及其在企业数据治理中的应用。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了使用postman进行接口测试的方法,以测试用户管理模块为例。首先需要下载并安装postman,然后创建基本的请求并填写用户名密码进行登录测试。接下来可以进行用户查询和新增的测试。在新增时,可以进行异常测试,包括用户名超长和输入特殊字符的情况。通过测试发现后台没有对参数长度和特殊字符进行检查和过滤。 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 本文由编程笔记小编整理,介绍了PHP中的MySQL函数库及其常用函数,包括mysql_connect、mysql_error、mysql_select_db、mysql_query、mysql_affected_row、mysql_close等。希望对读者有一定的参考价值。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
  • MyBatis错题分析解析及注意事项
    本文对MyBatis的错题进行了分析和解析,同时介绍了使用MyBatis时需要注意的一些事项,如resultMap的使用、SqlSession和SqlSessionFactory的获取方式、动态SQL中的else元素和when元素的使用、resource属性和url属性的配置方式、typeAliases的使用方法等。同时还指出了在属性名与查询字段名不一致时需要使用resultMap进行结果映射,而不能使用resultType。 ... [详细]
author-avatar
起来吧52
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有