postgresq高可用、负载均衡、复制说明(官方文档)

文章目录

  • 26.1不同的方案比较
  • 26.2 高可用
    • 26.2.1 主备要求
    • 26.2.2 备库处理Wal
    • 26.2.3 准备主库
    • 26.2.4 配置备库
      • 26.2.4.1 log模式复制
      • 26.2.4.2 streaming模式复制
    • 26.2.5 流复制
      • 26.2.5.1 流复制
      • 26.2.5.2 流复制监控
    • 26.2.6 复制槽
    • 26.2.7 级联复制
    • 26.2.8 同步复制
      • 26.2.8.1 基本配置
      • 26.2.8.2 多个同步备库
      • 26.2.8.3 性能规划
      • 26.2.8.4 高可用规划
    • 26.2.9 备库的归档
  • 26.3 故意故障转移
  • 26.4 hot standby

https://www.postgresql.org/docs/12/high-availability.html 写的真是稀烂啊

本节讨论不同方案实现高可用、负载均衡、复制。

26.1不同的方案比较

  • Shared Disk Failover:
    共享磁盘。只有一份磁盘数据避免了数据复制的开消,但当共享磁盘失效时主备服务器都宕机,备服务器不应该操作磁盘。
  • File System (Block Device) Replication
    文件系统复制。主库上的文件系统改变时能正确的同步到备服务器上,要求备库上的文件系统定入的顺序与主库一致,DRDB是常用的工具。
  • Write-Ahead Log Shipping
    预写日志。备库通过读取预写日志同步数据。当主库宕机时,备库几乎拥有主备的全部数据,并且可以快速切换到主库。同步可以是异步或者同步的,但是必须对所有主库的所有数据库同步。可以使用日志发送(file-based log Shipping)或者流streaming)来实现同步。
  • Logical Replication
    逻辑复制。逻辑复制允许数据库服务器将数据修改流发送到另一个服务器。PostgreSQL逻辑复制从WAL构造一个逻辑数据修改流。逻辑复制允许复制来自各个表的数据更改。
  • Trigger-Based Master-Standby Replication
    基于触发器的主备复制。主库实时的捕获修改的数据并异步发送到备库。复制的是表。
  • Statement-Based Replication Middleware
    基于语句的复制中间件。程序拦截每个SQL查询并将其发送到复制服务器。读写查询必须发送到所有服务器,以便每个服务器都能收到任何更改。但是只读查询只能发送到一台服务器,从而允许在它们之间分配读工作负载。random()、CURRENT_TIMESTAMP和sequence会有问题要特殊处理。
  • Asynchronous Multimaster Replication
    异步多主复制
  • Synchronous Multimaster Replication
    同步多主复制。多主复制每个库都可以接受读写请求,在每个事务提交之前,修改过的数据发送到其它服务器。大量的写活动可能会导致过度的锁定和提交延迟,从而导致较差的性能。同步多主复制最适合大多数读工作负载。多主复制数据在一台上修改后复制到其它库,因此不存在random()的问题。

各种方案的对比:
postgresq高可用、负载均衡、复制说明(官方文档)_第1张图片

另外两中数据处理方案:

  • Data Partitioning
    数据分区。将表分区,每个分区只能由一台服务器修改。应用程序可以同时查询多个分区,也可以使用主/备复制在另一台服务器上保留分区副本。

26.2 高可用

连续归档日志可用于搭建高可用集群。WAL即指归档日志。两中传输方式:log方式和streaming
主库运行在连续归档模式运行,备库运行在连续恢复模式。备库读取WAL并恢复中的数据。此种方式对主库的影响较小。
log方式主库每次传送一个WAL file(WAL段,默认16MB)到归档位置(可以配置为备库服务器上)。streaming不停的将recode传送到备库,一般来说延迟小至1秒。
注意,wal的传输是异步的,在主库提交事务后才传输wal,如果主库崩溃而wal没有传送并且wal丢失(磁盘损坏的情况),备库可能丢数据。archive_timeout参数设置WAL切换时间(到时间强制切换为新的WAL,防止空闲时不切换WAL导致无法同步少量WAL recode的情况),一般设置为1分钟左右,即备库有一分钟延迟。如果想更快的复制,使用streaming而不是log方式。

26.2.1 主备要求

主备的服务器、数据库配置应该尽可能相同。数据库使用的文件路径应该相同(当使用传输表空间时)。在给主库执行create tablespace之前,备库也必须有相应的路径及权限。硬件架构也必须相同,比如不支持32->64位,也不支持不同的操作系统。
主备pg库的版本必须相同,虽然小版本的差异也许是可以,但是PG官方不此提供支持。
当要升级主备版本时,先升级备库。

26.2.2 备库处理Wal

当pg的数据目录下有standby.signal文件时,则启动为备库。

备库读取wal日志或者streaming数据,此外备库还会读取备库pg_wal目录中的Wal(一般是拿到了wal还没执行完备库就重启了,重启之后继续执行)。

当备库启动时,调用restore_command命令读取归档日志目录(archive location)所有可用的wal日志,一旦到达可用的WAL的末尾并且restore_command失败,会读取pg_wal中的wal日志。如果上述步骤失败,并且未配置流复制或者流复制无法连接主库,则会重复 读取archive location中wal、读取pg_wal中wal、读取流复制的步骤,直到数据库停止或者触发failover。

当执行pg_ctl promote命令或找到触发文件(promote_trigger_file)时,退出备用模式,服务器切换到正常运行状态。在failover之前,任何在归档目录和pg_wal中的wal将被resotre,但不会去连接master(不尝试流复制)。

26.2.3 准备主库

为了在故障转移时备库切换为主库,为备库配置归档、身份认证等,即主备库配置一样。
要setup备库,把主为的备份文件导入到备库。并在备库的数据目录创建 standby.signal文件。

主库相关参数:
wal_level:

  • replica: 默认值,满足备库和归档要求的日志
  • logical: 在mnimal的基础上增加支持逻辑复制的日志
  • minimal:只保留crash和immediate shutdown所需要的数据
    fsync:
  • on: 事务提交时WAL被定入到磁盘上,不会丢失数据.为on时,执行fsync()函数(由参数wal_sync_method控制)
  • off: 没说,应该是即时提交,提交时不管WAL是否同步

synchronous_commit:
当提交事务时如何处理WAL,默认为ON

  • remote_apply:备库已经执行了WAL中的事务
  • on:主备库的WAL已经持久化(默认值)
  • remote_write:主库WAL已经持久化,备库的WAL已经写到系统缓冲中但并未写到磁盘上
  • local:WAL在主库已经持久化
  • off:WAL写到系统缓冲中,但未持久化

wal_sync_method:fsync为on时执行的函数:

  • open_datasync (write WAL files with open() option O_DSYNC)
  • fdatasync (call fdatasync() at each commit)
  • fsync (call fsync() at each commit)
  • fsync_writethrough (call fsync() at each commit, forcing write-through of any disk write cache)
  • open_sync (write WAL files with open() option O_SYNC)

26.2.4 配置备库

26.2.4.1 log模式复制

在主服务器上设置一个可以让备库访问的归档目录,即使主库关闭备库也可以读取该位置,也就是说该归档位置应该在一个双方都访问的目录里,或者就在备库主机上。(远程归档日志挺有意思)
配置restore_command命令从主库的归档日志目录读取wal。如果计划配置多个备库,把recovery_target_timeline配置为latest(默认值),以使备用服务器遵循故障转移到另一个备用服务器时发生的时间轴更改。
如果备库的WAL仅用于复制,则可以配置archive_cleanup_command命令尽快的删除用过的归档日志,该命令配合pg_archiivecleanup(删除归档)使用。如果WAL是做为恢复数据库使用(考虑切换为主库后的场景),则至少要保留能恢复数据库的归档日志。

26.2.4.2 streaming模式复制

配置primary_conninfo,包括主要主机名、端口、用户名、密码等。
如果要使用流复制,要在主库上设置身份验证以允许来自备库的连接请求。 在ph_hba.conf中加增加replication权限的条目。还要确保max_wal_sender设置足够大的值。如果使用复制槽(replication slots),max_replication_slots也要设置的足够大。
示例,postgresql.conf:

Primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass options= " -c wal_sender_timeout=5000 " '
restore_command =' cp /path/to/archive/%f %p'
archive_cleanup_command =' pg_archiveecleanup /path/to/archive %r'

可以有任意数量的备库,但要确保max_wal_sender设置的足够大便备库能同时连接。

26.2.5 流复制

26.2.5.1 流复制

流复制可以实时的从主库读取WAL记录,延迟很小。主服务器在生成WAL记录时将其以流的方式传输到备库,不需要等待WAL被填充。

默认情况下,流复制是异步的,在主服务器上提交事务和在备用服务器上看到更改之间会有一小段延迟。然而,此延迟比基于文件的日志传输要小得多,通常在一秒内。对于流复制不需要设置archive_timeout

存在备库在接收WAL记录之前WAL段可能会被回收,导致缺失了WAL记录而复制失败,此时要导出主库数据并重新初始化。为了防止WAL段被过早的回收,设置wal_keep_segments设置的足够大,或者为备库配置一个replication slot避免这种情况。

使用流复制,要先配置基于log复制,然后设置primary_conninfo 转化为流复制。当备用服务器启动并且primary_conninfo设置正确时,在重播存档中所有可用的WAL文件后,备用服务器将连接到主服务器。如果连接成功建立,您将看到备用服务器上有一个walreceiver进程,主服务器上有一个相应的walsender进程。

身份验证:
使用流复制时,要在主建立有权限的用户。只有superuser和有REPLICATION权限的账户才能读取WAL流。不要使用superuer,该用户有所有权限,应该建一个账号只授予REPLICATION权限。虽然REPLICATION权限也很大,但不能修改主库上的任何数据。
示例pg_hba.conf

#TYPE  DATABASE      USER    ADDRESS             METHOD
host   replication   foo     192.168.1.100/32    md5

26.2.5.2 流复制监控

流复制的一个重要运行状况指标是在主服务器中生成但尚未在备用服务器中应用的WAL记录的数量。可以通过比较主服务器上当前的WAL写位置与备用服务器接收到的最后一个WAL位置来计算这个延迟。可以分别使用主服务器上的pg_current_wal_lsn和备用服务器上的pg_last_wal_receive_lsn检索这些位置。

可以通过pg_stat_replication视图检索WAL发送方进程列表。pg_current_wal_lsn和视图的sent_lsn字段之间的较大差异可能表明主服务器处于高负载状态,而备用服务器上的sent_lsn和pg_last_wal_receive_lsn之间的差异可能表明网络延迟,或者备用服务器处于高负载状态。

在双机热备状态下,可以通过pg_stat_wal_receiver视图获取WAL接收方进程的状态。pg_last_wal_replay_lsn和视图的received_lsn之间的较大差异表明,接收WAL的速度比重播WAL的速度快。

26.2.6 复制槽

复制槽提供了一种自动的方法来确保主服务器在所有备用服务器接收到WAL段之前不会删除它们,并且即使在备用服务器断开连接时,主服务器也不会删除可能导致恢复冲突的行。

现有的复制槽可以在pg_replication_slots中查询。
创建复制槽:

postgres=# SELECT * FROM pg_create_physical_replication_slot('node_a_slot');
  slot_name  | lsn
-------------+-----
 node_a_slot |

postgres=# SELECT slot_name, slot_type, active FROM pg_replication_slots;
  slot_name  | slot_type | active 
-------------+-----------+--------
 node_a_slot | physical  | f
(1 row)

为备库配置复制槽:

primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass'
primary_slot_name = 'node_a_slot'

26.2.7 级联复制

级联复制特性允许备用服务器接受复制连接并将WAL记录流式传输到其他备用服务器,充当中继。这可以用来减少到主机的直接连接的数量,也可以减少站点间带宽开销。
级联备用服务器不仅发送从主服务器接收到的WAL记录,还发送从存档中恢复的WAL记录。因此,即使某些上游连接中的复制连接被终止,只要有新的WAL记录可用,流复制就会继续下游。
级联复制当前为异步复制。同步复制(参见26.2.8节)的设置目前对级联复制没有影响。无论采用何种级联方式,热备用反馈都会向上游传播。
要使用级联复制,需要设置级联standby,使其能够接受复制连接(即设置max_wal_sender和hot_standby,并配置基于主机的身份验证)。您还需要将下行备用服务器中的primary_conninfo设置为指向级联备用服务器。

26.2.8 同步复制

两步复制确保事务提交所做的更改已经传到至少一个备库上(主备库都写入到WAL中,仅写到系统的缓存中也算),synchronous_commit参数决定事务提交时的安全级别。同步复制事务最小影响时间是主-库之间的网络传输时间。

只读事务和事务回滚不需要等待备库的回应。子事务提交不需要备库回应,顶级事务提交才需要。

同步复制可以的备库可以是逻辑备库,或者任何消费WAL的程序。除了内轩的物理备库(相对于逻辑备库)、逻辑备库外,还包括pg_receive和pg_recvlogical等特殊程序,以及第三方的应用。

26.2.8.1 基本配置

配置完流复制后,配置同步复制只需要一个额外的配置步骤:synchronous_standby_names必须设置为非空值。Synchronous_commit也必须设置为on,但由于这是默认值,因此通常不需要更改。(参见19.5.1节和19.6.2节。)此配置将导致每次提交都等待确认备用服务器已将提交记录写入持久存储。Synchronous_commit可以在配置文件中为特定用户或数据库配置,也可以由应用程序动态配置,以便在每个事务的基础上控制持久性保证。

Synchronous_commit值:
remote_apply:备库已经执行了WAL中的事务
on:主备库的WAL已经持久化
remote_write:主库WAL已经持久化,备库的WAL已经写到系统缓冲中但并未写到磁盘上
local:WAL在主库已经持久化
off:WAL写到系统缓冲中,但未持久化

当未设置synchronous_standby_names时,remote_apply on remote_write local对主库来讲是一样的都是local

synchronous_standby_names的设置:

[FIRST] num_sync ( standby_name [, ...] )
ANY num_sync ( standby_name [, ...] )
standby_name [, ...]

大小写敏感。
standby_name是在Primary_conninfo中配置的,如:
Primary_conninfo = ‘host=dsj-csjq07 port=5432 user=replicat_user password=bfd@dev24 application_name=s08’

默认值:如果 cluster_name 配置参数的配置过了,那么 standby server 的 name 默认是 cluster_name 参数值,否则是 walreceiver。

[FIRST] num_sync ( standby_name [, …] ) FIRST 2 (s1,s2,s3)则从s1,s2,s3中选三个,越靠前的优先级越高。FIRST关键字是可选的,FIRST 2 (s1,s2,s3)与2 (s1,s2,s3)一样。
ANY num_sync ( standby_name [, …] ) ANY表示至少有其,ANY 3 (s1, s2, s3, s4),4个中至少有3个复制完成。ANY会尝试同步到所有的4个备库,只要至少3个同步完成就提交。

FIRST和ANY的区别是:

1.都会尝试同步所有在列表中的standy

2.first按列表中的优先级去一个个试试,直到满足要求。满足要求后剩下的standby是潜在的。

3.any,任意满足数量的都可以,没有优先级。

standby_name [, …]是9.6之前的做法,与FIRST一样,num_sync是1。s1,s2,s3等于FIRST 1 (s1,s2,s3)
*匹配任何的standby_name。
如果standby_name的名字叫FIRST ANY,则要加双引号。
如果standby_name重名,则没法判断优先级。
如果没有配置standby_name,则禁用同步。
即使配置了synchronous_standby_names,Synchronous_commit为local或者off时也不生效。

一个参数搞的么这复杂完全有毛病。
如果设置所有备库都同步,但任意一个备库无法同步时,主库事务就会无限等待,这显然会严重影响主库的使用。那么应该使用至少X个备库同步的策略即可,X一定要小于备库的数量。
当仅有一个备库时,不做同步复制,太危险了

26.2.8.2 多个同步备库

同步复制支持一个或多个同步备用服务器;事务将等待,直到所有被认为是同步的备用服务器确认接收到它们的数据。事务必须等待应答的同步备用服务器的数量在synchronous_standby_names中指定。此参数还指定备用名称列表和从列出的列表中选择同步备用的方法(FIRST和ANY)。

26.2.8.3 性能规划

PostgreSQL允许应用程序开发人员通过复制指定所需的持久性级别。这可以为整个系统指定,也可以为特定用户或连接,甚至单个事务指定。

例如,应用程序工作负载可能包括:10%的更改是重要的客户详细信息,而90%的更改是不太重要的数据,如果丢失,业务可以更容易地生存下来,例如用户之间的聊天消息。 通过在应用程序级别(在主服务器上)指定同步复制选项,我们可以为最重要的更改提供同步复制,而不会减慢总体工作负载的速度。应用程序级选项是一种重要而实用的工具,可以为高性能应用程序提供同步复制的好处。

虑网络带宽必须高于WAL数据的生成速率。

26.2.8.4 高可用规划

高可用性的最佳解决方案是确保按照要求保留尽可能多的同步备用服务器。这可以通过使用synchronous_standby_names命名多个潜在的同步备用服务器来实现。
在基于优先级的同步复制中,名称在列表中较早出现的备用服务器将被用作同步备用服务器。如果当前的一个备用服务器发生故障,那么在它们之后列出的备用服务器将接管同步备用服务器的角色。
如果需要在事务等待时重新创建备用服务器,请确保命令pg_start_backup()和pg_stop_backup()在synchronous_commit = off的会话中运行,否则这些请求将永远等待备用服务器的出现(只要local以上的级别都可能有这个问题)。

26.2.9 备库的归档

在备用服务器中使用连续的WAL归档时,有两种不同的场景:可以在主服务器和备用服务器之间共享WAL归档,或者备用服务器可以拥有自己的WAL归档。当备用服务器有自己的WAL归档时,将archive_mode设置为always,备用服务器将为它接收到的每个WAL段调用归档命令,无论是通过从归档恢复还是通过流式复制。共享归档也可以类似地处理,但是archive_command必须测试要归档的文件是否已经存在,以及现有文件是否具有相同的内容。这需要在archive_命令中更加小心,因为它必须小心地不覆盖具有不同内容的现有文件,但如果完全相同的文件被存档两次,则返回成功。如果两个服务器试图同时归档同一个文件,那么所有这些都必须在没有竞争条件的情况下完成。
如果archive_mode设置为on,则在恢复或备用模式下不启用归档器。如果备用服务器被提升,它将在提升后开始归档,但不会归档任何不是它自己生成的WAL或时间轴历史文件。要在存档中获得一系列完整的WAL文件,必须确保在所有WAL到达备用服务器之前对其进行存档。基于文件的日志传送本质上是这样的,因为备用服务器只能恢复在存档中找到的文件,但如果启用了流复制,则不能恢复。当服务器未处于恢复模式时,on和always模式没有区别。

26.3 故意故障转移

如果主服务器发生故障,备用服务器成为新的主服务器,然后旧的主服务器重新启动,那么必须有一种机制通知旧的主服务器它不再是主服务器。这有时被称为STONITH (Shoot The Other Node In The Head),这对于避免两个系统都认为自己是主节点的情况是必要的,这将导致混乱并最终导致数据丢失。
PostgreSQL不提供识别主数据库服务器故障并通知备用数据库服务器所需的系统软件。存在许多这样的工具,并且与成功的故障转移所需的操作系统设施(如IP地址迁移)很好地集成在一起。

将备库终止复制提升为主库。有两种方法,创建promote_trigger_file文件或者使用pg_ctl promote or pg_promote

26.4 hot standby

这部分主要讲备库做为查询库时的一些问题,需要用备库做查询的时候再仔细看。

当备用服务器上的hot_standby参数设置为true时,一旦恢复将系统恢复到一致状态,它将开始接受连接。所有这些连接都是严格只读的;甚至临时表也不能写入。

备用服务器上的数据需要一些时间才能从主服务器到达,因此在主服务器和备用服务器之间存在可测量的延迟。因此,在主服务器和备用服务器上几乎同时运行相同的查询可能会返回不同的结果。

你可能感兴趣的:(postgresql)