在集群间复制数据库企业版Aura 不可用2026.03 引入
预览功能
|
跨集群数据库复制功能按“原样”(AS-IS)提供,具体如您与 Neo4j 的协议中所述,且仅应将其用于内部开发目的。 当此功能正式发布(Generally Available)后,您将需要升级到最新的 Neo4j 版本(可能需要停机)才能将该功能用于非开发用途。 在预览期内,拥有有效合同的客户可通过标准支持渠道联系 Neo4j 支持部门。请注意,根据支持条款,任何与此预览功能相关的案例默认将被归类为严重性 4 (Severity 4)。 |
概述
2026.03 版本引入了跨集群数据库复制 (CCDR)。它提供了将一个集群中的数据库复制到另一个集群的功能。原始数据库称为上游 (upstream) 或源 (source),而复制数据的数据库称为副本 (replica)。副本会持续轮询上游数据库以获取新事务,并在新事务可用时立即应用它们(参见图 1)。
创建副本数据库的先决条件
假设您有两个独立运行的集群:集群 A 和 集群 B。
确保集群运行相同的 Neo4j 版本,且版本必须为 2026.03 或更高。
Cypher 的两个版本(Cypher 5 和 Cypher 25)均支持创建和提升副本数据库的过程。
|
在预览版本中,仅上游数据库和副本数据库支持 |
配置集群间加密
首先,确保每个集群都已使用集群内加密。为了确保集群 A 和 集群 B 能够相互认证,每个集群都必须信任签署对方集群证书的证书颁发机构 (CA)。
如果集群使用不同的 CA,则必须将集群 A 的 CA 证书安装到集群 B 的 trusted/ 目录中,反之亦然。
例如,以下是一种可能的证书文件夹配置
ClusterA
cluster/
├── private.key ← clusterA node private key
├── public.crt ← clusterA node certificate
├── trusted/
│ └── clusterB-ca.crt ← CA that signs ClusterB node certs
└── revoked/
ClusterB
cluster/
├── private.key ← ClusterB node private key
├── public.crt ← ClusterB node certificate
├── trusted/
│ └── clusterA-ca.crt ← CA that signs ClusterA node certs
└── revoked/
创建副本数据库
使用以下步骤创建副本数据库。
语法 |
|
||
描述 |
创建一个具有主节点和从节点拓扑的副本数据库。 |
||
输入参数 |
名称 |
类型 |
描述 |
|
|
当前集群中副本的名称。注意,databaseName 可以与 upstreamDatabaseName 相同。 |
|
|
|
副本主节点的数量。这些主节点将符合服务器上设置的模式限制,但因为它们仍是副本,所以不可写入。 |
|
|
|
副本从节点的数量。 |
|
|
|
远程集群中上游数据库的名称。 |
|
|
|
远程集群中服务器的集群端点列表。 |
|
模式 |
写入 (WRITE) |
||
在集群 A 上,数据库 foo 正在运行,并且有三台服务器,集群地址分别为:server01.example.com:6000, server02.example.com:6000, server03.example.com:6000。
要在集群 B 上创建副本数据库 foo-replica(包含三个主节点和两个从节点),并从集群 A 的上游数据库 foo 进行复制,请运行以下过程
CALL internal.dbms.createReplicaDatabase("foo-replica", 3, 2, {remote: "foo", addresses:["server01.example.com:6000","server02.example.com:6000","server03.example.com:6000"]});
所有副本数据库均为只读。副本数据库可以拥有遵循服务器模式限制的主节点和从节点拓扑。然而,无论主节点还是从节点都保持只读状态。
只有当副本数据库能够联系到集群 A 的服务器,且上游数据库 foo 存在并正在运行时,该命令才能成功执行。否则,命令将报错。
验证 foo-replica 数据库是否在预期的服务器数量上以预期的角色在线。请注意,类型被标记为 replica。
SHOW DATABASE foo-replica;
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | name | type | aliases | access | address | role | writer | requestedStatus | currentStatus | statusMessage | default | home | constituents| +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | "foo-replica" | "replica" | [] | "read-write" | "localhost:7687" | "primary" | FALSE | "online" | "online" | "" | FALSE | FALSE | [] | | "foo-replica" | "replica" | [] | "read-write" | "localhost:7688" | "primary" | FALSE | "online" | "online" | "" | FALSE | FALSE | [] | | "foo-replica" | "replica" | [] | "read-write" | "localhost:7689" | "primary" | FALSE | "online" | "online" | "" | FALSE | FALSE | [] | | "foo-replica" | "replica" | [] | "read-write" | "localhost:7690" | "secondary" | FALSE | "online" | "online" | "" | FALSE | FALSE | [] | | "foo-replica" | "replica" | [] | "read-write" | "localhost:7691" | "secondary" | FALSE | "online" | "online" | "" | FALSE | FALSE | [] | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 5 rows available after 3 ms, consumed after another 1 ms
通过驱动程序或 Cypher Shell 访问副本数据库
鉴于副本数据库是只读的,您必须确保驱动程序的 "AccessMode" 设置为 "READ",或者仅执行 executeRead。尝试向副本数据库写入数据将会失败。
此外,通过 Cypher Shell 访问数据库时,请确保在连接时将 --access-mode 也设置为 read。
bin/cypher-shell --access-mode=read -a neo4j://:7684 -d foo-replica
这是必要的,因为我们所有的副本都是只读的。否则会导致无法找到 WRITE 服务器。
通过 Neo4j Browser 访问数据库时,请确保访问模式 (Access mode) 设置为 Read。这可以在 Browser 设置 (Settings) 抽屉中找到。
设置路由策略
副本数据库遵循内置的路由策略。
- 示例 1
-
例如,如果您没有设置路由策略,查询
CALL dbms.routing.getRoutingTable({}, "foo-replica");将返回所有五台服务器作为读取器,且没有写入器。+-------------------------------------------------------------------------------------------------------------------------------+ | ttl | servers | +-------------------------------------------------------------------------------------------------------------------------------+ | 300 | [{addresses: ["localhost:7687", "localhost:7688", "localhost:7689", "localhost:7690", "localhost:7691"], role: "READ"} | +-------------------------------------------------------------------------------------------------------------------------------+ - 示例 2
-
如果您在 neo4j.conf 文件中设置
dbms.routing.reads_on_primaries_enabled=false以禁用主节点上的读取,则路由策略会导致以下路由表,其中只有两个具有从节点角色的副本是读取器。+-------------------------------------------------------------------------+ | ttl | servers | +-------------------------------------------------------------------------+ | 300 | [{addresses: ["localhost:7690", "localhost:7691"], role: "READ"} | +-------------------------------------------------------------------------+
管理用户角色和权限
|
复制数据库时,不会复制用户权限和角色。 |
权限和基于角色的访问控制必须在集群 A 和 集群 B 上单独设置,因为它们无法被复制。您应该将这两个集群视为独立的实体,仅在它们之间进行标准数据库复制。此外,system 数据库无法被复制。
监控副本数据库
副本从上游数据库异步复制数据。因此,跟踪上游数据库和副本数据库之间的复制延迟非常重要。为此,请绘制上游和副本数据库的 <prefix>.database.<db>.transaction.last_committed_tx_id 指标。此差异有效地体现了上游和副本之间的延迟。
灾难恢复场景
建议在两个不同的云区域中设置两个独立的集群。如果主区域发生故障,您可以提升灾难恢复集群 (DR-cluster) 中的复制数据库,并将数据流量重定向到提升后的数据库。
图 2. 灾难
|
图 3. 提升副本数据库
|
图 4. 重定向数据流量
|
提升副本数据库
如果源集群变得不可用,您可以提升副本数据库以接受写入。
|
提升是一个单向操作。一旦副本被提升,它就无法再重新连接到原始源。要恢复复制,您需要创建一个新的副本。 |
可以通过两种方式提升副本:保留其拓扑或修改其拓扑。
- 在不修改拓扑的情况下提升副本数据库
-
表 2. internal.dbms.promoteReplicaDatabase() 语法
internal.dbms.promoteReplicaDatabase(replicaDatabaseName)描述
将副本数据库转换为标准数据库,同时保留其当前拥有的数据和拓扑。
输入参数
名称
类型
描述
replicaDatabaseNameSTRING当前集群中即将被提升的副本名称。
模式
写入 (WRITE)
在集群 B 上,要提升副本数据库
foo-replica(采用现有拓扑,即三个主节点和两个从节点),请调用此过程CALL internal.dbms.promoteReplicaDatabase('foo-replica');该数据库将变为可写入状态。
验证
foo-replica数据库是否在预期的服务器数量上在线,且类型为standard。SHOW DATABASE foo-replica;+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | name | type | aliases | access | address | role | writer | requestedStatus | currentStatus | statusMessage | default | home | constituents| +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | "foo-replica" | "standard" | [] | "read-write" | "localhost:7687" | "primary" | TRUE | "online" | "online" | "" | FALSE | FALSE | [] | | "foo-replica" | "standard" | [] | "read-write" | "localhost:7688" | "primary" | FALSE | "online" | "online" | "" | FALSE | FALSE | [] | | "foo-replica" | "standard" | [] | "read-write" | "localhost:7689" | "primary" | FALSE | "online" | "online" | "" | FALSE | FALSE | [] | | "foo-replica" | "standard" | [] | "read-write" | "localhost:7690" | "secondary" | FALSE | "online" | "online" | "" | FALSE | FALSE | [] | | "foo-replica" | "standard" | [] | "read-write" | "localhost:7691" | "secondary" | FALSE | "online" | "online" | "" | FALSE | FALSE | [] | +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 5 rows available after 3 ms, consumed after another 1 ms
现在,其中一个主数据库已变为可写入,因为
writer等于TRUE。此时,我们的路由表将根据标准数据库返回写入器和读取器。 - 在修改拓扑的同时提升副本数据库
-
您可以使用以下过程在提升过程中更改副本的拓扑
Table 3. internal.dbms.promoteReplicaDatabaseWithTopology() 语法
internal.dbms.promoteReplicaDatabaseWithTopology(replicaDatabaseName, numPrimaries, numSecondaries)描述
将副本数据库转换为具有新拓扑的标准数据库,同时保留其当前拥有的数据。
输入参数
名称
类型
描述
replicaDatabaseNameSTRING当前集群中即将被提升的副本名称。
numPrimariesINTEGER(整数)新的主节点数量。这些主节点将符合服务器上设置的模式限制,并将变为可写状态。
numSecondariesINTEGER(整数)新的副本从节点数量。
模式
写入 (WRITE)
您必须指定主节点或从节点的数量
CALL internal.dbms.promoteReplicaDatabaseWithTopology('foo-replica', 3, 4);这将以三个主节点和四个从节点提升副本数据库。
故障恢复 (Failback)
故障恢复是在灾难恢复场景后使主集群恢复运行的过程。这假设提升后的数据库当前正在 DR 集群中运行。
要恢复之前的源数据库,请遵循以下步骤
-
在当前示例中,副本数据库的上游是 DR 集群(集群 B)中提升后的数据库
foo-replica(参见图 3)。
在主集群(集群 A)中创建一个副本数据库foo。图 5. 灾难后的恢复 -
停止集群 B 中提升后的数据库
foo-replica的写入操作。 -
检查指标以确保提升后的数据库和复制数据库的
tx_id完全相同。 -
提升集群 A 中的副本数据库
foo,这意味着该数据库开始处理写入操作,并再次成为处理流量的主数据库。 -
停止并删除 DR 集群中的数据库
foo-replica。创建一个新的副本foo-new-replica,其上游指向主集群中的主数据库foo(参见图 5)。图 6. 恢复主集群中的上游数据库