本页面介绍了如何使用 pglogical
复制进行切换和故障切换。
准备工作
在设置 pglogical
复制并提供可行的高可用性 (HA) 和灾难恢复 (DR) 解决方案,同时认识到逻辑复制未提供对所有数据库对象的 true
和全面复制后,您必须先测试此配置,然后才能开始使用它。
如需详细了解 pglogical
扩展程序,请参阅 pglogical
简介。
如需了解如何使用 pglogical
进行数据复制,请参阅在 Google Cloud AlloyDB 和 AlloyDB Omni 之间复制数据以及在 AlloyDB Omni 和其他数据库之间复制数据。
使用 pglogical 复制进行切换
切换是一个受控过程,用于在提供方数据库和订阅方数据库之间切换角色。执行切换时,两个数据库的角色(提供方和订阅方)会反转。提供方成为订阅方,订阅方成为提供方。
此切换功能对于操作系统升级、PostgreSQL 升级或故障切换测试非常重要。
如需在单向复制配置中实现此目的,您必须设置新的提供方/订阅方关系并移除旧的提供方/订阅方关系。
构建新的提供方/订阅方配置
停止应用向提供方系统写入数据,以防止进一步数据库更改,并检查复制延迟情况,以确保所有事务都在订阅方节点上重放:
SELECT application_name, state, sync_state, client_addr, client_hostname, pg_wal_lsn_diff(pg_current_wal_lsn(),sent_lsn) AS sent_lag, pg_wal_lsn_diff(sent_lsn,flush_lsn) AS receiving_lag, pg_wal_lsn_diff(flush_lsn,replay_lsn) AS replay_lag, pg_wal_lsn_diff(pg_current_wal_lsn(),replay_lsn) AS total_lag, now()-reply_time AS reply_delay FROM pg_stat_replication ORDER BY client_hostname;
当所有延迟字段均显示零时,表示复制是最新的,并且数据库已准备好进行切换。
输出类似于以下内容:
-[ RECORD 1 ]----+------------------------------ application_name | test_sub_1 state | streaming sync_state | async client_addr | 10.45.0.80 client_hostname | sent_lag | 0 receiving_lag | 0 replay_lag | 0 total_lag | 0 reply_delay | 00:00:26.203433
将订阅方数据库转换为提供方数据库:
- 停止现有订阅方订阅。
- 添加复制集(如有必要)。
- 将必要的表添加到复制集中。
- 在新的订阅方数据库中构建新的订阅方订阅。
- 将应用重定向到新提供方。
停止现有订阅方数据库的订阅,该数据库会成为新提供方:
SELECT pglogical.alter_subscription_disable(SUBSCRIPTION_NAME);
(可选)创建与原始提供方数据库定义匹配的复制集。如果您使用的是默认复制集,则无需执行此操作:
SELECT pglogical.create_replication_set(REPLICATION_SET_NAME);
将表添加到该复制集:
SELECT pglogical.replication_set_add_table(REPLICATION_SET_NAME, TABLE_NAME);
替换以下内容:
- REPLICATION_SET_NAME:复制集的名称。
- TABLE_NAME:架构所有者的表名称。例如,
ARRAY['public']
。
在之前是提供方数据库的新订阅方数据库中,创建新的订阅,并将
synchronize_data
选项设置为false
,以防止初始表加载:SELECT pglogical.create_subscription ( subscription_name := '<subscription name>', replication_sets := array['default'], synchronize_data := false, provider_dsn := 'host=<hostname or IP> port=5432 dbname=<db name> user=pglogical_replication password=<password>');
检查订阅是否在提供方节点上正常运行:
SELECT application_name, state, sync_state, client_addr, client_hostname, pg_wal_lsn_diff(pg_current_wal_lsn(),sent_lsn) AS sent_lag, pg_wal_lsn_diff(sent_lsn,flush_lsn) AS receiving_lag, pg_wal_lsn_diff(flush_lsn,replay_lsn) AS replay_lag, pg_wal_lsn_diff(pg_current_wal_lsn(),replay_lsn) AS total_lag, now()-reply_time AS reply_delay FROM pg_stat_replication ORDER BY client_hostname;
如果复制正常运行,请更改应用连接字符串以使用新提供方数据库并重启应用层。
如果您在订阅方停止后更改旧提供方节点上的数据,则这些更改不会复制,从而导致数据丢失。如果原始提供方数据库中存在未复制的数据更改,或者原始提供方数据库(即新订阅方)的状态与新提供方数据库(即旧订阅方)的状态不一致,则您必须完全构建新订阅方数据库。
移除旧提供方和订阅
如果您需要单向复制,则必须移除旧提供方/订阅方配置。
移除新提供方上的旧订阅
SELECT pglogical.drop_subscription('<subscription name>')
移除新订阅方上的复制集,或从复制集中移除所有表:
SELECT pglogical.drop_replication_set('<replication set name>')
SELECT pglogical.replication_set_remove_table('<replication set name>','<table name>')
双向复制
如需在不造成停机的情况下进行切换,或者确保不会因计划外的数据更改而导致数据丢失,您必须使用双向复制。在实现双向复制时,请考虑冲突解决方案,除非您已实施严格的控制措施来防止同时对两个节点进行写入访问。
您可以使用以下 pglogical.conflict_resolution
设置来设置冲突解决配置:
error
:当检测到冲突时,订阅方会停止。apply_remote
:无论订阅方数据库中的数据如何,都始终应用传入的更改。这是默认设置。keep_local
:始终忽略有冲突的传入数据并舍弃有冲突的更改。last_update_wins
:具有最新提交时间戳的数据版本是已提交的数据first_update_wins
:具有最早时间戳的数据版本是已提交的数据
如需设置双向复制,请设置提供方和订阅方,以便复制在双向进行。原始订阅方还会成为提供方,并使用与原始提供方相同的复制集。如需创建复制集,以复制初始提供方数据库中的原始复制集,请参阅创建表并将其添加到 Google Cloud AlloyDB 提供方数据库中的默认复制集。
您必须在原始提供方中添加新的订阅方。如需创建新的订阅方,确保命令 pglogical.create_subscription
的 synchronize_data
参数设置为 false
,请参阅在 AlloyDB Omni 订阅方数据库中创建节点和订阅。这样可以避免初始表中的数据复制。
使用 pglogical 复制进行故障切换
如果提供方数据库因任何原因变得不可用,则会发生故障切换,您必须将应用切换为使用订阅方数据库。
为防止任何重复数据意外应用于已进行故障切换的订阅方数据库,您必须停用订阅。这可确保在已恢复的提供方再次可用时,系统不会错误地应用该提供方的更改。
停止订阅方
test_sub_1
:SELECT pglogical.alter_subscription_disable(`test_sub_1`);
检查状态是否设置为
disabled
:SELECT pglogical.show_subscription_status('test_sub_1');
输出类似于以下内容:
show_subscription_status ---------------------------------------------------------------------------- (test_sub1,disabled,subscriber,"host=10.45.0.108 port=5432 dbname=my_test_db user=pglogical_replication",subscriber,{failover_set},{all})
检查状态输出中停用的关键字。
构建新的提供方/订阅方配置,以保持高可用性和灾难恢复能力。
创建新的复制集,其中包含最初复制的所有表,以便在旧提供方数据库恢复并转换为新订阅方时构建新订阅方。
如果您可以将旧提供方数据库恢复到发生故障的时间,请将此数据库设置为新订阅方。使用相同的步骤创建订阅,并将
pglogical.create_subscription
命令的synchronize_data
参数设置为false
,以避免初始表副本。移除已恢复节点上的旧提供方配置,以避免 WAL 文件堆积。
如果您使用的是旧提供方数据库,请删除完整的复制集,或从复制集中逐个移除所有表:
SELECT pglogical.drop_replication_set('<replication set name>')
SELECT pglogical.replication_set_remove_table('<replication set name>','<table name>')
切换应用以向新节点写入数据。