错误处理

运行数据库管理查询(例如 CREATE DATABASE)时,可能会遇到错误。

观察错误

由于数据库管理操作是异步执行的,这些错误可能不会在查询执行后立即返回。相反,您必须监控 SHOW DATABASE 命令的输出;特别是 statusMessagecurrentStatus 列。

示例 1. 创建数据库失败
neo4j@system> CREATE DATABASE foo;
0 rows available after 108 ms, consumed after another 0 ms
neo4j@system> SHOW DATABASE foo;

在独立模式下

+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| name   | type       | aliases | access       | address          | role      | writer | requestedStatus | currentStatus | statusMessage             | default | home  | constituents |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| "foo"  | "standard" | []      | "read-write" | "localhost:7687" | "primary" | TRUE   | "online"        | "dirty"       | "File system permissions" | FALSE   | FALSE | []           |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

1 rows available after 4 ms, consumed after another 1 ms

在集群中

+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| name   | type       | aliases | access       | address          | role      | writer | requestedStatus | currentStatus | statusMessage             | default | home  | constituents |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| "foo"  | "standard" | []      | "read-write" | "localhost:7687" | "primary" | TRUE   | "online"        | "online"      | ""                        | FALSE   | FALSE | []           |
| "foo"  | "standard" | []      | "read-write" | "localhost:7688" | "primary" | FALSE  | "online"        | "online"      | ""                        | FALSE   | FALSE | []           |
| "foo"  | "standard" | []      | "read-write" | "localhost:7689" | "primary" | FALSE  | "online"        | "dirty"       | "File system permissions" | FALSE   | FALSE | []           |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

3 row available after 100 ms, consumed after another 6 ms

数据库状态

数据库管理操作可能因多种原因失败。例如,如果文件系统实例权限不正确,或 Neo4j 本身配置错误。因此,SHOW DATABASE 查询结果中 statusMessage 列的内容可能差异很大。

但是,数据库只能处于以下几种状态之一

  • 在线

  • 离线

  • 正在启动

  • 正在停止

  • 存储复制中

  • 初始

  • 正在释放

  • 隔离

  • 未知

有关各种状态的更多详细信息,请参阅数据库状态。通常,当数据库管理操作失败时,Neo4j 会尝试将相关数据库转换为 offline 状态。如果系统确定尚未创建任何存储文件,则会将其转换为 initial 状态。类似地,如果系统怀疑数据库底层的存储文件无效(不完整、部分删除或损坏),则会将其转换为 dirty 状态。

重试失败的操作

数据库管理操作在失败时可以安全地重试。但是,这些重试不能保证成功,并且错误可能会在多次尝试后仍然存在。

如果数据库处于 quarantined 状态,重试上次操作将不起作用。

示例 2. 重试启动数据库
neo4j@system> START DATABASE foo;
0 rows available after 108 ms, consumed after another 0 ms
neo4j@system> SHOW DATABASE foo;
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| name   | type       | aliases | access       | address          | role      | writer | requestedStatus | currentStatus | statusMessage             | default | home  | constituents |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| "foo"  | "standard" | []      | "read-write" | "localhost:7687" | "primary" | TRUE   | "online"        | "offline"     | "File system permissions" | FALSE   | FALSE | []           |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

1 rows available after 4 ms, consumed after another 1 ms

在调查并解决底层问题后,您可以再次启动数据库并验证其是否正常运行

neo4j@system> START DATABASE foo;
0 rows available after 108 ms, consumed after another 0 ms
neo4j@system> SHOW DATABASE foo;
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| name     | type       | aliases | access       | address          | role      | writer | requestedStatus | currentStatus | statusMessage | default | home  | constituents |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| "foo"    | "standard" | []      | "read-write" | "localhost:7687" | "primary" | TRUE   | "online"        | "online"      | ""            | FALSE   | FALSE | []           |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

1 rows available after 4 ms, consumed after another 1 ms

如果命令的重复重试无效,或者数据库处于 dirty 状态,您可以删除并重新创建数据库,如创建数据库中所述。

在作为错误处理操作的一部分运行 DROP DATABASE 时,您还可以将 DUMP DATA 附加到命令中。它会生成一个数据库转储,可以进一步检查并可能修复。

隔离的数据库

当数据库在其正常运行期间遇到严重错误,阻止其进一步操作时,Neo4j 会停止该数据库并将其置于 quarantined 状态。这意味着,无法使用简单的 START DATABASE 命令重新启动它。您必须运行 CALL dbms.unquarantineDatabase(server, database, operation) 来解除隔离,将发生故障数据库的实例指定为 server

dbms.unquarantineDatabase() 过程在 Neo4j 2025.01 中引入,以取代现已弃用的 dbms.quarantineDatabase()

解除隔离后,实例将自动尝试将数据库带到所需状态。

语法

CALL dbms.unquarantineDatabase(server, database, operation)

输入参数

名称 类型 描述

服务器

字符串

将解除数据库隔离的服务器标识符。

数据库

字符串

将置于或移出隔离区的数据库名称。

操作

字符串

解除隔离时要应用的可选操作。

可选操作的可能值为

  • keepStateKeepStore — 不执行任何操作;保持存储和集群状态不变。

  • replaceStateKeepStore — 作为新成员加入,清除当前集群状态但保留存储。

  • replaceStateReplaceStore — 作为新成员加入,清除当前集群状态和存储。

如果您选择清除当前集群状态,服务器将尝试作为新成员加入,但只有在大多数旧成员“允许”新成员加入的情况下,这种加入才能成功。假设我们的集群具有三个主节点的拓扑。如果只有一个服务器处于 QUARANTINED 模式,则选择 replaceStateKeepStorereplaceStateReplaceStore 是安全的。如果有两个服务器处于 QUARANTINED 模式,则不应同时为两个服务器使用 replaceStateKeepStorereplaceStateReplaceStore,因为没有多数成员允许它们加入。

返回参数

该过程不返回任何值。

检查数据库是否被隔离
neo4j@system> SHOW DATABASE foo;
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| name  | type       | aliases | access       | address          | role      | writer | requestedStatus | currentStatus | statusMessage                                           | default | home  | constituents |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| "foo" | "standard" | []      | "read-write" | "localhost:7688" | "unknown" | FALSE  | "online"        | "quarantined" | "By neo4j at 2020-10-15T15:10:41.348Z: No reason given" | FALSE   | FALSE | []           |
| "foo" | "standard" | []      | "read-write" | "localhost:7689" | "primary" | FALSE  | "online"        | "online"      | ""                                                      | FALSE   | FALSE | []           |
| "foo" | "standard" | []      | "read-write" | "localhost:7687" | "primary" | TRUE   | "online"        | "online"      | ""                                                      | FALSE   | FALSE | []           |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

3 row available after 100 ms, consumed after another 6 ms

quarantined 状态对于用户数据库是持久的。这意味着如果数据库被隔离,即使 Neo4j 实例重新启动,它也将保持隔离状态。您只能通过运行 dbms.unquarantineDatabase() 过程来将其移除。

此规则的唯一例外是内置的 system 数据库。该数据库的任何隔离都会在实例重新启动后自动移除。

© . All rights reserved.