From 25e442736dff54f92d0bc54771ad01727afebdbc Mon Sep 17 00:00:00 2001 From: Natalia Ivakina <82437520+NataliaIvakina@users.noreply.github.com> Date: Wed, 2 Jul 2025 14:10:38 +0200 Subject: [PATCH 01/39] Update to 2025.07 (#2464) --- antora.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/antora.yml b/antora.yml index 83cc570bd..40bcfe6fa 100644 --- a/antora.yml +++ b/antora.yml @@ -1,14 +1,14 @@ name: operations-manual title: Operations Manual -version: '2025.06' +version: '2025.07' current: true start_page: ROOT:index.adoc nav: - modules/ROOT/content-nav.adoc asciidoc: attributes: - neo4j-version: '2025.06' - neo4j-version-minor: '2025.06' - neo4j-version-exact: '2025.06.0' - neo4j-buildnumber: '2025.06' - neo4j-debian-package-version: '1:2025.06.0@' + neo4j-version: '2025.07' + neo4j-version-minor: '2025.07' + neo4j-version-exact: '2025.07.0' + neo4j-buildnumber: '2025.07' + neo4j-debian-package-version: '1:2025.07.0@' From e507b34876a9cbbb2ad2894c33596f9b3599576a Mon Sep 17 00:00:00 2001 From: Ragnar Wernersson Date: Thu, 3 Jul 2025 17:33:39 +0200 Subject: [PATCH 02/39] Add new metric message_processing_timer (#2437) Co-authored-by: Natalia Ivakina <82437520+NataliaIvakina@users.noreply.github.com> --- modules/ROOT/pages/monitoring/metrics/reference.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/ROOT/pages/monitoring/metrics/reference.adoc b/modules/ROOT/pages/monitoring/metrics/reference.adoc index 12e003d8a..80d5ad3c9 100644 --- a/modules/ROOT/pages/monitoring/metrics/reference.adoc +++ b/modules/ROOT/pages/monitoring/metrics/reference.adoc @@ -464,6 +464,7 @@ This is not an indication of an error of any kind. |.cluster.raft.raft_log_entry_prefetch_buffer.sync_put|Raft Log Entry Prefetch buffer sync puts. (gauge) |.cluster.raft.message_processing_delay|Delay between receiving a Raft message and starting its processing. (gauge) +|.cluster.raft.message_processing_delay_timer|label:new[Introduced in 2025.07] Metrics Timer for Raft message processing delays. The Timer provides different types of statistics, for example, `min`, `max`, `p999`, and `mean_rate`. (counter, histogram) |.cluster.raft.message_processing_timer|Metrics Timer for Raft message processing, independent of the message type. The Timer provides different types of statistics, for example, `min`, `max`, `p999`, and `mean_rate`. (counter, histogram) |.cluster.raft.replication_new|The total number of Raft replication requests. It increases with write transactions (possibly internal) activity. (counter) |.cluster.raft.replication_attempt|The total number of Raft replication requests attempts. It is bigger or equal to the replication requests. (counter) From 78224e0fc55a8924f6c22749901d3ea71e9f9b47 Mon Sep 17 00:00:00 2001 From: Natalia Ivakina <82437520+NataliaIvakina@users.noreply.github.com> Date: Thu, 3 Jul 2025 18:26:01 +0200 Subject: [PATCH 03/39] Update configuration settings for 2025.07 (#2460) Partly based on https://github.com/neo-technology/neo4j/pull/31487 --- .../configuration/configuration-settings.adoc | 18 +++++++++++++++++- .../pages/configuration/dynamic-settings.adoc | 1 + 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/modules/ROOT/pages/configuration/configuration-settings.adoc b/modules/ROOT/pages/configuration/configuration-settings.adoc index 760651b71..035d5254b 100644 --- a/modules/ROOT/pages/configuration/configuration-settings.adoc +++ b/modules/ROOT/pages/configuration/configuration-settings.adoc @@ -184,6 +184,22 @@ a|An integer. m|+++600+++ |=== + +[role=label--new-2025.07 label--dynamic] +[[config_db.checkpoint.throughput.limit]] +=== `db.checkpoint.throughput.limit` + +.db.checkpoint.throughput.limit +[frame="topbot", stripes=odd, grid="cols", cols="<1s,<4"] +|=== +|Description +a|Limit the write throughput per second of the background checkpoint process. This setting is advisory. It is ignored in Neo4j Community Edition and is followed to best effort in Enterprise Edition. Limiting the write IO in this way leaves more bandwidth in the IO subsystem to service random-read IOs, which is important for the response time of queries when the database cannot fit entirely in memory. The only drawback of this setting is that longer checkpoint times may lead to slightly longer recovery times in case of a database or system crash. A lower number means lower IO pressure and, consequently, longer checkpoint times. Set this to null to disable the throughput limit and fallback to IOPS limit. +|Valid values +a|A byte size (valid multipliers are B, KiB, KB, K, kB, kb, k, MiB, MB, M, mB, mb, m, GiB, GB, G, gB, gb, g, TiB, TB, PiB, PB, EiB, EB) that is minimum 8.00KiB. +|Default value +m|++++++ +|=== + == Cloud storage integration settings Cloud integration settings allow you to specify custom Azure blob storage endpoints and host authorities, set the project ID for Google Cloud Storage buckets, and define the desired throughput for transfer operations in Amazon S3. @@ -1825,7 +1841,7 @@ For more information, see xref:/performance/statistics-execution-plans.adoc[Stat |Description a|The default language of a database determines which language is used to evaluate queries that do not explicitly select a language. This setting determines the default language used for new (and initial) databases where not specified as part of `CREATE` or `ALTER` database. |Valid values -a|One of [CYPHER_5, CYPHER_25] that the [] values acceptance depend on 'internal.dbms.cypher.enable_experimental_versions'. +a|One of [CYPHER_5, CYPHER_25]. label:changed[Changed in 2025.07] |Default value m|+++CYPHER_5+++ |=== diff --git a/modules/ROOT/pages/configuration/dynamic-settings.adoc b/modules/ROOT/pages/configuration/dynamic-settings.adoc index 5404ed39e..5828f1bcb 100644 --- a/modules/ROOT/pages/configuration/dynamic-settings.adoc +++ b/modules/ROOT/pages/configuration/dynamic-settings.adoc @@ -36,6 +36,7 @@ RETURN name | name | +----------------------------------------------------------------+ | "db.checkpoint.iops.limit" | +| "db.checkpoint.throughput.limit" | | "db.format" | | "db.lock.acquisition.timeout" | | "db.logs.query.annotation_data_format" | From e8522d520565934a3ae9147f8abc2752260354cd Mon Sep 17 00:00:00 2001 From: Reneta Popova Date: Fri, 4 Jul 2025 09:19:18 +0100 Subject: [PATCH 04/39] fix a few broken links (#2466) --- modules/ROOT/pages/installation/linux/tarball.adoc | 2 +- modules/ROOT/pages/installation/neo4j-desktop.adoc | 2 +- modules/ROOT/pages/introduction.adoc | 2 +- modules/ROOT/pages/kubernetes/plugins.adoc | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/ROOT/pages/installation/linux/tarball.adoc b/modules/ROOT/pages/installation/linux/tarball.adoc index ac3bbc84d..1eba07701 100644 --- a/modules/ROOT/pages/installation/linux/tarball.adoc +++ b/modules/ROOT/pages/installation/linux/tarball.adoc @@ -8,7 +8,7 @@ Before you install Neo4j on Linux from a tarball and run it as a console applica == Install Neo4j from a tarball . If it is not already installed, get link:https://openjdk.org/[OpenJDK 21] or link:https://www.oracle.com/java/technologies/downloads/?er=221886[Oracle Java 21]. -. Download the latest Neo4j tarball from link:link:{neo4j-download-center-uri}/?gdb-selfmanaged[Neo4j Deployment Center] and unpack it: +. Download the latest Neo4j tarball from link:{neo4j-download-center-uri}/?gdb-selfmanaged[Neo4j Deployment Center] and unpack it: + [source, shell, subs="attributes"] ---- diff --git a/modules/ROOT/pages/installation/neo4j-desktop.adoc b/modules/ROOT/pages/installation/neo4j-desktop.adoc index 2710103a8..a19418213 100644 --- a/modules/ROOT/pages/installation/neo4j-desktop.adoc +++ b/modules/ROOT/pages/installation/neo4j-desktop.adoc @@ -9,7 +9,7 @@ Neo4j Desktop is a convenient way for developers to work with local Neo4j databa Neo4j Desktop is not suited for production environments. ==== -To install Neo4j Desktop, go to link:link:{neo4j-download-center-uri}[Neo4j Deployment Center] and follow the instructions. +To install Neo4j Desktop, go to link:{neo4j-download-center-uri}[Neo4j Deployment Center] and follow the instructions. [TIP] ==== diff --git a/modules/ROOT/pages/introduction.adoc b/modules/ROOT/pages/introduction.adoc index ec2d775b3..208781bdc 100644 --- a/modules/ROOT/pages/introduction.adoc +++ b/modules/ROOT/pages/introduction.adoc @@ -279,7 +279,7 @@ a| APOC 450+ link:https://neo4j.com/docs/apoc/5/[Core Procedures and Functions] ==== By default, Neo4j Community Edition and Neo4j Enterprise Edition report a small amount of usage data. This helps Neo4j understand how its products are used and improve them. -For more information about what data is collected, see link:https://neo4j.com/docs/reference/usage-data/[Usage data report]. +For more information about what data is collected, see link:https://neo4j.com/docs/usage-data/[Usage data report]. ==== [[versioning]] diff --git a/modules/ROOT/pages/kubernetes/plugins.adoc b/modules/ROOT/pages/kubernetes/plugins.adoc index cd042f1fd..f47cd2e54 100644 --- a/modules/ROOT/pages/kubernetes/plugins.adoc +++ b/modules/ROOT/pages/kubernetes/plugins.adoc @@ -85,7 +85,7 @@ This way, you can ensure when building the container that the correct plugin ver [NOTE] ==== -link:link:{neo4j-download-center-uri}?bloom[The Neo4j Bloom] plugin requires a license activation key, which needs to be placed in a directory accessible by the Neo4j Docker container, for example, mounted to _/licenses_ (default). +link:{neo4j-download-center-uri}?bloom[The Neo4j Bloom] plugin requires a license activation key, which needs to be placed in a directory accessible by the Neo4j Docker container, for example, mounted to _/licenses_ (default). To obtain a valid license, reach out to your Neo4j account representative or use the form https://neo4j.com/contact-us/[Contact Neo4j]. ==== From 9a20db85f2cd0de0eac65d152e7cb275091a264d Mon Sep 17 00:00:00 2001 From: Satia Herfert Date: Wed, 9 Jul 2025 11:15:54 +0200 Subject: [PATCH 05/39] Allow multiple :START_ID/:END_ID columns in CSV input for importer (#2420) See https://github.com/neo-technology/neo4j/pull/31617 --- modules/ROOT/pages/import.adoc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/modules/ROOT/pages/import.adoc b/modules/ROOT/pages/import.adoc index ca23af6cd..303d2df84 100644 --- a/modules/ROOT/pages/import.adoc +++ b/modules/ROOT/pages/import.adoc @@ -1462,8 +1462,9 @@ Now use the previously defined ID spaces when connecting the actors to movies. [[import-tool-multiple-ids]] == Using multiple node IDs -A node header can also contain multiple `ID` columns, where the relationship data references the composite value of all those columns. -This also implies using `string` as `id-type`. +A node header can contain multiple `ID` columns. +The relationship data must then use a matching number of `START_ID` / `END_ID` columns as references to the composite value of those ID columns. +This implies using `string` as `id-type`. For each `ID` column, you can specify to store its values as different node properties. However, the composite value cannot be stored as a node property. @@ -1498,13 +1499,13 @@ Now use both IDs when defining the relationship: .relationships_header.csv [source, csv] ---- -:START_ID,:TYPE,:END_ID +:START_ID,:START_ID,:TYPE,:END_ID,:END_ID ---- .relationships.csv [source, csv] ---- -aa11,WORKS_WITH,bb22 +aa,11,WORKS_WITH,bb,22 ---- ==== @@ -1532,13 +1533,13 @@ Now use the defined ID space when connecting John with Paul, and use both IDs in .relationships_header.csv [source, csv] ---- -:START_ID(MyGroup),:TYPE,:END_ID(MyGroup) +:START_ID(MyGroup),:START_ID(MyGroup),:TYPE,:END_ID(MyGroup),:END_ID(MyGroup) ---- .relationships.csv [source, csv] ---- -aa11,WORKS_WITH,bb22 +aa,11,WORKS_WITH,bb,22 ---- ==== From c392de52fe51907ecea0806e947f16ccaf920e79 Mon Sep 17 00:00:00 2001 From: Reneta Popova Date: Wed, 9 Jul 2025 12:13:15 +0100 Subject: [PATCH 06/39] update the checkpoint messages (#2468) --- .../ROOT/pages/database-internals/checkpointing.adoc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/ROOT/pages/database-internals/checkpointing.adoc b/modules/ROOT/pages/database-internals/checkpointing.adoc index 0d22fbde4..000406e0c 100644 --- a/modules/ROOT/pages/database-internals/checkpointing.adoc +++ b/modules/ROOT/pages/database-internals/checkpointing.adoc @@ -115,42 +115,42 @@ The following details the expected messages to appear in the _logs\debug.log_ up + .... 2023-05-28 12:55:05.174+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Scheduled checkpoint for time threshold" @ txId: 49 checkpoint started... -2023-05-28 12:55:05.253+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Scheduled checkpoint for time threshold" @ txId: 49 checkpoint completed in 79ms +2023-05-28 12:55:05.253+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Scheduled checkpoint for time threshold" @ txId: 49 checkpoint completed in 79ms. Checkpoint flushed 74 pages (7% of total available pages), in 58 IOs. Checkpoint performed with IO limit: 789 IOPS, paused in total 0 times(0 millis). Average checkpoint flush speed: 592.0KiB/s. .... * Checkpoint based upon `db.checkpoint.interval.tx`: + .... 2023-05-28 13:08:51.603+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Scheduled checkpoint for tx count threshold" @ txId: 118 checkpoint started... -2023-05-28 13:08:51.669+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Scheduled checkpoint for tx count threshold" @ txId: 118 checkpoint completed in 66ms +2023-05-28 13:08:51.669+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Scheduled checkpoint for tx count threshold" @ txId: 118 checkpoint completed in 66ms. Checkpoint flushed 74 pages (7% of total available pages), in 58 IOs. Checkpoint performed with IO limit: 789 IOPS, paused in total 0 times(0 millis). Average checkpoint flush speed: 592.0KiB/s. .... * Checkpoint when `db.checkpoint=continuous`: + .... 2023-05-28 13:17:21.927+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Scheduled checkpoint for continuous threshold" @ txId: 171 checkpoint started... -2023-05-28 13:17:21.941+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Scheduled checkpoint for continuous threshold" @ txId: 171 checkpoint completed in 13ms +2023-05-28 13:17:21.941+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Scheduled checkpoint for continuous threshold" @ txId: 171 checkpoint completed in 13ms. Checkpoint flushed 74 pages (7% of total available pages), in 58 IOs. Checkpoint performed with IO limit: 789 IOPS, paused in total 0 times(0 millis). Average checkpoint flush speed: 592.0KiB/s. .... * Checkpoint as a result of database shutdown: + .... 2023-05-28 12:35:56.272+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Database shutdown" @ txId: 47 checkpoint started... -2023-05-28 12:35:56.306+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Database shutdown" @ txId: 47 checkpoint completed in 34ms +2023-05-28 12:35:56.306+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Database shutdown" @ txId: 47 checkpoint completed in 34ms. Checkpoint flushed 74 pages (7% of total available pages), in 58 IOs. Checkpoint performed with IO limit: 789 IOPS, paused in total 0 times(0 millis). Average checkpoint flush speed: 592.0KiB/s. .... * Checkpoint as a result of `CALL db.checkpoint()`: + .... 2023-05-28 12:31:56.463+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Call to db.checkpoint() procedure" @ txId: 47 checkpoint started... -2023-05-28 12:31:56.490+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Call to db.checkpoint() procedure" @ txId: 47 checkpoint completed in 27ms +2023-05-28 12:31:56.490+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Call to db.checkpoint() procedure" @ txId: 47 checkpoint completed in 27ms. Checkpoint flushed 74 pages (7% of total available pages), in 58 IOs. Checkpoint performed with IO limit: 789 IOPS, paused in total 0 times(0 millis). Average checkpoint flush speed: 592.0KiB/s. .... * Checkpoint as a result of a backup run: + .... 2023-05-28 12:33:30.489+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Full backup" @ txId: 47 checkpoint started... -2023-05-28 12:33:30.509+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Full backup" @ txId: 47 checkpoint completed in 20ms +2023-05-28 12:33:30.509+0000 INFO [o.n.k.i.t.l.c.CheckPointerImpl] Checkpoint triggered by "Full backup" @ txId: 47 checkpoint completed in 20ms. Checkpoint flushed 74 pages (7% of total available pages), in 58 IOs. Checkpoint performed with IO limit: 789 IOPS, paused in total 0 times(0 millis). Average checkpoint flush speed: 592.0KiB/s. .... https://neo4j.com/docs/operations-manual/current/monitoring/metrics/reference/#metrics-general-purpose[Checkpoint Metrics] are also available and are detailed in the following files, in the _metrics/_ directory: From fa28fdd6252c71a8e36e6eee997d88a49605c512 Mon Sep 17 00:00:00 2001 From: Reneta Popova Date: Wed, 9 Jul 2025 15:10:22 +0100 Subject: [PATCH 07/39] Improve enabling command expansion section (#2470) --- .../configuration/command-expansion.adoc | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/modules/ROOT/pages/configuration/command-expansion.adoc b/modules/ROOT/pages/configuration/command-expansion.adoc index 5687233ca..7e0628234 100644 --- a/modules/ROOT/pages/configuration/command-expansion.adoc +++ b/modules/ROOT/pages/configuration/command-expansion.adoc @@ -41,14 +41,31 @@ Scripts and their syntax differ between operating systems. == Enabling -The Neo4j startup script and the `neo4j` service can expand and execute the external commands by using the argument `--expand-commands`. +To enable command expansion, you must add the `--expand-commands` argument to the Neo4j startup script or _neo4j.service_ file. + +=== Starting Neo4j with command expansion + +To start Neo4j with command expansion enabled, you can use the following command: [source, shell] ---- bin/neo4j start --expand-commands ---- -If the startup script does not receive the `--expand-commands` argument, commands in the configuration file are treated as invalid settings. +=== Enabling command expansion in Neo4j as a service + +If you are using Neo4j as a service, you can enable command expansion by adding the `--expand-commands` argument to the _/etc/systemd/system/neo4j.service_  file. +Otherwise, the commands in the configuration file are treated as invalid settings. + +You must also add `Type=forking` under the `[Service]` section of _/etc/systemd/system/neo4j.service_ to allow for the command expansion. + +[source] +---- +[Service] +Type=forking +---- + +=== Security checks Neo4j performs the following basic security checks on the _neo4j.conf_ file. If they fail, Neo4j does not evaluate the script commands in _neo4j.conf_, and the Neo4j process does not start. From bc22295eca3b4c2a83c77603c9eb8d1c9543fd5c Mon Sep 17 00:00:00 2001 From: Reneta Popova Date: Fri, 11 Jul 2025 15:52:00 +0100 Subject: [PATCH 08/39] Update the Set up the repository for Linux rpm (#2475) --- .../ROOT/pages/installation/linux/rpm.adoc | 53 +++++++++++-------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/modules/ROOT/pages/installation/linux/rpm.adoc b/modules/ROOT/pages/installation/linux/rpm.adoc index 4ed932336..4846cb94f 100644 --- a/modules/ROOT/pages/installation/linux/rpm.adoc +++ b/modules/ROOT/pages/installation/linux/rpm.adoc @@ -31,18 +31,20 @@ Installation instructions can be found on the manufacturer's website: [[linux-rpm-install-standard]] === Set up the repository -To add the Neo4j repository to the package manager, run the following command as a sudo user: - -[source, shell, subs="attributes"] +. Import the Neo4j GPG public key into the system’s RPM keyring. +The key is required to verify the authenticity of the Neo4j packages you will install. ++ +[source, bash] ---- rpm --import https://debian.neo4j.com/neotechnology.gpg.key ---- -Create a `neo4j.repo` file: - -[source, shell, subs="attributes"] +. Create a `neo4j.repo` file in the `/etc/yum.repos.d/` directory. +This file contains the repository configuration for Neo4j. ++ +[source, bash] ---- -cat << EOF > /etc/yum.repos.d/neo4j.repo +cat < /etc/yum.repos.d/neo4j.repo [neo4j] name=Neo4j RPM Repository baseurl=https://yum.neo4j.com/stable/latest @@ -50,7 +52,7 @@ enabled=1 gpgcheck=1 EOF ---- - ++ [NOTE] ==== If you are upgrading from Neo4j 5.x or earlier, you may need to clear the package manager cache before Neo4j packages become available: @@ -58,13 +60,20 @@ If you are upgrading from Neo4j 5.x or earlier, you may need to clear the packag `yum clean dbcache` ==== +. Verify that the Neo4j repository is set up correctly by listing the available Neo4j packages versions: ++ +[source, bash] +---- +yum list neo4j --showduplicates +---- + === Install Neo4j Install Neo4j as `root` using the following commands depending on which edition you are using: * Community Edition + -[source, shell, subs="attributes"] +[source, bash, subs="attributes"] ---- yum install neo4j-{neo4j-version-exact} ---- @@ -75,7 +84,7 @@ Accept either the commercial or the evaluation license agreement before running The following are examples of using an interactive prompt and a non-interactive installation: + .Interactive installation of Enterprise Edition under the commercial license -[source, shell, subs="attributes"] +[source, bash, subs="attributes"] ---- yum install neo4j-enterprise-{neo4j-version-exact} ---- @@ -86,7 +95,7 @@ This should be done in the same line as the package is installed, to ensure bash As in the following example: + .Non-interactive installation of Enterprise Edition under the commercial license -[source, shell, subs="attributes"] +[source, bash, subs="attributes"] ---- NEO4J_ACCEPT_LICENSE_AGREEMENT=yes yum install neo4j-enterprise-{neo4j-version-exact} ---- @@ -98,7 +107,7 @@ For SUSE-based distributions, the steps are as follows: . Use the following as `root` to add the repository: + -[source, shell, subs="attributes"] +[source, bash, subs="attributes"] ---- zypper addrepo --refresh https://yum.neo4j.com/stable/latest neo4j-repository ---- @@ -107,7 +116,7 @@ zypper addrepo --refresh https://yum.neo4j.com/stable/latest neo4j-repository + * Community Edition + -[source, shell, subs="attributes"] +[source, bash, subs="attributes"] ---- zypper install neo4j-{neo4j-version-exact} ---- @@ -118,7 +127,7 @@ Accept either the commercial or the evaluation license agreement before running The following are examples of using an interactive prompt and a non-interactive installation: + .Interactive installation of Enterprise Edition under the commercial license -[source, shell, subs="attributes"] +[source, bash, subs="attributes"] ---- zypper install neo4j-enterprise-{neo4j-version-exact} ---- @@ -127,7 +136,7 @@ You have to choose either a link:https://legal.neo4j.com/[commercial license] or For a non-interactive installation, you can set the `NEO4J_ACCEPT_LICENSE_AGREEMENT` to `yes` (for the commercial license) or `eval` (for the evaluation license) as in the following example: + .Non-interactive installation of Enterprise Edition under the commercial license -[source, shell, subs="attributes"] +[source, bash, subs="attributes"] ---- NEO4J_ACCEPT_LICENSE_AGREEMENT=yes zypper install neo4j-enterprise-{neo4j-version-exact} ---- @@ -176,7 +185,7 @@ This must be one single command, and Neo4j Cypher Shell must be the first packag + * Community Edition + -[source, shell, subs="attributes"] +[source, bash, subs="attributes"] ---- rpm --install cypher-shell-{neo4j-version-exact}-1.noarch.rpm neo4j-{neo4j-version-exact}-1.noarch.rpm ---- @@ -186,14 +195,14 @@ rpm --install cypher-shell-{neo4j-version-exact}-1.noarch.rpm neo4j-{neo4j-versi Accept either the commercial or the evaluation license agreement before running the Neo4j Enterprise Edition. The following example uses an interactive prompt: + -[source, shell, subs="attributes"] +[source, bash, subs="attributes"] ---- rpm --install cypher-shell-{neo4j-version-exact}-1.noarch.rpm neo4j-enterprise-{neo4j-version-exact}-1.noarch.rpm ---- You have to choose either a link:https://legal.neo4j.com/[commercial license] or an link:https://neo4j.com/terms/enterprise_us/[evaluation license] before the interactive installation is allowed to complete. For a non-interactive installation, you can set the `NEO4J_ACCEPT_LICENSE_AGREEMENT` to `yes` (for the commercial license) or `eval` (for the evaluation license) as in the following example: + -[source, shell, subs="attributes"] +[source, bash, subs="attributes"] ---- NEO4J_ACCEPT_LICENSE_AGREEMENT=yes rpm --install cypher-shell-{neo4j-version-exact}-1.noarch.rpm neo4j-enterprise-{neo4j-version-exact}-1.noarch.rpm ---- @@ -203,7 +212,7 @@ NEO4J_ACCEPT_LICENSE_AGREEMENT=yes rpm --install cypher-shell-{neo4j-version-exa To enable Neo4j to start automatically on system boot, run the following command: -[source, shell] +[source, bash] ---- systemctl enable neo4j ---- @@ -227,7 +236,7 @@ Follow these steps to uninstall Neo4j: . (Optional) Create a xref:/backup-restore/index.adoc[backup] to avoid losing your data. . Uninstall Neo4j: + -[source, shell] ---- +[source, bash] +---- sudo yum remove neo4j ---- \ No newline at end of file +---- \ No newline at end of file From 4ee8e93becd4c95bd640d3b57fcd9078e27521b4 Mon Sep 17 00:00:00 2001 From: Lidia Zuin <102308961+lidiazuin@users.noreply.github.com> Date: Mon, 14 Jul 2025 15:18:16 +0200 Subject: [PATCH 09/39] Remove Nodes 25 banner --- publish.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/publish.yml b/publish.yml index 0b0e8836e..efb53ef2b 100644 --- a/publish.yml +++ b/publish.yml @@ -56,13 +56,3 @@ asciidoc: neo4j-base-uri: '' neo4j-docs-base-uri: /docs neo4j-download-center-uri: https://neo4j.com/deployment-center - # NODES 2025 CFP - page-ad-overline-link: https://neo4j.com/nodes-2025/ - page-ad-overline: '' - page-ad-image: '{neo4j-docs-base-uri}/assets/img/nodes-25.png' - page-ad-icon: '' - page-ad-title: Nov 6 2025 - page-ad-description: The Call for Papers is now open and we want to hear about your graph-related projects. Submit your talks by June 15 - page-ad-link: https://neo4j.com/nodes-2025/ - page-ad-underline-role: button - page-ad-underline: Submit your talk \ No newline at end of file From 89f9076d6cef42a76648884594bf329381801d4e Mon Sep 17 00:00:00 2001 From: Reneta Popova Date: Tue, 15 Jul 2025 10:42:11 +0100 Subject: [PATCH 10/39] Remove --show-metadata from neo4j-admin backup inspect (#2480) I have removed the `--show-metadata `from the usage and options sections following a failing doc's test and added a few notes on this page explaining the reason. It doesn't look great (I mean to have 6 notes saying the same), because this option is still valid for users on versions before 2025.07 and is also deprecated and not removed. I see no other way to document this right now unless we also change the code and make the option visible again. --- .../ROOT/pages/backup-restore/inspect.adoc | 54 ++++++++++++++----- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/modules/ROOT/pages/backup-restore/inspect.adoc b/modules/ROOT/pages/backup-restore/inspect.adoc index 6e2998a69..59450dd17 100644 --- a/modules/ROOT/pages/backup-restore/inspect.adoc +++ b/modules/ROOT/pages/backup-restore/inspect.adoc @@ -29,12 +29,17 @@ The metadata contains the following information: [source,role=noheader] ---- -neo4j-admin backup inspect [-h] [--empty] [--expand-commands] [--latest-backup] - [--latest-chain] [--show-metadata] [--verbose] - [--additional-config=] [--database=] - [--format=] +neo4j-admin backup inspect [-h] [--empty] [--expand-commands] [--latest-backup] [--latest-chain] + [--verbose] [--additional-config=] [--database=] [--format=] + ---- +[NOTE] +==== +Starting with Neo4j 2025.07, the backup metadata is always shown by default when using the `neo4j-admin backup inspect` command. +If you are on a previous version of Neo4j, you must specify the `--show-metadata` option to see the backup metadata. +==== + === Description Command to read the backup metadata. @@ -87,10 +92,6 @@ The `` parameter can also inspect backups stored in AWS S3 buckets, | List the full backup chain ending with the latest downloaded backup. | false -| --show-metadata -| Show the backup metadata. -| false - | --database= | Name of the database to inspect. | @@ -113,6 +114,12 @@ The `` parameter can also inspect backups stored in AWS S3 buckets, The `--latest-backup` and `--latest-chain` options cannot be used together. ==== +[NOTE] +==== +Starting with Neo4j 2025.07, the `--show-metadata` option is deprecated and ignored. +The backup metadata is always shown by default when using the `neo4j-admin backup inspect` command. +However, if you are on a previous version of Neo4j, you must specify the `--show-metadata` option to see the backup metadata. +==== [[aggregate-backup-example]] == Examples @@ -140,7 +147,7 @@ The following command lists the backup files' names along with their respective [source,shell] ---- -bin/neo4j-admin backup inspect /backups --show-metadata --empty +bin/neo4j-admin backup inspect /backups --empty ---- The `--empty` option is used to include the empty backups. @@ -163,13 +170,19 @@ Empty backups are used to record the backup history. | file:///backups/london-2024-10-07T16-03-51.backup | london | d4dae73c-dfef-4d28-88cd-fe6cc88ddca1 | 2024-10-07T16:03:51 | true | true | 1 | 5 | true | ---- +[NOTE] +==== +Starting with Neo4j 2025.07, the backup metadata is always shown by default when using the `neo4j-admin backup inspect` command. +If you are on a previous version of Neo4j, you must specify the `--show-metadata` option to see the backup metadata. +==== + === Listing the latest backups To list only the most recent backups performed for each database, use the `--latest-backup` option. [source,shell] ---- -bin/neo4j-admin backup inspect /backups --show-metadata --latest-backup +bin/neo4j-admin backup inspect /backups --latest-backup ---- .Example output @@ -181,6 +194,12 @@ bin/neo4j-admin backup inspect /backups --show-metadata --latest-backup | file:///backups/london-2024-10-07T16-04-05.backup | london | d4dae73c-dfef-4d28-88cd-fe6cc88ddca1 | 2024-10-07T16:04:05 | false | true | 6 | 6 | false | ---- +[NOTE] +==== +Starting with Neo4j 2025.07, the backup metadata is always shown by default when using the `neo4j-admin backup inspect` command. +If you are on a previous version of Neo4j, you must specify the `--show-metadata` option to see the backup metadata. +==== + === Inspecting backup chains A backup chain corresponds to a sequence of one or more backup(s) logically connected by their transaction IDs. @@ -188,7 +207,7 @@ To inspect the backup chains of a given database, use the `--latest-chain` optio [source,shell] ---- -bin/neo4j-admin backup inspect /backups --show-metadata --latest-chain --database=london +bin/neo4j-admin backup inspect /backups --latest-chain --database=london ---- .Example output @@ -206,6 +225,11 @@ The result returns a chain of size two: Those modifications are materialised by a sequence of transactions to apply. Its range is [6,6]. +[NOTE] +==== +Starting with Neo4j 2025.07, the backup metadata is always shown by default when using the `neo4j-admin backup inspect` command. +If you are on a previous version of Neo4j, you must specify the `--show-metadata` option to see the backup metadata. +==== === Inspecting a backup chain ending with a specific backup @@ -213,7 +237,7 @@ To inspect a backup chain ending with a specific backup, use the `--latest-chain [source,shell] ---- -bin/neo4j-admin backup inspect /backups/london-2024-10-07T16-04-05.backup --show-metadata --latest-chain +bin/neo4j-admin backup inspect /backups/london-2024-10-07T16-04-05.backup --latest-chain ---- .Example output @@ -229,6 +253,12 @@ bin/neo4j-admin backup inspect /backups/london-2024-10-07T16-04-05.backup --sho In this case, the `--database` option is unnecessary because the database identifier is part of the metadata stored in the header of the backup file _london-2024-10-07T16-04-05.backup_. ==== +[NOTE] +==== +Starting with Neo4j 2025.07, the backup metadata is always shown by default when using the `neo4j-admin backup inspect` command. +If you are on a previous version of Neo4j, you must specify the `--show-metadata` option to see the backup metadata. +==== + From db79312125c4237b51f910efc6913b216b71d948 Mon Sep 17 00:00:00 2001 From: Reneta Popova Date: Tue, 15 Jul 2025 10:42:51 +0100 Subject: [PATCH 11/39] Fix the helm install backup-name neo4j/neo4j-admin command (#2469) --- modules/ROOT/pages/kubernetes/operations/backup-restore.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/ROOT/pages/kubernetes/operations/backup-restore.adoc b/modules/ROOT/pages/kubernetes/operations/backup-restore.adoc index 154d6d207..647799c1c 100644 --- a/modules/ROOT/pages/kubernetes/operations/backup-restore.adoc +++ b/modules/ROOT/pages/kubernetes/operations/backup-restore.adoc @@ -675,7 +675,7 @@ To back up your database(s), you install the _neo4j-admin_ Helm chart using the + [source, shell, role='noheader'] ---- -helm install backup-name neo4j-admin -f /path/to/your/backup-values.yaml +helm install backup-name neo4j/neo4j-admin -f /path/to/your/backup-values.yaml ---- + The _neo4j/neo4j-admin_ Helm chart installs a cronjob that launches a pod based on the job schedule. @@ -847,7 +847,7 @@ resources: + [source, shell, role='noheader'] ---- -helm install backup-name neo4j-admin -f /path/to/your/backup-values.yaml +helm install backup-name neo4j/neo4j-admin -f /path/to/your/backup-values.yaml ---- . Monitor the pod logs using `kubectl logs pod/` to check the progress of the aggregate backup operation. . Verify that the aggregated backup file has replaced your backup chain in the cloud provider bucket or on-premises storage. From afb13360491f85f0d21118865ae48da7c54cd8d0 Mon Sep 17 00:00:00 2001 From: Reneta Popova Date: Tue, 15 Jul 2025 11:19:05 +0100 Subject: [PATCH 12/39] Fix a typo in one of the shell commands in Access the Neo4j cluster from inside Kubernetes (#2479) --- .../pages/kubernetes/quickstart-cluster/access-inside-k8s.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ROOT/pages/kubernetes/quickstart-cluster/access-inside-k8s.adoc b/modules/ROOT/pages/kubernetes/quickstart-cluster/access-inside-k8s.adoc index 09290fe5d..42e74e83a 100644 --- a/modules/ROOT/pages/kubernetes/quickstart-cluster/access-inside-k8s.adoc +++ b/modules/ROOT/pages/kubernetes/quickstart-cluster/access-inside-k8s.adoc @@ -199,7 +199,7 @@ The drivers will use them to obtain the initial routing table. + [source, shell, subs="attributes"] ---- -kubectl run --rm -it --namespace "neo4j" --image "neo4j:{neo4j-version-exact}-enterprise"cypher-shell -- cypher-shell -a \ "neo4j://my-cluster-headless.neo4j.svc.cluster.local:7687" -u neo4j -p "my-password" +kubectl run --rm -it --namespace "neo4j" --image "neo4j:{neo4j-version-exact}-enterprise" cypher-shell -- cypher-shell -a "neo4j://my-cluster-headless.neo4j.svc.cluster.local:7687" -u neo4j -p "my-password" ---- + [source, result, subs="attributes", role=nocopy] From e6cd3413e945a7d2b2b79fa3a58ed449f087f17c Mon Sep 17 00:00:00 2001 From: Reneta Popova Date: Wed, 16 Jul 2025 17:10:49 +0100 Subject: [PATCH 13/39] Remove against the system database from Handy tips (#2478) --- modules/ROOT/pages/tutorial/neo4j-admin-import.adoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/ROOT/pages/tutorial/neo4j-admin-import.adoc b/modules/ROOT/pages/tutorial/neo4j-admin-import.adoc index 900010904..a8dd5d9bd 100644 --- a/modules/ROOT/pages/tutorial/neo4j-admin-import.adoc +++ b/modules/ROOT/pages/tutorial/neo4j-admin-import.adoc @@ -34,9 +34,9 @@ However, the CSV files can be located in any directory of your file system. .Handy tips: ==== * The details of a CSV file header format can be found at xref:import.adoc#import-tool-header-format[CSV header format]. -* To show available databases, use the Cypher query `SHOW DATABASES` against the `system` database. -* To remove a database, use the Cypher query `DROP DATABASE database_name` against the `system` database. -* To create a database, use the Cypher query `CREATE DATABASE database_name` against the `system` database. +* To show available databases, use the Cypher query `SHOW DATABASES`. +* To remove a database, use the Cypher query `DROP DATABASE database_name`. +* To create a database, use the Cypher query `CREATE DATABASE database_name`. ==== From 7e2472c00609c27ebc72353eb12373b0cd4e4932 Mon Sep 17 00:00:00 2001 From: Gerrit Meier Date: Fri, 18 Jul 2025 10:59:34 +0200 Subject: [PATCH 14/39] Clarify version for parquet header support. (#2489) Unsure if this should be inline with the header or appear after the header. Searched the repository for comparable situations but haven't found any. Both looks ... both have their pros and cons ;) --------- Co-authored-by: Reneta Popova --- modules/ROOT/pages/import.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/ROOT/pages/import.adoc b/modules/ROOT/pages/import.adoc index 303d2df84..abcbc78bf 100644 --- a/modules/ROOT/pages/import.adoc +++ b/modules/ROOT/pages/import.adoc @@ -1136,6 +1136,7 @@ For example, you can use `uuid:ID(Person){label:Person}`, where the relationship * For examples of creating property uniqueness constraints, see link:{neo4j-docs-base-uri}/cypher-manual/current/constraints/managing-constraints/#create-property-uniqueness-constraints[Cypher Manual -> Create property uniqueness constraints]. ==== +[role=label--new-2025.04] === Extended header support for Parquet In addition to the header format supported by the CSV import, the Parquet import supports name-mapping header files. From c8e97aac0e0a52c435f25e8da7857fdeee534dfd Mon Sep 17 00:00:00 2001 From: Bledi Feshti <35537997+bfeshti@users.noreply.github.com> Date: Fri, 18 Jul 2025 17:01:31 +0200 Subject: [PATCH 15/39] Update Kubernetes oprations manual for backups (#2462) Co-authored-by: Reneta Popova --- .../kubernetes/operations/backup-restore.adoc | 131 ++++++++++++++++-- 1 file changed, 123 insertions(+), 8 deletions(-) diff --git a/modules/ROOT/pages/kubernetes/operations/backup-restore.adoc b/modules/ROOT/pages/kubernetes/operations/backup-restore.adoc index 647799c1c..235e988a0 100644 --- a/modules/ROOT/pages/kubernetes/operations/backup-restore.adoc +++ b/modules/ROOT/pages/kubernetes/operations/backup-restore.adoc @@ -8,6 +8,31 @@ For performing backups, Neo4j uses the _Admin Service_, which is only available For more information, see xref:kubernetes/accessing-neo4j.adoc[Accessing Neo4j]. ==== +[[kubernetes-backup-storage-options]] +== Backup storage options + +Neo4j's Helm chart supports both full and differential backups and can be configured to use cloud providers or local storage. + +=== Cloud storage + +Neo4j Helm chart uses Neo4j's native cloud storage integration with direct upload to create immutable backup objects. +This allows you to back up your Neo4j databases directly to cloud storage without the need for persistent volumes. +The chart can be configured to use cloud providers, such as AWS S3, Google Cloud Storage, and Azure Blob Storage, by setting the `cloudProvider` parameter to `aws`, `gcp`, or `azure` in the _backup-values.yaml_ file. + +The following features are supported: + +* *Direct cloud storage upload* - No intermediate local storage required. +* *Differential backup chains* with `preferDiffAsParent: true`. +* *Immutable backup objects* in cloud storage. +* *Support for S3-compatible endpoints*. +* *Enhanced S3 configuration* including custom CA certificates and endpoint settings. + +=== Local storage + +Local storage creates local backups in the `/backups` mount. +This mount must be configured to use a persistent storage for large databases using `tempVolume`. +The `cloudProvider` must be empty. + [[kubernetes-neo4j-backup-cloud]] == Prepare to back up a database(s) to a cloud provider (AWS, GCP, and Azure) bucket @@ -32,6 +57,12 @@ For more information, see link:https://min.io/docs/minio/linux/integrations/aws- * The latest Neo4j Helm charts. You can update the repository to get the latest charts using `helm repo update`. +[NOTE] +==== +When using cloud providers, differential backups do not require persistent volumes with previous backups. +Instead, the chart will first create a full backup in the cloud storage, and then, the subsequent backups will be differential backups that reference this full backup. +==== + === Create a Kubernetes secret You can create a Kubernetes secret with the credentials that can access the cloud provider bucket using one of the following options: @@ -120,6 +151,10 @@ backup: cloudProvider: "gcp" secretName: "gcpcreds" secretKeyName: "credentials" + # Enable cloud-native differential backups + preferDiffAsParent: true + type: "AUTO" # First backup will be FULL, subsequent ones DIFF + fallbackToFull: true consistencyCheck: enabled: true @@ -145,6 +180,10 @@ backup: cloudProvider: "aws" secretName: "awscreds" secretKeyName: "credentials" + # Enable cloud-native differential backups + preferDiffAsParent: true + type: "AUTO" # First backup will be FULL, subsequent ones DIFF + fallbackToFull: true consistencyCheck: enabled: true @@ -170,6 +209,10 @@ backup: cloudProvider: "azure" secretName: "azurecreds" secretKeyName: "credentials" + # Enable cloud-native differential backups + preferDiffAsParent: true + type: "AUTO" # First backup will be FULL, subsequent ones DIFF + fallbackToFull: true consistencyCheck: enabled: true @@ -209,6 +252,10 @@ backup: cloudProvider: "gcp" secretName: "" secretKeyName: "" + # Enable cloud-native differential backups + preferDiffAsParent: true + type: "AUTO" # First backup will be FULL, subsequent ones DIFF + fallbackToFull: true consistencyCheck: enabled: true @@ -236,6 +283,10 @@ backup: cloudProvider: "aws" secretName: "" secretKeyName: "" + # Enable cloud-native differential backups + preferDiffAsParent: true + type: "AUTO" # First backup will be FULL, subsequent ones DIFF + fallbackToFull: true consistencyCheck: enabled: true @@ -262,6 +313,10 @@ backup: database: "neo4j,system" cloudProvider: "azure" azureStorageAccountName: "storageAccountName" + # Enable cloud-native differential backups + preferDiffAsParent: true + type: "AUTO" # First backup will be FULL, subsequent ones DIFF + fallbackToFull: true consistencyCheck: enabled: true @@ -283,7 +338,8 @@ tempVolume: [NOTE] ==== -You need to create the persistent volume and persistent volume claim before installing the _neo4j-admin_ Helm chart. +You need to create the persistent volume and persistent volume claim before installing the _neo4j-admin_ Helm chart only when using local storage. +When using cloud providers, persistent volumes are not required for differential backups. For more information, see xref:kubernetes/persistent-volumes.adoc[Volume mounts and persistent volumes]. ==== @@ -306,6 +362,16 @@ backup: # Optional: Skip TLS verification (not recommended for production) s3SkipVerify: false + + # Optional: Force path-style addressing for S3 requests + s3ForcePathStyle: true + + # Optional: Specify S3 region + s3Region: "us-east-1" + + # Alternative: Use Kubernetes secret for CA certificate + s3CASecretName: "s3-ca-cert" + s3CASecretKey: "ca.crt" ---- The following are examples of how to configure the backup system for different S3-compatible storage providers: @@ -381,6 +447,29 @@ backup: * Legacy MinIO support through the `minioEndpoint` parameter is deprecated - use `s3Endpoint` instead. ==== +=== S3 CA certificate setup + +For S3 endpoints with custom CA certificates, use a Kubernetes secret to manage the CA certificate: + +. Create the CA certificate secret: ++ +[source, bash] +---- +kubectl create secret generic s3-ca-cert --from-file=ca.crt=/path/to/your/ca.crt +---- + +. Configure the backup job: ++ +[source, yaml] +---- +backup: + cloudProvider: "aws" + s3Endpoint: "https://your-s3-endpoint.com" + s3CASecretName: "s3-ca-cert" + s3CASecretKey: "ca.crt" + s3EndpointTLS: true # Automatically set when s3CASecretName is provided +---- + [[kubernetes-neo4j-backup-on-prem]] == Prepare to back up a database(s) to on-premises storage @@ -390,7 +479,8 @@ When configuring the _backup-values.yaml_ file, keep the “cloudProvider” fie [NOTE] ==== -You need to create the persistent volume and persistent volume claim before installing the _neo4j-admin_ Helm chart. +You need to create the persistent volume and persistent volume claim before installing the _neo4j-admin_ Helm chart only when using local storage. +When using cloud providers, persistent volumes are not required for differential backups. For more information, see xref:kubernetes/persistent-volumes.adoc[Volume mounts and persistent volumes]. ==== @@ -502,6 +592,13 @@ backup: s3CACert: "" # Optional: Skip TLS verification (not recommended for production) s3SkipVerify: false + # Optional: Force path-style addressing for S3 requests + s3ForcePathStyle: false + # Optional: Specify S3 region + s3Region: "" + # Alternative: Use Kubernetes secret for CA certificate + s3CASecretName: "" + s3CASecretKey: "" #name of the database to backup ex: neo4j or neo4j,system (You can provide command separated database names) # In case of comma separated databases failure of any single database will lead to failure of complete operation database: "" @@ -551,6 +648,11 @@ backup: parallelRecovery: false verbose: true heapSize: "" + # Enable differential backups using the latest differential backup as parent + # This eliminates the need for persistent volumes when using cloud providers + preferDiffAsParent: false + # Fallback to FULL backup if DIFF backup fails + fallbackToFull: true # https://neo4j.com/docs/operations-manual/current/backup-restore/aggregate/ # Performs aggregate backup. If enabled, NORMAL BACKUP WILL NOT BE DONE only aggregate backup @@ -890,12 +992,7 @@ cypher-shell -u neo4j -p -d system ---- DROP DATABASE neo4j; ---- -. Exit the Cypher Shell command-line console: -+ -[source, shell, role='noheader'] ----- -:exit; ----- +. Exit the Cypher Shell command-line console by typing `:exit;`. === Restore the database backup @@ -949,3 +1046,21 @@ For more information, see xref:backup-restore/restore-backup.adoc#restore-backup ==== To restore the `system` database, follow the steps described in xref:kubernetes/operations/dump-load.adoc[Dump and load databases (offline)]. ==== + +[[kubernetes-backup-migration]] +== Migrate from traditional to cloud-native backups + +To migrate from persistent volume-based backups to cloud-native backups, you need to follow these steps: + +. Perform a final traditional backup to ensure you have the latest data. +For more information, see <> and <>. +. Upload existing backups to the cloud storage bucket if needed. +You can use cloud provider CLI tools to transfer your backup files: +** For AWS S3: `aws s3 cp /path/to/backups s3://your-bucket/backups --recursive` +** For Google Cloud Storage: `gsutil cp -r /path/to/backups gs://your-bucket/backups` +** For Azure Blob Storage: `az storage blob upload-batch --source /path/to/backups --destination your-container` +. Update the _backup-values.yaml_ file to configure the cloud provider, bucket name, and credentials. +See <> for details. +. Install the _neo4j-admin_ Helm chart with the updated _backup-values.yaml_ file to back up your databases to the cloud provider bucket. +See <<_back_up_your_databases, Back up your databases>> for details. + From 968734ba6df5ff77c285565232c6473295273453 Mon Sep 17 00:00:00 2001 From: Reneta Popova Date: Mon, 21 Jul 2025 15:34:30 +0100 Subject: [PATCH 16/39] Restyle RBAC limitations and warn about use of fail-open DENY semantics (#2488) --- .../limitations.adoc | 174 +++++++++++++----- 1 file changed, 124 insertions(+), 50 deletions(-) diff --git a/modules/ROOT/pages/authentication-authorization/limitations.adoc b/modules/ROOT/pages/authentication-authorization/limitations.adoc index 9d5a6bc5d..d9f1881d6 100644 --- a/modules/ROOT/pages/authentication-authorization/limitations.adoc +++ b/modules/ROOT/pages/authentication-authorization/limitations.adoc @@ -14,26 +14,33 @@ CREATE ROLE unrestricted; [[access-control-limitations]] = Limitations -The known limitations and implications of Neo4j's role-based access control security are described in this section. +It is very important to apply the principle of least privilege when defining user roles and privileges. +Further to that, Neo4j's role-based access control has some limitations and implications that users should be aware of, such as: + +* Impact on query results regardless of whether indexes are used. +* Impact on query results when nodes have multiple labels. +* The need for careful management of user roles and privileges to avoid unintended data exposure. +* Potential performance impacts when querying large graphs with complex security rules. [[access-control-limitations-indexes]] == Security and indexes -As described in link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/search-performance-indexes/overview/[Cypher Manual -> Indexes for search performance], Neo4j {neo4j-version} supports the creation and use of indexes to improve the performance of Cypher queries. +Neo4j lets you create and use indexes to speed up Cypher queries. +See the link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/search-performance-indexes/[Cypher Manual -> Indexes] for more details on the different types of indexes available in Neo4j. -Note that the Neo4j security model impacts the results of queries, regardless if the indexes are used or not. -When using non full-text Neo4j indexes, a Cypher query will always return the same results it would have if no index existed. -This means that, if the security model causes fewer results to be returned due to restricted read access in xref:authentication-authorization/manage-privileges.adoc[Graph and sub-graph access control], +However, Neo4j’s security model still controls what results you see, regardless of whether or not you use indexes. +For example, when you use link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/search-performance-indexes/overview/[search-performance indexes] (non–full-text) indexes, queries return the same results they would without any index. +This means that, if the security model causes fewer results to be returned due to restricted read access in xref:authentication-authorization/manage-privileges.adoc[graph and sub-graph access control], the index will also return the same fewer results. -However, this rule is not fully obeyed by link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/semantic-indexes/full-text-indexes/[Cypher Manual -> Indexes for full-text search]. -These specific indexes are backed by _Lucene_ internally. -It is therefore not possible to know for certain whether a security violation has affected each specific entry returned from the index. -In face of this, Neo4j will return zero results from full-text indexes in case it is determined that any result might be violating the security privileges active for that query. +link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/semantic-indexes/full-text-indexes/[Full-text indexes] work differently. +These indexes use Lucene under the hood. +Because of that, Neo4j cannot check whether a security violation has affected each specific entry returned from the index. +So, if there is any chance a result might violate active security privileges for a query, Neo4j returns zero results from the full-text indexes. -Since full-text indexes are not automatically used by Cypher, they do not lead to the case where the same Cypher query would return different results simply because such an index was created. -Users need to explicitly call procedures to use these indexes. -The problem is only that, if this behavior is not known by the user, they might expect the full-text index to return the same results that a different, but semantically similar, Cypher query does. +Also, Cypher does not use full-text indexes automatically — you have to explicitly call procedures to use them. +This avoids a situation where the same Cypher query would return different results simply because such an index exists. +The problem is that if you do not know this behavior, you might expect the full-text index to return the same results that a different but semantically similar Cypher query does. === Example with denied properties @@ -54,16 +61,16 @@ Full-text indexes support multiple labels. See link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/semantic-indexes/full-text-indexes//[Cypher Manual -> Indexes for full-text search] for more details on creating and using full-text indexes. ==== -After creating these indexes, it would appear that the latter two indexes accomplish the same thing. +After creating these indexes, it may look that the latter two indexes accomplish the same thing. However, this is not completely accurate. The composite and full-text indexes behave in different ways and are focused on different use cases. A key difference is that full-text indexes are backed by _Lucene_, and will use the _Lucene_ syntax for querying. This has consequences for users restricted on the labels or properties involved in the indexes. Ideally, if the labels and properties in the index are denied, they can correctly return zero results from both native indexes and full-text indexes. -However, there are borderline cases where this is not as simple. +However, there are borderline cases where this is not that simple. -Imagine the following nodes were added to the database: +Imagine the following nodes are added to the database: [source, cypher] ---- @@ -120,7 +127,7 @@ CALL db.index.fulltext.queryNodes("userNames", "ndy") YIELD node, score RETURN node.name ---- -The problem now is that it is not certain whether the results provided by the index were achieved due to a match to the `name` or the `surname` property. +The problem now is that it is not certain whether the results provided by the index are achieved due to a match to the `name` or the `surname` property. The steps taken by the query engine would be: * Run a _Lucene_ query on the full-text index to produce results containing `ndy` in either property, leading to five results. @@ -180,40 +187,106 @@ Otherwise, it will process as described before. In this case, the query will return zero results rather than simply returning the results `Andy` and `Sandy`, which might have been expected. +=== Avoiding fail-open `DENY` behavior + +A `DENY` rule fails open when its criteria is not met, so Neo4j does not apply the restriction and it grants access by default if a broader `GRANT` exists. +This can lead to unintended data exposure if the `DENY` rule is not carefully crafted. +To avoid this, you can apply the principle of least privilege and allow access only to the specific data that the user should see. + +For example, consider the following scenarios: + +.Example of an un-met `DENY` failing open with property-based RBAC +==== +You grant a user access to a property and try to restrict it with a `DENY` rule. +However, if the `DENY` rule does not match any data, for example, if the property is null or misspelled, the `DENY` rule will not apply, and the user can still access the property. +[source, cypher] +---- +GRANT READ {salary} ON GRAPH * NODES Employee TO myRole +DENY READ {salary} ON GRAPH * FOR (e:Employee) WHERE e.position = 'CEO' TO myRole +---- +In this case, if the `e.position` property is null or misspelled, the `DENY` rule will not apply, and `myRole` will see the `salary` property. + +A better way is to apply the principle of least privilege and only grant access to the `salary` property for employees whose position is not 'CEO'. +[source, cypher] +---- +GRANT READ {salary} ON GRAPH * FOR (e:Employee) WHERE e.position <> 'CEO' TO myRole +---- + +Or, if for some reason using `DENY` is unavoidable, the problem can be mitigated by adding an additional `DENY` to cover the case where `e.position` is null: +[source, cypher] +---- +DENY READ {salary} ON GRAPH * FOR (e:Employee) WHERE e.position IS NULL TO myRole +---- +This way, if `e.position` is null, the user will not see the `salary` property, and the `DENY` will not apply. + +Alternatively, you can add a constraint to ensure that the `e.position` property cannot be null, so the `DENY` condition is always checkable: +[source, cypher] +---- +CREATE CONSTRAINT ON (e:Employee) ASSERT e.position IS NOT NULL; +---- +This way, the `DENY` will never apply due to null values, and the user will not see the `salary` property for employees whose position is 'CEO'. + +==== + +.Example of an un-met `DENY` failing open with label-based RBAC +==== + +In a similar way, a `DENY` rule will not apply when it is too broad and does not match the data. +[source, cypher] +---- +GRANT READ {salary} ON GRAPH * NODES * TO myRole; +---- + +This grants read access to the `salary` property on all nodes, including those that should not be accessible. + +Then, you try to restrict it with a `DENY` rule to prevent access to the `salary` property on nodes labeled `Management`: +[source, cypher] +---- +DENY READ {salary} ON GRAPH * NODES Management TO myRole; +---- +In this case, if the `Management` label is not present on a node that has the `salary` property, the `DENY` rule will not apply, and `myRole` will still see the `salary` property on that node. + +A better way is to apply the principle of least privilege and only grant access to the `salary` property for nodes that have a specific label, such as `IndividualContributor`: +[source, cypher] +---- +GRANT READ {salary} ON GRAPH * NODES IndividualContributor TO myRole; +---- +This way, the user will only see the `salary` property on nodes that have the `IndividualContributor` label, and not on any other nodes. +==== [[access-control-limitations-labels]] == Security and labels === Traversing the graph with multi-labeled nodes -The general influence of access control privileges on graph traversal is described in detail in xref:authentication-authorization/manage-privileges.adoc[Graph and sub-graph access control]. -The following section will only focus on nodes due to their ability to have multiple labels. -Relationships can only have one type of label and thus they do not exhibit the behavior this section aims to clarify. -While this section will not mention relationships further, the general function of the traverse privilege also applies to them. +In Neo4j, nodes can have multiple labels, but relationships only have one type. +This is important when it comes to controlling who can see what. + +The following section only focuses on nodes because they can have multiple labels. +The same general rules apply to relationships, but they are simpler. -For any node that is traversable, due to `GRANT TRAVERSE` or `GRANT MATCH`, -the user can get information about the attached labels by calling the built-in `labels()` function. -In the case of nodes with multiple labels, they can be returned to users that weren't directly granted access to. +For details on the general influence of access control privileges on graph traversal, see xref:authentication-authorization/manage-privileges.adoc[Graph and sub-graph access control]. -To give an illustrative example, imagine a graph with three nodes: one labeled `:A`, another labeled `:B` and one with the labels `:A` and `:B`. -In this case, there is a user with the role `custom` defined by: +If a user is granted access to a traversable node using `GRANT TRAVERSE` or `GRANT MATCH`, they will be able to get information about the attached labels by calling the built-in `labels()` function. +In the case of nodes with multiple labels, this means that the user will be able to see all labels attached to the node, even if they were not granted access to traverse on some of those labels. + +For example, if a user has the following role: [source, cypher] ---- GRANT TRAVERSE ON GRAPH * NODES A TO custom ---- -If that user were to execute - +And the graph contains three nodes: one labeled `:A`, another labeled `:B`, and one with both labels `:A` and `:B`. +If the user executes the following query: [source, cypher] ---- MATCH (n:A) RETURN n, labels(n) ---- +They will get a result with two nodes: the node with label `:A` and the node with labels `:A :B`. -They would get a result with two nodes: the node that was labeled with `:A` and the node with labels `:A :B`. - -In contrast, executing +In contrast, if the user executes: [source, cypher] ---- @@ -221,19 +294,20 @@ MATCH (n:B) RETURN n, labels(n) ---- -This will return only the one node that has both labels: `:A` and `:B`. -Even though `:B` did not have access to traversals, there is one node with that label accessible in the dataset due to the allow-listed label `:A` that is attached to the same node. +They will get only the node that has both labels: `:A` and `:B`. +Even though `:B` does not have access to traversals, there is one node with that label accessible in the dataset due to the allow-listed label `:A` that is attached to the same node. -If a user is denied to traverse on a label they will never get results from any node that has this label attached to it. +If a user is denied to traverse on a label, they will never get results from any node that has this label attached to it. Thus, the label name will never show up for them. -As an example, this can be done by executing: +For example, if the user has the following role: [source, cypher] ---- DENY TRAVERSE ON GRAPH * NODES B TO custom ---- -The query +And the graph contains the same three nodes as before, the user will not be able to traverse the node with label `:B`. +Thus, the query [source, cypher] ---- @@ -257,25 +331,22 @@ In contrast to the normal graph traversal described in the previous section, the That means: * If a label is explicitly whitelisted (granted), it will be returned by this procedure. -* If a label is denied or isn't explicitly allowed, it will not be returned by this procedure. - -Reusing the previous example, imagine a graph with three nodes: one labeled `:A`, another labeled `:B` and one with the labels `:A` and `:B`. -In this case, there is a user with the role `custom` defined by: +* If a label is denied or is not explicitly allowed, it will not be returned by this procedure. +For example, if a user has the following role: [source, cypher] ---- GRANT TRAVERSE ON GRAPH * NODES A TO custom ---- -This means that only label `:A` is explicitly allow-listed. -Thus, executing - +and the graph contains three nodes: one labeled `:A`, another labeled `:B`, and one with both labels `:A` and `:B`, +the user will be able to execute the following query: [source, cypher] ---- CALL db.labels() ---- - -will only return label `:A`, because that is the only label for which traversal was granted. +This will return a list of labels, which in this case will only include the label `:A`. +The label `:B` will not be returned, because the user does not have access to traverse on it. [[access-control-limitations-non-existing-labels]] === Privileges for non-existing labels, relationship types, and property names @@ -332,15 +403,17 @@ To ensure success on the first attempt, when setting up the privileges for the ` In this example, when creating the custom role, connect to `testing` and run `CALL db.createLabel('A')` to ensure Alice creates the node successfully on her first attempt. - [[access-control-limitations-db-operations]] == Security and performance -The rules of a security model may impact the performance of some database operations. -This is because extra security checks are necessary, and they require additional data access. +=== Security rules and database operations + +The rules of a security model may impact the performance of some database operations, because Neo4j has to do extra security checks, which require additional data access. For example, count store operations, which are usually fast lookups, may experience notable differences in performance. -The following example shows how the database behaves when adding security rules to roles `restricted` and `unrestricted`: +Let's take the following example. +The database has two roles defined `restricted` and `unrestricted`. +The `restricted` role has limited access to traversals, while the `unrestricted` role has no restrictions. [source, cypher] ---- @@ -389,10 +462,11 @@ So due to the additional data access required by the security checks, this opera |=== [[property-based-access-control-limitations]] -=== Property-based access control limitations +=== Security rules based on property rules and performance + Extra node or relationship-level security checks are necessary when adding security rules based on property rules, and these can have a significant performance impact. -The following example shows how the database behaves when adding security rules for nodes to roles `restricted` and `unrestricted`. +The following example shows how the database behaves when adding security rules for nodes to roles `restricted` and `unrestricted`. The same limitations apply to relationships. [source, cypher] From f01eb32bb87e017526c615dd0fc08f63b1612b25 Mon Sep 17 00:00:00 2001 From: Jack Waudby <33488812+jackwaudby@users.noreply.github.com> Date: Wed, 23 Jul 2025 10:52:49 +0100 Subject: [PATCH 17/39] Server tags are not used during database allocation (#2499) --- modules/ROOT/pages/clustering/servers.adoc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/ROOT/pages/clustering/servers.adoc b/modules/ROOT/pages/clustering/servers.adoc index 2ce4ce6ea..01ab89863 100644 --- a/modules/ROOT/pages/clustering/servers.adoc +++ b/modules/ROOT/pages/clustering/servers.adoc @@ -67,7 +67,7 @@ This may not be specified in combination with `allowedDatabases`. | tags | list of server tags, e.g. `["tag1", "tag2"]` -| List of server tags used during database allocation and for load balancing and routing policies. +| List of server tags used for load balancing and routing policies. |=== [NOTE] @@ -218,7 +218,7 @@ Composite databases do not currently appear in this list, though they do appear | {check-mark} | tags -| Tags are user provided strings that can be used while allocating databases. +| Tags are user provided strings that can be used for load balancing and routing policies. | LIST | | {check-mark} @@ -279,7 +279,7 @@ The `allowedDatabases` and `deniedDatabases` are mutually exclusive and if both Optionally, it is possible to automatically enable free servers by setting the xref:configuration/configuration-settings.adoc#config_initial.dbms.automatically_enable_free_servers[`initial.dbms.automatically_enable_free_servers`] to `true`. This can be changed after startup using the xref:procedures.adoc#procedure_dbms_cluster_setAutomaticallyEnableFreeServers[`dbms.cluster.setAutomaticallyEnableFreeServers`] procedure. -Server `tags` are used during database allocation and when configuring load balancing and replication policies. +Server `tags` are used when configuring load balancing and replication policies. They cannot contain duplicates, so `tags:['eu', 'eu']` will return an error. Server tags also cannot contain commas. When altering server tags via cypher, the encoding is done via UTF-8. @@ -443,7 +443,7 @@ This may not be specified in combination with `allowedDatabases`. | tags | list of server tags, e.g. `["tag1", "tag2"]` -| List of server tags used during database allocation and for load balancing and routing policies. +| List of server tags used for load balancing and routing policies. |=== [NOTE] From e77643223ee5085b6c0fe529b9682c4e217968c6 Mon Sep 17 00:00:00 2001 From: Reneta Popova Date: Wed, 23 Jul 2025 15:14:12 +0100 Subject: [PATCH 18/39] Fix the restore metadata paths (#2498) --- .../pages/authentication-authorization/manage-users.adoc | 6 +++--- modules/ROOT/pages/backup-restore/restore-backup.adoc | 6 +++--- modules/ROOT/pages/database-internals/store-formats.adoc | 6 ++++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/modules/ROOT/pages/authentication-authorization/manage-users.adoc b/modules/ROOT/pages/authentication-authorization/manage-users.adoc index 2cdafb969..20ee6ec58 100644 --- a/modules/ROOT/pages/authentication-authorization/manage-users.adoc +++ b/modules/ROOT/pages/authentication-authorization/manage-users.adoc @@ -784,7 +784,7 @@ The `'password'` can either be a string value or a string parameter with default The `PLAINTEXT` and `ENCRYPTED` keywords are optional and can be used to specify the format of the password, i.e. whether Neo4j needs to hash it or it has already been hashed. By default, all passwords are encrypted (hashed) when stored in the Neo4j `system` database. * The optional `PLAINTEXT` in `SET PLAINTEXT PASSWORD` has the same behavior as `SET PASSWORD`. -* The optional `ENCRYPTED` is used to recreate an existing user when the plaintext password is unknown, but the encrypted password is available in the _data/databases/databasename/tools/metadata_script.cypher_ file of a database backup. +* The optional `ENCRYPTED` is used to recreate an existing user when the plaintext password is unknown, but the encrypted password is available in the _/data/scripts/databasename/restore_metadata.cypher_ file of restored database backup. See xref:backup-restore/restore-backup#_restore_users_and_roles_metadata[Restore users and roles metadata]. + With `ENCRYPTED`, the password string is expected to be in the format of `,,`, where, for example: ** `0` is the first version and refers to the `SHA-256` cryptographic hash function with iterations `1`. @@ -852,7 +852,7 @@ SET AUTH 'native' {SET PASSWORD 'abcd1234' SET PASSWORD CHANGE REQUIRED} .Create user with an encrypted password ====== -Or you can create the user `Jake` in an active state, with an encrypted password (taken from the _data/databases/databasename/tools/metadata_script.cypher_ of a database backup), and the requirement to not change the password by running: +Or you can create the user `Jake` in an active state, with an encrypted password (taken from the _/data/scripts/databasename/restore_metadata.cypher_ of a restored database backup), and the requirement to not change the password by running: [source,cypher,role=noplay] ---- @@ -1008,7 +1008,7 @@ The `'password'` can either be a string value or a string parameter with default The `PLAINTEXT` and `ENCRYPTED` keywords are optional and can be used to specify the format of the password, i.e. whether Neo4j needs to hash it or it has already been hashed. By default, all passwords are encrypted (hashed) when stored in the Neo4j `system` database. * The optional `PLAINTEXT` in `SET PLAINTEXT PASSWORD` has the same behavior as `SET PASSWORD`. -* The optional `ENCRYPTED` is used to recreate an existing user when the plaintext password is unknown, but the encrypted password is available in the _data/databases/databasename/tools/metadata_script.cypher_ file of a database backup. +* The optional `ENCRYPTED` is used to recreate an existing user when the plaintext password is unknown, but the encrypted password is available in the _/data/scripts/databasename/restore_metadata.cypher_ file when you restore a database backup. See xref:backup-restore/restore-backup#_restore_users_and_roles_metadata[Restore users and roles metadata]. + With `ENCRYPTED`, the password string is expected to be in the format of `,,`, where, for example: ** `0` is the first version and refers to the `SHA-256` cryptographic hash function with iterations `1`. diff --git a/modules/ROOT/pages/backup-restore/restore-backup.adoc b/modules/ROOT/pages/backup-restore/restore-backup.adoc index 933dcfb51..98895743d 100644 --- a/modules/ROOT/pages/backup-restore/restore-backup.adoc +++ b/modules/ROOT/pages/backup-restore/restore-backup.adoc @@ -300,16 +300,16 @@ For more information, see xref:clustering/databases.adoc#cluster-seed[Designated If you have backed up a database with the option `--include-metadata`, you can manually restore the users and roles metadata. -From the __ directory, you run the Cypher script _data/databases/databasename/tools/metadata_script.cypher_, which the `neo4j-admin database restore` command outputs, using xref:cypher-shell.adoc[]: +From the __ directory, you run the Cypher script _/data/scripts/databasename/restore_metadata.cypher_, which the `neo4j-admin database restore` command outputs, using xref:cypher-shell.adoc[]: *Using `cat` (UNIX)* [source, shell, role=nocopy noplay] ---- -cat data/databases/databasename/tools/metadata_script.cypher | bin/cypher-shell -u user -p password -a ip_address:port -d system --param "database => 'databasename'" +cat ../data/scripts/databasename/restore_metadata.cypher | bin/cypher-shell -u user -p password -a ip_address:port -d system --param "database => 'databasename'" ---- *Using `type` (Windows)* [source, shell, role=nocopy noplay] ---- -type data\databases\databasename\tools\metadata_script.cypher | bin\cypher-shell.bat -u user -p password -a ip_address:port -d system --param "database => 'databasename'" +type ..\data\scripts\databasename\restore_metadata.cypher | bin\cypher-shell.bat -u user -p password -a ip_address:port -d system --param "database => 'databasename'" ---- diff --git a/modules/ROOT/pages/database-internals/store-formats.adoc b/modules/ROOT/pages/database-internals/store-formats.adoc index 6f4f89185..4c725aa6c 100644 --- a/modules/ROOT/pages/database-internals/store-formats.adoc +++ b/modules/ROOT/pages/database-internals/store-formats.adoc @@ -203,14 +203,16 @@ For example: ---- @system> ALTER DATABASE mydb SET ACCESS READ ONLY; ---- -. In your command-line tool, back up that database using the xref:backup-restore/online-backup.adoc[`neo4j-admin database backup`] command. +. In your command-line tool, back up that database using the xref:backup-restore/online-backup.adoc[`neo4j-admin database backup`] command with the `--include-metadata=all` option to include all users and roles associated with it. For example: + [source,shell] ---- bin/neo4j-admin database backup mydb --to-path=/path/to/your-backup-folder --include-metadata=all ---- -. Back in Cypher Shell, drop the database to delete it and all users and roles associated with it: ++ +The command creates a backup archive that contains both the database and the metadata associated with it. +. In Cypher Shell, drop the database to delete it and all users and roles associated with it: + [source,cypher] ---- From ddeab82aebc85c386860946ab9175ca9fe8e9102 Mon Sep 17 00:00:00 2001 From: Jack Waudby <33488812+jackwaudby@users.noreply.github.com> Date: Fri, 25 Jul 2025 09:43:52 +0100 Subject: [PATCH 19/39] `DEALLOCATING` is an irreversible server state (#2500) Co-authored-by: Reneta Popova --- modules/ROOT/pages/clustering/databases.adoc | 2 +- modules/ROOT/pages/clustering/servers.adoc | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/modules/ROOT/pages/clustering/databases.adoc b/modules/ROOT/pages/clustering/databases.adoc index f4f9143d3..c2def73b3 100644 --- a/modules/ROOT/pages/clustering/databases.adoc +++ b/modules/ROOT/pages/clustering/databases.adoc @@ -138,7 +138,7 @@ By default, a newly created database has both read and write access. [[deallocate-databases]] == Deallocate databases -To relieve the load of a specific server(s), you can use one of the following procedures to deallocate databases causing the pressure from the server(s): +To relieve the load of a specific server(s), you can use one of the following procedures to deallocate databases, causing the databases to be removed from the server(s) under pressure: * xref:procedures.adoc#procedure_dbms_cluster_deallocateDatabaseFromServer[`dbms.cluster.deallocateDatabaseFromServer("server-name", "database-name")`] * xref:procedures.adoc#procedure_dbms_cluster_deallocateDatabaseFromServers[`dbms.cluster.deallocateDatabaseFromServers(["server-name1", "server-name2"\], "database-name")`] diff --git a/modules/ROOT/pages/clustering/servers.adoc b/modules/ROOT/pages/clustering/servers.adoc index 01ab89863..777b8f99d 100644 --- a/modules/ROOT/pages/clustering/servers.adoc +++ b/modules/ROOT/pages/clustering/servers.adoc @@ -82,10 +82,16 @@ Once enabled, the server may be allocated databases to host. [[deallocating-state]] === Deallocating state -When a server is no longer needed, it cannot be removed from the cluster while it is still allocated to host any databases. +A server in a deallocating state means that it can no longer host databases. +It may be that the server is no longer needed and you want to remove it from the cluster. The command `DEALLOCATE DATABASE[S] FROM SERVER[S] _server_[,...]` is used to transition servers to the _Deallocating_ state, reallocating all their hosted databases to other servers in the cluster. -Additionally, servers which are deallocating will not have any further databases allocated to them. +[NOTE] +==== +This state is *irreversible*. +Once a server is in a deallocating state, it subsequently cannot have databases allocated to it. +If you want to deallocate databases from a server in a *reversible manner*, see xref:clustering/databases.adoc#deallocate-databases[Deallocate databases] for more information. +==== === Deallocated state From 5597e399d4bef61a92f42cd6b32b19e0bb30d2e1 Mon Sep 17 00:00:00 2001 From: Reneta Popova Date: Fri, 25 Jul 2025 12:19:56 +0100 Subject: [PATCH 20/39] Remove externalService and add services.neo4j.spec.loadBalancerIP (#2494) --- .../pages/kubernetes/accessing-neo4j.adoc | 57 +++++++++++-------- .../ROOT/pages/kubernetes/configuration.adoc | 23 +++++++- 2 files changed, 53 insertions(+), 27 deletions(-) diff --git a/modules/ROOT/pages/kubernetes/accessing-neo4j.adoc b/modules/ROOT/pages/kubernetes/accessing-neo4j.adoc index 07c95ba14..c50cfa383 100644 --- a/modules/ROOT/pages/kubernetes/accessing-neo4j.adoc +++ b/modules/ROOT/pages/kubernetes/accessing-neo4j.adoc @@ -291,7 +291,7 @@ kubectl get service `-lb-neo4j` -ocustom-columns=ip:.status.loadB kubectl get service -l helm.neo4j.com/service=neo4j,helm.neo4j.com/name= -ocustom-columns=ip:.status.loadBalancer.ingress[].ip ---- -If the Kubernetes `LoadBalancer` implementation that you are using supports setting a static IP, the IP address of the `LoadBalancer` can be configured in the Neo4j Helm release by setting `externalService.loadBalancerIP`. +If the Kubernetes `LoadBalancer` implementation that you are using supports setting a static IP, the IP address of the `LoadBalancer` can be configured in the Neo4j Helm release by setting `services.neo4j.spec.loadBalancerIP`. If a static IP address is not explicitly set, then Kubernetes does not guarantee that a dynamically assigned IP address will not change. When exposing a Neo4j database on the Internet, it is recommended to use a static IP and configure SSL on the exposed services. @@ -306,33 +306,40 @@ The default values are: ---- services: neo4j: - annotations: { } - loadBalancerIP: NULL - ports: - http: - enabled: true - # uncomment to publish http on port 80 (neo4j default is 7474) - # port: 80 - # targetPort: 7474 - # name: http - https: - enabled: true + enabled: true + annotations: { } + spec: + type: LoadBalancer + loadBalancerIP: NULL + ports: + http: + enabled: true # Set this to false to remove HTTP from this service (this does not affect whether http is enabled for the neo4j process) + # uncomment to publish http on port 80 (neo4j default is 7474) + #port: 80 + #targetPort: 7474 + #name: http + #nodePort: , enabled only when type set to NodePort + https: + enabled: true # Set this to false to remove HTTPS from this service (this does not affect whether https is enabled for the neo4j process) # uncomment to publish http on port 443 (neo4j default is 7473) - # port: 443 - # targetPort: 7473 - # name: https - bolt: - enabled: true + #port: 443 + #targetPort: 7473 + #name: https + #nodePort: , enabled only when type set to NodePort + bolt: + enabled: true # Set this to false to remove BOLT from this service (this does not affect whether https is enabled for the neo4j process) # Uncomment to explicitly specify the port to publish Neo4j Bolt (7687 is the default) - # port: 7687 - # targetPort: 7687 - # name: tcp-bolt - backup: - enabled: false + #port: 7687 + #targetPort: 7687 + #name: tcp-bolt + #nodePort: , enabled only when type set to NodePort + backup: + enabled: false # Set this to true to expose backup port externally (n.b. this could have security implications. Backup is not authenticated by default) # Uncomment to explicitly specify the port to publish Neo4j Backup (6362 is the default) - # port: 6362 - # targetPort: 6362 - # name: tcp-backup + #port: 6362 + #targetPort: 6362 + #name: tcp-backup + #nodePort: , enabled only when type set to NodePort ---- Disabling/enabling a port on the `services.neo4j` object removes it from the load balancer but does not affect whether it is disabled/enabled in Neo4j. diff --git a/modules/ROOT/pages/kubernetes/configuration.adoc b/modules/ROOT/pages/kubernetes/configuration.adoc index 898e5759a..a6903ac44 100644 --- a/modules/ROOT/pages/kubernetes/configuration.adoc +++ b/modules/ROOT/pages/kubernetes/configuration.adoc @@ -211,7 +211,7 @@ For more information, see xref:kubernetes/security.adoc[Configure SSL]. Some examples of possible K8s configurations:: -* Configure (or disable completely) the Kubernetes LoadBalancer that exposes Neo4j outside the Kubernetes cluster by modifying the `externalService` object in the _values.yml_ file. +* Configure (or disable completely) the Kubernetes LoadBalancer that exposes Neo4j outside the Kubernetes cluster by modifying the `services.neo4j.spec.loadBalancerIP` object in the _values.yml_ file. * Set the `securityContext` used by Neo4j Pods by modifying the `securityContext` object in the _values.yml_ file. * Configure manual persistent volume provisioning or set the `StorageClass` to be used as the Neo4j persistent storage. @@ -269,7 +269,7 @@ neo4j: # The operations pod ends successfully if the server is enabled, or it was already enabled operations: enableServer: false - image: "neo4j/helm-charts-operations:5.26.0" + image: "neo4j/helm-charts-operations:2025.06.2" # protocol can be "neo4j or "neo4j+ssc" or "neo4j+s". Default set to neo4j # Note: Do not specify bolt protocol here...it will FAIL. protocol: "neo4j" @@ -283,6 +283,7 @@ neo4j: # Email inquiries can be directed to: licensing@neo4j.com # # Set acceptLicenseAgreement: "yes" to confirm that you have a Neo4j license agreement. + # Set acceptLicenseAgreement: "eval" to use Neo4j Enterprise Edition for evaluation purposes. acceptLicenseAgreement: "no" # # set offlineMaintenanceModeEnabled: true to restart the StatefulSet without the Neo4j process running @@ -508,6 +509,9 @@ services: # If enabled: is set to false, the LoadBalancer will be orphaned and will have to manually deleted post uninstall and the hook job will not be created cleanup: enabled: true + # Pod annotations for the cleanup job + podAnnotations: + sidecar.istio.io/inject: "false" image: registry: docker.io repository: bitnami/kubectl @@ -557,6 +561,14 @@ config: # server.memory.heap.initial_size: "317m" # server.memory.heap.max_size: "317m" + # Enable automatic reloading of TLS certificates + dbms.security.tls_reload_enabled: "true" + + # SPeeDy (Sharded Property Database) feature flag + # Enables the sharded property database feature for improved performance with large datasets + # Set to "true" to enable SPeeDy, "false" to disable (default: false) + internal.dbms.sharded_property_database.enabled: "false" + apoc_config: {} # apoc.trigger.enabled: "true" # apoc.import.file.enabled: "true" @@ -600,6 +612,8 @@ containerSecurityContext: # Because Neo4j uses Java these values are large to distinguish between long Garbage Collection pauses (which don't require a restart) and an actual failure. # These values should mark Neo4j as not ready after at most 5 minutes of problems (20 attempts * max 15 seconds between probes) readinessProbe: + tcpSocket: + port: 7687 failureThreshold: 20 timeoutSeconds: 10 periodSeconds: 5 @@ -608,6 +622,8 @@ readinessProbe: # Because Neo4j uses Java these values are large to distinguish between long Garbage Collection pauses (which don't require a restart) and an actual failure. # These values should trigger a restart after at most 10 minutes of problems (40 attempts * max 15 seconds between probes) livenessProbe: + tcpSocket: + port: 7687 failureThreshold: 40 timeoutSeconds: 10 periodSeconds: 5 @@ -617,6 +633,8 @@ livenessProbe: # When restoring Neo4j from a backup it's important that startup probe gives time for Neo4j to recover and/or upgrade store files # When using Neo4j clusters it's important that startup probe give the Neo4j cluster time to form startupProbe: + tcpSocket: + port: 7687 failureThreshold: 1000 periodSeconds: 5 @@ -660,6 +678,7 @@ ssl: # Kubernetes cluster domain suffix clusterDomain: "cluster.local" + # Override image settings in Neo4j pod image: imagePullPolicy: IfNotPresent From dcf808dd134db3e21df4c7ac34a4b5791bffa5fc Mon Sep 17 00:00:00 2001 From: Natalia Ivakina <82437520+NataliaIvakina@users.noreply.github.com> Date: Wed, 30 Jul 2025 09:18:46 +0200 Subject: [PATCH 21/39] Improve the table formatting (#2453) (#2510) This is a suggestion to improve the table formatting. I raised the PR against the `5.x` branch. If we like this improvement, we can cherry-pick it to `dev` and `main` branches. --- modules/ROOT/pages/introduction.adoc | 29 ++++++++-------------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/modules/ROOT/pages/introduction.adoc b/modules/ROOT/pages/introduction.adoc index 208781bdc..31b528769 100644 --- a/modules/ROOT/pages/introduction.adoc +++ b/modules/ROOT/pages/introduction.adoc @@ -66,9 +66,7 @@ a| link:https://www.gnu.org/licenses/quick-guide-gplv3.html[Open source under GP |{check-mark} | -^s| Native Graph -| -| +3+^s| Native Graph | link:{neo4j-docs-base-uri}/cypher-manual/current/queries/basic/[Property graph model] | {check-mark} @@ -126,9 +124,7 @@ a| link:https://neo4j.com/docs/cdc/current/[Change Data Capture (CDC)] | {check-mark} | {check-mark} -^s| Clients and APIs -| -| +3+^s| Clients and APIs | xref:cypher-shell.adoc[Cypher Shell] | {check-mark} @@ -162,9 +158,7 @@ a| APOC 450+ link:https://neo4j.com/docs/apoc/5/[Core Procedures and Functions] | | {check-mark} -^s| Indexes and constraints -| -| +3+^s| Indexes and constraints | link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/search-performance-indexes/overview/[Fast writes via native label indexes] | {check-mark} @@ -198,9 +192,7 @@ a| APOC 450+ link:https://neo4j.com/docs/apoc/5/[Core Procedures and Functions] | | {check-mark} -^s| Security -| -| +3+^s| Security | xref:authentication-authorization/manage-privileges.adoc[Role-based access control] | @@ -218,9 +210,7 @@ a| APOC 450+ link:https://neo4j.com/docs/apoc/5/[Core Procedures and Functions] | | {check-mark} -^s| Data management -| -| +3+^s| Data management | xref:import.adoc#import-tool-full[Offline import] | {check-mark} @@ -242,9 +232,8 @@ a| APOC 450+ link:https://neo4j.com/docs/apoc/5/[Core Procedures and Functions] | {check-mark} | {check-mark} -^s| Scale and availability -| -| +3+^s| Scale and availability + | Online xref:backup-restore/online-backup.adoc[backup] and xref:/backup-restore/restore-backup.adoc[restore] | | {check-mark} @@ -261,9 +250,7 @@ a| APOC 450+ link:https://neo4j.com/docs/apoc/5/[Core Procedures and Functions] | | {check-mark} -^s| xref:monitoring/index.adoc[Monitoring and management] -| -| +3+^s| xref:monitoring/index.adoc[Monitoring and management] | xref:monitoring/metrics/expose.adoc#_prometheus[Endpoints and metrics for monitoring via Prometheus] | From e6bfc0ec8845b69f2956ad968afa015fcbfc2dad Mon Sep 17 00:00:00 2001 From: Natalia Ivakina <82437520+NataliaIvakina@users.noreply.github.com> Date: Thu, 31 Jul 2025 13:42:01 +0200 Subject: [PATCH 22/39] Update to 2025.08 (#2514) --- antora.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/antora.yml b/antora.yml index 40bcfe6fa..a1ad7d02b 100644 --- a/antora.yml +++ b/antora.yml @@ -1,14 +1,14 @@ name: operations-manual title: Operations Manual -version: '2025.07' +version: '2025.08' current: true start_page: ROOT:index.adoc nav: - modules/ROOT/content-nav.adoc asciidoc: attributes: - neo4j-version: '2025.07' - neo4j-version-minor: '2025.07' - neo4j-version-exact: '2025.07.0' - neo4j-buildnumber: '2025.07' - neo4j-debian-package-version: '1:2025.07.0@' + neo4j-version: '2025.08' + neo4j-version-minor: '2025.08' + neo4j-version-exact: '2025.08.0' + neo4j-buildnumber: '2025.08' + neo4j-debian-package-version: '1:2025.08.0@' From 1e91ab0f7beb7e2743b59a77b4e6cf79592ab580 Mon Sep 17 00:00:00 2001 From: Natalia Ivakina <82437520+NataliaIvakina@users.noreply.github.com> Date: Fri, 1 Aug 2025 13:54:26 +0200 Subject: [PATCH 23/39] Update the metric in the cluster endpoint description (#2516) --- modules/ROOT/pages/clustering/monitoring/endpoints.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ROOT/pages/clustering/monitoring/endpoints.adoc b/modules/ROOT/pages/clustering/monitoring/endpoints.adoc index dcc886886..cd0646717 100644 --- a/modules/ROOT/pages/clustering/monitoring/endpoints.adoc +++ b/modules/ROOT/pages/clustering/monitoring/endpoints.adoc @@ -173,7 +173,7 @@ A cluster member may still report `"isHealthy": true` even if the database curre Not relevant to secondaries, and hence is not included. | `raftCommandsPerSecond` label:deprecated[] | number | yes | `124` | An estimate of the average Raft state machine throughput over a sampling window configurable via `clustering.status_throughput_window` setting. `raftCommandsPerSecond` is not an effective way to monitor that servers are not falling behind in updated and is hence deprecated and will be removed in the next major release of Neo4j. -It is recommended to use the metric `.clustering.core.commit_index` on each server and look for divergence instead. +It is recommended to use the metric `.cluster.raft.commit_index` on each server and look for divergence instead. |=== After an instance has been switched on, the status endpoint can be accessed in order to make sure all the guarantees listed in the table below are met. From afc8c6a98794a8a01fb0bb4ce2e1d3e1596cfe25 Mon Sep 17 00:00:00 2001 From: Natalia Ivakina <82437520+NataliaIvakina@users.noreply.github.com> Date: Mon, 4 Aug 2025 11:45:42 +0200 Subject: [PATCH 24/39] Clarify that consistency check is not supported for diff backups (#2515) --- .../pages/backup-restore/consistency-checker.adoc | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/modules/ROOT/pages/backup-restore/consistency-checker.adoc b/modules/ROOT/pages/backup-restore/consistency-checker.adoc index 48f511431..9a7249480 100644 --- a/modules/ROOT/pages/backup-restore/consistency-checker.adoc +++ b/modules/ROOT/pages/backup-restore/consistency-checker.adoc @@ -2,7 +2,7 @@ [[consistency-checker]] = Check database consistency -You can use the `neo4j-admin database check` command to check the consistency of a database, a dump, or a backup. +You can use the `neo4j-admin database check` command to check the consistency of a database, a dump, or a full backup. The `neo4j-admin` tool is located in the _/bin_ directory. == Syntax @@ -22,7 +22,7 @@ neo4j-admin database check [-h] [--expand-commands] [--force] [--verbose] === Description -This command allows for checking the consistency of a database, a dump, or a backup. +This command allows for checking the consistency of a database, a dump, or a full backup. It cannot be used with a database that is currently in use. Some checks can be quite expensive, so it may be useful to turn some of them off for very large databases. @@ -30,7 +30,7 @@ Increasing the heap size might be a good idea. [NOTE] ==== -It is not recommended to use an NFS to check the consistency of a database, a dump, or a backup as this slows the process down significantly. +It is not recommended to use an NFS to check the consistency of a database, a dump, or a full backup as this slows the process down significantly. ==== === Parameters @@ -199,6 +199,12 @@ Consistency check === Check the consistency of a backup/dump +[NOTE] +==== +Note that consistency check is not supported for differential backups. +The backup chain must be aggregated into a full backup artifact before running consistency check. +==== + Run with the `--from-path` option to check the consistency of a backup or a dump: [source,shell] @@ -209,7 +215,7 @@ bin/neo4j-admin database check --from-path= neo4j [[check-database-from-cloud-uris]] === Check the consistency of a backup/dump stored in a cloud storage -The following examples show how to check the consistency of a backup or a dump stored in a cloud storage bucket using the `--from-path` option. +The following examples show how to check the consistency of a full backup or a dump stored in a cloud storage bucket using the `--from-path` option. [.tabbed-example] ===== From 22324cf49eb41847b6ed79f20d5faf52f5dffcb7 Mon Sep 17 00:00:00 2001 From: Reneta Popova Date: Mon, 4 Aug 2025 12:14:24 +0200 Subject: [PATCH 25/39] Clarify seed from a URI that dumps can also be used as seeds (#2509) Co-authored-by: Natalia Ivakina <82437520+NataliaIvakina@users.noreply.github.com> --- .../standard-databases/seed-from-uri.adoc | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/modules/ROOT/pages/database-administration/standard-databases/seed-from-uri.adoc b/modules/ROOT/pages/database-administration/standard-databases/seed-from-uri.adoc index d5e3edd75..570c19d4b 100644 --- a/modules/ROOT/pages/database-administration/standard-databases/seed-from-uri.adoc +++ b/modules/ROOT/pages/database-administration/standard-databases/seed-from-uri.adoc @@ -54,9 +54,13 @@ Starting from Neo4j 2025.01, seed from URI can also be used in combination with [[neo4j-seed-providers]] == Seed providers in Neo4j -The seed can either be a full backup, a differential backup (see <>), or a dump from an existing database. +The seed can be a full backup, a differential backup (see <>), or a dump from an existing database. +When using `CloudSeedProvider`, the URI can point also to a folder which contains a backup chain. The sources of seeds are called _seed providers_. +Backups have a `.backup` extension, while the dump file can have whatever extension the user chooses. +For example, the backup file can be called `myBackup.backup`, while the dump can be called `myDump.dump` or also `myBackup.backup`, or any other name. + The mechanism is pluggable, allowing new sources of seeds to be supported (see link:https://www.neo4j.com/docs/java-reference/current/extending-neo4j/project-setup/#extending-neo4j-plugin-seed-provider[Java Reference -> Implement custom seed providers] for more information). The product has built-in support for seed from a mounted file system (file), FTP server, HTTP/HTTPS server, Amazon S3, Google Cloud Storage, and Azure Cloud Storage. @@ -114,6 +118,7 @@ include::partial$/aws-s3-overrides.adoc[] include::partial$/aws-s3-credentials.adoc[] . Create database from `myBackup.backup`. +This backup can be a full backup, a differential backup, or a dump file. + Using Cypher 5: + @@ -136,6 +141,7 @@ CREATE DATABASE foo OPTIONS { seedURI: 's3://myBucket/myBackup.backup' } include::partial$/gcs-credentials.adoc[] . Create database from `myBackup.backup`. +This backup can be a full backup, a differential backup, or a dump file. + Using Cypher 5: + @@ -158,6 +164,7 @@ CREATE DATABASE foo OPTIONS { seedURI: 'gs://myBucket/myBackup.backup' } include::partial$/azb-credentials.adoc[] . Create database from `myBackup.backup`. +This backup can be a full backup, a differential backup, or a dump file. + Using Cypher 5: + @@ -190,7 +197,7 @@ The `S3SeedProvider` supports: [NOTE] ==== Neo4j comes bundled with necessary libraries for AWS S3 connectivity. -Therefore, if you use `S3SeedProvider`, `aws cli` is not required (as it instead is with `CloudSeedProvider`). +Therefore, if you use `S3SeedProvider`, `aws cli` is not required as it is for `CloudSeedProvider`. ==== The `S3SeedProvider` requires additional configuration. @@ -236,31 +243,41 @@ Where `` and `` are provided by AWS. | `file:` | `FileSeedProvider` | `file:/tmp/backup1.backup` + `file:/tmp/backup1.dump` | `ftp:` | `URLConnectionSeedProvider` | `\ftp://myftp.com/backups/backup1.backup` +`\ftp://myftp.com/backups/backup1.dump` | `http:` | `URLConnectionSeedProvider` | `\http://myhttp.com/backups/backup1.backup` +`\http://myhttp.com/backups/backup1.dump` | `https:` | `URLConnectionSeedProvider` | `\https://myhttp.com/backups/backup1.backup` +`\https://myhttp.com/backups/backup1.dump` | `s3:` | `S3SeedProvider` label:deprecated[Deprecated in 5.26], + `CloudSeedProvider` | `s3://mybucket/backups/backup1.backup` +`s3://mybucket/backups/backup1.dump` +`s3://mybucket/backups/` (folder containing a backup chain, only used by `CloudSeedProvider`) | `gs:` | `CloudSeedProvider` | `gs://mybucket/backups/backup1.backup` +`gs://mybucket/backups/backup1.dump` +`gs://mybucket/backups/` (folder containing a backup chain) | `azb:` | `CloudSeedProvider` | `azb://mystorageaccount.blob/backupscontainer/backup1.backup` +`azb://mystorageaccount.blob/backupscontainer/backup1.dump` +`azb://mystorageaccount.blob/backupscontainer/` (folder containing a backup chain) |=== From 2cd1738cb3a8a76f123c5c25ff3e64b8f72076ae Mon Sep 17 00:00:00 2001 From: Neil Dewhurst Date: Wed, 13 Aug 2025 10:16:14 +0100 Subject: [PATCH 26/39] Use v2 workflows rc-1 (#2528) --- .github/workflows/docs-branch-checks.yml | 8 ++++---- .github/workflows/docs-pr-checks.yml | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/docs-branch-checks.yml b/.github/workflows/docs-branch-checks.yml index d96cb50ea..72f98fc99 100644 --- a/.github/workflows/docs-branch-checks.yml +++ b/.github/workflows/docs-branch-checks.yml @@ -30,7 +30,7 @@ jobs: docs-build: if: ${{ inputs.html || github.event_name == 'push' }} name: Generate HTML - uses: neo4j/docs-tools/.github/workflows/reusable-docs-build.yml@v1.2.0 + uses: neo4j/docs-tools/.github/workflows/reusable-docs-build.yml@v2.0.0-rc-1 with: retain-artifacts: 14 deploy-id: 0 @@ -38,16 +38,16 @@ jobs: docs-verify: name: Verify HTML needs: docs-build - uses: neo4j/docs-tools/.github/workflows/reusable-docs-verify.yml@v1.2.0 + uses: neo4j/docs-tools/.github/workflows/reusable-docs-verify.yml@v2.0.0-rc-1 docs-links: if: ${{ inputs.links || github.event_name == 'push' }} name: Check links needs: docs-build - uses: neo4j/docs-tools/.github/workflows/reusable-docs-links.yml@v1.2.0 + uses: neo4j/docs-tools/.github/workflows/reusable-docs-links.yml@v2.0.0-rc-1 docs-lint: if: ${{ inputs.lint || github.event_name == 'push' }} name: Lint docs - uses: neo4j/docs-tools/.github/workflows/reusable-docs-lint.yml@v1.2.0 + uses: neo4j/docs-tools/.github/workflows/reusable-docs-lint.yml@v2.0.0-rc-1 diff --git a/.github/workflows/docs-pr-checks.yml b/.github/workflows/docs-pr-checks.yml index a98780604..0dfcdfeca 100644 --- a/.github/workflows/docs-pr-checks.yml +++ b/.github/workflows/docs-pr-checks.yml @@ -13,17 +13,18 @@ jobs: # Generate HTML docs-build-pr: - uses: neo4j/docs-tools/.github/workflows/reusable-docs-build.yml@v1.2.0 + uses: neo4j/docs-tools/.github/workflows/reusable-docs-build.yml@v2.0.0-rc-1 with: deploy-id: ${{ github.event.number }} retain-artifacts: 14 + antora-extensions-exclude: "@neo4j-antora/xref-hash-validator" # Exclude the xref hash validator extension # Parse the json log output from the HTML build, and output warnings and errors as annotations # Optionally, fail the build if there are warnings or errors # By default, the job fails if there are errors, passes if there are warnings only. docs-verify-pr: needs: docs-build-pr - uses: neo4j/docs-tools/.github/workflows/reusable-docs-verify.yml@v1.2.0 + uses: neo4j/docs-tools/.github/workflows/reusable-docs-verify.yml@v2.0.0-rc-1 with: failOnWarnings: true @@ -55,7 +56,7 @@ jobs: docs-updates-comment-pr: if: needs.docs-build-pr.outputs.pages-listed == 'success' needs: [docs-build-pr, docs-changes-pr] - uses: neo4j/docs-tools/.github/workflows/reusable-docs-pr-changes.yml@v1.2.0 + uses: neo4j/docs-tools/.github/workflows/reusable-docs-pr-changes.yml@v2.0.0-rc-1 with: pages-modified: ${{ needs.docs-changes-pr.outputs.pages-modified }} pages-added: ${{ needs.docs-changes-pr.outputs.pages-added }} From b6e04e9c6b7718b63246036951fd17c9699cecfe Mon Sep 17 00:00:00 2001 From: Reneta Popova Date: Wed, 13 Aug 2025 13:30:33 +0200 Subject: [PATCH 27/39] Add cypher-5 and cypher-25 role labels (#2527) --- package.json | 1 + preview.yml | 1 + publish.yml | 1 + 3 files changed, 3 insertions(+) diff --git a/package.json b/package.json index b36c6d4e7..ae22c8992 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "@neo4j-antora/antora-page-roles": "^0.3.2", "@neo4j-antora/antora-table-footnotes": "^0.3.2", "@neo4j-antora/antora-unlisted-pages": "^0.1.0", + "@neo4j-antora/roles-labels": "^0.1.0-beta.2", "@neo4j-documentation/macros": "^1.0.2", "@neo4j-documentation/remote-include": "^1.0.0" }, diff --git a/preview.yml b/preview.yml index 096a9b673..5040a9d04 100644 --- a/preview.yml +++ b/preview.yml @@ -25,6 +25,7 @@ urls: antora: extensions: - require: "@neo4j-antora/antora-unlisted-pages" + - "@neo4j-antora/roles-labels" asciidoc: extensions: diff --git a/publish.yml b/publish.yml index efb53ef2b..c05d8621c 100644 --- a/publish.yml +++ b/publish.yml @@ -26,6 +26,7 @@ urls: antora: extensions: - require: "@neo4j-antora/antora-unlisted-pages" + - "@neo4j-antora/roles-labels" asciidoc: extensions: From 0595063395348408555955a5d3d5e5ee9d9c3005 Mon Sep 17 00:00:00 2001 From: Fi Quick <47183728+fiquick@users.noreply.github.com> Date: Wed, 13 Aug 2025 14:25:31 +0100 Subject: [PATCH 28/39] remove 'open a support ticket' requirement with neo4j-admin database upload (#2526) https://trello.com/c/qQJjbYjA/528-remove-open-a-support-ticket-requirement-with-neo4j-admin-database-upload --------- Co-authored-by: Reneta Popova --- .../standard-databases/upload-to-aura.adoc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/ROOT/pages/database-administration/standard-databases/upload-to-aura.adoc b/modules/ROOT/pages/database-administration/standard-databases/upload-to-aura.adoc index d51b1c031..1a03add84 100644 --- a/modules/ROOT/pages/database-administration/standard-databases/upload-to-aura.adoc +++ b/modules/ROOT/pages/database-administration/standard-databases/upload-to-aura.adoc @@ -138,8 +138,7 @@ Otherwise, the command aborts and throws an error. [CAUTION] ==== -This command does not currently support https://neo4j.com/docs/aura/classic/platform/security/secure-connections/#_vpc_isolation[private linking]. -Please https://support.neo4j.com/s/[raise a support ticket] if you have public traffic disabled and need to use this command. +If you have public traffic disabled and need to use this command, see https://neo4j.com/docs/aura/security/secure-connections/#_network_access[Network Access] ==== [source, shell,role=nocopy] From fbf7179fa98d1a831cf6d6d0bf0b28608d5959a6 Mon Sep 17 00:00:00 2001 From: Reneta Popova Date: Wed, 13 Aug 2025 18:30:10 +0200 Subject: [PATCH 29/39] Fixes the rendering of some pages (#2532) --- modules/ROOT/pages/clustering/setup/discovery.adoc | 2 +- modules/ROOT/pages/configuration/configuration-settings.adoc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/ROOT/pages/clustering/setup/discovery.adoc b/modules/ROOT/pages/clustering/setup/discovery.adoc index 82d977cd9..53ddb214c 100644 --- a/modules/ROOT/pages/clustering/setup/discovery.adoc +++ b/modules/ROOT/pages/clustering/setup/discovery.adoc @@ -112,7 +112,7 @@ The following settings are used to configure for this scenario: * Set `dbms.cluster.discovery.resolver_type=K8S`. * Set `xref:configuration/configuration-settings.adoc#config_dbms.kubernetes.label_selector[dbms.kubernetes.label_selector]` to the label selector for the cluster services. For more information, see the link:https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors[Kubernetes official documentation]. -* Set xref:configuration/configuration-settings.adoc#config_dbms.kubernetes.discovery.service_port_name[`dbms.kubernetes.discovery.service_port_name]` to the name of the service port used in the Kubernetes service definition for the Core's discovery port. +* Set xref:configuration/configuration-settings.adoc#config_dbms.kubernetes.discovery.service_port_name[`dbms.kubernetes.discovery.service_port_name`] to the name of the service port used in the Kubernetes service definition for the Core's discovery port. For more information, see the link:https://kubernetes.io/docs/reference/kubernetes-api/service-resources/service-v1/[Kubernetes official documentation]. With this configuration, `dbms.cluster.endpoints` is not used and any value assigned to it is ignored. diff --git a/modules/ROOT/pages/configuration/configuration-settings.adoc b/modules/ROOT/pages/configuration/configuration-settings.adoc index 035d5254b..612285063 100644 --- a/modules/ROOT/pages/configuration/configuration-settings.adoc +++ b/modules/ROOT/pages/configuration/configuration-settings.adoc @@ -4517,7 +4517,7 @@ a|a URI [frame="topbot", stripes=odd, grid="cols", cols="<1s,<4"] |=== |Description -a|A list of procedures (comma separated) that are to be loaded. The list may contain both fully-qualified procedure names, and partial names with the wildcard `*`. The default (`*`) loads all procedures. If no value is specified, no procedures will be loaded. +a|A list of procedures (comma separated) that are to be loaded. The list may contain both fully-qualified procedure names, and partial names with the wildcard `\*`. The default (`*`) loads all procedures. If no value is specified, no procedures will be loaded. |Valid values a|A comma-separated list where each element is a string. |Default value From 5fa926d74c0e3ed9a0239709756e348ee7b92df6 Mon Sep 17 00:00:00 2001 From: Reneta Popova Date: Thu, 14 Aug 2025 15:48:21 +0200 Subject: [PATCH 30/39] Document throughput based checkpoint limiter (#2535) --- .../database-internals/checkpointing.adoc | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/modules/ROOT/pages/database-internals/checkpointing.adoc b/modules/ROOT/pages/database-internals/checkpointing.adoc index 000406e0c..2ef608ba4 100644 --- a/modules/ROOT/pages/database-internals/checkpointing.adoc +++ b/modules/ROOT/pages/database-internals/checkpointing.adoc @@ -98,7 +98,7 @@ The default value of `db.tx_log.rotation.retention_policy` is changed from `2 da For more information, see xref:database-internals/transaction-logs.adoc#transaction-logging-log-retention[Configure transaction log retention policy]. Having the least amount of transaction log data speeds up the checkpoint process. -To configure the number of IOs per second the checkpoint process is allowed to use, use the configuration parameter xref:configuration/configuration-settings.adoc#config_db.checkpoint.iops.limit[`db.checkpoint.iops.limit`]. +To configure the number of IOs per second the checkpoint process is allowed to use, set the configuration parameter xref:configuration/configuration-settings.adoc#config_db.checkpoint.iops.limit[`db.checkpoint.iops.limit`]. [NOTE] ==== @@ -106,6 +106,23 @@ Disabling the IOPS limit can cause transaction processing to slow down a bit. For more information, see xref:performance/disks-ram-and-other-tips.adoc#performance-checkpoint-iops-limit[Checkpoint IOPS limit] and xref:configuration/configuration-settings.adoc#_transaction_log_settings[Transaction log settings]. ==== +Additionally, starting from 2025.07, you can also use xref:configuration/configuration-settings.adoc#config_db.checkpoint.throughput.limit[`db.checkpoint.throughput.limit`] to define checkpoint speed in terms of bytes per second. +Compared to the IOPS limit, the throughput limit enforces a stricter control over flush speed, with the checkpoint process yielding more to stay within the configured throughput. + +Starting from 2025.07, the checkpoint log messages also include the average flush speed: + +.Example of a log message with IOPS-limited checkpoint +[results] +---- +Checkpoint triggered by "Call to db.checkpoint() procedure" @ txId: 92, append index: 92 checkpoint completed in 7s 464ms. Checkpoint flushed 251909 pages (9% of total available pages), in 249641 IOs. Checkpoint performed with IO limit: 600 IOPS, paused in total 70 times(6026 millis). Average checkpoint flush speed: 281.1MiB/s. +---- + +.Example of a log message with throughput-limited checkpoint +[results] +---- +Checkpoint triggered by "Call to db.checkpoint() procedure" @ txId: 88, append index: 88 checkpoint completed in 39s 457ms. Checkpoint flushed 314688 pages (12% of total available pages), in 311753 IOs. Checkpoint performed with IO limit: 64.00MiB/s, paused in total 77 times(38085 millis). Average checkpoint flush speed: 63.04MiB/s. +---- + [[checkpoint-logging-and-metrics]] == Checkpoint logging and metrics From 3e14389b155bcb7af34fec1837fdb0d788c34778 Mon Sep 17 00:00:00 2001 From: Lidia Zuin <102308961+lidiazuin@users.noreply.github.com> Date: Fri, 15 Aug 2025 10:33:16 +0200 Subject: [PATCH 31/39] First batch of refreshed images (#2525) --- .../ROOT/images/backup-chain-aggregation.svg | 26 +++++- modules/ROOT/images/cluster-on-k8s.svg | 81 +++++++++++++++++ modules/ROOT/images/federation-sharding.png | Bin 50705 -> 0 bytes modules/ROOT/images/federation-sharding.svg | 73 +++++++++++++++ modules/ROOT/images/manage-dbs-community.png | Bin 23153 -> 0 bytes modules/ROOT/images/manage-dbs-community.svg | 9 ++ modules/ROOT/images/manage-dbs-default.png | Bin 51124 -> 0 bytes modules/ROOT/images/manage-dbs-default.svg | 31 +++++++ modules/ROOT/images/manage-dbs-enterprise.png | Bin 43814 -> 0 bytes modules/ROOT/images/manage-dbs-enterprise.svg | 31 +++++++ modules/ROOT/images/remote-alias-overview.svg | 83 +++++++++--------- .../composite-databases/concepts.adoc | 2 +- .../pages/database-administration/index.adoc | 6 +- .../quickstart-cluster/server-setup.adoc | 2 +- 14 files changed, 296 insertions(+), 48 deletions(-) create mode 100644 modules/ROOT/images/cluster-on-k8s.svg delete mode 100644 modules/ROOT/images/federation-sharding.png create mode 100644 modules/ROOT/images/federation-sharding.svg delete mode 100644 modules/ROOT/images/manage-dbs-community.png create mode 100644 modules/ROOT/images/manage-dbs-community.svg delete mode 100644 modules/ROOT/images/manage-dbs-default.png create mode 100644 modules/ROOT/images/manage-dbs-default.svg delete mode 100644 modules/ROOT/images/manage-dbs-enterprise.png create mode 100644 modules/ROOT/images/manage-dbs-enterprise.svg diff --git a/modules/ROOT/images/backup-chain-aggregation.svg b/modules/ROOT/images/backup-chain-aggregation.svg index 7323dc17d..bd59cae57 100644 --- a/modules/ROOT/images/backup-chain-aggregation.svg +++ b/modules/ROOT/images/backup-chain-aggregation.svg @@ -1 +1,25 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/ROOT/images/cluster-on-k8s.svg b/modules/ROOT/images/cluster-on-k8s.svg new file mode 100644 index 000000000..08fb8e674 --- /dev/null +++ b/modules/ROOT/images/cluster-on-k8s.svg @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/ROOT/images/federation-sharding.png b/modules/ROOT/images/federation-sharding.png deleted file mode 100644 index a34e6af96252e5a8440cff18df2ebea84e89261a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50705 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 HjD!9Uq2djS diff --git a/modules/ROOT/images/federation-sharding.svg b/modules/ROOT/images/federation-sharding.svg new file mode 100644 index 000000000..b95fe20fc --- /dev/null +++ b/modules/ROOT/images/federation-sharding.svg @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/ROOT/images/manage-dbs-community.png b/modules/ROOT/images/manage-dbs-community.png deleted file mode 100644 index f3ff5068e1a1504044d4dacd74f30e1cba85b4ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23153 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 CPUH&! diff --git a/modules/ROOT/images/manage-dbs-community.svg b/modules/ROOT/images/manage-dbs-community.svg new file mode 100644 index 000000000..fd87ba36e --- /dev/null +++ b/modules/ROOT/images/manage-dbs-community.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/modules/ROOT/images/manage-dbs-default.png b/modules/ROOT/images/manage-dbs-default.png deleted file mode 100644 index 24ddaeae22e72e26e32ce3dba91216a98e6cc117..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51124 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 diff --git a/modules/ROOT/images/manage-dbs-default.svg b/modules/ROOT/images/manage-dbs-default.svg new file mode 100644 index 000000000..fa3788270 --- /dev/null +++ b/modules/ROOT/images/manage-dbs-default.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/ROOT/images/manage-dbs-enterprise.png b/modules/ROOT/images/manage-dbs-enterprise.png deleted file mode 100644 index bb28c14893e413a7ba8c9b9dc825da69cadf7014..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43814 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

wJ7*{kZ_j|0^-})zR5F|$+A_|V zB6ZWP=e6pJrTUSu$ndSSsLWii7r0xx=cQd=-(EY~8AZ71!%BhMn~CFXyhVfCyb@*it#0ym84{GhG2Q ztiIxC1ZO}ECLSSEf;xT6ZE9WX1*Ck@62p9SXOof~_|XE~T9{hAE6w`mgPU`GQfp@~ z&SqDxANSZ>9w>|$bE3zDL1BAmRT)bzUqpqW*{nvFFb##l(EJ2(>KEo1+h$$$j(;Hl z<=<@PX}&i*vt?dg_UREz@(C5phm!5l0lsJcnc!&ZHqMU>(#OwtvabK>*?zCfVKb&a zbD2Y}kH&_Yo`NOf;7%T=YuL%<%o>pPGtf1Mql{4#O;|K?QoEa|VCWgnoMVQxcc%2Q zAK%iR22qu}yl>$RbA2;l z)`+EK(MM>3_=Kzn9CeB5VdX5vGo{j}rK9k8f2CV;#7!#-!EFz-Kr);)qe+>_W*|_# zb%NEbvnXTNFflFU;(!NaL|>*T&QvIq9f>Qm$^XS;z_eMlOUhe5nF?lpC2+e=QA*p# zFm!^L%i>YROnn@~N$G-#%~YTCw^MSJ^+%v*Mr@s>j9E96-3Y79q7Tl|vDh{3O#nQ6 zJ!1_olxIxG#ORNVc+Dc}9MQFs(`U~2`1j_4U%zOALZ9U1%va74&p?;Pvc_Uyhhg0g zlu<@EQNtHCe2P(cIK0$7Xru^MOE}wx4Eor)Xm#nmLbR5YMYOelq$1KtrK+GIZV7pt zFbW@(uj+n{v{EyRS84T)vLO=WK^ntl#&*KWuvwxA!m8KfpyZ;cS97kH7(PHGC4wQR zHn<8Fadeg?{}!HInR$1!CeO%dx~;It4vwaFtbK+pr>oV#>zBa;H2{w8rUYgrJkj`&6n3)9&=!(v$MFV*Q0fG&DJvxqh zt%)c2N-R%s8FI(2A`Kb4r@9&qPXF4nipryBH|mm#A2lR zQC;3BEM2HC|9TyMfsXvnBD;1m^0|cqzB3RRa?azFCEc>_VZ_dI>Y0UXE_1Y`pBgDM z+jpNza1et?19WLqF((#cX5=k}Hd?VoV5k@EDTpeSjLvIpB!664omeG+8mu1B>5uR! znL&@0NQ1O;N+dt5txstg-Jcfj#ru0|XlE_nt836^Ypq#5(I}mi)Pu`vcX0DW-7}3k zsr(cC2Op~LLfAu?2i`a)O~*m&dOPzqIg3}GK`glq@Fgd$J@Wd65o7`_QLaqfVswO* z6?`2l-np3K+2GgBcLQXPUIg|X6b){j78se77>C1v{moeWxfnISSa21vlL(o`3 z!xYvq1(B1F#yZnQn~I@djtt4};cqN6Z&U{J!l**sRk}hoCXhSIpv>v9_K${EIc;hv=jOY867B>DB(fnDaC4k=nAm)({_!j;z4}JRNBHA( z$(q%ES6>7b4meKqvI9Lc;Ye2rd%l#tCKlVGjV*Q-j$b~b4Oad5Ze7-vfxCLD273su zV>D6ZC532~9kQ4Odl19h^^-nk9e(_c_VVxf#3gcYRE>9I+e_^!aJ`lg%LDUJYp|+t z7q>e2V&bQNp3)vK*)v4$@`@lzTS zezYXb0gu7}KlX(e{e~ODN-<|v?7i_7CrIe6k=!r#GoU|CCka1fl!a8S@q|Hb%4*qL<<1+4z%Hr!0sa~TEXn2zJ zX)^#c;zq=6OO32!IX~*P3iO(27`W%l!=@&{7B$qeX6t=%{*IQ#+gM2QQG8I>NSHfq zrxN-HI>^B5$9E%=7{;_Ev#cPO_yvtHse{EN+l;Do4#nI|IEzC3Tcz$<=wMJlEuL4f zlutk7?+40f@^uTQ+yljtnPx4nd7#lB*;z^CvN;y(v!Kqo^0@%;G%1T6ue4D6JA#Uj z4Q8S&xetM1oO>vN_SF4`2b=74mF)Dp%C3(9 z`a?w8wlOz~bHSJ|AW{ar$lg%~W-MSnzdP|Rq}vGHeMuLT?(QTE(wmnP_l~m_A(@5n zxsq!!U&W1C0K6gnP1b_h$qZFC0Tfv*8!^MG2Pa2Y!;&f!={e%~5x5mAhZ#!5|1H77 z`V}~$W-$v47PrUon50)dS&uT}Cx#GGCi+1PpIzseSLM>+Vuug?tit*^Pa=O#3_=4C zrbRx461E8-5+}0`l8WQ;^8_CQeuH-0a#F5Ji>5Q||KQrGa~7E|%ryWwzpU=%p=#z! zf8i>3*u(xoViD7Zw(Bg}IwNIB^0_1oCWlX*b3kg5%Ypu*YCy2qN3V+qI_gej$4>=I zh(CNUd!{mwTgl)2bFgSTfa_z+&*x;HLJl~c{r)JeV#nhbf}@6PJP>m%Z|>B2+khsqai}abtwVp2BA`pKq|bP z`K_Rc+uI0riFZ_b?CtiDYuWBZ@=gCZVOoKEJ~j&bddnds3XF5j33UnEF`j9Xdop5- zdp3zpZRu|X>+v|sRDGhM0CG<0Srza?BV9B;(q|kzRZGUZgZa`w9xgvOR$y3l6a)hn z+u&m@k&C2KD;UG@c}5MdBFVCbUVlQJh*;L3r2-~KzAzEYmP;}pq|N?Jhi3IvN&ADw zx8$mZm4_SS6n%iuM@O6mW_WPquARwL5c_pCuq4*r*Ex3EM@3ST7$H5j0I04g-?xF` zwvlM45y?21aS~)D13L~UJ_?URV=V>k!vlb}74TIaa=`>6l$)LQn^{d--#8-O=A{k! zh||_z2!F8cb_x?2<^wf@I|m!U@c|y8^#X@^ZKl(TYK?S9^6Jf{juaaPSh1&ZO7^#( zbiEaM+;C@j&;N)zfpDnHc=&c(&BlA}3l5xFyTLE4^E$n1QF`sw>00%gd*-Nxq(TV& zBMK#pu5}G&B%q00e$s3|RnzOC?pu1itdB8p<)fT}Wc@bddX#n2?|h>3Ad*v~Zi?fU z%3M=dcZtA-Sm7i2GQoaL^|*@3WeR{Z3zgp$>BBwAk&(^?(kB8ryJ@7oRy7S-=zo33g^A+~gz2+mQcdzbcxW^E> zp%%U3Rup> zlURa;?kelUxZxS(c>VXk0A|arRB7UxZO{99$2of z8Xdr=)E7c|v3iKZR`<5hv33CcNJtoh6}zoo(+>s+(VbEq;+*5eDDK>}vGQ zql$BlHGDgMJf;=&{Ik0z2XtqWaS`+3W@&uubs|8(yuY_vU zU&!4;NPM$C&jjn1viIl>lr3kZ1R6Ha4q44Tm6lp;ps-Z-IE@y~G z0Q%_stHmmcd{lm|bHQPbjz0KUBw6Hl!41Mlxe^_udQQU@WTkcjoIv)~9(nQ9e0;HD zq7L@!p&kgeN6D0oubc%Q?|@wkp1R^?+$BOWBYKjU5Jm|D@MQdShQT!U=vNix-kdw> z+j2+IROx*h3c!YmHli zb0S6`V2m1hjL&x(`K2G;ZMd_i?Z1D|+mmNo(N%ZA;*tf4bjftMI+1$f*m59&qeyqwi%#$bX)r7oaV|?qW25dZ*6dGj9-C z-*UKx0~;g|Pcx`)Kdb1Ha!MTF^`P8_anP+>>obDXe_3&KfFMw^B7`)9H7z+tPi49o zu(GZ@{5+mOCelmvA=LM4e6y_6r$_#4>C)0bT$XA}SR=A0iUVp!PU#waLv|nn%!mJ6 zEM->(VdB{nQ`n>)2oP)()U3gCOQ~bm+%M#vs&@-zU8+TR8^BG;EZ{ucmWK%l?yT=12W*tKqdHQO{z*Db-1A(^UB$b1wE#xpcV+wC)a zV^9#FVHH?iHiZr2KdSCpw4Ew}HQ;HtleQ4Fht9UJEL zRKGRS)(c#F#BBew5b8B}EUSivQhm*VNVh?n#^)+;U$82^FzU@iNZ*L>F6r0?hJV06 z9gb48ZDv^2KM2y?#OB#}bO-jBm^(UbZy6zRb@d$!UydssTb7tU=m^(g z3@dp9l4=CLhbgoe3gvO|?y`?n*tj2^?3JVq#^uY0gNT47%%yk_+q3>_&7EbhTUCL% z9TI&k=r?{4tJbHYhk`(tUpwKfkysb~Vf375g9tGP%02-yR3D-_?Rm~>aa_q?t?6!T ze(xQn(eQuQ)MPA*j+q~R7>!@E+pdM6#*S@RkS9q18Auy&!Z~Pui3b~q#04_-Ret*M zAFyob_i%Yb+$}yF00b5jl!Y+CTf<_p>)G&| z^#YyNTbG&>h`VJrz&<#2Byae9*M2dzsGJsp8=OjHS*g&LcVG(6wHPn|Dvft1 zR3Ga}`&_=MVDh&nTuWA1Xc?FU*r<55dN;?A7d4s%w5D#5nef!yObQFL#4f_ig>5*5!BQm)qrsKiPILK;& zPK(79`-YznIrRnB%v1ZINK-G({ZJHpwx?t{OfAVJx=x zj2ml?RCO+p&-)hv>PW##_RE&0ma8kjx9G$8(h6;7mfCb}F@|m@U~nwy z5L*1RnQ)xV^U&qE+1RI-v?EM5&jc{Dr4AYvqZwcDwm66-W5Whnf60B0gM|R5k72cp zXJ8orN#z}9z0)l!5Wmmw`r2xz_*(ZhJID)h?1TAh4?9wlUCOeY64}LMkAgq zyyulSZ4TR2Ak){7einw7cvz_erM?|Rwd1F-^5W0;fA8#d-Q|*d-|FF--3~LkJhi(t zJztk+Vom%@u*uBULxD0{TRjp2m$qOY+kccSS^E|?X1W9Y?9sta^2}`XsO=Cgj_ZEDiCt;4oMLhly{vVTo?OR!gpMr44>Rs|y z|MImr2~3MReCO~HEpkzH`+^7B4dW8b;IPKmA=sI4hapP&2)H%D82&qqk(O27wg4vf z9)x+IyvXCQF9Uu0%;52jU|$0H6}MNrI^Ogit8n$5XT8|c)Or=nyFbA9w}Z_8v3vZR z9t0pG=s$+b)cq>heE$C1yAtLB4L&U=BIOT3FRW;nogr&A^zGYS?%6u_eP)mLK7D!Q z`CbIGdwpXGwhzzR&!A85p74-Td*I}>5~lUv)!bh8e!{&jPKF0oGt`HG_v=CLx+X&VP&{SDvbsrzAHe?E3S_KOweY8!<3ap}^E zRaigcpV4XiC-k&SL02}N#X#!wuQ~(}SB6dV!JgW8kz@WO46ED;$WQ2VQ5o=H)^hT% zf9vZLc6;BsyQ+C_2Edq|RhTz&hiI&uCn}FUouCz((A#hl{DUdlo~^p={OVLFIDBdO zC~OV)KM>{@r;@%mX^TLS(9%>BF+(x;RJbUB%{ zzmnx^Y}L)xe-(kNk60OS{~ZfHLT0xW-dFyp!=Zl#>9553XwcP#?;~risVM=JrbN_v zLtALW&jECHpEbkAqvVg$ZT7H=mCPMJ6Pwr2u*zlKrpuBWS=;z+y3H9hg2%*iuKo2b z8LAbV8}(Q2nU=4$CE^EQ@=s$9_+P4SE8EnY8v2%(FTx6M4?^3T)SKsemsS>m@&7-p z?{4!gulPmPZ3}kv^gKEuozO*!qq+pzo`NxzANoB$du5>f&#=Tm@EjRv&N{As z-*^A&M}=;`6w9Jt2{APblFEzgwquj7N8%KJ1vJO@%(Shu*op;#p2phyPe*Z#PnLKL zVO~0~=mhMD_n$DcCrlwtOqe}qSu4%94AE7~9>6#F8>dH} z2|@mOY!!bdzH2`OkOSw(v@i5~!y};;G_#~+L)!EOmSjnvb5>E4+cZ+vJAAC z<@f4;luIifjGALpDMm##`yEL9_^>4}=R2frx~9p~@h-G4_i>=}SP1x>R5Hu7G!~r| z?TDo|qoeXJ)>?nP)d;UoiHUdhGMFRon>>w%EPen%I~{_dt5oT}Hbs-#ziVDoFS>W_ z9}m1=SuLKpy4!Ab)H|NW-k^<&jrl6e9q{#-#LImL$qrfj)N1 z*q{<&QIa!4RJZKQ61X#`nuOcXiRigPh$$?v zAVy=F$1wb6jD`nh-h`%2f|`WZ$KYZgV4B%`&8;n;(w3FDMh(Bup?FF8e49=GS7dPc zU~)(Zm}1o7W~_a9u7BB@$J))%AM5Ts_p{!-7}D1xJ+v1q3R;R(cd4;T(`O<76G7MM zKx+bo{75iKIQ(VKl(-0;Wff?!1IHiZo7@0r&i7iI<+g+=V7&n(mKNq#-^oP_rKaDC z4%Ef5%LDj}eT}sxcBeSSH@D~kG55ty=zO-I{2ssE%Dc*TBF#=%AbwYzQ#KJM{L?VH z4goJuhEN}exzi40V1ouvqiKWr`5rZtcn^>r9d%5_0qx1>U^g!P0~gnXg6hqK!HTWD zvc!PL`Mn0_m+RjFkNYa}a~^diGc1Fw73le{d^2o@#DcLGi6=gKB*S3M{OS;HUPqp= zX?7^I2pG?U2kv$pQT!`iqAdhzopRl&jlww7L|mB;%@@boDE#`++=`WydFU~_(xoAw z5o6aQ^uUE^LK(F%r&fb2!4qBW1$)|Qn(|ZJ!}Oj*m9$iEa zW>DLZ)4-tbciNm^^{=RSEZ8Pi*8X4tm|O2dbZ+}*JW26SRt_*f4lnc-*&J9vMbjrK ztds>IHxjs$Ll!NjQUnGFI!i~oI(9^7Fl#Vr*^K;QG8Hwrwi_nzy(oL9sfOTgRrXGehyDp&)d+!2#BXVKM@Z@OMVA~Z4bF2i1 zKSMEO5Yy@%y!CDMn$zYG^G2O5-rc`e>^!u!cNrYRsmJC|wr~rZVbL6H(Yl2Kp19RQ zK+an+aq$fZ`+R4PM>lf4PP_1;J?4X16ey|Xp*M|bRHhrwJa(7`?GOe|G*BCkaY=;n z+YU{Fgmws~;C5Kco6w5u!ENf{m0B-#9Uk6o&6RuW8)^H=ZtItZ8#Jd}Q|=3(oqi3> z?>yA6@8gnq@nls(638sXq$v|~iZbGvcz&7FrM`}F@~4zxJW;*q?MwNVl^KyKFCiw z4LzgpE8TX3fAaKK%;jrVwuZuM`#g@^#k+J|`o%@2g1=xED}Qf0RaRKoU_ziyY70^KY8k}!b@Lz@j&aL1DN7Q8asqx>LEJqF=mO0 zJQ#RBXPC=XWD~YASjPa4lJKPvq7;CPgitSrWvmDS-UF;$5U%LhDtu-*i#3k;4r|A? zxOzcQTLl3i>pyi}g~ZUPqVJ~}`H=J40dxjoZBzR&O!gVN5wHk`cbO`DAUbO!QrDyT z3uPluz4!Oul& zn1-P^bcKN1mIGn_O)+8EG@)Urblv{f#jrgS`zFx4Dj*ZD!Ne;3mjaG zD9D$94b4R(_oS=JU>XqAYFD!SY*IFY!R-a3o0KeVvio4Q#Ypo7U1^{9IvhJa%PL;Q zyS>oTY`g&>Ov}cGd+XJotjvtPA4g|cmnUKs$qPW=OCVuRN++EyOr^FrISzf(;_+R; zG)~J2%TsNdYn?yG_avMm{~B&Jch_vLY3<2*E@_>x+$?(EpCKK^*AvpmTVia|t4uwQ ztZndF$b(qUg$2P0VUN$(v}4%I2}y6s4yf2+><PIVIvG{~4g8E*{_bU!sXM^&=4WLNou;aW{z*e5cX4 zxrN*Ix{pNR{=!^1#M!|3N$cp97H~u%nQ*~s*fVURUg#x7!}Bl|X*x8tGoT$T0F#`9 zDh{{WcV8QMH}44L1X`4==;n6EWq`aFddxeh&ru8Xj!YwCu~RUhF$F^z*Ll3!2OcF~ z$5g%7<^8KS7+Q19fj#!1sB8)!l|bkyFar+a=v-V{oR2}`nNkOxggV*IrQQc4KMX<6*?V40v4*+E46}IH}x3LqeADbMW6KjC{;&9~{?qOrJ?5^D$)6+^Pyf1@G<>Fo69GWD z5q|61imxxt(TmlJ)gQGqg)1BC8(KwkU0Bo&Gr{~Z&XvJJ-eT$t(5PE=(!fpS$d#rx z0lN4sDvO1L(x^Nkj7s*&FJ%rjotSfZXpyXCvs&le#fc z*W_{1D>2_5`#I3=Snzo2_xecDVumdG^;i_PVy#2HXxUL;j|o$`iK$f(@ZZ!majg*U z4}GK6-{ff5>h?J=zi-iTb4@7YX_(4;rjjOVi76Tta_Cy_49%l2!nb}A=zjvt_izAA zQ=mm^G)XgQvMTgDqw6m;!l6j#>5bhliIYd1B}V3AdM1SW)WYM$w@&_{cy7yY#Xt6~ zg$;;?pN`EynmA!Y9iBpWv1Mi_B=$D$6oeavTEp>G^hCcbmAx*uVTdSHKhS;~&5F@6js1O(kVJ|T)1w0W#d*4>LT#eR*tw}4+FV+pW zC~)Z5*hIl6865w@@KLOBD!HZ9t2UUX_(0Ar-fo`q%5L~Z9y|ow zmJnXEgU+JD1pbgq{obkTp3XLHm>tt8QHSv&#{=gsagxnR9^5*;7sh#`y`ugnGX{pS zkckkVwzs$JpmKW(`2Icx{+}St(F^p$1-WrJ2abJnFs$$$mu7pv)GOAic_pt0XIE^p zJKJiZy@y5NJE2}p=Q^B!<{iZ>F~V&twB-!b9k!V;@ninIT!@bG325GMU`I$Z{gMAc z(@+~T50IW~l(hm~*L8BZ5Ou8w#giXCBEE6bT_VTsv4mD}j$i!KteeE~C3D3~+n+in zJ>bU`OcCczxKhk2ImN;y_8GK=<(8G zEv{Xq9`UJ~GIa|uuQcZPDvcA%YjtJRg+swsUAQrY29E0WtxDt-+Z^xg*S$16N=L4V>gogg-+Q65)U4K1Rh0RYq5%isO;|`(Q)&h_(5d5)w z{rwv?2C&8`i@)JVUYG|h+457XtmlYr|)i_TJquYhz898%p< zq8Vext7?9E6Zt3f7{Wqrg>?wMP>J#I^ateYMXr=LqBI;X%urD7fB43bmwVXr~9caxXjRx9})j6Y1c;<#UOH6U0+iu#-e7i$V!ub607{fmu^q-5af_1OLIqyrb@(xgp;`I z19u3ajQ?`4)Iz^XwbZJ1eP5|Ao&q-K9KG!elF#Zk{G1pv{;P<3h84=sH-VW!d zMs(=vq~@Y2Bn_n=SH1Fp*2*#`H>#YRb}Tvn3}s9 z)+1Vzy$ang;EXEHUFy&N$$9720FS=~Puh7JTIQ%J-x&H-*CscIfw)?+LcI z*4EZHg{+Qu%;Gl4mY5>H(`MJb!wsd6fURqSJ|<@-g!qXzq0azMD8;vESz;`FA|FOy zp-SyJrP@&L*0xaNp41-5oK#sa&Y3jVE_icOAYnGlT_nyLbCD(B zHdMVO-rid-b{yI=q)hQ-TBlXt=8Y_~{0L~l7#el|q!*E`>hf13l#fR>lZD( zJD30|)_#zqaDNnz&n4Fao6Xv^rq*He?D2cN+h9G|2CLUD2+%62FWhh3UtXuH*7~p> zYCFObL)JD5sao8+vczD0e0PqSj~N-mFh1oMlcxLse|zTvU{!VP{e8|YQ|=UIU@Fo< zL5v+WHUwK@nkLco`cl5n_mVFrQPh}Z@?K&~ucpUn+5@ApVMV}L5Jdq2ks_UGwCUxR z^ZnMj_rlCD?athpxp!C_)|_+C*=LvkK4-7J*Is)q27nVS6PU&~fD)T?9H#BYq1ntk z7w-c`>b0x$rCt$N-OfRdksoi#pQM5YJTb(Tk5qmZIQ-TGVR>uH0)^%Zj-h}ve!&| zyop{(bk8}gB8twObEG%a~q&M-4+4*o9fiEWD~|w|W1}&*HA?oKCGFGg+_S2NOKi z%ouwT%)j2eb#Nmh=vU3=1M5vq)84_)UOVNO+#gc@;y^je2(!(sai_cc$z?X~L5bUg z&C>3|>Z%py{x|+;s=*{YH1;sM%XZXXWhNFir`iJokx01A z_WO@VEBVpd*$=NO$;&J6GecTtZe6eJroSyB*t3A7JgP^{h3^Q zw2!nb%#uEu^xD*#LGP?PQ@ zF-IyJPc!;VhX;=;M=D%!cCbY8w|(E3S4nAP#L<_;EforVxD2C;p-ZiVY3*&;VeVe@ zLvu#W1?JMJS7BFV!r=j8|%{M#M4j7$wi zXRgA`5y|Zdhpn&H+&K3Qsb!HVVvYFVC7kxb(5(q{Z08bhvBA(sOU2_)WM^mnz_HCY z>FV6Q(~_Qskw?H?H@B><5#!vr@8(N3Nr^09H~=@3_Uo0QPrZ6U-oZ02F}2Ok%ca?o z`&pVe9(F!)Z%vbc@r)*7fgJoDGG?RsdEsfDE~w(KP%%@X1=Go5!ynn?9;AcX1m8!!W=6bcDmyE zL#_LqV&$C?)jHU8J@#O z{PVk>GIecO=+=-_1f-KE!CiFnUxJxG5lh_iskhLG85L2VhF&@n<&!LZQ-`t4^~{-IPQ)o%QJUm zoWQlEDOS{8i<7ntJ)E|-J`7A3zHYKvmwO(;`Ag8NqihwAP&cRvP*t;Q)au&TP(MU zxI90jz&!?hQAIY1Kae1XbXM$s##Q?3FC%yH>l?y>6lYXEoGR1ZqDhKhOntcu5f8_3DTQH^~QOkI@FQe8IL zLk-javdhdJYdy^TE0qi89q!P_or!xF+qslaW?Wyjj9AX`2yEqJUM20Db?1_MZOdE4 zJM=LIZuxyZulI)$0dypgx~!mwza#FR*s^@ZjtR@`?r{4LV~GZwRoXIi*@y09O}RgY zV}xo#Hb06ULtG&Wihso-kWs^g=Ro9_b);dUO9;vl7jH*}5l+ zfr$jc&t)6R)cb@Dh=Op~m7$RNQteH1U+eII#nKHQzx^Lb;`>~0qcazik{HA>A7njt zNz9$8k(s*xjt775vGXbs&)!CU6PO8huNcuGb3IKm0(9=+{#@9!f30T0C2J3-&K_we zoHw2k`X{*7tKy?PgK}7D1dVRIyyc50w3-_(-ikw@pE0oKmie$sVh$ravL}u~lihkD z5^}y>bK^xXyM@7Tx>uanI9A#%k)$m{A6GQ4O-z}-UK4GD{=OBmCN5sa)>f}H`I&_< z_fuU1G}8)ZxlB5){L$a^hBF>wA$J*ID>m5I)~qxeVd8bI2k0LL#*qcTmvBMr`b->%&E?QA*qBy)FDQ}h4G0IOq?W6az< zzu)r-zBEiFT01)4>;7CEnwT^E0c#fbUz9le7R-OM_|7Fiq)8bxn2*u6D4}WFc8}k% zTy3EZp0UE=@6_Bl@0ECtggwH)2=d$*|*mt9HS>&4+WMt(oJ@qV4d=Xe~K>Jxxy1m!VIe(B9@P zbJw3m0dBBCn54}1h2;AR_;c7IHr|xO*voS#p(%fy8JAsV#GiPU4-;o1u1->rWrLPr zv+K`&UvniI>bqS{{k<^q8kF*y+8ddJ_bJUys5G*EFH#BP*~xS6mePctAI*{Z;DZRp z>pA{D(jNSA%{MNo?xwz0SuSw~+`aQjmW+^ugNB2`~M zZyk(affMmRjd7A|8GuS$Y^SOiz5`5yJ7vJeU}--c_wO9j^2@3lF0VN%K?ZH5In!qF z0p1SdWof0K;xG$Vj`3p#ZI|OG;U%On|2`~<`NoBn=DLNyEGaK$Z@2vg-h*kly_J39 z2@VU7Dy?4V3jrCVtYzaVNjN4A#E9YetvOS z6x7ZtpJ$%g?&=mL4SHdoGDwK-Q+IbIxoHa%&-UfGgNQL1V@+OWfy?0YFtM7=3||!9 z+`aB7z{%D)S#uY~I255=MLCyoqd3>h;Gw?lkjud9TMwE;ZTsE4nuCq~(g{dLMFqD4 zw!|50cQTS26=_5nx%d%x9^za6Mb&~MVz{mq%&U0309%CLgP9AX9Z=xed^+>@VXk-w z+hl&!)mL4#>eQGX47`rJfF7TaMyYc-82A6`ZIzAM|HBeST}|B25_cxE z!#o|Zbwp|4=hE){lR-Kiw)3Z^VDQgJ>A^_y>^t{n=DZ!;zs9dZDD7tFQjN6j47P9I z?)Q~AuECY7PyC$u*AkRwXfVC7teM~ zX8$c0%M9z9()~?LGBVI?CxYYnt-o&EzqoH8o%a2dH!Dz$sQvz~gSMF1_jg5iE??%g&4*B$ z`~c(ZDZHClOw}3tK+p$2n%ik+i|8IC9}k*P_@2re=dbTJEotw7b1H6GVdfUDdDAzf zEkj?wX?>tISm~|3OGRTk{#1Oyhbkol*b>#{XkA z(9XtcqMZ-WtFK_t^GH)D_;j~3vn~*!w-8{Adm3!?d)&IP%k2UGqwR(r!-QO^4AxLcoIi1hIqW|mh`he^~$JkoXcw$$}u{p}*ak`zAcEwqLm zbW5#=QE0ul`s?%7^#~72a4_@JSr+*g@h|N$UYguUTZUd=SMT3}{dHM)mUZnbrhmwV zT$y^$Z{B;3|G0~jSj7|E#D2Yrh%uzm$P>PZ*OK3S?!Hn;_F!L#WJ~Pk=xY@KF^Qlaa-&>mF{00&HI%adNBuCcW1egNr zuq(K;BKOv(f0kwY&$KJX?r8v4y`wM2OdT4_+ahz7aq}G z@AyFc9RCYtIVI=t^On)T%%xgs%g|d|TRfrx{>t8en+qqs(>2}tt{ERTdHylx{*8Zh zt+vJ6?N~pGvYt4r5kKj1?R>#a@bg5%_%nArFg`zDMOyE9b~|=swevxF}mdez6mu5o_bL zX7HWb875ATzKgoO=0u$5f}zOD{q4&)b+=^EQv->^6_ahIdo9nk41zu>IQ0~Fu-9d# zPJ7&vnQav_2>U}r`*R0-Dr?nE^R|=UU9{)lGHm~Ocq+Ss_u>KuD`m7NHsvYxu^n2F zzBDr<-v_2IfbApL5LnjLhCnwES>x__Fvm9e=YXXsw$AA$PFh|{TZS%Zi+R3r~zH!I8LV?+b2%-*`{s z4|jyK19Xze-mR%H!?AoAnRFZ?;`71~Su#$obvzl7^C5@n)IzKu2Ptn*K5RO;-F%>% zIj*5{uQs+guOm)JxwwZJZcjj?AX8dq@+^MvrXJ>5*(uZ~0_tJ<1d*Y~3nKf0+{Mj4kCEX05N2UxQBG7+YO z&(ZOce1-C}G-BVFt8r% zdE}U!t;?)@?xc5{OQv3VlzCghOWdgnR`WBepT7V9UHzhHc@~WKmG~{s49B)-^U=&e z@oO?4&2a!*7!}{b;OYFi#(RTRYnZ(piOc`wg=k04r;92w3PQBB36Z+2jYY__osO)L z&a0AZyU2JO-}xJG_I1G~^!z&SD^09WM;Q49Jop8wb$Mb5BssQajir8{@)+xUZ%)qt zmYLA~Z54}IDQRrN{c69o8Dm=2uTnB0*DA|c9bmE^jUw_qFBHemc^U9h!jM^|le zsawB;Fmj)#z~c|2SeW@a^0>I)&n7D(%PYLc-?F^E(@VTXcj0yK)q1nyP*1b`q`dZpk3^ z)o{dlJ`xVTys!PaEq&n?$Bm;U+tU15o|#BGkhoc_(Z>CNka=#` z6RzQxOK_DM58}D(s+pg5XYWh4J!oF5dOl%W=kc`C>BydDb6V+n=He;ub9VrAb+IZl zbHPj8%(~mw;+6aP6>P>c^1%o#aWA7VQaX9Un266`W<@*`>C&g7Sv}sdA}DZ~65@>I zn8SycMW>s|Z(;5pu1WV#A0tP`(6IoMaL?U4aAtn-ok|dahmV|68^L$G1SqgR;1x*>TGpq?~m_(CJq#epJ zc2Z0eNjn$PQUO{ri=!}niWFt`?(>PZvupF7B@t<7%W0x+2T8G-=C6ej?FmN=n#s;i zuN~f5+0V&jF7|EoP|1plNR2UDxhwP!w!V$Y$TBne>|~uDNsPe(kb`j)`93W_*s`R? z2wn!{NgkMy=AZ%zHLN zmf*xY+Gq>nz3t@UIV?H6+hydU#oje6+4e6NC&8;g}9s#SB^}_8m&mU z-tyS>NYI;{pr^UX2{$y<9%$~m#ivsl2J-{aTR~1=ZmSJS=`AHy-EH!u#{72nhR z(RL;dR`+DqO*@C32FteV?MS5F@q}SoR#Q`Bu%X^$$WnqR|0O@r&iNTlxn3uL`CQK> zKHIs5vWX&;NFW9jc*h6&Xb<^W6Kvbu0#=t5?M7`!`BbMklr(GzfN22-vi225lijxfj_tR=O6QHD+GB5~^~ zi9z3m%o@0f^)@CGj`J4B4JI5~-`?7~YfzFH7}lAZ)_d1wPx<)V$?i6^ zIpgP=qU_Snv+fuGVo`7LmVdZzWc$s`tf^jM*4L~uRjer|joEd~G|A_p_*WV@&de@8!<@p73vnbPV)mXw4g2%| zcm1zj8}(v__81F@(--;*O-`mS;K_8t_H>VD%zWm$m(gjRPHz-Q9v&3J>J z$cfB^Pv|RdpZB9{?C+(sdI!Rfo!L2=&jlQ3N#y&>pKoi59E1bYkuGl^@XWo>0;EiY z!|m+#`LodMnBlQ=E=3-62~6h{@JU)b!;Bb^iDQ+%!V$*TSImz0c_*b$J{QJ$7AI>R ztKeT{XNDhhPFuXAs=cv}B^D8{@%j!RV1@7idM7+7^kSzJki_JdN3t0p=GqZ&w&nF? zd#!MuNMdXg&c$Z|3bIIIM2RwD`QnloUiu(72f-vNiQ&kSNuzD7I?EHOH(^h6tJB^T zZVflq?~gQfHE-Oh41@W>@?c*1q};4PMmc$3mf^8J$Z+FKDer)j?T5r|z-bTBgQJR} z3r51Ugh`8svUjpK{haah-7Rfh@e?K}%5y^RJK>YALzMNkub55y*O@&H+i**IkacF! z#Twb*;rq_VX8icvDU|gjGrQwNG0nuxcld0$H# zGs_L3QNZ92w{vsQ!wxW$Z@k{w)c#|rNaHQM`YE9PN5XMoJTYnhP5AZioI zL*i@HUDFz_-)t)_%*rWbI#Y^X2 zRNsK`QT(Y7RmkvUnp_;cj6-x@mNUUj$eU)4%bSANw{q8bj)>U%3gUA0jeW0~C*S%f zgOk_$lsc?vDf>)Wj#U~tvuJbs8BgsEMXaXGc28UF{+1x4oDfW2ru74x5%g8q!Q4l* zX7-kOOrXG9P*UK}hy?v1<1esn{}g0_GXnv0mWAUwO|3W+vF`*pa0@ z$B5qXqVR>X{t85nAEjKLzTzi--__hb1BP%0MrQsmRjzV8zBRTP^Kx0X^?Jw@ZFTN= zvL+a5Z>eh&i)t+)vmWj8ernApUYuK*rH2xN9DJ$%3^FrAVo_Vb` z6t3l7-N97{8&kFo`%%Y!Md4j2G-u@)Zy+D5d*g6HdlJ%ubHU~9tj(Xm_s%jwl7hPp z*4;^yqy&d2nNiEo1wIj>Z>W9MWo*LGFPi)=Gjr^z1}pqMqAN^OT#E{cLY)MZw_xNg zF!VY+qa84ZSnfH{QtKY&T4S)DK|qsf54F0pdeI<{z*xn9BC{o9Gd1+kcgt+sPu|(+ zkLCFCVBYy`DH~@Bvx?l~7@VfawG0nR;|WeJ+Q@t3{?%sL_D5ZY-rwbeddL3}HUNHz zA|A?g?Cppv*P-6DzAQUut8-k=F6XS}bQrBoZB71mxMGMOA+vW=*c>c~40#6<@60nM z*k)|lQ)oQikg>fP*%^MXV;A6bl660O5}o->`q1`qB5p zb>y(Az1b_8Fnb*c0^oeVJa5 z&tr!RooRL%W1mT^=hD8`DYngCdSkd2Q*3h^dFWf3JVo5Ssm+tQy*J$D9t$v=5xQ@t zRD)*dNAkkzpC!5 z@l1Rt%r45pd`=D~GsgJ5vg5)&kuLgFX5(kjEze|?Kj0QU!Tz!z)jeQ^Bb^n2`|;37 zM@egj-e0CC%l`!{J%y_4ow;y-0Ii>XNN3F5<)EJUaCi}XDiUMWbMiZtVca=)V z$vHLQ#>fORTNd_0(r16D?7Zj!NFhW`LuZIOuc zuYGsE4`Xe;hxLmVwU?fL?RLlOETdi@k73{YLrJN|hSE39y>#!bF zY1x5onU>j3>+C2ASk-36@ik#*)&cv@3+i~ETiDSMcH7zbBc66zh|sm2rH$o!f7&_R zp5?K4cTk-xYIR!Y93VFyoT!kI@o^8M%iJnqtY0J<9Ie}0K%3&fB z?{5%hx1(;eOAl}QtC_+2`Dvx+GHXA@jLk0YZ!+D+lb6e#h0FHbAq+A|IM7nVYt8gR5vw=hUwt4!@H0%!-T7sg1Y({47%q>YAD!t6``uoYdU`~=-O~gkuk&R1>Zy7? zV!(!g4@DTu;hf(lAe!7kHnhpM6w&O)np>vh4LBZ#IX+|MXP9jKS=sE5#cCNgN!dz+ z*aDSg6vsF^c?^DJdyQP9^Ewj9kKq0}a&d&tVjuro?UCSL`dfsmy)Bi+$7MZWd+f`p zhwSqnx!|t98wN~5*2&R=$lz1X>^8P&HDX7o9_dn@<2Us%jfNb{s%Jn_N2Gcu5{Pa= z%yu>RY3Hnvj0UBhu>!<4wtT;|Gwqo{ljX1(I-lmxLs>e{=Xdf@=F5ZW(9RC+Y+Aq=qrgGgb_C>!im0C$HX?8~6eT+< zO{a;B-Y~6g43g3-q%A|AHgQ^0d3mncwW0qEy<^h|6I@;Of=dBku9?6Z`rFvYJ-u+Y zs|hb6_f!dDs#PrFZNZt!>(wh6#Jn|NCf>15BB^*}9TVI{b^oHCpTsDJt6(N+#yev7 zqvNZKe|VjaZf70;D7h0GCAe{7f8y~;@NgO(%bbGe;z#}0F>|Z^D;^3+p*xno!bs+y z%-}vxod>Ro+rJzK7>il4g-KB{AVfIaHgX>2_(zVho9-dj&e14bIWiiQW{sv4JH~%@ zPF>=pT)T3FU&{cugnGLu^yk^Z#)%EaWuS;%7$j~c6lymikIxsh ztx%*bY=^BNPgp*5+{5i%Q+D1Ro%C4Jv({zErvESU!#`L(td_3%z$RP z^}3Ev{kuBz#`bMb**DK=raQ4^nTGgs0$2%%wLT7A=)J}~2J2*?w*p@)NSygr z;f^ZA1U?^O;J0y61Y3uw3BJ)Z33R((BC6<4vE@34AHIwEo^3)DoSBK0A5dQAN}AIR z2X3@au@A5cQ?s~l2@;GHadK;@WX5UD`)L2FcO(sdH{=jL*f`W(0G(FR$A%nvQo^ShC{`8thk#*c)xpkjnQD*Qmoz56~Q7cg3j|<0Xbg7VNysKS8tHJL^7P<1w-lw z?+;6ojlHb13E}!R=k)B6`8G%Xj$d1;a8OLF^g9`qUws5^qIiQlPdPLD5fb{b^T~f{ zWnnpt$ykKG5;r0PkW2AKJU#%)0a+-l;@PitfnY<}FDt~f4WgA7f~@(Qpx?2ahuw~b zsY)Md23<+t)kvw170HF-v&hbKU7!;%M9AQ&d|sNKZvCuR;UCMUqAfEowLja(AUWOU ze!9-EZH1v>#v+sANa5XV-&5(jYDOUUf4SR7Ob9;$2|Op-Au2Y7qlH~#gKnbL@@~qeyZzn$Vh(RcG2XU8v{y@Vd8aql zS&jcsIYv2CtEi+l_iNH5#&G0lo=v7#e(PH*q>lCze|xd+#*^>D3JgK%kMoWwQuu;y9H{1!HK0rNc!7^gNK^Oa8LA%y)fBdH#`? ze>9Lbg|Q``rIOPyGYi#>%o|$LI?$4jH9@J-9f-v#tS>eMJ01D)lH|%sp}6GCoUV!Y z&k1S4UI)m0X-S)>O{@z|Kur|Cp(+O~Qce#(m@-t%l{Kk0U&;mtA zdIb$l?VXvVx+}p0D~~D91;ESvKaSTLg^3b5mOCuU)k(SPObN1kg>wGFM@)f1vz` z9z9b%%~frpXJ5YVbNE#sGvde7a$gSiMFm@=?AYW4fFCr}CO}zmN`Z>n=+K3gxnS?W zsTmGGLH*lzL67T{H>gjP6WJ}aXFJZdb~SF39(PG0;X_DZaOT4M$`0Tm=72|qEnJ@M zZJXQ-o23An=4(^JX)*u3%k6{H^X6&I;P8-Dx*Ie#d}RL4vAD(-^+kuf5_054&$qVp zbd$ODkqgf&Pnj^M0|s3;_UdAjTem~)HHA%K;0;s4H>J-tsh=8)Cs+{aEWC&JL6_7G z(F-JhmOXrUqfd!EP_@$b0jIQ|zXllvPPQI)XFMj`e1UL#*r<^5pO`T_W&3);*1Kt9QLeWd z>WQS>VPJsWhBl{tU4hW#%RgmQEm`FFfed;p+XAof!((b z9CO0d8izfRC#wg^uPZ*B;xG0zCPXnIvKM-sBwCvzEs)B^bjnV_^9#&nPCJ8nA&lvq zg@!Khlz};H-`CwAYndDb@2!#O4In%tB7DMS*2z6VmbM?5HW$TETM_*^eBw7qW{I;t*ia;OL%)FU?aG^S*gc49ed=JH`Q2CUAr6_sd%*c(CF2QN^Zv=>xEEcN#b~Z;lOU|| zmVtWANq)Fm&Y>AFSsnIi^&4$eh}~yHH8$!yHMv7|u&a;x)W`Fg5_~bP!a|Yj&e?Qw zQ!^@y`D=~kNxc5_NzJXUtf=Wwi8rB~t2HrYdfMSdmcp~5oevLBdoM}aI9E4QFY=g{ ziF8?mCetZ>unj}0d%4JSdR+59{gAUueS5s7!~iMM!pd=>S-bN$)ZWakDYI%kqdp3l zNXvIwg4BzNhye@P-=!HX80|h>d~=x&Uf<+!l7GP}qysAk@oFNs1k9t3+!Ao~@6Qhn z&*!=w7T`=<9k}xAdfyJP8Xk=03a@Fs8!|nZ@V4GO%ldPl!zeNdr;l5dt?d7|RREjEFwVqQW zn}x)T#O#Dr9oi^J?~%|mFB;;+XozONJyv+$%`cspZTzHyE<^*&Ra~ z#F3uQtz2y&t$G`5@YoGrFEdIg@u^-W#_8JZQ7IDug0;nF4kWw%RWFq*4Rxx)>?o!a zuYdbB&SnG~p6YLZPOTleX=Tpdo3Ey#EuRp*oPOLM9|`uxTJUH`mByhW$IJ$^K4T@m z&3bHQ@!w@KmE=DGr=_LA_E?rb*ib=}zHymnSlQ$XNoIcA-`EArk4 z(Z57lAaN^D{Oqj6FEUlHz5CEnPmFWaImnW*&!CU&7Ndq*Bv${m==WK_qbjBL=bk{_ zo?yS8nz4TH;9TAA!f(ecB@4f3qxqar+^_qiLhYgHfYm2q3j098rR%h7ll@U|`6YQA z%TXV*ja;J=hGU^8diITdBWs2tkl%+^I*;B29B>R@Fve@{>3( zA~hFe^Bl)NLYS)L%~lhEFmto#J1sz|Nb~OT_S6qp)FNMi_ifS*?~FwJ}@qDgfLczsb*Z7|d8sv=PD5oGp<)59LKy6s76tJY>RbY|pX z;Mi04@bq!Um|WSWh2TT>8=l}nf7QSRTJP*YVUtk^^?XE0E#)>Y_FIFn8dcAoYsdJ> z3RY7{i;6}LH+paTMn0gD{!42DXJwb^jF878+g6}6j9?plh@+XC!}vPJp8i031v{J| zc%uoIGFYgpe=ypK_gr$OmYqEgaRL0j-C1_HEZ@~f)row+gy>vutNm#9;C$uJZPSMp z|En>oU?0BY3Bc+J9|(-i;4{ZnbIF$cgef`QUBN&~5%x+Ol^{62B69yE{pTxnGlw6U zX-6O;BI)Pq)LV_H4B)mPkh4swpG3@_;@Hu00nTt8voXR7%IE8f|wm(o+14jsJ{~7f)gY8V zVqu@OU&t-vE&Mw%9!tR@=gRl2cr`SDff%NiepU2XJkgP0o5#oSrG3(hAH_+X+|a-D z-0+V(#-%Ji!Tju^m6KCxMn8Uh6g=rL1ud}oVV@pNyUc#s;mCgj#|E8yntO1RAC{0i zmJs0AFlcG~iJ;hkiCvpkQ*58K;7DV^7>RG)M>eCQTz}}YQJ$B%0Q3RC8dGXIF%$ug z?<5h2xdnnk(-#lQ7c6uSeEZ6O1dMui&M$=&+>20XpG;7vwOw^N4BHXk^;>@g*e*ON z#yHuM3UdKm8IuD5I!p!9BcYwPpVUw=X+L?2QePWW{|>NPSFIj{?6hNMS9RGH-2{}~ zc+|UUzy$2_Gj)UH0Roi5n%Mc95q&kaV)0)7UzrN$^) z$Q)c5IQLF4a&sS`nb&?iGMmyWNaclE6*>@8Zk+9)HHf3q4A_M{#A{83>M z7|+u6s{|W+L@^HlRu&3HmkDfGgP@UTV0#?fQs+g>>6uEdDxEen2-V{1oxVCxaHqPf zM{YL@p=rO#XrzfpRUkZxy7f%4>4`NsrT;2{@d;V1)F4r-#h=^3K7hntY; z1-YVqEQPSydi$5@c+$LWSTTF^r4hbQ3Ynvl+if_FfpQ-eni^zj8tqYA`Udo-@w-v5 zX~|{&rm4)}BbQ#FnRau#iLkO~Kq{8Z6soJ=g0qt z)+3S`^A0gvwMy~vN?lYAh%3K+zFH$X@cy3$z!z_Khbor-r_W4)*YrnBcUq`}=1`F%`J~`iSdw06ia=6Af z!x<~Uh&O%>oc?Z0YeBNj?%xzCSz=(S z^gJFoTN=weDQ73l*so1{faAwWnhKiL&4Vg{Dv1LL#tCl!$vAWxQIl{u;9eAHe+@cR zzPAR64Ru8nTIZWMw&v(YIalDZEbe{r!WP7W;EekMC)Uv;4auaPoCKGDLfjdDq2AEH zNn076l78BRS!^9m(tqUgifE!#u`D`^nJ z*vSBct<9K3lCvDjUS*In1`;2jbmmh~+t9B$PpS5rbchnlks^#s6`KL!vIFrz zEs}rx7$%RD63x$YI^+_Pmqj_KLCl&OY%+|bap(f^Y*e0C*+1p??EJ*&{9$`yIu=ru^TNy+h%W|xZ-6sh&&v-eib&0i z3jJrnc&zS+)R{hl3wWCVf({v{*?g{Oi6YFyHO=-7$_1}E_E*;5zx})!S36`p9-!$3 zF6-fAsD&=gLyOs8K4kq*h*s^zD;auQoMWl!z6|4EPHh0%_qeMbn#o+-0GVVQ5K{55l@uV1X z(O1F*y|Kd@J%gur&`fmsWT*hZZr&C&xy^*}2IM3>(RYzIayCnW7c8VJ4HW>LE0hsj z)CmHfAg!*Ju5bn&zHWq5g<`)nM`ZX$0x9Bry7MaPlk!LsDb{kPqZv@tym+KjF8zw{ zAm$a&5`bQNeLiaI!);vM#?*W(3aFgOjIQ^@Sy&?trE{?`&j^(wl@$d0#y6T0?#OUK ziQjMWPuMS42EGX<}|Z2Poz z5Y6RwP9^*KyfWgw*zez65!O*`e-=!RC2hEYN%VJqb#3`iw4E*rTu>RJ7qSxY!J;Tb zUsQ?W_$&JVKB=M({vL{c;#vOaxJMgjaugEcV?of0+<={a`4--l@P#bR2%ds}6!z2T z(tghT;QWQHz!G@-kh7>az3n1b@X|r<1b;D#hg;R?Ki$pr@JO*Rmoi=v+)nP<>PCd8 z;BcffD}%4&OXGD3VP+11E<1$yLVd3|-2!n609_i_^LTR2ygs+I{n zh=tMl@+lrqH=!jfuc+;wU4iQXzGMUY8CNYyy+RnA%%Bu_A6#VfkG z&jp|LqgVXC-k}AA(B*u->-~ez5E2qFM6E>AE=Ng=EJrTwZQgp%J!H^OfxS%j%J5i1 z|0rl@c49m2PRr$c$106a0`&fi9c04ZXnrlfU+~!#KHLv9Cd9Z9Iw%q%Jd{*6PS;_@ zc)b0=`0jA2`mhkM-#5u|itI9hQjY!d^PN)Lx2G^^94G3I)`U-E(gjS6K<@G}se<^Q zD0fVRIJujfSTU-%+f^FOz%`2iDikerf;wTnRlK-s8}A z)Fnj4c9=x!5eE&r+mkr-I8PL+4VBdpiQ!pAw}bPl`cVl{PJjfEk=^ZaQcfP2(?0i} zCPCHgL@!iJTWFLSCW2b>*`PWaA|C0^4>?rYI4{K{l115$k^ zY3J}s8Zc-mLybsK9$0}k3@*{Y>^F9_JUD)&&8YZM4-N`pJUfRaMj*2x~TUC`Gt6)^Jr7_WtzoO!BI`&mZY#{q(0}Vqn8ftiUw-YTgN5&JdA@!r!V48F%>Irhw?3L}vaINu;LN`e;-s=#tOidJY7w>F)m)gpjV ziVxcaDVMOV#V05H*+NRwKb2&ndKyubw_%_8c20#Fs20@I)l0F0o=x8ItJ?C3lAYSK z`A0XAIliRAU=23DeHScWNny~3w#eKSEhb`v1xif|2pMR?Jg`CtAO~{0>_XK;azdI> zz?}nT8Yn2I8lwZ^c}Ei;`^PQ!Xlam|eRggR74Mbx$V7KmQe;*$EO#h76FH^v@Y>AZ z3|EQ!u0L=s91HeB=-d;mbK_iWh2E4A+U$`qB$3eS3llz%`CRqUGA-6y`XLE2Iw{5# z8FMn2Fg4K(FX$a^YRRU#tf#v19x0e6)<&u7f7wEmK&e*-5@5A`S zIV!%GkK1L`f?|%?)tVcY6YV9%WtObptx_M`rd z-4AGZ0>uD7MkDjo>kQi~S5-SsmC5$Io`xj!8#jjeG_Zvu%qQc}!{)HRb2?riF>-BP z7fN)ibj?ufThPcl=QX*FI`eJA63t9D!ndWP*EZfLb?&2O>`s7q?Xkhc!pIie;u4`( zmXm5{Uv@lSt4~agN59$Y*fq@B0Y`cuy&E+Uvu$HIK3D$b_c4^6j(q=o-((QHD4%$g zmqeHj`&(3}@L~xh^e(H)2$}MQrBw?Wd#e4h-zr8KHLcyj(e3E5b#gK%r+_8}IreB7 z%mrQr!(b{uEPTbJB1Xy%1@C6%cgruZ;Hxc20vS$w;(Q^FLSSrVA|fFhsq0<(^D<{8 zE9J{4VFv#02#gFZ*am4a?y@nOJG{!*odH#lVkIWJoM^xF%=GXNZT-byy0HqkmiuGq}Atc!Q4~7!Ah|b)tR1k zi41yC5xN}4Acc`9E`cM#wIGc2Bjk>JQ#7r!k2@KJjUF7?eweeH8%lTLMO7X`Mmw(4 zh=E^xUq%|3QW&u!ha>;k7ReGE<|XA%>+1p>A;^1G>de0HB^}=rD#-mJ{=-odthXfv}DjJhCwQ9w8PtE@{2-x6hLAb zrB@!$7S=P7krD8SdGUIOq0|yryOaw9UbAEKezkP4Ce5eQKV5#W~)<4C}y zxqcX=&$HZh)Z;4-u{=f?Xzl^9AOc+uRblm97yoPx$sixLZvm|>{^Um8)7w1 zqu@)B}A7H`E5o+ z^;JNh`ngk6B_nP@=^vB)JElYfd@jYwh{5?7+9b~_1T>n?pJ?{?jw6aCYTn}6HgYXI z;R5%U8>G4xTQItcWC_JfkRA)AWd<57lfkVh|4w6`>EB_B7iYhPQ#>OR^#;wj2fX+Z zvc5k@4C9(iqv1ZV&GUIU%u8FsQMAP_bxkb{ zsT%emBtjf-_cLT3W-rN;Pb+N6Jwz`Bzyr!RuPy{-5Q z*1zy1{Hr9F7wIx?cp)-^6_&UR9TfAFEleF_;Wc@W<`o71kvtsG?VsVTa(6qoP{ zPOMgTgiqE^RVi`6gHa;P;~^jRuVfPMkU!^p%L4BVr>k1H&N+=*u=WHjlll@zp&KyD zq^?zAF5jjZGJ3(8{{b)X5wovLGUe60A_CW?UYC;R_C|3dfw_49uT8$JZ_%kBrR0uP@K z7aFMd1f!P!+dKTT;vV6;Qj`qWl;?VQS9Q#!c0n0czg|#s5&m_b{|$KhkdU}Vc?6FU zt^fE82|NWpINm>fEG;hi*8&m{;4S~R`edtgSja<8-~qr7(oi?Mw13Svgf1BYv8z^C z?zji)wD1H(S?3m#gL4r6v&;YMi4;VU&359os@@vV{cq!c-}`%6)stU+M)DA>4)PlL R2ta`U6lK+9Dy7WA{tF#F){X!G diff --git a/modules/ROOT/images/manage-dbs-enterprise.svg b/modules/ROOT/images/manage-dbs-enterprise.svg new file mode 100644 index 000000000..56926f92a --- /dev/null +++ b/modules/ROOT/images/manage-dbs-enterprise.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/ROOT/images/remote-alias-overview.svg b/modules/ROOT/images/remote-alias-overview.svg index 6a06a319e..d51cdcda9 100644 --- a/modules/ROOT/images/remote-alias-overview.svg +++ b/modules/ROOT/images/remote-alias-overview.svg @@ -1,43 +1,42 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/ROOT/pages/database-administration/composite-databases/concepts.adoc b/modules/ROOT/pages/database-administration/composite-databases/concepts.adoc index 20806234e..e48095027 100644 --- a/modules/ROOT/pages/database-administration/composite-databases/concepts.adoc +++ b/modules/ROOT/pages/database-administration/composite-databases/concepts.adoc @@ -54,7 +54,7 @@ using a _proxy node_ modeling pattern, where nodes with a specific label must be In one of the graphs, nodes with that specific label contain all the data related to that label, while in the other graph, the same label is associated with a proxy node that only contains the `ID` property. The `ID` property allows you to link data across the graphs in this federation. -image::federation-sharding.png[title="Data federation and sharding", width=450, role=middle] +image::federation-sharding.svg[title="Data federation and sharding", width=450, role=popup] [TIP] ==== diff --git a/modules/ROOT/pages/database-administration/index.adoc b/modules/ROOT/pages/database-administration/index.adoc index e2536c089..bea952374 100644 --- a/modules/ROOT/pages/database-administration/index.adoc +++ b/modules/ROOT/pages/database-administration/index.adoc @@ -45,7 +45,7 @@ For details, see xref:database-administration/standard-databases/configuration-p The following image illustrates an installation of Neo4j containing the three standard databases, named `marketing`, `sales`, and `hr`, and the `system` database. The default database is `sales`: -image::manage-dbs-default.png[title="A multiple database Neo4j installation, with a default database.", role="middle"] +image::manage-dbs-default.svg[title="A multiple database Neo4j installation, with a default database.",role=popup] [NOTE] ==== @@ -78,10 +78,10 @@ Most of the available administrative commands are restricted to users with speci An example of configuring security privileges is described in xref:tutorial/access-control.adoc[Fine-grained access control]. .A default installation, including the `system` database and a single standard database named `neo4j`: -image::manage-dbs-community.png[title="A default Neo4j installation.", role="middle"] +image::manage-dbs-community.svg[title="A default Neo4j installation.",role=popup] .An installation of Neo4j with multiple active databases, named `marketing`, `sales`, and `hr`: -image::manage-dbs-enterprise.png[title="A multiple database Neo4j installation.", role="middle"] +image::manage-dbs-enterprise.svg[title="A multiple database Neo4j installation.",role=popup] == Composite databases diff --git a/modules/ROOT/pages/kubernetes/quickstart-cluster/server-setup.adoc b/modules/ROOT/pages/kubernetes/quickstart-cluster/server-setup.adoc index e55aa2fd3..da01b1484 100644 --- a/modules/ROOT/pages/kubernetes/quickstart-cluster/server-setup.adoc +++ b/modules/ROOT/pages/kubernetes/quickstart-cluster/server-setup.adoc @@ -9,7 +9,7 @@ By separating the charts up, users can create a different topology of Neo4j and The following diagram is a schematic representation of the Helm charts involved and the Kubernetes and Cloud resources they instantiate when installed: .Neo4j cluster setup -image:cluster-on-k8s.png[] +image::cluster-on-k8s.svg[Example of Neo4j cluster setup in Kubernetes,width=700,role=popup] The diagram shows an example of a Neo4j cluster setup with three servers. The Kubernetes setup includes a headless service for accessing the cluster from inside Kubernetes and a load-balancer service for accessing the cluster from outside Kubernetes. From 6b3aea35d3cb0c6453b304dee90709d6a493d91d Mon Sep 17 00:00:00 2001 From: Therese Magnusson Date: Tue, 19 Aug 2025 14:57:04 +0200 Subject: [PATCH 32/39] Add documentation for the alter database privileges on database level (#2490) Since we moved them over from DBMS level (while still keeping the DBMS level syntax, just as another syntax for `DATABASE *`) --------- Co-authored-by: Mark Dixon <1756429+mnd999@users.noreply.github.com> Co-authored-by: Reneta Popova --- ...nt_and_deny_syntax_database_privileges.svg | 100 +------ .../images/privileges_hierarchy_database.svg | 10 +- .../database-administration.adoc | 267 ++++++++++++++++-- .../dbms-administration.adoc | 39 ++- 4 files changed, 280 insertions(+), 136 deletions(-) diff --git a/modules/ROOT/images/privileges_grant_and_deny_syntax_database_privileges.svg b/modules/ROOT/images/privileges_grant_and_deny_syntax_database_privileges.svg index 4e0babc35..59ffa7f49 100644 --- a/modules/ROOT/images/privileges_grant_and_deny_syntax_database_privileges.svg +++ b/modules/ROOT/images/privileges_grant_and_deny_syntax_database_privileges.svg @@ -1,99 +1 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/modules/ROOT/images/privileges_hierarchy_database.svg b/modules/ROOT/images/privileges_hierarchy_database.svg index 0ccfd067d..dbdf28cfb 100644 --- a/modules/ROOT/images/privileges_hierarchy_database.svg +++ b/modules/ROOT/images/privileges_hierarchy_database.svg @@ -1,9 +1 @@ - - - - - - - - - + \ No newline at end of file diff --git a/modules/ROOT/pages/authentication-authorization/database-administration.adoc b/modules/ROOT/pages/authentication-authorization/database-administration.adoc index b90723fd5..0582e255d 100644 --- a/modules/ROOT/pages/authentication-authorization/database-administration.adoc +++ b/modules/ROOT/pages/authentication-authorization/database-administration.adoc @@ -5,8 +5,10 @@ [source, cypher, role=test-setup] ---- CREATE ROLE regularUsers; +CREATE ROLE alterDbUsers; CREATE ROLE databaseAdminUsers; CREATE DATABASE `remote-db`; +CREATE COMPOSITE DATABASE `composite`; CREATE USER jake SET PASSWORD 'abcd1234' CHANGE NOT REQUIRED; ---- //// @@ -72,7 +74,7 @@ This can be quite powerful as it allows permissions to be switched from one data For more details about the syntax descriptions, see xref:database-administration/syntax.adoc[]. ==== -.General grant +ON DATABASE+ privilege syntax +.`GRANT ON DATABASE` privilege syntax [cols="<15s,<85"] |=== @@ -92,7 +94,7 @@ GRANT [IMMUTABLE] database-privilege ON { HOME DATABASE \| DATABASE[S] { * \| na |=== -.General deny +ON DATABASE+ privilege syntax +.`DENY ON DATABASE` privilege syntax [cols="<15s,<85"] |=== @@ -112,7 +114,7 @@ DENY [IMMUTABLE] database-privilege ON { HOME DATABASE \| DATABASE[S] { * \| nam |=== -.General revoke +ON DATABASE+ privilege syntax +.`REVOKE GRANT ON DATABASE` privilege syntax [cols="<15s,<85"] |=== @@ -132,7 +134,7 @@ REVOKE [IMMUTABLE] GRANT database-privilege ON { HOME DATABASE \| DATABASE[S] { |=== -.General revoke +ON DATABASE+ privilege syntax +.`REVOKE DENY ON DATABASE` privilege syntax [cols="<15s,<85"] |=== @@ -152,7 +154,7 @@ REVOKE [IMMUTABLE] DENY database-privilege ON { HOME DATABASE \| DATABASE[S] { * |=== -.General revoke +ON DATABASE+ privilege syntax +.`REVOKE ON DATABASE` privilege syntax [cols="<15s,<85"] |=== @@ -184,12 +186,13 @@ See link:{neo4j-docs-base-uri}/status-codes/{page-version}/notifications/all-not The hierarchy between the different database privileges is shown in the image below. +// TODO: do we want two pictures, one for Cypher 5 and one for Cypher 25? I'd guess not but I'm not sure image::privileges_hierarchy_database.svg[title="Database privileges hierarchy"] -.Database privilege syntax +.`GRANT ACCESS` privilege syntax [cols="<15s,<85"] |=== @@ -216,7 +219,7 @@ Grants the specified roles the privilege to access: |=== -.Database privilege syntax +.`GRANT START | STOP` privilege syntax [cols="<15s,<85"] |=== @@ -237,8 +240,54 @@ GRANT [IMMUTABLE] { START \| STOP } |=== +[role=label--new-2025.08 label--cypher-25] +.`GRANT ALTER DATABASE | SET DATABASE ACCESS | SET DATABASE DEFAULT LANGUAGE` privilege syntax +[cols="<15s,<85"] +|=== + +| Command +m| +GRANT { ALTER DATABASE \| SET DATABASE ACCESS \| SET DATABASE DEFAULT LANGUAGE }+ + +| Syntax +a| +[source, syntax, role="noheader", indent=0] +---- +GRANT [IMMUTABLE] { ALTER DATABASE \| SET DATABASE ACCESS \| SET DATABASE DEFAULT LANGUAGE } + ON { HOME DATABASE \| DATABASE[S] {* \| name[, ...] } } + TO role[, ...] +---- + +| Description +| Grants the specified roles the privilege to modify everything, database access or default language of the home database, specific database(s), or all databases. +Only applies to standard databases. + +|=== + +[role=label--new-2025.08 label--cypher-25] +.`GRANT ALTER COMPOSITE DATABASE` privilege syntax +[cols="<15s,<85"] +|=== -.Database privilege syntax +| Command +m| +GRANT { ALTER COMPOSITE DATABASE }+ + +| Syntax +a| +[source, syntax, role="noheader", indent=0] +---- +GRANT [IMMUTABLE] { ALTER COMPOSITE DATABASE } + ON { HOME DATABASE \| DATABASE[S] {* \| name[, ...] } } + TO role[, ...] +---- + +| Description +| Grants the specified roles the privilege to modify the home database, specific database(s), or all databases. +Only applies to composite databases. + +|=== + + +.`GRANT CREATE | DROP | SHOW INDEX` privilege syntax [cols="<15s,<85"] |=== @@ -260,7 +309,7 @@ GRANT [IMMUTABLE] { CREATE \| DROP \| SHOW } INDEX[ES] |=== -.Database privilege syntax +.`GRANT INDEX` privilege syntax [cols="<15s,<85"] |=== @@ -282,7 +331,7 @@ GRANT [IMMUTABLE] INDEX[ES] [MANAGEMENT] |=== -.Database privilege syntax +.`GRANT CREATE | DROP | SHOW CONSTRAINT` privilege syntax [cols="<15s,<85"] |=== @@ -304,7 +353,7 @@ GRANT [IMMUTABLE] { CREATE \| DROP \| SHOW } CONSTRAINT[S] |=== -.Database privilege syntax +.`GRANT CONSTRAINT` privilege syntax [cols="<15s,<85"] |=== @@ -326,7 +375,7 @@ GRANT [IMMUTABLE] CONSTRAINT[S] [MANAGEMENT] |=== -.Database privilege syntax +.`GRANT CREATE NEW LABEL` privilege syntax [cols="<15s,<85"] |=== @@ -348,7 +397,7 @@ GRANT [IMMUTABLE] CREATE NEW [NODE] LABEL[S] |=== -.Database privilege syntax +.`GRANT CREATE NEW TYPE` privilege syntax [cols="<15s,<85"] |=== @@ -370,7 +419,7 @@ GRANT [IMMUTABLE] CREATE NEW [RELATIONSHIP] TYPE[S] |=== -.Database privilege syntax +.`GRANT CREATE NEW NAME` privilege syntax [cols="<15s,<85"] |=== @@ -392,7 +441,7 @@ GRANT [IMMUTABLE] CREATE NEW [PROPERTY] NAME[S] |=== -.Database privilege syntax +.`GRANT NAME` privilege syntax [cols="<15s,<85"] |=== @@ -414,7 +463,7 @@ GRANT [IMMUTABLE] NAME [MANAGEMENT] |=== -.Database privilege syntax +.`GRANT ALL` privilege syntax [cols="<15s,<85"] |=== @@ -436,7 +485,7 @@ GRANT [IMMUTABLE] ALL [[DATABASE] PRIVILEGES] |=== -.Database privilege syntax +.`GRANT { SHOW \| TERMINATE } TRANSACTION` privilege syntax [cols="<15s,<85"] |=== @@ -458,7 +507,7 @@ GRANT [IMMUTABLE] { SHOW \| TERMINATE } TRANSACTION[S] [( { * \| user[, ...] } ) |=== -.Database privilege syntax +.`GRANT TRANSACTION` privilege syntax [cols="<15s,<85"] |=== @@ -479,8 +528,8 @@ GRANT [IMMUTABLE] TRANSACTION [MANAGEMENT] [( { * \| user[, ...] } )] |=== - -image::privileges_grant_and_deny_syntax_database_privileges.svg[title="Syntax of GRANT and DENY Database Privileges"] +// TODO: do we want two pictures, one for Cypher 5 and one for Cypher 25? I'd guess not but I'm not sure +image::privileges_grant_and_deny_syntax_database_privileges.svg[title="Syntax of `GRANT` and `DENY` database privileges"] [[access-control-database-administration-access]] @@ -564,7 +613,7 @@ DENY [IMMUTABLE] START TO role[, ...] ---- -For example, to deny the role `regularUsers` the ability to start to the database `neo4j`, use: +For example, to deny the role `regularUsers` the ability to start to the database `system`, use: [source, cypher, role=noplay] ---- @@ -596,7 +645,7 @@ DENY [IMMUTABLE] STOP TO role[, ...] ---- -For example, to deny the role `regularUsers` the ability to stop the database `neo4j`, use: +For example, to deny the role `regularUsers` the ability to stop the database `system`, use: [source, cypher, role=noplay] ---- @@ -628,6 +677,172 @@ a|Rows: 6 Note that `START` and `STOP` privileges are not included in the xref:authentication-authorization/database-administration.adoc#access-control-database-administration-all[`ALL DATABASE PRIVILEGES`]. ==== +[role=label--new-2025.08 label--cypher-25] +[[access-control-database-administration-alter-db]] +== The alter database-related privileges + +The `ALTER DATABASE`, `SET DATABASE ACCESS`, `SET DATABASE DEFAULT LANGUAGE`, and `ALTER COMPOSITE DATABASE` privileges can be granted both as database privileges and as DBMS privileges. +The DBMS privilege is equivalent to granting the database privilege for all databases, `DATABASE *`. +For more information on the DBMS privilege versions, see xref:authentication-authorization/dbms-administration.adoc#access-control-dbms-administration-database-management[The `DBMS DATABASE MANAGEMENT` privileges]. + + +The `ALTER DATABASE` privilege is used to enable the ability to modify a standard database: + +[source, syntax, role="noheader"] +---- +GRANT [IMMUTABLE] ALTER DATABASE + ON { HOME DATABASE | DATABASE[S] { * | name[, ...] } } + TO role[, ...] +---- + +For example, to grant the role `alterDbUsers` the ability to modify the database `neo4j`, use: + +[source, cypher, role=noplay] +---- +GRANT ALTER DATABASE ON DATABASE neo4j TO alterDbUsers +---- + +The `ALTER DATABASE` privilege can also be denied: + +[source, syntax, role="noheader"] +---- +DENY [IMMUTABLE] ALTER DATABASE + ON { HOME DATABASE | DATABASE[S] { * | name[, ...] } } + TO role[, ...] +---- + +For example, to deny the role `alterDbUsers` the ability to modify to the database `system`, use: + +[source, cypher, role=noplay] +---- +DENY ALTER DATABASE ON DATABASE system TO alterDbUsers +---- + +The `SET DATABASE ACCESS` privilege can be used to enable the ability to modify access, read-only or read-write, to a standard database: + +[source, syntax, role="noheader"] +---- +GRANT [IMMUTABLE] SET DATABASE ACCESS + ON { HOME DATABASE | DATABASE[S] { * | name[, ...] } } + TO role[, ...] +---- + +This should not be confused with the `ACCESS` privileges that enables the ability for a user to access a database. + +For example, to grant the role `alterDbUsers` the ability to modify the access of the database `neo4j`, use: + +[source, cypher, role=noplay] +---- +GRANT SET DATABASE ACCESS ON DATABASE neo4j TO alterDbUsers +---- + +The `SET DATABASE ACCESS` privilege can also be denied: + +[source, syntax, role="noheader"] +---- +DENY [IMMUTABLE] SET DATABASE ACCESS + ON { HOME DATABASE | DATABASE[S] { * | name[, ...] } } + TO role[, ...] +---- + +For example, to deny the role `alterDbUsers` the ability to modify the access of the database `neo4j`, use: + +[source, cypher, role=noplay] +---- +DENY SET DATABASE ACCESS ON DATABASE neo4j TO alterDbUsers +---- + +The `SET DATABASE DEFAULT LANGUAGE` privilege can be used to enable the ability to modify the default language of a standard database: + +[source, syntax, role="noheader"] +---- +GRANT [IMMUTABLE] SET DATABASE DEFAULT LANGUAGE + ON { HOME DATABASE | DATABASE[S] { * | name[, ...] } } + TO role[, ...] +---- + +For example, to grant the role `alterDbUsers` the ability to modify the default Cypher language version of the database `neo4j`, use: + +[source, cypher, role=noplay] +---- +GRANT SET DATABASE DEFAULT LANGUAGE ON DATABASE neo4j TO alterDbUsers +---- + +The `SET DATABASE DEFAULT LANGUAGE` privilege can also be denied: + +[source, syntax, role="noheader"] +---- +DENY [IMMUTABLE] SET DATABASE DEFAULT LANGUAGE + ON { HOME DATABASE | DATABASE[S] { * | name[, ...] } } + TO role[, ...] +---- + +For example, to deny the role `alterDbUsers` the ability to modify the default language of the database `system`, use: + +[source, cypher, role=noplay] +---- +DENY SET DATABASE DEFAULT LANGUAGE ON DATABASE system TO alterDbUsers +---- + +The `ALTER COMPOSITE DATABASE` privilege can be used to enable the ability to modify a composite database: + +[source, syntax, role="noheader"] +---- +GRANT [IMMUTABLE] ALTER COMPOSITE DATABASE + ON { HOME DATABASE | DATABASE[S] { * | name[, ...] } } + TO role[, ...] +---- + +For example, to grant the role `alterDbUsers` the ability to modify the home database as long as it's a composite database, use: + +[source, cypher, role=noplay] +---- +GRANT ALTER COMPOSITE DATABASE ON HOME DATABASE TO alterDbUsers +---- + +The `ALTER COMPOSITE DATABASE` privilege can also be denied: + +[source, syntax, role="noheader"] +---- +DENY [IMMUTABLE] ALTER COMPOSITE DATABASE + ON { HOME DATABASE | DATABASE[S] { * | name[, ...] } } + TO role[, ...] +---- + +For example, to deny the role `alterDbUsers` the ability to modify to the composite database `composite`, use: + +[source, cypher, role=noplay] +---- +DENY ALTER COMPOSITE DATABASE ON DATABASE composite TO alterDbUsers +---- + +The privileges granted can be seen using the `SHOW PRIVILEGES` command: + +[source, cypher, role=noplay] +---- +SHOW ROLE alterDbUsers PRIVILEGES AS COMMANDS +---- + +.Result +[options="header,footer", width="100%", cols="m"] +|=== +|command +|"DENY ALTER COMPOSITE DATABASE ON DATABASE `composite` TO `alterDbUsers`" +|"DENY ALTER DATABASE ON DATABASE `system` TO `alterDbUsers`" +|"DENY SET DATABASE ACCESS ON DATABASE `neo4j` TO `alterDbUsers`" +|"DENY SET DATABASE DEFAULT LANGUAGE ON DATABASE `system` TO `alterDbUsers`" +|"GRANT ALTER COMPOSITE DATABASE ON HOME DATABASE TO `alterDbUsers`" +|"GRANT ALTER DATABASE ON DATABASE `neo4j` TO `alterDbUsers`" +|"GRANT SET DATABASE ACCESS ON DATABASE `neo4j` TO `alterDbUsers`" +|"GRANT SET DATABASE DEFAULT LANGUAGE ON DATABASE `neo4j` TO `alterDbUsers`" +a|Rows: 8 +|=== + +[NOTE] +==== +Note that `ALTER DATABASE`, `SET DATABASE ACCESS`, `SET DATABASE DEFAULT LANGUAGE`, and `ALTER COMPOSITE DATABASE` privileges are not included in the xref:authentication-authorization/database-administration.adoc#access-control-database-administration-all[`ALL DATABASE PRIVILEGES`]. +==== + [[access-control-database-administration-index]] == The `INDEX MANAGEMENT` privileges @@ -873,7 +1088,7 @@ GRANT [IMMUTABLE] ALL [[DATABASE] PRIVILEGES] [NOTE] ==== -Note that the privileges for starting and stopping all databases, and transaction management, are not included in the `ALL DATABASE PRIVILEGES` grant. +Note that the privileges for starting, stopping, and modifying all databases, and transaction management, are not included in the `ALL DATABASE PRIVILEGES` grant. These privileges are associated with administrators while other database privileges are of use to domain and application developers. ==== @@ -906,7 +1121,7 @@ a|Rows: 1 The right to run the commands `SHOW TRANSACTIONS`, `TERMINATE TRANSACTIONS`, and the deprecated procedures `dbms.listTransactions`, `dbms.listQueries`, `dbms.killQuery`, `dbms.killQueries`, `dbms.killTransaction` and `dbms.killTransactions` is now managed through the `SHOW TRANSACTION` and `TERMINATE TRANSACTION` privileges. -.Database privilege syntax +.`GRANT SHOW TRANSACTION` privilege syntax [cols="<15s,<85"] |=== @@ -928,7 +1143,7 @@ GRANT [IMMUTABLE] SHOW TRANSACTION[S] [( { * \| user[, ...] } )] |=== -.Database privilege syntax +.`GRANT TERMINATE TRANSACTION` privilege syntax [cols="<15s,<85"] |=== @@ -950,7 +1165,7 @@ GRANT [IMMUTABLE] TERMINATE TRANSACTION[S] [( { * \| user[, ...] } )] |=== -.Database privilege syntax +.`GRANT TRANSACTION` privilege syntax [cols="<15s,<85"] |=== diff --git a/modules/ROOT/pages/authentication-authorization/dbms-administration.adoc b/modules/ROOT/pages/authentication-authorization/dbms-administration.adoc index c0d7206ff..4869f4a6f 100644 --- a/modules/ROOT/pages/authentication-authorization/dbms-administration.adoc +++ b/modules/ROOT/pages/authentication-authorization/dbms-administration.adoc @@ -1070,6 +1070,13 @@ GRANT [IMMUTABLE] DATABASE MANAGEMENT |=== +[NOTE] +==== +From Cypher 25 (Neo4j server 2025.08), the `ALTER DATABASE`, `SET DATABASE ACCESS`, `SET DATABASE DEFAULT LANGUAGE`, and `ALTER COMPOSITE DATABASE` privileges can be granted both as database privileges and as DBMS privileges. +The DBMS privilege version is equivalent to granting the privilege for all databases, `DATABASE *`. +For more information on the database privilege versions, see xref:authentication-authorization/database-administration.adoc#access-control-database-administration-alter-db[The alter database-related privileges]. +==== + === Grant privilege to create standard databases You can grant the privilege to create standard databases using the `CREATE DATABASE` privilege. + @@ -1200,6 +1207,13 @@ SHOW ROLE databaseModifier PRIVILEGES AS COMMANDS; a|Rows: 1 |=== +[NOTE] +==== +From Cypher 25 (Neo4j server 2025.08), the `ALTER DATABASE` privileges can be granted both as database privileges and as DBMS privileges. +The DBMS privilege version is equivalent to granting the privilege for all databases, `DATABASE *`. +For more information on the database privilege versions, see xref:authentication-authorization/database-administration.adoc#access-control-database-administration-alter-db[The alter database-related privileges]. +==== + === Grant privilege to modify access to standard databases You can grant the privilege to modify access to standard databases using the `SET DATABASE ACCESS` privilege. + @@ -1226,7 +1240,14 @@ SHOW ROLE accessModifier PRIVILEGES AS COMMANDS; a|Rows: 1 |=== -[rol=label--new-2025.06] +[NOTE] +==== +From Cypher 25 (Neo4j server 2025.08), the `SET DATABASE ACCESS` privileges can be granted both as database privileges and as DBMS privileges. +The DBMS privilege version is equivalent to granting the privilege for all databases, `DATABASE *`. +For more information on the database privilege versions, see xref:authentication-authorization/database-administration.adoc#access-control-database-administration-alter-db[The alter database-related privileges]. +==== + +[role=label--new-2025.06] === Grant privilege to modify the default language of standard databases You can grant the privilege to modify the default language of standard databases using the `SET DATABASE DEFAULT LANGUAGE` privilege. + @@ -1253,7 +1274,14 @@ SHOW ROLE languageModifier PRIVILEGES AS COMMANDS; a|Rows: 1 |=== -[rol=label--new-2025.06] +[NOTE] +==== +From Cypher 25 (Neo4j server 2025.08), the `SET DATABASE DEFAULT LANGUAGE` privileges can be granted both as database privileges and as DBMS privileges. +The DBMS privilege version is equivalent to granting the privilege for all databases, `DATABASE *`. +For more information on the database privilege versions, see xref:authentication-authorization/database-administration.adoc#access-control-database-administration-alter-db[The alter database-related privileges]. +==== + +[role=label--new-2025.06] [[grant-privilege-alter-composite-database]] === Grant privilege to modify composite databases @@ -1281,6 +1309,13 @@ SHOW ROLE compositeDatabaseModifier PRIVILEGES AS COMMANDS; a|Rows: 1 |=== +[NOTE] +==== +From Cypher 25 (Neo4j server 2025.08), the `ALTER COMPOSITE DATABASE` privileges can be granted both as database privileges and as DBMS privileges. +The DBMS privilege version is equivalent to granting the privilege for all databases, `DATABASE *`. +For more information on the database privilege versions, see xref:authentication-authorization/database-administration.adoc#access-control-database-administration-alter-db[The alter database-related privileges]. +==== + === Grant privilege to manage composite databases You can grant the privilege to create, delete, and modify composite databases using the `COMPOSITE DATABASE MANAGEMENT` privilege. + From 495aa877e5d2624d761239d480c118abdfea9ba3 Mon Sep 17 00:00:00 2001 From: Natalia Ivakina <82437520+NataliaIvakina@users.noreply.github.com> Date: Tue, 19 Aug 2025 15:37:47 +0200 Subject: [PATCH 33/39] Update the description of the history option (#2543) --- modules/ROOT/pages/changes-deprecations-removals.adoc | 4 ++++ modules/ROOT/pages/cypher-shell.adoc | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/ROOT/pages/changes-deprecations-removals.adoc b/modules/ROOT/pages/changes-deprecations-removals.adoc index a626150de..5029e0dde 100644 --- a/modules/ROOT/pages/changes-deprecations-removals.adoc +++ b/modules/ROOT/pages/changes-deprecations-removals.adoc @@ -612,6 +612,10 @@ For details, refer to the xref:backup-restore/copy-database.adoc#off-heap-memory === Cypher Shell +Neo4j 2025.08:: + +A new argument `disable` is added to the `--history` option. + Neo4j 2025.06:: The default value of the `--error-format` option is changed from `legacy` to `gql`. diff --git a/modules/ROOT/pages/cypher-shell.adoc b/modules/ROOT/pages/cypher-shell.adoc index dfb0cbf9f..3e64c8bb3 100644 --- a/modules/ROOT/pages/cypher-shell.adoc +++ b/modules/ROOT/pages/cypher-shell.adoc @@ -106,7 +106,7 @@ After executing all statements, Cypher Shell shuts down. | |--history HISTORY-BEHAVIOUR -|File path of a query and a command history file or `in-memory` for in-memory history. +|label:new[Changed in 2025.08] File path of a query and a command history file, `in-memory` for in-memory history or `disable` to disable history. If the option is omitted, history is saved to `/.neo4j/.cypher_shell_history`. Can also be set using the environment variable `NEO4J_CYPHER_SHELL_HISTORY`. | From 2f3b2ca68aebec8f645a5151dbaf43e0a18b48fa Mon Sep 17 00:00:00 2001 From: Natalia Ivakina <82437520+NataliaIvakina@users.noreply.github.com> Date: Wed, 20 Aug 2025 10:07:53 +0200 Subject: [PATCH 34/39] Add tabbed examples for multiple node IDs (#2512) The Operations manual covers all releases of 2025.xx series. That's why we cannot simply replace examples with new ones, as new functionality has been added. We also need to retain examples for earlier versions of Neo4j. --- modules/ROOT/pages/import.adoc | 82 +++++++++++++++++++++++++++------- 1 file changed, 67 insertions(+), 15 deletions(-) diff --git a/modules/ROOT/pages/import.adoc b/modules/ROOT/pages/import.adoc index abcbc78bf..bf08ad403 100644 --- a/modules/ROOT/pages/import.adoc +++ b/modules/ROOT/pages/import.adoc @@ -1464,30 +1464,30 @@ Now use the previously defined ID spaces when connecting the actors to movies. == Using multiple node IDs A node header can contain multiple `ID` columns. -The relationship data must then use a matching number of `START_ID` / `END_ID` columns as references to the composite value of those ID columns. + +Starting from 2025.07, the relationship data must then use a matching number of `START_ID` / `END_ID` columns as references to the composite value of those ID columns. This implies using `string` as `id-type`. For each `ID` column, you can specify to store its values as different node properties. However, the composite value cannot be stored as a node property. -[NOTE] +[IMPORTANT] ==== Incremental import doesn't support the use of multiple node identifiers. This functionality is only available with a full import. ==== -.Define multiple IDs as node properties -==== -You can define multiple `ID` columns in the node header. -For example, you can define a node header with two `ID` columns. +=== Define multiple IDs as node properties +. Define multiple `ID` columns in the node header. ++ .nodes_header.csv [source, csv] ---- :ID,:ID,name ---- - ++ .nodes.csv [source, csv] ---- @@ -1495,8 +1495,35 @@ aa,11,John bb,22,Paul ---- +. Define the relationship between two established nodes. ++ +[.tabbed-example] +===== +[role=include-with-single-ID-column] +====== + Now use both IDs when defining the relationship: +.relationships_header.csv +[source, csv] +---- +:START_ID,:TYPE,:END_ID +---- + +.relationships.csv +[source, csv] +---- +aa11,WORKS_WITH,bb22 +---- + +====== +[role=include-with-multiple-ID-columns label--new-2025.07] +====== + +Starting from 2025.07, you can use a matching number of `START_ID` / `END_ID` columns when defining the relationship. +However, do not mix how to refer to composite IDs. +Either all references must use a single `START_ID` / `END_ID` column or all references must use a matching number of them. + .relationships_header.csv [source, csv] ---- @@ -1508,20 +1535,20 @@ Now use both IDs when defining the relationship: ---- aa,11,WORKS_WITH,bb,22 ---- -==== +====== +===== [[multiple-IDs-Id-spaces]] -.Define multiple IDs stored in ID spaces -==== - -Define a `MyGroup` ID space in the _nodes_header.csv_ file. +=== Define multiple IDs stored in ID spaces +. Define a `MyGroup` ID space in the _nodes_header.csv_ file. ++ .nodes_header.csv [source, csv] ---- personId:ID(MyGroup),memberId:ID(MyGroup),name ---- - ++ .nodes.csv [source, csv] ---- @@ -1529,7 +1556,30 @@ aa,11,John bb,22,Paul ---- -Now use the defined ID space when connecting John with Paul, and use both IDs in the relationship. +. Now use the defined ID space when connecting John with Paul, and use both IDs in the relationship. ++ +[.tabbed-example] +===== +[role=include-with-single-ID-column] +====== + +.relationships_header.csv +[source, csv] +---- +:START_ID(MyGroup),:TYPE,:END_ID(MyGroup) +---- + +.relationships.csv +[source, csv] +---- +aa11,WORKS_WITH,bb22 +---- + +====== +[role=include-with-multiple-ID-columns label--new-2025.07] +====== + +Starting from 2025.07, you have to use a matching number of `START_ID` / `END_ID` columns when defining the relationship: .relationships_header.csv [source, csv] @@ -1542,7 +1592,9 @@ Now use the defined ID space when connecting John with Paul, and use both IDs in ---- aa,11,WORKS_WITH,bb,22 ---- -==== +====== +===== + [[import-tool-id-types-header]] == Storing a different value type for IDs in a group From 53edba8ffa978c6c4129739269b863dfe1902a35 Mon Sep 17 00:00:00 2001 From: Reneta Popova Date: Thu, 21 Aug 2025 13:49:16 +0100 Subject: [PATCH 35/39] Document the configuration settings introduced for the Unix Domain Socket connector (#2537) Co-authored-by: Natalia Ivakina <82437520+NataliaIvakina@users.noreply.github.com> --- .../configuration/configuration-settings.adoc | 135 ++++++++++++++++++ 1 file changed, 135 insertions(+) diff --git a/modules/ROOT/pages/configuration/configuration-settings.adoc b/modules/ROOT/pages/configuration/configuration-settings.adoc index 612285063..edecb288b 100644 --- a/modules/ROOT/pages/configuration/configuration-settings.adoc +++ b/modules/ROOT/pages/configuration/configuration-settings.adoc @@ -1406,6 +1406,141 @@ a|A long that is minimum `1`. m|+++950+++ |=== +[role=label--new-2025.08] +[[config_server.bolt.unix_socket_auth]] +=== `server.bolt.unix_socket_auth` + +.server.bolt.unix_socket_auth +[frame="topbot", stripes=odd, grid="cols", cols="<1s,<4"] +|=== +|Description +a|Enable or disable authentication via the Bolt Unix Domain Socket connector. If disabled, connected clients gain all permissions so long as they are able to access the Unix Domain Socket file. +|Valid values +a|A boolean. +|Default value +m|+++true+++ +|=== + +[role=label--new-2025.08] +[[config_server.bolt.unix_socket_delete]] +=== `server.bolt.unix_socket_delete` + +.server.bolt.unix_socket_delete +[frame="topbot", stripes=odd, grid="cols", cols="<1s,<4"] +|=== +|Description +a|Whether or not to delete an existing file for use with the Unix Domain Socket based interface. This improves the handling of the case where a previous hard shutdown was unable to delete the file. +|Valid values +a|A boolean. +|Default value +m|+++false+++ +|=== + +[role=label--new-2025.08] +[[config_server.bolt.unix_socket_enabled]] +=== `server.bolt.unix_socket_enabled` + +.server.bolt.unix_socket_enabled +[frame="topbot", stripes=odd, grid="cols", cols="<1s,<4"] +|=== +|Description +a|Enable or disable the Bolt Unix Domain Socket connector.Requests submitted via this connector will be placed within a dedicated thread pool which is isolated from all other Bolt connections. +|Valid values +a|A boolean. +|Default value +m|+++false+++ +|=== + +[role=label--new-2025.08] +[[config_server.bolt.unix_socket_path]] +=== `server.bolt.unix_socket_path` + +.server.bolt.unix_socket_path +[frame="topbot", stripes=odd, grid="cols", cols="<1s,<4"] +|=== +|Description +a|The absolute path of the file for use with the Unix Domain Socket interface. This file must be specified and will be created at runtime and deleted on shutdown. +|Valid values +a|A path. +|Default value +m|++++++ +|=== + +[role=label--new-2025.08] +[[config_server.bolt.unix_socket_permission_mask]] +=== `server.bolt.unix_socket_permission_mask` + +.server.bolt.unix_socket_permission_mask +[frame="topbot", stripes=odd, grid="cols", cols="<1s,<4"] +|=== +|Description +a|Sets the default permission mask applied to the Unix Domain Socket file. This mask should be set as restrictive as possible (especially when authentication is disabled on this connector).Note, however, that this permission may not be honored by Posix systems other than Linux. +|Valid values +a|A set of file permissions. +|Default value +m|+++rwx--x--x+++ +|=== + +[role=label--new-2025.08] +[[config_server.bolt.unix_socket_thread_pool_keep_alive]] +=== `server.bolt.unix_socket_thread_pool_keep_alive` + +.server.bolt.unix_socket_thread_pool_keep_alive +[frame="topbot", stripes=odd, grid="cols", cols="<1s,<4"] +|=== +|Description +a|The maximum time an idle thread in the thread pool bound to the Unix Domain Socket connector waits for new tasks. +|Valid values +a|A duration (Valid units are: ns, μs, ms, s, m, h and d; default unit is s). +|Default value +m|+++5m+++ +|=== + +[role=label--new-2025.08] +[[config_server.bolt.unix_socket_thread_pool_max_size]] +=== `server.bolt.unix_socket_thread_pool_max_size` + +.server.bolt.unix_socket_thread_pool_max_size +[frame="topbot", stripes=odd, grid="cols", cols="<1s,<4"] +|=== +|Description +a|The maximum number of threads allowed in the thread pool bound to the Unix Domain Socket connector. +|Valid values +a|An integer that is minimum 1. +|Default value +m|+++20+++ +|=== + +[role=label--new-2025.08] +[[config_server.bolt.unix_socket_thread_pool_min_size]] +=== `server.bolt.unix_socket_thread_pool_min_size` + +.server.bolt.unix_socket_thread_pool_min_size +[frame="topbot", stripes=odd, grid="cols", cols="<1s,<4"] +|=== +|Description +a|The number of threads, including idle, to keep in the thread pool bound to the Unix Domain Socket connector. +|Valid values +a|An integer that is minimum 0. +|Default value +m|+++0+++ +|=== + +[role=label--new-2025.08] +[[config_server.bolt.unix_socket_use_dedicated_thread_pool]] +=== `server.bolt.unix_socket_use_dedicated_thread_pool` + +.server.bolt.unix_socket_use_dedicated_thread_pool +[frame="topbot", stripes=odd, grid="cols", cols="<1s,<4"] +|=== +|Description +a|Whether or not to allocate a dedicated thread pool for use with the Unix Domain Socket based interface. This permits the use of the Unix Domain Socket connector as an emergency access connector when the server is over capacity. +|Valid values +a|A boolean. +|Default value +m|+++true+++ +|=== + [[config_server.http.advertised_address]] === `server.http.advertised_address` From 8fc0f4706361ff6e07c9fc30f99b28c229fe411c Mon Sep 17 00:00:00 2001 From: Reneta Popova Date: Wed, 27 Aug 2025 11:55:38 +0100 Subject: [PATCH 36/39] Fix the broken links (#2538) --- .../authentication-authorization/dbms-administration.adoc | 2 +- .../pages/authentication-authorization/limitations.adoc | 4 ++-- modules/ROOT/pages/changes-deprecations-removals.adoc | 2 +- modules/ROOT/pages/configuration/neo4j-conf.adoc | 2 +- .../standard-databases/create-databases.adoc | 8 ++++---- .../ROOT/pages/kubernetes/operations/backup-restore.adoc | 4 ++-- modules/ROOT/pages/procedures.adoc | 6 +++--- .../ROOT/pages/tutorial/tutorial-sso-configuration.adoc | 2 +- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/modules/ROOT/pages/authentication-authorization/dbms-administration.adoc b/modules/ROOT/pages/authentication-authorization/dbms-administration.adoc index 4869f4a6f..9c78099f3 100644 --- a/modules/ROOT/pages/authentication-authorization/dbms-administration.adoc +++ b/modules/ROOT/pages/authentication-authorization/dbms-administration.adoc @@ -97,7 +97,7 @@ This includes the following tasks and their relevant privileges: * Manage xref:authentication-authorization/privileges-reads.adoc[read] and xref:authentication-authorization/privileges-writes.adoc[write] sub-graph privileges. * Manage <>. * Manage <>. -* Manage <>. +* Manage xref:authentication-authorization/load-privileges.adoc[load data security]. To enable a user to perform these tasks, you can grant them the `admin` role, but it is also possible to make a custom role with a subset of these privileges. All privileges are also assignable using Cypher commands. diff --git a/modules/ROOT/pages/authentication-authorization/limitations.adoc b/modules/ROOT/pages/authentication-authorization/limitations.adoc index d9f1881d6..b71036ab3 100644 --- a/modules/ROOT/pages/authentication-authorization/limitations.adoc +++ b/modules/ROOT/pages/authentication-authorization/limitations.adoc @@ -26,10 +26,10 @@ Further to that, Neo4j's role-based access control has some limitations and impl == Security and indexes Neo4j lets you create and use indexes to speed up Cypher queries. -See the link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/search-performance-indexes/[Cypher Manual -> Indexes] for more details on the different types of indexes available in Neo4j. +See the link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/[Cypher Manual -> Indexes] for more details on the different types of indexes available in Neo4j. However, Neo4j’s security model still controls what results you see, regardless of whether or not you use indexes. -For example, when you use link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/search-performance-indexes/overview/[search-performance indexes] (non–full-text) indexes, queries return the same results they would without any index. +For example, when you use link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/search-performance-indexes/[search-performance indexes] (non–full-text) indexes, queries return the same results they would without any index. This means that, if the security model causes fewer results to be returned due to restricted read access in xref:authentication-authorization/manage-privileges.adoc[graph and sub-graph access control], the index will also return the same fewer results. diff --git a/modules/ROOT/pages/changes-deprecations-removals.adoc b/modules/ROOT/pages/changes-deprecations-removals.adoc index 5029e0dde..6bc5c9a32 100644 --- a/modules/ROOT/pages/changes-deprecations-removals.adoc +++ b/modules/ROOT/pages/changes-deprecations-removals.adoc @@ -408,7 +408,7 @@ Replaced by xref:procedures.adoc#procedure_dbms_unquarantineDatabase[`dbms.unqua | label:deprecated[Deprecated in 5.26] + label:removed[Removed in Cypher 25] + Replaced by the Cypher command `CREATE VECTOR INDEX`. -For more information, see the link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/semantic-indexes/vector-indexes/#create-vector-index/[Cypher Manual → Create a vector index]. +For more information, see the link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/semantic-indexes/vector-indexes/#create-vector-index[Cypher Manual → Create a vector index]. | xref:procedures.adoc#procedure_dbms_cluster_uncordonServer[`dbms.cluster.uncordonServer()`] diff --git a/modules/ROOT/pages/configuration/neo4j-conf.adoc b/modules/ROOT/pages/configuration/neo4j-conf.adoc index ebf868058..6e4c4844c 100644 --- a/modules/ROOT/pages/configuration/neo4j-conf.adoc +++ b/modules/ROOT/pages/configuration/neo4j-conf.adoc @@ -6,7 +6,7 @@ The _neo4j.conf_ file is the main source of configuration settings in Neo4j and The location of the _neo4j.conf_ file in the different configurations of Neo4j is listed in xref:configuration/file-locations.adoc[Default file locations]. Most of the configuration settings in the _neo4j.conf_ file apply directly to Neo4j itself, but there are also other settings related to the Java Runtime (the JVM) on which Neo4j runs. -For more information, see the xref:configuration/neo4j-conf.adoc#neo4j-conf-JVM[JVM specific configuration settings]. +For more information, see the <>. Many of the configuration settings are also used by `neo4j` launcher scripts. diff --git a/modules/ROOT/pages/database-administration/standard-databases/create-databases.adoc b/modules/ROOT/pages/database-administration/standard-databases/create-databases.adoc index e14406874..f6d371f6c 100644 --- a/modules/ROOT/pages/database-administration/standard-databases/create-databases.adoc +++ b/modules/ROOT/pages/database-administration/standard-databases/create-databases.adoc @@ -137,7 +137,7 @@ Replaced by `existingDataSeedServer`. | URI to a backup or a dump from an existing database. | Defines an identical seed from an external source which will be used to seed all servers. -For more information, see xref::database-administration/standard-databases/seed-from-uri.adoc[Seed from a URI]. +For more information, see xref:database-administration/standard-databases/seed-from-uri.adoc[Create a database from a URI]. | `seedConfig` | Comma-separated list of configuration values. @@ -198,14 +198,14 @@ Defines a seed from an external source, which will be used to seed all servers. | `seedConfig` | Comma-separated list of configuration values. | -For more information see xref::clustering/databases.adoc#cluster-seed-uri[Seed from URI]. +For more information see xref:database-administration/standard-databases/seed-from-uri.adoc[Create a database from a URI]. -| `txLogEnrichment` +| `txLogEnrichment`§ | `FULL` \| `DIFF` \| `OFF` | Defines the level of enrichment applied to transaction logs for Change Data Capture (CDC) purposes. -For details about enrichment mode, see link:{neo4j-docs-base-uri}/cdc/current/get-started/self-managed/#set-enrichment-mode/[Change Data Capture Manual -> Enable CDC on self-managed instances -> Set the enrichment mode]. +For details about enrichment mode, see link:{neo4j-docs-base-uri}/cdc/current/get-started/self-managed/#tweak-mode[Change Data Capture Manual -> Enable CDC on self-managed instances -> Toggle CDC mode]. | `storeFormat` | `aligned` \| `standard` \| `high_limit` \| `block` diff --git a/modules/ROOT/pages/kubernetes/operations/backup-restore.adoc b/modules/ROOT/pages/kubernetes/operations/backup-restore.adoc index 235e988a0..027f57f8c 100644 --- a/modules/ROOT/pages/kubernetes/operations/backup-restore.adoc +++ b/modules/ROOT/pages/kubernetes/operations/backup-restore.adoc @@ -1053,7 +1053,7 @@ To restore the `system` database, follow the steps described in xref:kubernetes/ To migrate from persistent volume-based backups to cloud-native backups, you need to follow these steps: . Perform a final traditional backup to ensure you have the latest data. -For more information, see <> and <>. +For more information, see <> and <<#_back_up_your_databases, Back up your databases>>. . Upload existing backups to the cloud storage bucket if needed. You can use cloud provider CLI tools to transfer your backup files: ** For AWS S3: `aws s3 cp /path/to/backups s3://your-bucket/backups --recursive` @@ -1062,5 +1062,5 @@ You can use cloud provider CLI tools to transfer your backup files: . Update the _backup-values.yaml_ file to configure the cloud provider, bucket name, and credentials. See <> for details. . Install the _neo4j-admin_ Helm chart with the updated _backup-values.yaml_ file to back up your databases to the cloud provider bucket. -See <<_back_up_your_databases, Back up your databases>> for details. +See <<#_back_up_your_databases, Back up your databases>> for details. diff --git a/modules/ROOT/pages/procedures.adoc b/modules/ROOT/pages/procedures.adoc index 9b078fba8..ce2ffc8f1 100644 --- a/modules/ROOT/pages/procedures.adoc +++ b/modules/ROOT/pages/procedures.adoc @@ -829,7 +829,7 @@ For more information, see the link:{neo4j-docs-base-uri}/cypher-manual/current/p ==== As of Neo4j 2025.05, `dbms.components()` returns the supported Cypher versions in a row where the `name` column has the value `"Cypher"`. As of Neo4j 2025.06, the row has the value `["5", "25"]`, indicating that both Cypher 5 and Cypher 25 are supported from this release onward. -For more information about Cypher versions, see the link:{neo4j-docs-base-uri}/cypher-manual/queries/select-version/[Cypher Manual -> Select Cypher version]. +For more information about Cypher versions, see the link:{neo4j-docs-base-uri}/cypher-manual/current/queries/select-version/[Cypher Manual -> Select Cypher version]. ==== [[procedure_dbms_info]] @@ -1140,7 +1140,7 @@ Starting with Neo4j 2025.04, the default database can also be set to a local or | `quarantined` | `BOOLEAN` | Whether or not the database is quarantined. | `result` | `STRING` | Details about the outcome of the procedure. | *Mode* 3+| DBMS -| *Replaced by* 3+| xref:procedures.adoc#procedure_dbms_unquarantineDatabase[`dbms.unquarantineDatabase()`] +| *Replaced by* 3+| <> |=== [NOTE] @@ -1296,7 +1296,7 @@ The types are still enforced as `LIST`. .2+| *Return arguments* | *Name* | *Type* | *Description* | `node` | `NODE` | The node on which the vector property was set. | *Mode* 3+| WRITE -| *Replaced by* 3+| xref:procedures.adoc#procedure_db_create_setNodeVectorProperty[`db.create.setNodeVectorProperty()`] and xref:procedures.adoc#procedure_db_create_setRelationshipVectorProperty[`db.create.setRelationshipVectorProperty()`] +| *Replaced by* 3+| <> and <> |=== .Known issue diff --git a/modules/ROOT/pages/tutorial/tutorial-sso-configuration.adoc b/modules/ROOT/pages/tutorial/tutorial-sso-configuration.adoc index 9e9653458..65e6e4ad5 100644 --- a/modules/ROOT/pages/tutorial/tutorial-sso-configuration.adoc +++ b/modules/ROOT/pages/tutorial/tutorial-sso-configuration.adoc @@ -291,7 +291,7 @@ dbms.security.oidc.azure.config=token_type_principal=id_token;token_type_authent [IMPORTANT] ==== `sub` is the only claim guaranteed to be unique and stable. -For details, see link:https://learn.microsoft.com/en-us/azure/active-directory/develop/id-tokens#using-claims-to-reliably-identify-a-user-subject-and-object-id[Microsoft documentation] as well as the https://openid.net/specs/openid-connect-core-1_0.html#ClaimStability[OpenId spec]. +For details, see link:https://learn.microsoft.com/en-us/azure/active-directory/develop/id-tokens[Microsoft documentation] as well as the https://openid.net/specs/openid-connect-core-1_0.html#ClaimStability[OpenId spec]. ==== + [source, properties] From f82603a4a954990aae5021fc4f15aa8b2c665ca2 Mon Sep 17 00:00:00 2001 From: Natalia Ivakina <82437520+NataliaIvakina@users.noreply.github.com> Date: Wed, 27 Aug 2025 14:27:13 +0200 Subject: [PATCH 37/39] Fix broken links (#2548) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To update the links to the Cypher manual following the renaming of several pages. --------- Co-authored-by: Jens Pryce-Åklundh <112686610+JPryce-Aklundh@users.noreply.github.com> --- .../pages/authentication-authorization/built-in-roles.adoc | 2 +- modules/ROOT/pages/introduction.adoc | 2 +- modules/ROOT/pages/monitoring/metrics/essential.adoc | 2 +- modules/ROOT/pages/performance/index-configuration.adoc | 6 +++--- modules/ROOT/pages/procedures.adoc | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/ROOT/pages/authentication-authorization/built-in-roles.adoc b/modules/ROOT/pages/authentication-authorization/built-in-roles.adoc index a014d1feb..4c758a42d 100644 --- a/modules/ROOT/pages/authentication-authorization/built-in-roles.adoc +++ b/modules/ROOT/pages/authentication-authorization/built-in-roles.adoc @@ -827,7 +827,7 @@ These include the rights to perform the following classes of tasks: * Manage xref:authentication-authorization/database-administration.adoc[database privileges] to control the rights to perform actions on specific databases: ** Manage access to a database and the right to start and stop a database. -** Manage link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/search-performance-indexes/overview/[indexes] and link:{neo4j-docs-base-uri}/cypher-manual/current/constraints/[constraints]. +** Manage link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/[indexes] and link:{neo4j-docs-base-uri}/cypher-manual/current/constraints/[constraints]. ** Allow the creation of labels, relationship types, or property names. ** Manage transactions. * Manage xref:authentication-authorization/dbms-administration.adoc[DBMS privileges] to control the rights to perform actions on the entire system: diff --git a/modules/ROOT/pages/introduction.adoc b/modules/ROOT/pages/introduction.adoc index 31b528769..a034c7ad1 100644 --- a/modules/ROOT/pages/introduction.adoc +++ b/modules/ROOT/pages/introduction.adoc @@ -160,7 +160,7 @@ a| APOC 450+ link:https://neo4j.com/docs/apoc/5/[Core Procedures and Functions] 3+^s| Indexes and constraints -| link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/search-performance-indexes/overview/[Fast writes via native label indexes] +| link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/[Fast writes via native label indexes] | {check-mark} | {check-mark} diff --git a/modules/ROOT/pages/monitoring/metrics/essential.adoc b/modules/ROOT/pages/monitoring/metrics/essential.adoc index fc9cf2235..06712d8ec 100644 --- a/modules/ROOT/pages/monitoring/metrics/essential.adoc +++ b/modules/ROOT/pages/monitoring/metrics/essential.adoc @@ -19,7 +19,7 @@ Reading the xref:performance/index.adoc[] section is recommended to better under Monitoring the hardware resources shows the strain on the server running Neo4j. -You can use utilities, such as the https://www.collectd.org/[collectd] daemon or `systemd` on Linux, to gather information about the system. +You can use utilities, such as the https://collectd.org/[collectd] daemon or `systemd` on Linux, to gather information about the system. These metrics can help with capacity planning as your workload grows. [options="header", cols="1,3a"] diff --git a/modules/ROOT/pages/performance/index-configuration.adoc b/modules/ROOT/pages/performance/index-configuration.adoc index bb1de95bb..8401a052c 100644 --- a/modules/ROOT/pages/performance/index-configuration.adoc +++ b/modules/ROOT/pages/performance/index-configuration.adoc @@ -21,7 +21,7 @@ When you write a Cypher query, you do not need to specify which indexes to use. Cypher's query planner decides which of the available indexes to use. The rest of this page provides information on the available indexes and their configuration aspects. -For further details on creating, querying, and dropping indexes, see link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/search-performance-indexes/overview/[Cypher Manual -> Indexes for search performance] and link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/semantic-indexes/full-text-indexes/[Cypher Manual -> Indexes to support full-text search]. +For further details on creating, querying, and dropping indexes, see link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/search-performance-indexes/[Cypher Manual -> Indexes for search performance], link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/semantic-indexes/full-text-indexes/[Full-text indexes], and link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/semantic-indexes/vector-indexes/[Vector indexes]. The type of an index can be identified according to the table below: @@ -77,7 +77,7 @@ Exact lookups are the only non-spatial query that this index type supports. For more information on the queries a point index can be used for, refer to link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/search-performance-indexes/using-indexes/[Cypher Manual -> Query Tuning -> The use of indexes]. Point indexes optionally accept configuration properties for tuning the behavior of spatial search. -For more information on configuring point index, refer to link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/search-performance-indexes/overview/[Cypher Manual -> Indexes for search performance]. +For more information on configuring point index, refer to link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/search-performance-indexes/[Cypher Manual -> Indexes for search performance]. [[index-configuration-text]] @@ -94,7 +94,7 @@ The default provider is `text-2.0`. For more information on the queries a text index can be used for, refer to link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/search-performance-indexes/using-indexes/[Cypher Manual -> Query Tuning -> The use of indexes]. -For more information on the different index types, refer to link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/search-performance-indexes/overview/[Cypher Manual -> Indexes for search performance]. +For more information on the different index types, refer to link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/search-performance-indexes/[Cypher Manual -> Indexes for search performance]. [[index-configuration-text-limitations]] === Limitations diff --git a/modules/ROOT/pages/procedures.adoc b/modules/ROOT/pages/procedures.adoc index ce2ffc8f1..c3bfa3b1c 100644 --- a/modules/ROOT/pages/procedures.adoc +++ b/modules/ROOT/pages/procedures.adoc @@ -1432,7 +1432,7 @@ The types are still enforced as `LIST`. For more information, see: * xref:performance/index-configuration.adoc[] -* link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/search-performance-indexes/overview/[Cypher Manual -> Search performance indexes] +* link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/search-performance-indexes/[Cypher Manual -> Search performance indexes] * link:{neo4j-docs-base-uri}/cypher-manual/current/indexes/semantic-indexes/full-text-indexes[Cypher Manual -> Full-text indexes] [[procedure_db_awaitIndex]] From 5b4c8d70449004c247449533da4c1e6a48ba59e6 Mon Sep 17 00:00:00 2001 From: Natalia Ivakina <82437520+NataliaIvakina@users.noreply.github.com> Date: Thu, 28 Aug 2025 15:18:06 +0200 Subject: [PATCH 38/39] Clarify backup/restore strategy regarding system db (#2521) --- .../ROOT/pages/backup-restore/planning.adoc | 80 +++++++++++-------- 1 file changed, 46 insertions(+), 34 deletions(-) diff --git a/modules/ROOT/pages/backup-restore/planning.adoc b/modules/ROOT/pages/backup-restore/planning.adoc index 03c03d2f6..d7ad162bb 100644 --- a/modules/ROOT/pages/backup-restore/planning.adoc +++ b/modules/ROOT/pages/backup-restore/planning.adoc @@ -38,7 +38,7 @@ If you have zero tolerance for downtime and data loss, you might want to conside ** use SSL/TLS for the backup network communication (online only). ** keep your databases as archive files (online or offline). * How many backups you want to keep. -* Where the backups will be stored — drive or remote server, cloud storage, different data center, different location, etc. +* Where the backups will be stored — drive or remote server, cloud storage, different data center, different location, etc. + [TIP] ==== @@ -51,15 +51,14 @@ This ensures that if for some reason your Neo4j DBMS crashes, you will be able t == Backup and restore options Neo4j supports backing up and restoring both online and offline databases. -It uses xref:neo4j-admin-neo4j-cli.adoc[Neo4j Admin tool] commands, which can be run from a live, as well as from an offline Neo4j DBMS. +It uses xref:neo4j-admin-neo4j-cli.adoc[Neo4j Admin tool] commands that can be executed on a Neo4j DBMS, whether it is running or offline. All `neo4j-admin` commands must be invoked as the `neo4j` user to ensure the appropriate file permissions. -* `neo4j-admin database backup/restore` (Enterprise only) -– used for performing online backup (xref:backup-restore/modes.adoc#full-backup[full] and xref:backup-restore/modes.adoc#differential-backup[differential]) and restore operations. -The database to be backed up must be in **online** mode. -The command produces an immutable artifact, which has an inspectable API to aid management and operability. -This command is suitable for production environments, where you cannot afford downtime. -+ -The command can also be invoked over the network if access is enabled using `server.backup.listen_address`. +* `neo4j-admin database backup/restore` label:enterprise[Enterprise Edition] – used for performing online backup (xref:backup-restore/modes.adoc#full-backup[full] and xref:backup-restore/modes.adoc#differential-backup[differential]) and restore operations. +** The database to be backed up must be in **online** mode. +** The command produces an immutable artifact, which has an inspectable API to aid management and operability. +** This command is suitable for production environments, where you cannot afford downtime. +** The command can also be invoked over the network if access is enabled using `server.backup.listen_address`. + [NOTE] ==== @@ -73,9 +72,9 @@ For more information, refer to the xref:backup-restore/online-backup.adoc#backup When using `neo4j-admin database backup` in a cluster, it is recommended to back up from an external instance as opposed to reuse instances that form part of the cluster. ==== * `neo4j-admin database dump/load` –- used for performing offline dump and load operations. -The database to be dumped must be in **offline** mode. -The dump command can only be invoked from the server command line and is suitable for environments where downtime is not a factor. -The command produces an archive file that follows the format _.dump_. +** The database to be dumped must be in **offline** mode. +** The dump command can only be invoked from the server command line and is suitable for environments where downtime is not a factor. +** The command produces an archive file that follows the format _.dump_. * `neo4j-admin database copy` –- used for copying an offline database or backup. This command can be used for cleaning up database inconsistencies and reclaiming unused space. @@ -84,23 +83,9 @@ This command can be used for cleaning up database inconsistencies and reclaiming File system copy-and-paste of databases is not supported and may result in unwanted behavior, such as corrupt stores. ==== -=== Considerations for backing up and restoring databases in a cluster - -Backing up a database in a clustered environment is not essentially different from a standalone backup, apart from the fact that you must know which server in a cluster to connect to. -Use `SHOW DATABASE ` to learn which servers are hosting the database you want to back up. -See xref:clustering/monitoring/show-databases-monitoring.adoc#show-databases-monitoring-listing-single[Listing a single database] for more information. - -However, _restoring_ a database in a cluster is different since it is not known in advance how a database is going to be allocated to the servers in a cluster. -This method relies on the seed already existing on one of the servers. -The recommended way to restore a database in a cluster is to xref::database-administration/standard-databases/seed-from-uri.adoc[seed from URI]. +The following table summarizes the commands' capabilities and usage. -[NOTE] -==== -The Neo4j Admin commands `backup`, `restore`, `dump`, `load`, `copy`, and `check-consistency` are not supported for use on xref:database-administration/composite-databases/concepts.adoc[Composite databases]. -They must be run directly on the databases that are associated with that Composite database. -==== - -.The following table describes the commands' capabilities and usage. +.`neo4j-admin` commands for backing up and restoring databases [cols="<,^,^,^",frame="topbot",options="header"] |=== | Capability/ Usage @@ -184,18 +169,45 @@ They must be run directly on the databases that are associated with that Composi | {check-mark} |=== + +[NOTE] +==== +The Neo4j Admin commands `backup`, `restore`, `dump`, `load`, `copy`, and `check-consistency` are not supported for use on xref:database-administration/composite-databases/concepts.adoc[Composite databases]. +They must be run directly on the databases that are associated with that Composite database. +==== + + +== Considerations for backing up and restoring databases in a cluster + +Backing up a database in a clustered environment is not essentially different from a standalone backup, apart from the fact that you must know which server in a cluster to connect to. +Use `SHOW DATABASE ` to learn which servers are hosting the database you want to back up. +See xref:clustering/monitoring/show-databases-monitoring.adoc#show-databases-monitoring-listing-single[Listing a single database] for more information. + +Restoring from the command line involves putting a copy of the database on disk on each server that will need it. +That can be awkward to achieve. +The recommended way to restore a database in a cluster is to xref::database-administration/standard-databases/seed-from-uri.adoc[seed from URI]. + +[IMPORTANT] +==== +By default, a database backup includes only the database contents. +If you choose to include metadata, the backup also stores the role-based access control (RBAC) settings associated with the database. + +When restoring, you have the flexibility to define the target topology (how many primaries and secondaries are desired for the database), which may differ from the topology at backup time. +The database will then be allocated across the available servers according to that topology. +==== + [[backup-planning-databases]] -== Databases to backup +== Databases to back up A Neo4j DBMS can host multiple databases. -Both Neo4j Community and Enterprise Editions have a default user database, called `neo4j`, and a `system` database, which contains configurations, e.g., operational states of databases, security configuration, schema definitions, login credentials, and roles. -In the Enterprise Edition, you can also create additional user databases. +Both Neo4j Community and Enterprise Editions have a default user database named `neo4j` and a `system` database. +The `system` database contains configurations, e.g., operational states of databases, security configuration, schema definitions, login credentials, and roles. + +In the Enterprise Edition, you can also create multiple user databases. Each of these databases is backed up independently of one another. -[NOTE] -==== It is very important to store a recent backup of your databases, including the `system` database, in a safe location. -==== + [[backup-planning-additional]] == Additional files to back up @@ -215,4 +227,4 @@ If you have a cluster, you should back up these files for each cluster member. For any backup, it is important that you store your data separately from the production system, where there are no common dependencies, and preferably off-site. If you are running Neo4j in the cloud, you may use a different availability zone or even a separate cloud provider. -Since backups are kept for a long time, the longevity of archival storage should be considered as part of backup planning. \ No newline at end of file +Since backups are kept for a long time, the longevity of archival storage should be considered as part of backup planning. From 7613a006000951d453aff455ca6c6ded99e792fe Mon Sep 17 00:00:00 2001 From: Natalia Ivakina <82437520+NataliaIvakina@users.noreply.github.com> Date: Mon, 1 Sep 2025 14:49:48 +0200 Subject: [PATCH 39/39] Fix the name of `neo4j-admin server unbind` cmd (#2558) --- modules/ROOT/pages/clustering/servers.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ROOT/pages/clustering/servers.adoc b/modules/ROOT/pages/clustering/servers.adoc index 777b8f99d..e83fd59b4 100644 --- a/modules/ROOT/pages/clustering/servers.adoc +++ b/modules/ROOT/pages/clustering/servers.adoc @@ -120,7 +120,7 @@ Once dropped, a server cannot rejoin a cluster. [NOTE] ==== -The same physical hardware can rejoin the cluster, provided the Neo4j installation has been "reset" (either re-installing, or running `neo4j-admin unbind`), causing it to receive a new generated server ID on next startup. +The same physical hardware can rejoin the cluster, provided the Neo4j installation has been "reset" (either re-installing, or running `neo4j-admin server unbind`), causing it to receive a new generated server ID on next startup. ==== == Listing servers