你需要经常使用逻辑复制吗?你担心其给主用数据库带来的压力吗?
复制的背景 总体而言,PostgreSQL 支持两种主要的复制类型:流式/物理复制和逻辑复制。预写式日志可以通过连接流式传输整组的物理文件,并将整个数据库在磁盘上进行重放。逻辑复制提供了一种更细粒度的方法,您可以指定要复制到远程服务器的单个数据库对象(例如表,甚至特定行)。
PostgreSQL 中的备用服务器是通过对主服务器进行基础备份,并持续应用在主服务器上所做的所有更改来创建的。热备服务器是指可以提升为主服务器的备用服务器。PostgreSQL 将修改保存在 WAL(预写日志)记录中,并将它们从主服务器复制到备用服务器。如果备用服务器需要表中的行,则配置参数 hot_standby_feeedback
可防止表行过早地从主服务器中删除。
从备用数据库进行复制的示例设置 假设我们有三台不同的 PostgreSQL 服务器,用于管理一家全球物流公司的库存,其仓库遍布全球。主服务器存储仓库和库存信息,备用服务器是一台物理复制的高可用服务器,第三台服务器用于获取特定的更改以用于分析报告。
主机 在主实例中,您需要具有复制权限的用户。在本例中,我创建了一个用户,用于将更改流式传输到备用实例,并创建了另一个用户,用于将更改发布到订阅实例。
CREATE ROLE repuser WITH REPLICATION LOGIN ENCRYPTED PASSWORD 'somestrongpassword' ; CREATE ROLE pubuser WITH REPLICATION LOGIN ENCRYPTED PASSWORD 'differentstrongpassword' ;
接下来,创建一个物理复制槽,用于将更改从主服务器复制到备用服务器。严格来说,这不是必需的,但实际上确实需要。如果没有物理复制槽,任何一个节点重启或连接断开都会中断复制过程:
SELECT pg_create_physical_replication_slot( 'hot_standby_1' );
假定我们只关心上海仓库的库存,其代码为 SH
。在主服务器上,我们将为 inventory
表所依赖的表创建一个发布 inventory_requirements
,并创建另一个名为 inventory_sh_pub
的发布:
表:warehouses (仓库)
表:inventory (库存)
CREATE PUBLICATION inventory_requirements_pub FOR TABLE regions, countries, warehouses, products; CREATE PUBLICATION inventory_sh_pub FOR TABLE inventory WHERE (warehouse = 'SH' ); GRANT SELECT ON TABLE regions, countries, warehouses, products, inventory TO pubuser;
备机 此时,可以创建备用实例了。我们将使用 pg_basebackup
来初始化备用实例。恢复备机的数据目录后,您需要编辑其中的 postgresql.conf
,并确保其具有一些参数( 如此处所述 ):
# Provide feedback to the primary or upstream standby about # queries currently executing on this standby hot_standby_feedback = on # Use the physical replication slot we created previously primary_slot_name = 'hot_standby_1' hot_standby = on archive_mode = on # If level is changed to below logical, slots will be dropped wal_level = logical # standby streams changes from the primary primary_conn_info = 'host=127.0.0.1 port=5432 user=repuser password=somestrongpassword' max_wal_senders = 10 # max number of walsender processes max_replication_slots = 10 # max number of replication slots # If an upstream standby server is promoted to become the new # primary, downstream servers will continue to stream from # the new primary recovery_target_timeline = 'latest'
连接到该备用服务器,可以确认它处于只读模式:
SELECT pg_is_in_recovery(); pg_is_in_recovery ------------------- t
此时我们有:
• 主实例通过物理复制槽同步到一个备用实例,并设置了 hot_standby_feedback = on
• 名为 inventory_requirements_pub
和 inventory_sh_pub
的发布 备机上的逻辑副本 现在我们可以登录用于分析报告的 PostgreSQL 实例,订阅备用数据库的更改。在 PostgreSQL 16 以前的版本中,该操作会失败。
逻辑复制的一大优势是,您可以订阅不同版本的 PostgreSQL 服务器的变更!这为您在使用不同版本 PostgreSQL 的应用程序时提供了极大的灵活性。
CREATE SUBSCRIPTION inventory_requirements_sub CONNECTION 'dbname=inventory host=127.0.0.1 port=5434 user=pubuser password=differentstrongpassword' PUBLICATION inventory_requirements_pub; CREATE SUBSCRIPTION inventory_sh_sub CONNECTION 'dbname=inventory host=127.0.0.1 port=5434 user=pubuser password=differentstrongpassword' PUBLICATION inventory_sh_pub;
如果主服务器空闲,该操作会挂起。这是因为备用服务器正在等待来自主服务器的信息。您可以通过在主服务器上调用新函数 pg_log_standby_snapshot()
,来加快创建这些对象的速度。在本例中,我们会调用两次,因为我们要创建两个订阅。
SELECT pg_log_standby_snapshot(); pg_log_standby_snapshot ------------------------- 0 / 23000180
这样允许副本继续运行,并生成类似这样的消息,告诉我们已在备用服务器上创建了一个复制槽。
NOTICE : created replication slot "inventory_requirements_sub" on publisher CREATE SUBSCRIPTION
我们可以在备用服务器上的 pg_stat_replication
系统视图中验证这一点。
SELECT pid, application_name, state, sync_state FROM pg_stat_replication; pid | application_name | state | sync_state -------+----------------------------+-----------+------------ 23265 | inventory_sh_sub | streaming | async 23251 | inventory_requirements_sub | streaming | async ( 2 rows )
一旦更改同步到了备用服务器,它们就会被同步到下游的报告服务器,我们将在那里看到这些更改。请注意,只有 SH
仓库的记录会被同步过来。
SELECT * FROM inventory ORDER BY product_id; warehouse | product_id | quantity -----------+------------+---------- SH | 11 | 7 SH | 13 | 13 SH | 15 | 18 SH | 22 | 15 SH | 24 | 20
如果需要,我们还可以在这里为不同的区域和仓库创建多个逻辑副本。
阅读原文:原文链接
该文章在 2025/7/1 22:50:17 编辑过