管理集群中的数据库
在创建数据库时可以设置主服务器和辅助服务器的数量,并在创建后进行更改。可以使用 CREATE DATABASE
命令指定初始拓扑,可以使用 ALTER DATABASE
命令在创建数据库后更改拓扑。如果不再需要数据库,则命令 DROP DATABASE
会从集群中删除该数据库。
CREATE DATABASE
在集群中创建数据库的命令与在非集群环境中创建数据库的命令没有太大区别(有关单服务器上数据库管理的更多信息,请参阅 创建、启动和停止数据库)。集群环境中的区别在于可以指定拓扑,即希望数据库有多少个主服务器和辅助服务器。要创建具有 3 个服务器(以主模式托管数据库)和 2 个服务器(以辅助模式托管数据库)的数据库 foo
,命令如下所示
CREATE DATABASE foo TOPOLOGY 3 PRIMARIES 2 SECONDARIES
只有在集群的服务器能够满足指定的拓扑结构时,才能成功执行该命令。如果它们不能满足,则该命令会导致错误。例如,如果集群的服务器设置为具有模式约束,以包含两个主服务器和三个辅助服务器,或者如果只有四个服务器存在,则该命令将失败并出现错误。
如果未指定 |
|
ALTER DATABASE
要更改数据库的拓扑结构或读/写访问权限,请在创建数据库后使用命令 ALTER DATABASE
。
更改数据库拓扑结构
要更改先前示例中数据库 foo
的拓扑结构,命令可以如下所示
ALTER DATABASE foo SET TOPOLOGY 2 PRIMARIES 1 SECONDARY
与 CREATE DATABASE
命令一样,如果集群不包含足够的服务器来满足请求的拓扑结构,则此命令会导致错误。
此外,ALTER DATABASE
可选地是幂等的,如果数据库不存在,也会导致错误。可以将 IF EXISTS
附加到命令中,以确保如果数据库不存在,则不会返回错误。
当存在多个指定拓扑结构的可能排列时,Neo4j 使用分配器来决定如何在集群中传播数据库。请注意,与 CREATE DATABASE
一样,ALTER DATABASE
命令会分配数据库,并且不需要执行 REALLOCATE DATABASES
,除非希望在集群中的所有服务器之间重新平衡数据库。
这通常发生在集群配置的服务器数量超过任何一个数据库的主服务器和辅助服务器数量之和时。
无法自动转换为具有单个主机的拓扑结构。尝试这样做会导致错误。
但是,可以手动执行此转换。第一步是备份数据库,有关更多信息,请参阅 备份和恢复。备份数据库后,下一步是删除数据库,有关更多信息,请参阅 删除数据库。最后一步是从备份中使用新拓扑结构播种集群,或在单个服务器上恢复备份。有关播种的信息,请参阅后面的 播种集群。
此外,还可以自动从具有单个主机的拓扑结构转换为多个主机的拓扑结构。请记住,在此类转换期间,数据库将在短时间内不可用。
ALTER DATABASE
命令可选地是幂等的,默认行为是在数据库不存在时失败并出现错误。将 IF EXISTS
附加到命令中可确保不返回错误,并且如果数据库不存在,则不会发生任何事情。
如果 ALTER DATABASE
命令减少了数据库的分配数量,则首先删除 隔离服务器 上的分配。
ALTER DATABASE nonExisting IF EXISTS SET TOPOLOGY 1 PRIMARY 0 SECONDARY
0 行
释放数据库
要减轻特定服务器的负载,可以使用以下过程之一来释放导致服务器压力增大的数据库
您必须具有 |
例如,server01
托管两个小型数据库 foo
和 bar
,以及一个非常大的数据库 baz
,而其他服务器包含更少或更小的数据库,并且 server01
承受着压力。
您可以使用以下方法之一从 server01
中释放 baz
或从 server01
中释放一定数量的数据库
// With dry run
neo4j@system> CALL dbms.cluster.deallocateDatabaseFromServer("server01", "baz", true);
// Without dry run
neo4j@system> CALL dbms.cluster.deallocateDatabaseFromServer("server01", "baz");
// With dry run
neo4j@system> CALL dbms.cluster.deallocateDatabaseFromServers(["server01", "server02"], "baz", true);
// Without dry run
neo4j@system> CALL dbms.cluster.deallocateDatabaseFromServers(["server01", "server02"], "baz");
// With dry run
neo4j@system> CALL dbms.cluster.deallocateNumberOfDatabases("server01", 3, true);
// Without dry run
neo4j@system> CALL dbms.cluster.deallocateNumberOfDatabases("server01", 3);
重新分配数据库
要重新平衡集群中的所有数据库分配(例如,因为您添加了新服务器),请使用过程或 Cypher 命令将数据库重新分配到新服务器上。
使用过程重新分配数据库
您可以使用过程 dbms.cluster.reallocateDatabase
重新平衡集群中的特定数据库,或使用 dbms.cluster.reallocateNumberOfDatabases
重新平衡集群中的多个数据库分配并减轻过载服务器的压力。请注意,如果集群已经平衡,则运行这些过程时不会发生任何重新分配。这些过程不需要服务器名称,并且可以在进行或不进行预运行的情况下执行。
您必须具有 |
例如,您添加了三个新服务器,并希望将一个非常大的数据库 baz
从包含它的所有服务器移动到新服务器。
// With dry run
neo4j@system> CALL dbms.cluster.reallocateDatabase("baz", true);
// Without dry run
neo4j@system> CALL dbms.cluster.reallocateDatabase("baz");
// With dry run
neo4j@system> CALL dbms.cluster.reallocateNumberOfDatabases(3, true);
// Without dry run
neo4j@system> CALL dbms.cluster.reallocateNumberOfDatabases(3);
使用 Cypher 命令重新分配数据库
您可以使用 Cypher 命令 REALLOCATE DATABASES
重新平衡集群中的所有数据库分配并减轻过载服务器的压力。此命令也可以与 DRYRUN
一起使用以预览数据库的新分配。
在具有许多数据库的大型集群上使用 |
|
neo4j@neo4j> DRYRUN REALLOCATE DATABASES;
+----------------------------------------------------------------------------------------------------------------------------------------+
| database | fromServerName | fromServerId | toServerName | toServerId | mode |
+----------------------------------------------------------------------------------------------------------------------------------------+
| "bar" | "server-1" | "00000000-27e1-402b-be79-d28047a9418a" | "server-5" | "00000003-b76c-483f-b2ca-935a1a28f3db" | "primary" |
| "bar" | "server-3" | "00000001-7a21-4780-bb83-cee4726cb318" | "server-4" | "00000002-14b5-4d4c-ae62-56845797661a" | "primary" |
+----------------------------------------------------------------------------------------------------------------------------------------+
重新创建数据库
Neo4j 5.24 引入了 dbms.cluster.recreateDatabase()
过程,它允许您
-
将数据库存储更改为指定的备份,同时保留数据库的所有关联权限。
-
在数据库丢失(例如,由于灾难导致)后,使其再次可写。
重新创建过程仅适用于真实用户数据库,而不适用于复合数据库或 请记住,重新创建过程会导致停机时间,同时存储更新。时间是无限的,可能取决于不同的因素,例如存储的大小、网络速度等。 |
重新创建数据库时,相关数据库可以处于 online
或 offline
状态,但无论其先前状态如何,成功操作都会启动数据库。
如果启用了数据库的更改数据捕获 (CDC),则重新创建数据库时,CDC 链将停止,即使重新创建的数据库中仍启用 CDC。要恢复 CDC 功能,请按照有关 如何从现有数据库初始化 CDC 应用程序 的指南操作。
在重新创建数据库之前,需要解决任何最终的隔离状态。有关更多信息,请参阅 标准数据库 → 错误处理。
您需要 CREATE DATABASE
和 DROP DATABASE
权限 才能运行重新创建过程。
要检查重新创建是否成功,请使用 SHOW DATABASES
命令并验证所有分配是否已启动。
此外,您还可以选择在重新创建过程中修改 拓扑结构。但是,请注意,在重新创建过程中无法更改存储格式、访问权限和增强功能。
播种选项
在重新创建数据库期间使用的存储可以通过不同的方式定义。一种方法使用备份,而其他方法使用集群中的可用分配。
您可以使用 seedURI
或 seedingServers
来指定应从中重新创建数据库的源。
-
如果两者都没有定义,则会抛出错误。
-
如果同时定义了这两个选项,则
seedingServers
必须为空列表。有关更多详细信息,请参阅 未定义服务器与回退备份。 -
如果
seedingServers
不为空且seedURI
也已定义,则会发生错误。
使用备份作为种子
如果您提供备份或转储的 URI,则所有分配上的存储将被给定 URI 处的备份或转储替换。新的分配可以放在集群中的任何ENABLED
服务器上。有关更多详细信息,请参阅从 URI 播种。
CALL dbms.cluster.recreateDatabase("neo4j", {seedURI: "s3:/myBucket/myBackup.backup"});
使用可用服务器作为种子
重建完成后,数据库将拥有来自种子服务器的最新数据存储。
重建基于剩余的存储或用户定义的存储。这意味着丢失或未定义的存储不会用于重建。如果未使用的存储比已使用的存储更新,则会导致数据丢失。 |
指定服务器
您可以指定一组可用服务器。所有分配上的存储将与定义的服务器中最新的存储同步。定义的服务器数量不能超过所需拓扑中总分配的数量。
CALL dbms.cluster.recreateDatabase("neo4j", {seedingServers: ["serverId1", "serverId2", "serverId3"]});
播种集群
有两种不同的方法可以使用数据播种集群。第一种选择是使用指定种子,其中使用指定的服务器在集群中的其他服务器上创建备份数据库。另一种选择是从 URI 播种集群,其中所有要托管数据库的服务器都使用来自 URI 指定的外部源的相同种子进行播种。请记住,在某些情况下,使用指定种子可能会出现问题,因为无法预先知道数据库将如何分配到集群中的服务器。此外,此方法依赖于种子已经存在于其中一台服务器上。
指定种子
为了将集群中的服务器指定为种子,使用neo4j-admin database restore
命令将数据库备份传输到该服务器。随后,该服务器将用作其他集群成员从中复制备份数据库的源。
此示例创建一个名为foo
的用户数据库,该数据库在三台服务器上以主模式托管。foo
数据库不应以前存在于集群中的任何服务器上。
如果与您的备份同名的数据库已存在,请使用命令DROP DATABASE
删除它以及与其关联的所有用户和角色。
-
在一台服务器上还原
foo
数据库。在此示例中,使用server01
成员。bin/neo4j-admin database restore --from-path=/path/to/foo-backup-dir foo
-
通过登录 Cypher Shell 并运行
SHOW SERVERS
查找server01
的服务器 ID。交叉引用地址以查找服务器 ID。使用任何数据库进行连接。SHOW SERVERS YIELD serverId, name, address, state, health, hosting;
+-----------------------------------------------------------------------------------------------------------------------------------------------------+ | serverId | name | address | state | health | hosting | +-----------------------------------------------------------------------------------------------------------------------------------------------------+ | "25a7efc7-d063-44b8-bdee-f23357f89f01" | "25a7efc7-d063-44b8-bdee-f23357f89f01" | "localhost:7689" | "Enabled" | "Available" | ["system", "neo4j"] | | "782f0ee2-5474-4250-b905-4cd8b8f586ba" | "782f0ee2-5474-4250-b905-4cd8b8f586ba" | "localhost:7688" | "Enabled" | "Available" | ["system", "neo4j"] | | "8512c9b9-d9e8-48e6-b037-b15b0004ca18" | "8512c9b9-d9e8-48e6-b037-b15b0004ca18" | "localhost:7687" | "Enabled" | "Available" | ["system", "neo4j"] | +-----------------------------------------------------------------------------------------------------------------------------------------------------+
在这种情况下,
server01
的地址为localhost:7687
,因此服务器 ID 为8512c9b9-d9e8-48e6-b037-b15b0004ca18
。 -
在一台服务器上,使用
system
数据库并使用server01
的服务器 ID 创建数据库foo
。foo
的拓扑存储在system
数据库中,当您创建它时,它会根据默认拓扑进行分配(可以使用CALL dbms.showTopologyGraphConfig
显示)。这可能与备份时foo
的拓扑不同。如果要确保在整个集群中进行特定分配,则可以在CREATE DATABASE
命令中使用TOPOLOGY
子句指定所需的拓扑。有关更多信息,请参阅CREATE DATABASE
。CREATE DATABASE foo TOPOLOGY [desired number of primaries] PRIMARIES [desired number of secondaries] SECONDARIES OPTIONS {existingData: 'use', existingDataSeedServer: '8512c9b9-d9e8-48e6-b037-b15b0004ca18'};
-
验证
foo
数据库是否在所需数量的服务器上以所需的角色联机。如果foo
数据库的大小相当大,则命令的执行可能需要一些时间。SHOW DATABASE foo;
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | name | type | aliases | access | address | role | writer | requestedStatus | currentStatus | statusMessage | default | home | constituents | +------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | "foo" | "standard" | [] | "read-write" | "localhost:7687" | "primary" | FALSE | "online" | "online" | "" | FALSE | FALSE | [] | | "foo" | "standard" | [] | "read-write" | "localhost:7688" | "primary" | FALSE | "online" | "online" | "" | FALSE | FALSE | [] | | "foo" | "standard" | [] | "read-write" | "localhost:7689" | "primary" | TRUE | "online" | "online" | "" | FALSE | FALSE | [] | +------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 9 rows available after 3 ms, consumed after another 1 ms
从 URI 播种
此方法使用来自外部源的相同种子播种所有服务器,该外部源由 URI 指定。种子可以是现有数据库的备份或转储。种子的来源称为种子提供程序。
该机制是可插拔的,允许支持新的种子源(有关更多信息,请参阅Java 参考→实现自定义种子提供程序)。该产品内置支持从已挂载的文件系统(文件)、FTP 服务器、HTTP/HTTPS 服务器、Amazon S3、Google Cloud Storage(从 Neo4j 5.25 开始)和 Azure Cloud Storage(从 Neo4j 5.25 开始)播种。
Amazon S3、Google Cloud Storage 和 Azure Cloud Storage 默认受支持,但其他提供程序需要配置 |
在发出CREATE DATABASE
命令时指定种子的 URI
CREATE DATABASE foo OPTIONS {existingData: 'use', seedURI:'s3://myBucket/myBackup.backup'}
仅在启动新数据库时才执行种子的下载和验证。如果失败,则数据库不可用,并且具有SHOW DATABASES
命令的statusMessage
:无法启动数据库
。
neo4j@neo4j> SHOW DATABASES;
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| name | type | aliases | access | address | role | writer | requestedStatus | currentStatus | statusMessage | default | home | constituents |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| "seed3" | "standard" | [] | "read-write" | "localhost:7682" | "unknown" | FALSE | "online" | "offline" | "Unable to start database `DatabaseId{3fe1a59b[seed3]}`" | FALSE | FALSE | [] |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
要确定问题的原因,建议查看debug.log
。
种子提供程序
URLConnectionSeedProvider
支持以下内容
-
文件
-
ftp
-
http
-
https
S3SeedProvider
支持
-
s3
Neo4j 5 带有 AWS S3 连接所需的必要库。因此,如果您使用 |
S3SeedProvider
需要额外的配置。这由seedConfig
选项指定。此选项期望一个逗号分隔的配置列表。每个配置值都指定为名称后跟=
和值,如下所示
CREATE DATABASE foo OPTIONS { existingData: 'use', seedURI: 's3:/myBucket/myBackup.backup', seedConfig: 'region=eu-west-1' }
S3SeedProvider
还需要传入凭据。这些通过seedCredentials
选项安全地从 Cypher 命令传递到托管数据库的每个服务器。为了使此功能正常工作,集群中每台服务器上的 Neo4j 必须配置相同的密钥库。这与远程别名所需的配置相同,请参阅远程数据库别名配置的 DBMS 配置。如果未执行此配置,则seedCredentials
选项将失败。
CREATE DATABASE foo OPTIONS { existingData: 'use', seedURI: 's3:/myBucket/myBackup.backup', seedConfig: 'region=eu-west-1', seedCredentials: [accessKey];[secretKey] }
其中accessKey
和secretKey
由 AWS 提供。
CloudSeedProvider
支持
-
s3
-
gs
-
azb
Neo4j 使用 AWS SDK v2 通过 AWS URL 调用 AWS 上的 API。或者,您可以覆盖端点,以便 AWS SDK 可以使用系统变量 |
-
按照 AWS 官方文档中的说明安装 AWS CLI——安装 AWS CLI 版本 2。
-
使用 AWS CLI 创建 S3 存储桶和用于存储备份文件的目录
aws s3 mb --region=us-east-1 s3://myBucket aws s3api put-object --bucket myBucket --key myDirectory/
有关如何创建存储桶和使用 AWS CLI 的更多信息,请参阅 AWS 官方文档——使用 AWS CLI 使用 Amazon S3和使用 AWS CLI 使用高级(s3)命令。
-
通过运行以下命令验证
~/.aws/config
文件是否正确cat ~/.aws/config
输出应如下所示
[default] region=us-east-1
-
通过在
~/.aws/credentials
文件中设置aws_access_key_id
和aws_secret_access_key
,并在必要时使用存储桶策略来配置对 AWS S3 存储桶的访问。例如-
使用
aws configure set aws_access_key_id aws_secret_access_key
命令设置来自 AWS 的 IAM 凭据,并验证~/.aws/credentials
是否正确cat ~/.aws/credentials
输出应如下所示
[default] aws_access_key_id=this.is.secret aws_secret_access_key=this.is.super.secret
-
此外,您可以使用基于资源的策略来授予对 S3 存储桶及其中的对象的访问权限。创建具有以下内容的策略文档并将其附加到存储桶。请注意,这两个资源条目对于能够下载和上传文件都很重要。
{ "Version": "2012-10-17", "Id": "Neo4jBackupAggregatePolicy", "Statement": [ { "Sid": "Neo4jBackupAggregateStatement", "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:GetObject", "s3:PutObject", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::myBucket/*", "arn:aws:s3:::myBucket" ] } ] }
-
-
从
myBackup.backup
创建数据库。CREATE DATABASE foo OPTIONS { existingData: 'use', seedURI: 's3:/myBucket/myBackup.backup' }
-
确保您拥有 Google 帐户和在 Google Cloud Platform (GCP) 中创建的项目。
-
按照 Google 官方文档中的说明安装
gcloud
CLI——安装 gcloud CLI。 -
使用 Google 官方文档创建服务帐户和服务帐户密钥——创建服务帐户和创建和管理服务帐户密钥。
-
下载服务帐户的 JSON 密钥文件。
-
分别将
GOOGLE_APPLICATION_CREDENTIALS
和GOOGLE_CLOUD_PROJECT
环境变量设置为 JSON 密钥文件的路径和项目 IDexport GOOGLE_APPLICATION_CREDENTIALS="/path/to/keyfile.json" export GOOGLE_CLOUD_PROJECT=YOUR_PROJECT_ID
-
使用您创建的服务帐户的电子邮件地址、JSON 密钥文件的路径和项目 ID 对
gcloud
CLI 进行身份验证gcloud auth activate-service-account service-account@example.com --key-file=$GOOGLE_APPLICATION_CREDENTIALS --project=$GOOGLE_CLOUD_PROJECT
有关更多信息,请参阅 Google 官方文档——gcloud auth activate-service-account。
-
使用 Google 官方文档在 Google Cloud Storage 中创建存储桶——创建存储桶。
-
通过运行以下命令验证存储桶是否已创建
gcloud storage ls
输出应列出创建的存储桶。
-
-
从
myBackup.backup
创建数据库。CREATE DATABASE foo OPTIONS { existingData: 'use', seedURI: 'gs:/myBucket/myBackup.backup' }
-
确保您拥有 Azure 帐户、Azure 存储帐户和 Blob 容器。
-
您可以使用 Azure 门户创建存储帐户。
有关更多信息,请参阅 Azure 官方文档上的创建存储帐户。 -
在 Azure 门户中创建 Blob 容器。
更多信息,请参阅 Azure 官方文档:快速入门:使用 Azure 门户上传、下载和列出 Blob。
-
-
按照 Azure 官方文档中的说明安装 Azure CLI:Azure 官方文档。
-
使用默认 Azure 凭据对 neo4j 或 neo4j-admin 进程进行 Azure 身份验证。
更多信息,请参阅 Azure 官方文档:默认 Azure 凭据。az login
然后您应该就可以在 neo4j 或 neo4j-admin 中使用 Azure URL 了。
-
要验证您是否可以使用登录凭据访问容器,请运行以下命令
# Upload a file: az storage blob upload --file someLocalFile --account-name accountName - --container someContainer --name remoteFileName --auth-mode login # Download the file az storage blob download --account-name accountName --container someContainer --name remoteFileName --file downloadedFile --auth-mode login # List container files az storage blob list --account-name someContainer --container someContainer --auth-mode login
-
从
myBackup.backup
创建数据库。CREATE DATABASE foo OPTIONS { existingData: 'use', seedURI: 'azb://myStorageAccount/myContainer/myBackup.backup' }
例如,在 S3SeedProvider
(默认提供程序)的情况下,seedCredentials: [accessKey];[secretKey]
,其中 accessKey
和 secretKey
由 AWS 提供。
种子提供程序参考
URL 方案 | 种子提供程序 | URI 示例 |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
控制允许/拒绝数据库的位置
默认情况下,数据库可以分配到集群中的任何服务器上运行。但是,可以限制特定数据库托管的服务器。这通过 ENABLE SERVER
和 ALTER SERVER
完成,如 管理集群中的服务器 中所述。以下选项可用
-
allowedDatabases
- 允许在服务器上托管的一组数据库。 -
deniedDatabases
- 禁止在服务器上托管的一组数据库。允许和禁止是互斥的。 -
modeConstraint
- 控制数据库可以在服务器上以何种模式(主、辅或无)托管。如果未设置,则服务器上没有模式约束。
更改默认数据库
您可以使用过程 dbms.setDefaultDatabase("newDefaultDatabaseName")
更改 DBMS 的默认数据库。
-
确保要设置为默认的数据库存在,否则使用命令
CREATE DATABASE <database-name>
创建它。 -
使用命令
SHOW DEFAULT DATABASE
显示当前默认数据库的名称和状态。 -
使用命令
STOP DATABASE <database-name>
停止当前默认数据库。 -
对
system
数据库运行CALL dbms.setDefaultDatabase("newDefaultDatabaseName")
以设置新的默认数据库。 -
可选地,您可以使用
START DATABASE <database-name>
启动之前的默认数据库作为非默认数据库。
请注意,自动创建的初始默认数据库可能具有与默认配置值不同的拓扑结构。更多信息,请参阅 集群中的默认数据库。 |