Timescale Cloud:性能、扩展、企业级
自托管产品
MST
本节概述了如何在单个或多个数据库副本上设置异步流复制。
在 Timescale 上免费试用
Timescale 是一项完全托管服务,提供自动备份和恢复、带复制功能的高可用性、无缝扩展和调整大小等功能。您可以免费试用 Timescale 三十天。
在开始之前,请确保您至少有两个独立的 TimescaleDB 实例正在运行。如果您使用 Docker 容器安装 TimescaleDB,请使用 PostgreSQL 入口点脚本 来运行配置。有关更高级的示例,请参阅 Timescale Helm Charts 仓库
。
要在自托管 TimescaleDB 上配置复制,您需要执行以下步骤
要配置主数据库,您需要一个具有允许初始化流复制角色的 PostgreSQL 用户。这是每个副本用于从主数据库进行流式传输的用户。
在主数据库上,以具有超级用户权限(例如
postgres
用户)的用户身份,将密码加密级别设置为scram-sha-256
SET password_encryption = 'scram-sha-256';创建一个名为
repuser
的新用户CREATE ROLE repuser WITH REPLICATION PASSWORD '<PASSWORD>' LOGIN;
重要提示
scram-sha-256
加密级别是 PostgreSQL 中最安全的基于密码的身份验证方式。它仅在 PostgreSQL 10 及更高版本中可用。
postgresql.conf
配置文件中有几个复制设置需要添加或编辑。
- 将
synchronous_commit
参数设置为off
。 - 将
max_wal_senders
参数设置为来自副本或备份客户端的并发连接总数。最小应等于您打算拥有的副本数量。 - 将
wal_level
参数设置为写入 PostgreSQL 预写日志 (WAL) 的信息量。为了使复制正常工作,WAL 中需要有足够的数据来支持归档和复制。默认值通常是合适的。 - 将
max_replication_slots
参数设置为主数据库可以支持的复制槽总数。 - 将
listen_addresses
参数设置为主数据库的地址。不要将此参数保留为本地回环地址,因为远程副本必须能够连接到主数据库以流式传输 WAL。 - 重启 PostgreSQL 以应用更改。这必须在创建复制槽之前完成。
最常见的流复制用例是具有一个或多个副本的异步复制。在此示例中,WAL 会流式传输到副本,但主服务器不会等待 WAL 已写入主服务器或副本磁盘的确认。这是性能最高的复制配置,但它确实存在系统故障时少量数据丢失的风险。它也不能保证副本与主服务器完全同步,这可能会导致主服务器和副本上的读取查询之间出现不一致。此用例的示例配置:
listen_addresses = '*'wal_level = replicamax_wal_senders = 2max_replication_slots = 2synchronous_commit = off
如果您需要在副本上获得更强的一致性,或者如果您的查询负载足够重,以至于在异步模式下导致主节点和副本节点之间出现显著延迟,请考虑同步复制配置。有关不同复制模式的更多信息,请参阅复制模式部分。
配置 postgresql.conf
并重启 PostgreSQL 后,您可以为每个副本创建一个复制槽。复制槽可确保主服务器在副本接收到 WAL 段之前不会删除它们。这在副本长时间停机的情况下非常重要。主服务器需要验证 WAL 段是否已被副本使用,以便安全地删除数据。您可以为此目的使用归档
,但复制槽为流复制提供了最强的保护。
在
psql
槽位,创建第一个复制槽。槽的名称是任意的。在此示例中,它被称为replica_1_slot
SELECT * FROM pg_create_physical_replication_slot('replica_1_slot', true);对每个所需的复制槽重复此操作。
有几个复制设置需要添加到 pg_hba.conf
配置文件中或进行编辑。在此示例中,这些设置将复制连接限制为来自 REPLICATION_HOST_IP
的流量,使用 PostgreSQL 用户 repuser
和有效密码。REPLICATION_HOST_IP
可以从该机器启动流复制,无需额外凭据。您可以更改 address
和 method
值以匹配您的安全和网络设置。
有关 pg_hba.conf
的更多信息,请参阅 pg_hba
文档。
打开
pg_hba.conf
配置文件并添加或编辑此行TYPE DATABASE USER ADDRESS METHOD AUTH_METHODhost replication repuser <REPLICATION_HOST_IP>/32 scram-sha-256重启 PostgreSQL 以应用更改。
副本通过流式传输主服务器的 WAL 日志并在 PostgreSQL 恢复模式下重放其事务来工作。为此,副本需要处于可以重放日志的状态。您可以通过从主实例的基础备份中恢复副本来实现这一点。
停止 PostgreSQL 服务。
如果副本数据库已包含数据,请在运行备份之前删除它,方法是移除 PostgreSQL 数据目录
rm -rf <DATA_DIRECTORY>/*如果您不知道数据目录的位置,请使用
show data_directory;
命令查找。使用主数据库的 IP 地址和复制用户名从基础备份中恢复。
pg_basebackup -h <PRIMARY_IP> \-D <DATA_DIRECTORY> \-U repuser -vP -W-W
标志会提示您输入密码。如果您在自动化设置中使用此命令,您可能需要使用pgpass
文件。
备份完成后,在数据目录中创建一个
standby.signal
文件。当 PostgreSQL 在其数据目录中找到
standby.signal
文件时,它将以恢复模式启动并通过复制协议流式传输 WAL。touch <DATA_DIRECTORY>/standby.signal
成功创建基础备份和 standby.signal
文件后,您可以配置复制和恢复设置。
在副本的
postgresql.conf
文件中,添加与主服务器通信的详细信息。如果您使用的是流复制,primary_conninfo
中的application_name
应与主服务器synchronous_standby_names
设置中使用的名称相同primary_conninfo = 'host=<PRIMARY_IP> port=5432 user=repuserpassword=<POSTGRES_USER_PASSWORD> application_name=r1'primary_slot_name = 'replica_1_slot'添加详细信息以镜像主数据库的配置。如果您使用异步复制,请使用这些设置
hot_standby = onwal_level = replicamax_wal_senders = 2max_replication_slots = 2synchronous_commit = offhot_standby
参数必须设置为on
以允许在副本上进行只读查询。在 PostgreSQL 10 及更高版本中,此设置默认为on
。重启 PostgreSQL 以应用更改。
至此,您的副本应已与主数据库完全同步,并准备好从中进行流式传输。您可以通过检查副本上的日志来验证其是否正常工作,日志应如下所示:
LOG: database system was shut down in recovery at 2018-03-09 18:36:23 UTCLOG: entering standby modeLOG: redo starts at 0/2000028LOG: consistent recovery state reached at 0/3000000LOG: database system is ready to accept read only connectionsLOG: started streaming WAL from primary at 0/3000000 on timeline 1
任何客户端都可以在副本上执行读取操作。您可以通过在主数据库上运行插入、更新或其他数据修改,然后查询副本以确保它们已正确复制过来进行验证。
在大多数情况下,异步流复制已足够。但是,您可能需要主数据库和副本之间更高的一致性,尤其是在工作负载较重的情况下。在重负载下,副本可能会远远落后于主数据库,为从副本读取的客户端提供过时数据。此外,在任何数据丢失都是致命的情况下,异步复制可能无法提供足够的持久性保证。PostgreSQL 的 synchronous_commit
功能有多种选项,具有不同的一致性和性能权衡。
在 postgresql.conf
文件中,将 synchronous_commit
参数设置为
on
:这是默认值。服务器只有在 WAL 事务已写入主服务器和任何副本的磁盘后才返回success
。off
:当 WAL 事务已发送到操作系统以写入主服务器磁盘上的 WAL 时,服务器返回success
,但不会等待操作系统实际写入。如果服务器在某些数据未写入时崩溃,这可能会导致少量数据丢失,但不会导致数据损坏。关闭synchronous_commit
是 PostgreSQL 中一种广为人知的优化方法,适用于可以承受系统崩溃时少量数据丢失的工作负载。local
:仅在主服务器上强制执行on
行为。remote_write
:当 WAL 记录已发送到操作系统以写入副本上的 WAL,但在确认记录已实际持久化到磁盘之前,数据库会向客户端返回success
。这类似于异步提交,不同之处在于它也等待副本以及主服务器。实际上,等待副本产生的额外等待时间会显著减少复制延迟。remote_apply
:要求确认 WAL 记录已写入 WAL 并应用于所有副本上的数据库。这提供了synchronous_commit
选项中最强的一致性。在此模式下,副本始终反映主服务器的最新状态,并且复制延迟几乎不存在。
重要提示
如果 synchronous_standby_names
为空,则 on
、remote_apply
、remote_write
和 local
设置都提供相同的同步级别,并且事务提交会等待本地刷新到磁盘。
此矩阵显示了每种模式提供的一致性级别。
模式 | WAL 发送到操作系统(主) | WAL 持久化(主) | WAL 发送到操作系统(主和副本) | WAL 持久化(主和副本) | 事务已应用(主和副本) |
---|---|---|---|---|---|
关 | ✅ | ❌ | ❌ | ❌ | ❌ |
本地 | ✅ | ✅ | ❌ | ❌ | ❌ |
远程写入 | ✅ | ✅ | ✅ | ❌ | ❌ |
开 | ✅ | ✅ | ✅ | ✅ | ❌ |
远程应用 | ✅ | ✅ | ✅ | ✅ | ✅ |
synchronous_standby_names
设置是 synchronous_commit
的补充设置。它列出了主数据库支持同步复制的所有副本的名称,并配置了主数据库如何等待它们。synchronous_standby_names
设置支持以下格式:
FIRST num_sync (replica_name_1, replica_name_2)
:这会等待前num_sync
个副本的确认,然后才返回success
。replica_names
列表决定了副本的相对优先级。副本名称由副本上的application_name
设置决定。ANY num_sync (replica_name_1, replica_name_2)
:这会等待所提供列表中num_sync
个副本的确认,无论其优先级或在列表中的位置如何。这用作仲裁功能。
同步复制模式强制主服务器等待所有必需的副本写入 WAL 或应用数据库事务(取决于 synchronous_commit
级别)。如果所需的副本崩溃,这可能会导致主服务器无限期挂起。当副本重新连接时,它会重放任何需要追赶的 WAL。只有到那时,主服务器才能恢复写入。为了缓解这种情况,请在 synchronous_standby_names
设置下配置比所需节点数量更多的节点,并将它们列在 FIRST
或 ANY
子句中。这允许主服务器只要有足够数量的副本写入了最新的 WAL 事务即可继续进行。停止服务的副本能够异步重新连接并重放错过的 WAL 事务。
PostgreSQL pg_stat_replication
视图提供了关于每个副本的信息。此视图对于计算复制延迟特别有用,复制延迟衡量了副本当前状态与主数据库之间的差距。
replay_lag
字段衡量了主数据库上最新 WAL 事务与副本上最后报告的数据库提交之间的秒数。结合 write_lag
和 flush_lag
,这提供了关于副本落后程度的洞察。*_lsn
字段也提供了有用的信息,允许您比较主数据库和副本之间的 WAL 位置。state
字段有助于精确确定每个副本当前正在做什么;可用模式包括 startup
、catchup
、streaming
、backup
和 stopping
。
要查看数据,请在主数据库上运行此命令
SELECT * FROM pg_stat_replication;
输出如下所示
-[ RECORD 1 ]----+------------------------------pid | 52343usesysid | 16384usename | repuserapplication_name | r2client_addr | 10.0.13.6client_hostname |client_port | 59610backend_start | 2018-02-07 19:07:15.261213+00backend_xmin |state | streamingsent_lsn | 16B/43DB36A8write_lsn | 16B/43DB36A8flush_lsn | 16B/43DB36A8replay_lsn | 16B/43107C28write_lag | 00:00:00.009966flush_lag | 00:00:00.03208replay_lag | 00:00:00.43537sync_priority | 2sync_state | sync-[ RECORD 2 ]----+------------------------------pid | 54498usesysid | 16384usename | repuserapplication_name | r1client_addr | 10.0.13.5client_hostname |client_port | 43402backend_start | 2018-02-07 19:45:41.410929+00backend_xmin |state | streamingsent_lsn | 16B/43DB36A8write_lsn | 16B/43DB36A8flush_lsn | 16B/43DB36A8replay_lsn | 16B/42C3B9C8write_lag | 00:00:00.019736flush_lag | 00:00:00.044073replay_lag | 00:00:00.644004sync_priority | 1sync_state | sync
PostgreSQL 提供了一些故障转移功能,即在发生故障时将副本提升为主数据库。这可以通过使用 pg_ctl
命令或
trigger_file
来实现。然而,PostgreSQL 不支持自动故障转移。有关更多信息,请参阅 PostgreSQL 故障转移文档。如果您需要具有自动故障转移功能的可配置高可用性解决方案,请查看 Patroni
。
关键词