迁移因果集群

本章介绍将因果集群从 Neo4j 3.5 直接迁移到 4.x 所需的步骤。

将因果集群从 Neo4j 3.5 迁移到 4.x 需要停机时间。因此,建议在类似生产的环境中执行测试迁移,以获取有关停机时间的信息。

每个集群成员都必须完成先决条件和迁移步骤。

先决条件

确保您已完成迁移清单中的所有任务。

准备迁移

迁移集群部署的策略是从一个集群实例完成脱机复制,然后使用复制的存储来为新集群播种。

请记住,迁移是一个单一事件。不要对每个实例执行独立的迁移!应该有一个单一的迁移事件,并且该迁移的存储将成为所有其他集群实例的事实来源。这很重要,因为在迁移时,Neo4j 会生成随机的存储 ID,如果独立完成,您的集群最终将拥有与您拥有的实例一样多的存储 ID。如果出现这种情况,Neo4j 将无法启动。因此,一些集群迁移步骤将在单个实例上执行,而其他步骤将在所有实例上执行。每个步骤都会告诉您在哪里执行必要的操作。

在此阶段,您应该选择一个实例来操作。这将是实际发生迁移的实例。后续步骤将告诉您是否在选定的实例上、剩余的实例上或所有实例上执行该步骤。

在每个集群成员上
  1. 验证您已关闭所有集群成员(核心和只读副本)。您可以检查neo4j.log

  2. 在每个实例上安装您要迁移到的Neo4j版本。有关如何安装您正在使用的发行版的更多信息,请参阅运维手册→安装

  3. neo4j.conf文件替换为您在准备一个新的neo4j.conf文件供新安装使用部分中为每个实例准备的文件。

  4. 复制所有用于加密的文件,例如私钥、公钥证书以及受信任和吊销目录的内容(位于<neo4j-home>/certificates/中)。

    如果您的旧安装修改了以dbms.directories.*或设置dbms.active_database开头的配置,请验证新的neo4j.conf文件是否已正确配置以查找这些目录。

迁移数据

在选定的实例上

使用 4.x Neo4j 管理工具,迁移 3.5 Neo4j 的数据存储。neo4j-admin copy命令还会删除任何不一致的节点、属性和关系,并且不会将它们复制到新创建的存储中。

  1. <neo4j-home>文件夹中,运行以下命令以复制数据存储。您需要指定旧存储位置和目标更新数据库的名称

    bin/neo4j-admin copy --from-path=/path/to/3.5.x/graph.db --to-database=<db_name>
    Starting to copy store, output will be saved to:  $neo4j_home/logs/neo4j-admin-copy-2020-11-26.16.07.19.log
    2020-11-26 16:07:19.939+0000 INFO [StoreCopy] ### Copy Data ###
    2020-11-26 16:07:19.940+0000 INFO [StoreCopy] Source: /path/to/3.5.x/graph.db (page cache 8m)
    2020-11-26 16:07:19.940+0000 INFO [StoreCopy] Target:  $neo4j_home/data/databases/db_name (page cache 8m)
    2020-11-26 16:07:19.940+0000 INFO [StoreCopy] Empty database created, will start importing readable data from the source.
    2020-11-26 16:07:21.661+0000 INFO [o.n.i.b.ImportLogic] Import starting
    
    Import starting 2020-11-26 16:07:21.699+0000
      Estimated number of nodes: 50.00 k
      Estimated number of node properties: 50.00 k
      Estimated number of relationships: 0.00
      Estimated number of relationship properties: 50.00 k
      Estimated disk space usage: 2.680MiB
      Estimated required memory usage: 8.598MiB
    
    (1/4) Node import 2020-11-26 16:07:22.220+0000
      Estimated number of nodes: 50.00 k
      Estimated disk space usage: 1.698MiB
      Estimated required memory usage: 8.598MiB
    .......... .......... .......... .......... ..........   5% ∆239ms
    .......... .......... .......... .......... ..........  10% ∆1ms
    .......... .......... .......... .......... ..........  15% ∆1ms
    .......... .......... .......... .......... ..........  20% ∆0ms
    .......... .......... .......... .......... ..........  25% ∆1ms
    .......... .......... .......... .......... ..........  30% ∆0ms
    .......... .......... .......... .......... ..........  35% ∆0ms
    .......... .......... .......... .......... ..........  40% ∆1ms
    .......... .......... .......... .......... ..........  45% ∆0ms
    .......... .......... .......... .......... ..........  50% ∆1ms
    .......... .......... .......... .......... ..........  55% ∆0ms
    .......... .......... .......... .......... .........-  60% ∆51ms
    .......... .......... .......... .......... ..........  65% ∆0ms
    .......... .......... .......... .......... ..........  70% ∆0ms
    .......... .......... .......... .......... ..........  75% ∆1ms
    .......... .......... .......... .......... ..........  80% ∆0ms
    .......... .......... .......... .......... ..........  85% ∆0ms
    .......... .......... .......... .......... ..........  90% ∆1ms
    .......... .......... .......... .......... ..........  95% ∆0ms
    .......... .......... .......... .......... .......... 100% ∆0ms
    
    (2/4) Relationship import 2020-11-26 16:07:22.543+0000
      Estimated number of relationships: 0.00
      Estimated disk space usage: 1006KiB
      Estimated required memory usage: 15.60MiB
    (3/4) Relationship linking 2020-11-26 16:07:22.879+0000
      Estimated required memory usage: 7.969MiB
    (4/4) Post processing 2020-11-26 16:07:23.272+0000
      Estimated required memory usage: 7.969MiB
    -......... .......... .......... .......... ..........   5% ∆356ms
    .......... .......... .......... .......... ..........  10% ∆0ms
    .......... .......... .......... .......... ..........  15% ∆1ms
    .......... .......... .......... .......... ..........  20% ∆0ms
    .......... .......... .......... .......... ..........  25% ∆0ms
    .......... .......... .......... .......... ..........  30% ∆1ms
    .......... .......... .......... .......... ..........  35% ∆0ms
    .......... .......... .......... .......... ..........  40% ∆0ms
    .......... .......... .......... .......... ..........  45% ∆1ms
    .......... .......... .......... .......... ..........  50% ∆0ms
    .......... .......... .......... .......... ..........  55% ∆0ms
    .......... .......... .......... .......... ..........  60% ∆0ms
    .......... .......... .......... .......... ..........  65% ∆1ms
    .......... .......... .......... .......... ..........  70% ∆0ms
    .......... .......... .......... .......... ..........  75% ∆0ms
    .......... .......... .......... .......... ..........  80% ∆0ms
    .......... .......... .......... .......... ..........  85% ∆0ms
    .......... .......... .......... .......... ..........  90% ∆0ms
    .......... .......... .......... .......... ..........  95% ∆1ms
    .......... .......... .......... .......... .......... 100% ∆0ms
    
    
    IMPORT DONE in 2s 473ms.
    Imported:
      1 nodes
      0 relationships
      1 properties
    Peak memory usage: 15.60MiB
    2020-11-26 16:07:24.140+0000 INFO [o.n.i.b.ImportLogic] Import completed successfully, took 2s 473ms. Imported:
      1 nodes
      0 relationships
      1 properties
    2020-11-26 16:07:24.668+0000 INFO [StoreCopy] Import summary: Copying of 100704 records took 4 seconds (25176 rec/s). Unused Records 100703 (99%) Removed Records 0 (0%)
    2020-11-26 16:07:24.669+0000 INFO [StoreCopy] ### Extracting schema ###
    2020-11-26 16:07:24.669+0000 INFO [StoreCopy] Trying to extract schema...
    2020-11-26 16:07:24.920+0000 INFO [StoreCopy] ... found 1 schema definitions. The following can be used to recreate the schema:
    2020-11-26 16:07:24.922+0000 INFO [StoreCopy]
    
    CALL db.createIndex('index_5c0607ad', ['Person'], ['name'], 'native-btree-1.0', {`spatial.cartesian-3d.min`: [-1000000.0, -1000000.0, -1000000.0],`spatial.cartesian.min`: [-1000000.0, -1000000.0],`spatial.wgs-84.min`: [-180.0, -90.0],`spatial.cartesian-3d.max`: [1000000.0, 1000000.0, 1000000.0],`spatial.cartesian.max`: [1000000.0, 1000000.0],`spatial.wgs-84-3d.min`: [-180.0, -90.0, -1000000.0],`spatial.wgs-84-3d.max`: [180.0, 90.0, 1000000.0],`spatial.wgs-84.max`: [180.0, 90.0]})
    2020-11-26 16:07:24.923+0000 INFO [StoreCopy] You have to manually apply the above commands to the database when it is stared to recreate the indexes and constraints. The commands are saved to $neo4j_home/logs/neo4j-admin-copy-2020-11-26.16.07.19.log as well for reference.

    使用直接路径时,索引不会自动迁移,因此您必须重新创建它们。运行存储迁移后,neo4j-admin copy命令会提取模式并生成一个命令列表,您稍后可以使用该列表在新的 4.x 存储上重新创建您的模式。重新创建模式命令也保存在迁移日志文件中,该文件位于/logs目录中。

准备为集群播种

在选定的实例上

使用neo4j-admin dump对您新迁移的数据库和事务进行转储。

bin/neo4j-admin dump --database=neo4j --to=$BACKUP_DESTINATION/neo4j.dump

请注意,迁移后,Neo4j Admin 命令可能略有不同,因为 Neo4j 现在支持多个数据库。

请**不要**立即启动服务器。

为集群播种

如果您迁移到 4.3 之前的 Neo4j 版本,并且迁移的数据库在neo4j.conf中设置为default数据库,则应将迁移的数据库目录从选定的实例复制到所有其他实例以播种集群。此步骤是必需的,以便在启动数据库时所有实例都具有数据库的相同副本。如果迁移的数据库不是default数据库并且 Neo4j 版本为 4.3 或更高版本,则不需要此步骤。

  1. 将转储复制到其余实例。

  2. 使用neo4j-admin load --from=<archive-path> --database=<db_name> --force将每个数据库替换为在选定实例上迁移的数据库

    bin/neo4j-admin load --from=$BACKUP_DESTINATION/neo4j.dump --database=neo4j --force

启动集群

在每个集群成员上,包括选定的实例

在继续之前,请确保以下活动已发生并已成功完成

  • neo4j.conf的内容正确,并且所有实例都应用了所需的更改。

  • 在选定的实例上发生了单一的迁移事件。

  • 在选出的实例上执行已迁移存储的备份(通过neo4j-admin dump)。

  • 已迁移存储的备份已传输到其余实例。

  • 在其余实例上加载存储(通过neo4j-admin load)。

  1. 如果列表中的所有操作都成功,您可以继续启动集群的所有实例。

    bin/neo4j start

    systemctl start neo4j
  2. 如果已迁移的数据库是default数据库,则它应该在实例启动时自动启动,并且此步骤不是必需的。如果已迁移的数据库不是default数据库,则它仍处于STOPPED状态。您现在需要启动数据库。在一个集群成员上,在 Neo4j 浏览器或 Cypher® Shell 中运行以下命令

    Neo4j 4.0/4.1/4.2
    CREATE DATABASE <db_name>;
    Neo4j 4.3+
    CREATE DATABASE <db_name> OPTIONS { existingData : 'use', existingDataSeedInstance: '<seedInstanceId>'};

    其中<seedInstanceId>是选定实例的 ID,可以通过调用CALL dbms.cluster.overview()找到。

重新创建索引

最后一步是重新创建neo4j-admin copy命令输出的任何索引或约束。在一个集群成员上,将活动数据库更改为新迁移的数据库,然后运行以下过程

CALL db.createIndex('index_5c0607ad', ['Person'], ['name'], 'native-btree-1.0', {`spatial.cartesian-3d.min`: [-1000000.0, -1000000.0, -1000000.0],`spatial.cartesian.min`: [-1000000.0, -1000000.0],`spatial.wgs-84.min`: [-180.0, -90.0],`spatial.cartesian-3d.max`: [1000000.0, 1000000.0, 1000000.0],`spatial.cartesian.max`: [1000000.0, 1000000.0],`spatial.wgs-84-3d.min`: [-180.0, -90.0, -1000000.0],`spatial.wgs-84-3d.max`: [180.0, 90.0, 1000000.0],`spatial.wgs-84.max`: [180.0, 90.0]})

迁移后

重新创建用户数据

Neo4j 3.5.x 将用户和角色信息存储在位于 $NEO4J_HOME/data/dbms 目录下的平面文件中。从 Neo4j 4.0 开始,此信息改为存储在system数据库中。如果您正在使用本地用户,则需要重新创建它们。转到旧$NEO4J_HOME/data/dbms目录的备份内容。身份验证数据位于auth文件中,这是一个类似于以下格式的以逗号分隔的 CSV 文件

neo4j:SHA256,1066956C2D4E46C810CA39AE218AAD128854F2C08E9E831C379958CBFA6FF17D,899F9D67F2
96746766848D92B325B29EAFD9AC93940257713BA7CF4CF2B166FF:

第一列包含用户名,第二列包含密码信息。可以使用针对system数据库的CREATE USER语句重新创建用户,例如

CREATE USER neo4j SET ENCRYPTED PASSWORD
‘0,1066956C2D4E46C810CA39AE218AAD128854F2C08E9E831C379958CBFA6FF17D,899F9D67F29
6746766848D92B325B29EAFD9AC93940257713BA7CF4CF2B166FF’ CHANGE NOT REQUIRED

其中字符串 SHA-256 被替换为字符 0(零)。

角色数据位于角色文件中,如下所示

admin:neo4j

这可以通过再次针对系统数据库运行以下命令来重新创建

GRANT ROLE admin TO neo4j

您可以使用 Neo4j 解析 auth 和 roles 文件。这将处理这些文件并生成重新创建所有用户和角色所需的所有CREATE USERGRANT ROLE命令。为此,您只需要将备份的 auth 和 roles 文件都移动到 Neo4j 的/import目录即可。之后,您可以使用以下两个查询,一个用于用户,另一个用于角色

重新创建所有用户
LOAD CSV FROM 'file:///auth' as line
with split(line[0], ":")[0] as user, split(line[2], ":") as hash
with user, hash[0] as pwd, CASE hash[1] WHEN "" THEN "NOT" ELSE "" END as
pwdChange
with "CREATE OR REPLACE USER "+user+" SET ENCRYPTED PASSWORD '0,"+pwd+"' CHANGE
"+pwdChange+" REQUIRED" as cypher
return *
重新创建所有角色
LOAD CSV FROM 'file:///roles' as line FIELDTERMINATOR ':'
WITH line[0] as role, split(line[1],",") as users
UNWIND users as user
with "GRANT ROLE "+role+" TO "+user as cypher
return *

每个查询都返回一个 Cypher 命令列表,当针对system数据库执行时,将重新创建先前在 Neo4j 3.5.x 部署中使用的所有用户和角色。

查看日志和指标

建议您查看日志和指标以确保一切正常。一切顺利,您应该会看到无错误的日志和正确报告的指标。

重新启动服务器/集群

建议您最后再重新启动一次服务器/集群,以清除所有内容并假设最新的配置更改。

重新激活连接到 Neo4j 的外部应用程序

重新启动并确认一切已成功迁移并运行良好后,您可以继续重新激活连接到 Neo4j 的任何应用程序。此时,Neo4j 存储迁移已完成,您需要专注于应用程序方面,确保所有请求都得到服务并且您的应用程序处于健康状态。

清理空间

您可以清理迁移所需的额外备份占用的磁盘空间。

备份

建议使用空的目标目录执行完整备份