• PostgreSQL实战之物理复制和逻辑复制(二)


    目录

    物理复制和逻辑复制(二)

    前言

    2.1 同步流复制

    2.1.1 synchronous_commit参数详解

    2.1.2 配置同步流复制

    2.1.3 同步流复制的典型“陷阱”


    物理复制和逻辑复制(二)

    前言

    异步流复制指主库上提交事务时不需要等待备库接收并写入WAL日志时便返回成功,如果主库异常宕机,主库上已提交的事务可能还没来得及发送给备库,就会造成备库数据丢失,备库丢失的数据量和WAL复制延迟有关,WAL复制延迟越大,备库上丢失的数据量越大。
    同步流复制在主库上提交事务时需等待备库接收并WAL日志,当主库至少收到一个备库发回的确认信息时便返回成功,同步流复制确保了至少一个备库收到了主库发送的WAL日志,一方面保障了数据的完整性,另一方面增加了事务响应时间,因此同步流复制主库的吞吐量相比异步流复制主库吞吐量低。
    这一小节将介绍同步流复制的部署,同步流复制的部署与异步流复制部署过程没有太大差别,只是postgresql.conf和recovery.conf配置文件的几个参数需要额外配置。

    2.1 同步流复制

    2.1.1 synchronous_commit参数详解

    在介绍同步流复制部署之前先来介绍synchronous_commit参数,synchronous_commit参数是流复制配置中的重点参数,理解它的含义能够更好地理解同步流复制、异步流复制的工作原理。
    synchronous_commit参数是postgresql.conf配置文件中WAL相关配置参数,是指当数据库提交事务时是否需要等待WAL日志写入硬盘后才向客户端返回成功,此参数可选值为on、off、local remote_apply、remote_write,要理解每个参数的含义可能没那么容易,这里尽可能详细解释这些选项值的含义,分单实例和流复制环境介绍。
    场景一:单实例环境
    (1)on :当数据库提交事务时,WAL先写入WAL BUFFER再写入WAL日志文件,设置成on表示提交事务时需等待本地WAL写入WAL日志后才向客户端返回成功,设置成on非常安全,但数据库性能有损耗。
    (2)off:设置成off表示提交事务时不需等待本地WAL BUFFER写入WAL日志后向客户端返回成功,设置成off时也不会对数据库带来风险,虽然当数据库宕机时最新提交的少量事务可能丢失,但数据库重启后会认为这些事务异常中止,设置成off能够提升数据库性能,因此对于数据准确性没有非常精确要求同时追求数据库性能的场景建议设置成off。
    (3)local : local的含义和on类似,表示提交事务时需等待本地WAL写入后才向客户端返回成功。
    场景二:流复制环境
    (1)remote_write:当流复制主库提交事务时,需等待备库接收主库发送的WAL日志流并写人备节点操作系统缓存中,之后向客户端返回成功,这种情况下备库实例出现异常关闭时不会有已传送的WAL日志丢失风险,但备库操作系统异常宕机就有已传送的WAL丢失风险了,此时WAL可能还没完全写入备节点WAL文件中,简单地说remote_write表示本地WAL已落盘,备库的WAL还在备库操作系统缓存中,也就是说只有一份持久化的WAL,这个选项带来的事务响应时间较低。
    (2)on:设置成on表示流复制主库提交事务时,需等待备库接收主库发送的WAL日志流并写入WAL文件,之后才向客户端返回成功,简单地说on表示本地WAL已落盘,备库的WAL也已落盘,也就是说有两份持久化的WAL,但备库此时还没有完成重做,这个选项带来的事务响应时间较高。
    (3)remote_apply:表示表示流复制主库提交事务时,需等待备库接收主库发送的WAL并写入WAL文件,同时备库已经完成重做,之后才向客户端返回成功,简单地说remote_apply表示本地WAL已落盘,备库WAL已落盘并且已完成重做,这个设置保证了拥有两份持久化的WAL,同时备库也完成了重做,这个选项带来的事务响应时间最高。

    2.1.2 配置同步流复制

    备库recovery.conf配置文件设置以下参数,如下所示:

    primary_conninfo = 'host=192.168.28.74 port=1921 user=repuser application_name=node2'

    primary_conninfo参数添加 application_name选项,application_name选项指定备节点的别名,主库postgresql.conf的synchronous_standby_names参数可引用备库application_name选项设置的值,这里设置成node2。
    主库上postgresql.conf配置文件设置以下参数,其他参数和异步流复制配置一致。

    1. synchronous_commit = on 或 remote_apply
    2. synchronous_standby_names = 'node2'

    wal_level配置也和异步流复制配置一致,设置成replica或 logical 即可。
    (1)synchronous_commit参数配置成on或remote_apply,通常设置成on,表示有两份持久化的WAL日志。
    (2)synchronous_standby_names参数配置同步复制的备库列表,可以配置多个同步备库,实验环境为一主一备环境,因此这里设置成node2,这个值必须和同步备库recovery.conf文件的primary_conninfo参数的 application_name选项设置值一致。配置完成后,主库执行以下命令使配置生效:

    1. [postgres@pghost1 ~] $ pg_ctl reload
    2. server signaled

    wal_level参数调整后需重启数据库生效,synchronous_commit和 synchronous_standby_names参数调整后不需要重启数据库生效,只需执行pg_ctl reload命令重新载人配置文件即可。由于配置异步流复制时wal_level已经配置成replica,因此不需要再调整此参数配置。
    备库调整了recovery.conf参数后需重启生效,pghost2上重启数据库,如下所示:

    1. [postgres@pghost2 ~]$ pg_ctl restart -m fast
    2. waiting for server to shut down . . .. done
    3. server stopped

    之后查看主库是否建立了WAL发送进程,备库上是否建立了WAL接收进程,如果有异常,查看数据库日志排查错误。
    主库上查看复制状态,如下所示:

    1. [postgres@pghost2 ~] $ pg_ctl restart -m fastwaiting for server to shut down . . . . done
    2. server stopped

    之后查看主库是否建立了WAL发送进程,备库上是否建立了WAL接收进程,如果有异常,查看数据库日志排查错误。
    主库上查看复制状态,如下所示:

    1. postgres=# SELECT usename,application_name,client_addr,sync_state
    2. FROM pg_stat_replication ;
    3. usename | application_name | client_addr | sync_state
    4. ------—-+------------------+--------------+------------
    5. repuser | node2 | 192.168.28.75 | sync
    6. (1 row)

    此时pg_stat_replication视图的sync_state字段已变成了sync状态,sync表示主库与备库之间采用同步复制方式,以上就是同步流复制主要配置步骤。

    2.1.3 同步流复制的典型“陷阱”

    同步流复制模式中,由于主库提交事务时需等待至少一个备库接收WAL并返回确认信息后主库才向客户端返回成功,一方面保障了数据的完整性,另一方面对于一主一备的同步流复制环境存在一个典型的“陷阱”,具体表现为如果备库宕机,主库上的写操作将处于等待状态。接下来在刚部署完成的同步流复制环境做个测试,环境为一主一备,pghost1 上的数据库为主库,pghost2上的数据库为同步备库。
    先把备库停掉模拟备库故障,如下所示:

    1. [ postgres@pghost2 ~]$ pg_ctl stop -m fast
    2. waiting for server to shut down . . .. done
    3. server stopped

    之后尝试在主库上执行读操作,如下所示:

    1. postgres=#SELECT * FROM test_sr LIMIT 1;
    2. id
    3. --------
    4. 1
    5. (1 row)

    同步备库宕机后,主库上的查询操作不受影响。之后在主库上尝试插入一条记录,如下所示:
     

    1. postgres=# INSERT INTO test_sr (id)VALUES (5);
    2. --注意这里命令被阻塞。

    这时主库上的INSERT语句一直处于等待状态,也就是说同步备库宕机后,主库上的读操作不受影响,写操作将处于阻塞状态,因为主库上的事务需收到至少一个备库接收WAL后的返回信息才会向客户端返回成功,而此时备库已经停掉了,主库上收不到备库发来的确认信息,如果是生产库,将对生产系统带来严重影响。
    通常生产系统一主一备的情况下不会采用同步复制方式,因为备库宕机后同样对生产系统造成严重影响,PostgreSQL支持一主多从的流复制架构,比如一主两从,将其中一个备库设为同步备库,另一个备库设为异步备库,当同步备库宕机后异步备库升级为同步备库,同时主库上的读写操作不受影响。

  • 相关阅读:
    【PyTorch 攻略 (4/7)】张量和梯度函数
    android 12 /mnt/media
    Android红外遥控ConsumerIrManager
    C++:多态 详解
    【技术积累】Python中的PyTorch库【一】
    git 申请合并冲突:rebase 解决合成一条再成功合并
    面试面经|Java面试MySQL面试题
    微前端 - micro-app 数据通信
    RabbitMQ系列【15】AmqpAdmin使用详解
    信息系统项目管理师(2022年)—— 重点内容:项目进度管理(6)
  • 原文地址:https://blog.csdn.net/Auspicious_air/article/details/127788750