知识库

系统数据库概述

Neo4j 4.0 及以上版本支持在同一个 DBMS 中管理多个数据库。所有这些数据库都通过一个名为 system 的特殊数据库进行控制。

本文简要介绍了 system 数据库的架构概览。

system 数据库的作用是 定义配置 给其他数据库。数据库的配置可能有多种类型。例如

  • 运行时配置

    • 存在性(是否存在)

    • 状态(在线/离线)

  • 安全配置(基于角色的访问控制,RBAC)

  • neo4j.conf(尚未由 system 数据库维护,但未来版本有计划加入)

configuration

在单机和集群环境中,有大量有趣的运行时工作在幕后进行,这由名为 reconciler(调和器)的组件处理。请参见下面的图 2。

reconciler

system 数据库在集群中会被复制,并且它也有一个 leader,和其他数据库一样。自 4.0 起,每个数据库都属于独立的 Raft 组。这意味着 core-1 可以是 system 数据库的 leader,而 core-2 可以是 mydb 数据库的 leader。system 数据库内部的所有内容同样存储为图数据模型。不过,只有 DDL 命令(CREATE、DROP、SHOW 等)可在该数据库中执行,常规的 Cypher 命令(例如 MATCH)则不行。图中有表示其他数据库的节点(本例中 Fig 2 的 neo4jmydb)。

reconciler 与另一个名为 database manager(数据库管理器)的组件通信,后者负责管理实际的数据库。每个实例都会调和所有数据库的本地副本。如果上例中 core-2 上的 reconciler 知道 mydb 在 leader(core-1)上已上线,它会确保该实例中的 mydb 也上线。每个实例的 system 数据库都配备了 reconciler 和 database manager。

reconciler 的职责是调和期望状态(STOPPED、STARTED、DROPPED)与当前状态之间的差异。

reconciler 的一个重要特性是它完全异步运行,并始终基于写入 system 数据库的已复制的“真实来源”期望状态。如果某个服务器暂时与集群其他节点分区,或因某些原因落后,它将无法收到“期望状态”的更新,因而该服务器上的 reconciler 仍不会执行其他服务器已经完成的运行时变更。当然,一旦集群恢复正常连通,reconciler 将继续工作。

当创建名为 mydb 的数据库时,会在 system 数据库中创建一个标签为 Database 的节点。该节点还有一些属性,如 namestatusuuid,如上图所示。值得注意的是,当 mydb 数据库被删除时,节点的标签会变为 DeletedDatabase

下面是单个 Database 节点的示例

( n:Database { name : mydb, uuid: 7242f697-7f4f-4bbf-b989-aad3e8980bfb, status: online } )

如果它被删除,只需将 Database 标签改为 DeletedDatabase

( n:DeletedDatabase { name : mydb, uuid: 7242f697-7f4f-4bbf-b989-aad3e8980bfb, status: offline } )

在内部唯一标识数据库的属性是 uuid,类型为 UUID。因此,你可以先 DROP 数据库 neo4j,再 CREATE 它。内部上,第一次删除后该节点会保留 DeletedDatabase 标签,而新创建的则带有 Database 标签并拥有不同的 uuid

备份 system 数据库时,请记住其中包含运行时配置。比如,当对 system 数据库进行在线备份时,mydb 正处于停止状态。于是,恢复 system 数据库备份后,mydb 仍会保持停止状态。因此,运行时状态始终由 system 数据库中的内容决定。

下面是状态图(图 3),展示了在执行 SHOW DATABASES 命令时 reconciler 会发布的所有状态。

states

文件系统中某个文件夹的存在(例如 $neo4j_home/data/database/mydb)并不决定数据库是否存在。数据库的存在由 system 数据库中的记录决定。如果 system 数据库中没有该数据库的记录,即使文件夹已存在也不会被注册。要让系统识别该数据库,需要执行 CREATE DATABASE mydb

另外,如果 system 数据库中有 Xdb 数据库,而在恢复之前 $neo4j_home/data/database/ 位置不存在该数据库,则 reconciler 会创建相应的文件夹,此时会得到一个空的 Xdb。但如果集群中其他实例已经在运行 Xdb 数据库,集群绑定过程会对该数据库执行 store copy(存储复制),而不会创建空库。

最后,以下是从多数据库运维角度需要注意的几点

  1. system 数据库需要以与其他数据库相同的频率进行备份。

  2. 查看 debug.log 时会发现,Raft 成员的 MemberId 对每个数据库而言并不不同。单个实例内的所有数据库共享同一个 MemberId

  3. 所有多数据库管理命令必须针对 system 数据库执行。当通过 Bolt 连接到 DBMS 时,这些管理命令会自动路由到 system 数据库。

  4. 本地用户存储在 system 数据库中,安全模型也位于此。

  5. neo4j-admin unbind 在特定服务器上的所有数据库上运行。

  6. dbms.memory.pagecache.sizedbms.memory.heap.initial_sizedbms.memory.heap.max_size 设置均为实例级别。所有数据库在同一个 JVM 下运行,共享相同的页面缓存和堆内存。

© . This site is unofficial and not affiliated with Neo4j, Inc.