使用 SymmetricDS 的双活 PostgreSQL 配置

问题描述

我在使用 SymmetricDS(开源版本)在 2 个 Postgres 服务器之间复制数据时遇到问题。以下是了解我的问题的相关信息:

我已经使用 Vagrant 部署了 3 个服务器:

  • symmetricds.local [192.168.44.9]
  • postgres01.local [192.168.44.10]
  • postgres02.local [192.168.44.11]

symmetricds.local 服务器中,我将 SymmetricDS 作为服务安装。 在 postgres##.local 服务器上,我安装了 postgres 11 并加载了 Sakila data(示例数据)。

然后我在 symmetricds.local 服务器中创建以下配置文件

cat <<EOF >>/opt/symmetric-server-3.12.10/engines/postgres01.properties
engine.name=postgres01
db.driver=org.postgresql.Driver
db.url=jdbc:postgresql://192.168.44.10:5432/postgres?stringtype=unspecified
db.user=postgres
db.password=postgres
registration.url=
sync.url=http://192.168.44.9:31415/sync/postgres01
group.id=primary
external.id=postgres01
auto.registration=true
initial.load.create.first=true
EOF

cat <<EOF >>/opt/symmetric-server-3.12.10/engines/postgres02.properties
engine.name=postgres02
db.driver=org.postgresql.Driver
db.url=jdbc:postgresql://192.168.44.11:5432/postgres?stringtype=unspecified
db.user=postgres
db.password=postgres
registration.url=http://192.168.44.9:31415/sync/postgres01
sync.url=http://192.168.44.9:31415/sync/postgres02
group.id=primary
external.id=postgres02
EOF

之后我启动 SymmetricDS 服务:

sudo /opt/symmetric-server-3.12.10/bin/sym_service start

此时所有 sym_ 表都在两个 Postgres 服务器中创建。

我在 postgres01.local 服务器中添加了一些数据,以便在两个 Postgres 服务器之间复制工作:

INSERT INTO sym_node_group_link (source_node_group_id,target_node_group_id,data_event_action)
VALUES ('primary','primary','P');

INSERT INTO sym_trigger (trigger_id,source_schema_name,source_table_name,channel_id,sync_on_update,sync_on_insert,sync_on_delete,sync_on_update_condition,sync_on_insert_condition,sync_on_delete_condition,last_update_time,create_time)
VALUES ('public.all','public','*','default',1,'1=1',CURRENT_TIMESTAMP,CURRENT_TIMESTAMP);

INSERT INTO sym_router (router_id,source_node_group_id,router_type,router_expression,use_source_catalog_schema,create_time,last_update_by,last_update_time)
VALUES ('primary_2_primary',NULL,'console',CURRENT_TIMESTAMP);

INSERT INTO sym_trigger_router (trigger_id,router_id,enabled,initial_load_order,last_update_time)
VALUES ('public.all','primary_2_primary',10,CURRENT_TIMESTAMP);

最后,我在 symmetricds.local 服务器中运行它以允许注册

sudo /opt/symmetric-server-3.12.10/bin/symadmin -e postgres01 open-registration primary postgres02

几分钟后,将创建触发器并在 sym_ 表之间共享数据。但不会复制用户数据(Sakila 表)。

我尝试强制重新加载表:

INSERT INTO sym_table_reload_request (source_node_id,target_node_id,trigger_id,last_update_time) VALUES ('postgres01','postgres02','ALL',CURRENT_TIMESTAMP);

但后来我在 SymmetricDS 日志中收到此错误

2021-07-01 15:03:19,097 ERROR [postgres01] [InitialLoadService] [postgres01-job-11] Error while queuing initial loads StackTraceKey.init [SymmetricException:46596748] org.jumpmind.symmetric.SymmetricException: Unable to issue an update for sym_node_security.  Check the sym_trigger_hist for sym_node_security.
    at org.jumpmind.symmetric.service.impl.DataService.insertNodeSecurityUpdate(DataService.java:2230)
    at org.jumpmind.symmetric.service.impl.DataService.insertsqlEventsPriorToReload(DataService.java:1227)
    at org.jumpmind.symmetric.service.impl.DataService.insertReloadEvents(DataService.java:1006)
    at org.jumpmind.symmetric.service.impl.InitialLoadService.processtableRequestLoads(InitialLoadService.java:282)
    at org.jumpmind.symmetric.service.impl.InitialLoadService.queueLoads(InitialLoadService.java:98)
    at org.jumpmind.symmetric.job.InitialLoadJob.doJob(InitialLoadJob.java:43)
    at org.jumpmind.symmetric.job.AbstractJob.invoke(AbstractJob.java:227)
    at org.jumpmind.symmetric.job.AbstractJob.run(AbstractJob.java:298)
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
    at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305)
    at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:829)

2021-07-01 15:03:29,118 INFO [postgres01] [InitialLoadService] [postgres01-job-14] Found 1 table reload requests to process.
2021-07-01 15:03:29,131 INFO [postgres01] [InitialLoadService] [postgres01-job-14] Cancelling load 2 for node postgres02
2021-07-01 15:03:29,134 INFO [postgres01] [InitialLoadService] [postgres01-job-14] Marked 1 load requests as OK for node postgres02
2021-07-01 15:03:29,136 INFO [postgres01] [InitialLoadService] [postgres01-job-14] Marked 0 extract requests as OK for node postgres02
2021-07-01 15:03:29,137 INFO [postgres01] [InitialLoadService] [postgres01-job-14] Marked 0 batches as OK for node postgres02
2021-07-01 15:03:29,147 INFO [postgres01] [DataService] [postgres01-job-14] queueing up an initial load to node postgres02
2021-07-01 15:03:29,175 ERROR [postgres01] [InitialLoadService] [postgres01-job-14] Error while queuing initial loads StackTraceKey [SymmetricException:46596748]

仍然没有复制任何内容sym_trigger_hist 上的 postgres01 表为空,但 postgres02 上的所有表都已满。

云你能帮我理解我的配置问题吗?

解决方法

您应该在 postgres01 上运行 symadmin sync-triggers 命令来构建触发器。检查日志以查看是否有任何错误。如果触发器成功创建,则 sym_trigger_hist 表应填充到 postgres01 中。

要执行以构建触发器的命令是:

symadmin sync-triggers -e postgres01
,

“同步触发器”过程应在注册后立即自动运行,并且它会在 sym_trigger_hist 中为每个复制的 SYM 表放置一个条目。初始加载等操作需要这些条目。如果 sym_trigger_hist 为空,则说明运行“同步触发器”时出现问题。成功后,日志将如下所示:

2021-07-07 13:21:42,799 INFO [postgres01] [RegistrationService] [qtp2060037930-34] Completed registration of node primary:postgres02
2021-07-07 13:21:46,598 INFO [postgres02] [TriggerRouterService] [postgres02-job-2] Synchronizing triggers
2021-07-07 13:21:48,668 INFO [postgres02] [PostgreSqlSymmetricDialect] [postgres02-sync-triggers-1] Creating SYM_ON_I_FOR_SYM_ND_SCRTY_CLNT trigger for SYM_NODE_SECURITY
2021-07-07 13:21:48,679 INFO [postgres02] [PostgreSqlSymmetricDialect] [postgres02-sync-triggers-1] Creating SYM_ON_U_FOR_SYM_ND_SCRTY_CLNT trigger for SYM_NODE_SECURITY
2021-07-07 13:21:48,690 INFO [postgres02] [PostgreSqlSymmetricDialect] [postgres02-sync-triggers-1] Creating SYM_ON_D_FOR_SYM_ND_SCRTY_CLNT trigger for SYM_NODE_SECURITY
...
2021-07-07 13:21:48,701 INFO [postgres02] [TriggerRouterService] [postgres02-job-2] Done synchronizing triggers
2021-07-07 13:21:49,439 INFO [postgres02] [RegistrationService] [postgres02-job-2] Successfully registered node [id=postgres02]

您应该能够返回日志并查看注册期间遇到的错误。您可以通过重新启动 SymmetricDS 来修复它,这会导致它再次运行“同步触发器”。