灾难恢复

数据库可能由于不同系统级别的问题而变得不可用。例如,数据中心故障转移可能导致多台服务器丢失,进而导致一组数据库变得不可用。

本节提供了逐步指南,说明如何恢复无法提供写入和/或读取服务的不可用数据库。本指南将恢复不可用数据库并使其完全运行,同时最大程度地减少对集群中其他数据库的影响。但是,如果数据库由于其他原因未能按预期运行,则本节无法提供帮助。

如果 Neo4j 集群中的所有服务器都在灾难中丢失,则无法恢复当前集群。您必须创建一个新集群并恢复数据库,有关更多信息,请参阅部署基本集群种子化数据库

集群中的故障

集群中的数据库可能在集群内以不同方式分配,并且可能具有不同数量的主数据库和辅助数据库。其结果是,所有服务器在托管的数据库方面可能都不同。在集群中丢失一台服务器可能导致某些数据库丢失一个成员,而其他数据库不受影响。因此,在一台或多台服务器发生故障的灾难中,某些数据库可能继续运行,影响甚微或没有影响,而其他数据库可能丢失其所有分配的资源。

指南概述

本指南中使用以下术语

  • 离线服务器是指未运行但可能可重启的服务器。

  • 然而,丢失的服务器是指当前未运行且无法重启的服务器。

  • 可写入数据库能够提供写入服务,而不可写入数据库则不能。

从灾难中恢复集群有四个步骤

  1. 在所有未丢失的服务器上启动 Neo4j 进程。有关更多信息,请参阅启动 Neo4j 进程

  2. 使 system 数据库能够提供写入操作,以便可以修改集群。有关更多信息,请参阅使 system 数据库可写入

  3. 将任何可能丢失的服务器从集群中分离,并用新服务器替换它们。有关更多信息,请参阅使服务器可用

  4. 通过启动或继续管理数据库并验证它们是否可写入来完成灾难恢复。有关更多信息,请参阅使数据库可写入

每个步骤在以下三个部分中描述

  1. 目标 — 集群需要达到的状态,附带可选说明。

  2. 验证状态 — 如何验证状态的示例。

  3. 达到正确状态的路径 — 建议达到正确状态的一系列步骤。

建议在继续下一步之前验证每个状态,无论灾难场景如何,以确保集群完全运行。

灾难恢复步骤

灾难有时可能会影响驱动程序的路由功能,并可能阻止使用 neo4j 方案进行路由。一种补救方法是使用 bolt 而非 neo4j 直接连接到服务器。有关 bolt 方案的更多信息,请参阅服务器端路由

启动 Neo4j 进程

目标

Neo4j 进程在所有未丢失的服务器上启动。

达到正确状态的路径

在所有离线服务器上启动 Neo4j 进程。如果服务器无法启动,请检查日志并联系支持人员。该服务器可能必须被视为永久丢失。

使 system 数据库可写入

目标

system 数据库能够提供写入操作。

system 数据库包含集群的视图。这包括存在哪些服务器和数据库,它们位于何处以及如何配置。在灾难期间,集群视图可能需要更改以反映新的实际情况,例如移除丢失的服务器。数据库可能还需要重新创建以重新获得写入可用性。由于这两个步骤都是通过修改 system 数据库来执行的,因此使 system 数据库可写入是灾难恢复期间至关重要的第一步。

验证状态

可以使用状态检查过程验证 system 数据库的写入可用性。

CALL dbms.cluster.statusCheck(["system"]);

状态检查过程无法验证配置为具有单个主数据库的数据库的写入可用性。相反,通过运行 SHOW DATABASES 检查主数据库是否分配在可用服务器上,并且其 currentStatus = online

达到正确状态的路径

如果 system 数据库已丢失,请使用以下步骤重新获得其写入可用性。这些步骤将从集群中找到的最新 system 数据库副本创建新的 system 数据库。获取尽可能最新的 system 数据库非常重要,这样它才能与灾难发生前的视图紧密对应。

指南

灾难恢复指南的这一部分使用 neo4j-admin 命令。有关所用命令的更多信息,请参阅neo4j-admin 命令

  1. 关闭所有服务器上的 Neo4j 进程。这将导致集群中所有数据库停机,直到本节末尾再次启动这些进程。

  2. 在每台服务器上,运行 bin/neo4j-admin dbms unbind-system-db 以重置服务器上的 system 数据库状态。

  3. 在每台服务器上,运行 bin/neo4j-admin database info system 并比较 lastCommittedTransaction 以找出哪台服务器拥有最新的 system 数据库副本。

  4. 在最新的服务器上,运行 bin/neo4j-admin database dump system --to-path=[path-to-dump] 以转储当前 system 数据库并将其存储在可访问的位置。

  5. 对于每个丢失的服务器,根据向集群添加服务器添加一个新的无约束服务器。重要的是新服务器是无约束的,否则本指南的下一步中解除分配服务器可能会被阻止,即使已添加了足够的服务器。

    虽然建议这样做,但在此步骤中添加新服务器并非严格必要。还可以选择更改辅助分配上的 system 数据库模式 (server.cluster.system_database_mode),使其成为新 system 数据库的主分配。所需主分配的数量由 dbms.cluster.minimum_initial_system_primaries_count 定义。有关更多信息,请参阅配置设置。请注意,在本指南的下一步中,当数据库从丢失的服务器移动到可用的服务器时,不替换服务器可能会导致集群过载。

  6. 在每台服务器上,运行 bin/neo4j-admin database load system --from-path=[path-to-dump] --overwrite-destination=true 以加载当前的 system 数据库转储。

  7. 在每台服务器上,确保发现设置正确。有关更多信息,请参阅集群服务器发现

  8. 在所有服务器上启动 Neo4j 进程。

使服务器可用

目标

集群视图中的所有服务器均可用且已启用。

丢失的服务器仍将存在于 system 数据库的集群视图中,但处于不可用状态。此外,根据集群视图,这些丢失的服务器仍在托管它们在丢失之前拥有的数据库。因此,仅告知集群丢失了哪些服务器是不够的。托管在丢失服务器上的数据库也需要移动到集群中可用的服务器上,然后才能移除丢失的服务器。

验证状态

可以通过列出服务器来查看集群的服务器视图。有关更多信息,请参阅列出服务器。如果所有服务器都显示 health = Availablestatus = Enabled,则状态已得到验证。

SHOW SERVERS;

达到正确状态的路径

使用以下步骤移除丢失的服务器并将新服务器添加到集群。要移除丢失的服务器,它们托管的任何分配都必须移动到集群中可用的服务器。这通过两个不同的步骤完成

  • 任何无法自行移动的分配都需要重新创建数据库,以便强制其移动。

  • 任何可以移动的分配将通过解除分配服务器来指示其移动。

指南
  1. 对于每个 Unavailable 服务器,在其中一台可用服务器上运行 CALL dbms.cluster.cordonServer("unavailable-server-id")。这会阻止新的数据库分配移动到此服务器。

  2. 对于每个 Cordoned 服务器,请确保已向集群添加新的无约束服务器以替代它。有关更多信息,请参阅向集群添加服务器

    如果已在本指南的使 system 数据库可写入步骤中添加了服务器,则此处可能不需要额外的服务器。重要的是新服务器是无约束的,否则即使添加了足够的服务器,解除分配服务器也可能会被阻止。

    虽然建议这样做,但在此步骤中添加新服务器并非严格必要。但是,不添加新服务器会降低集群处理工作的能力。此外,它可能需要更改数据库的拓扑结构,以便解除分配服务器和重新创建数据库成为可能。

  3. 对于每个已停止的数据库 (currentStatus= offline),通过运行 START DATABASE stopped-db 启动它们。这是必要的,因为已停止的数据库无法从服务器解除分配。状态检查过程也需要准确指示此数据库是否应重新创建。在进入下一步之前,请验证所有分配在未丢失的服务器上是否处于 currentStatus = online 状态。如果数据库无法启动,则在本指南的下一步中重新创建它。

    在启动数据库之前,可以使用以下命令将其设置为 READ-ONLY,以避免对数据库进行更新:ALTER DATABASE database-name SET ACCESS READ ONLY

  4. 在每台服务器上,运行 CALL dbms.cluster.statusCheck([]) 以检查此服务器上以主模式运行的所有数据库的写入可用性。有关更多信息,请参阅监控复制

    状态检查过程无法验证配置为具有单个主数据库的数据库的写入可用性。相反,通过运行 SHOW DATABASES 检查主数据库是否分配在可用服务器上,并且其 currentStatus = online

  5. 对于每个不可写入的数据库,重新创建它以将其从丢失的服务器移动并重新获得写入可用性。有关重新创建选项的更多信息,请转到重新创建数据库。请记住,在重新创建数据库之前,请确保数据库有最新备份。有关更多信息,请参阅在线备份。如果任何数据库在可用服务器上的 currentStatus = quarantined,请使用备份作为种子从备份中重新创建它们。

    如果您使用未定义服务器带有备用备份的未定义服务器重新创建数据库,则在 system 数据库已恢复的某些边缘情况下,存储可能无法尽可能最新地重新创建。

  6. 对于每个 Cordoned 服务器,在其中一台可用服务器上运行 DEALLOCATE DATABASES FROM SERVER cordoned-server-id。这将把所有数据库分配从该服务器移动到集群中的可用服务器。

    如果集群中没有添加足够的无约束服务器来替换丢失的服务器,此操作可能会失败。另一个原因是某些可用服务器也是 Cordoned

  7. 对于每个正在解除分配或已解除分配的服务器,运行 DROP SERVER deallocated-server-id。这将从集群视图中移除该服务器。

使数据库可写入

目标

所有希望启动的数据库都可写入。

一旦验证此状态,灾难恢复即完成。但是,请记住,在此过程中,以前停止的数据库可能已启动。如果它们仍希望处于停止状态,请运行 STOP DATABASE started-db WAIT

请记住,重新创建数据库需要不确定的时间,因为它可能涉及将存储复制到新服务器,如重新创建数据库中所述。因此,currentStatus = starting 的分配很可能会在一段时间后达到 requestedStatus

验证状态

您可以使用状态检查过程验证所有集群数据库的写入可用性。

CALL dbms.cluster.statusCheck([]);

状态检查过程无法验证配置为具有单个主数据库的数据库的写入可用性。相反,通过运行 SHOW DATABASES 检查主数据库是否分配在可用服务器上,并且其 currentStatus = online

可以进行更严格的验证,以验证所有数据库在所有服务器上都处于其所需状态。对于更严格的检查,运行 SHOW DATABASES 并验证所有服务器上的所有数据库分配的 requestedStatus = currentStatus

达到正确状态的路径

使用以下步骤使集群中的所有数据库再次可写入。它们包括重新创建任何不可写入的数据库,并识别任何无法完成的重新创建。重新创建可能会因不同原因而失败,但一个例子是不同服务器上相同事务的校验和不匹配。

指南
  1. 通过运行 CALL dbms.cluster.statusCheck([]) 来识别所有不可写入的数据库,如本灾难恢复步骤的示例验证部分所述。过滤掉所有希望停止的数据库,以便不必要地重新创建它们。

  2. 重新创建所有不可写入且之前未重新创建的数据库。有关更多信息,请参阅重新创建数据库。请记住,在重新创建数据库之前,请确保数据库有最新备份。有关更多信息,请参阅在线备份。如果任何数据库在可用服务器上的 currentStatus = quarantined,请使用备份作为种子从备份中重新创建它们。

    如果您使用未定义服务器带有备用备份的未定义服务器重新创建数据库,则在 system 数据库已恢复的某些边缘情况下,存储可能无法尽可能最新地重新创建。

  3. 运行 SHOW DATABASES 并检查任何重新创建但不可写入的数据库。如果在消息字段中显示以下任一消息,则数据库的重新创建将不会完成

    • 种子服务器 ServerId1 和 ServerId2 对事务 TransactionId 具有不同的校验和。所有种子服务器对于相同的追加索引必须具有相同的校验和。

    • 种子服务器 ServerId1 和 ServerId2 具有不兼容的 storeId。所有种子服务器必须具有兼容的 storeId。

    • 在任何种子服务器 ServerId1、ServerId2…​上未找到存储。

  4. 对于每个无法完成重新创建的数据库,请使用备份作为种子从备份中重新创建它们。

© . All rights reserved.