Skip to content

Commit 302d08d

Browse files
renetapopovaJPryce-AklundhNataliaIvakinaRagnarWloveleif
authored
2025.04 merge dev (#2304)
Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: Jens Pryce-Åklundh <[email protected]> Co-authored-by: NataliaIvakina <[email protected]> Co-authored-by: Ragnar Wernersson <[email protected]> Co-authored-by: Love Kristofer Leifland <[email protected]> Co-authored-by: Neil Dewhurst <[email protected]> Co-authored-by: David Pond <[email protected]> Co-authored-by: Gerrit Meier <[email protected]> Co-authored-by: Tony Butterfield <[email protected]> Co-authored-by: Tselmeg Baasan <[email protected]> Co-authored-by: Phil Wright <[email protected]> Co-authored-by: Therese Magnusson <[email protected]> Co-authored-by: Jack Waudby <[email protected]> Co-authored-by: Hannes Sandberg <[email protected]> Co-authored-by: Therese Magnusson <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Anna Sjerling <[email protected]> Co-authored-by: Natalia Ivakina <[email protected]> Co-authored-by: Robsdedude <[email protected]> Co-authored-by: Satia Herfert <[email protected]> Co-authored-by: Nick Giles <[email protected]> Co-authored-by: Frannie-Ludmilla <[email protected]>
1 parent ef079e3 commit 302d08d

File tree

18 files changed

+576
-103
lines changed

18 files changed

+576
-103
lines changed

antora.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
name: operations-manual
22
title: Operations Manual
3-
version: '2025.03'
3+
version: '2025.04'
44
current: true
55
start_page: ROOT:index.adoc
66
nav:
77
- modules/ROOT/content-nav.adoc
88
asciidoc:
99
attributes:
10-
neo4j-version: '2025.03'
11-
neo4j-version-minor: '2025.03'
12-
neo4j-version-exact: '2025.03.0'
13-
neo4j-buildnumber: '2025.03'
14-
neo4j-debian-package-version: '1:2025.03.0@'
10+
neo4j-version: '2025.04'
11+
neo4j-version-minor: '2025.04'
12+
neo4j-version-exact: '2025.04.0'
13+
neo4j-buildnumber: '2025.04'
14+
neo4j-debian-package-version: '1:2025.04.0@'

modules/ROOT/pages/authentication-authorization/limitations.adoc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -390,8 +390,10 @@ So due to the additional data access required by the security checks, this opera
390390

391391
[[property-based-access-control-limitations]]
392392
=== Property-based access control limitations
393-
Extra node-level security checks are necessary when adding security rules based on property rules, and these can have a significant performance impact.
394-
The following example shows how the database behaves when adding security rules to roles `restricted` and `unrestricted`:
393+
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.
394+
395+
The following example shows how the database behaves when adding security rules for nodes to roles `restricted` and `unrestricted`.
396+
The same limitations apply to relationships.
395397

396398
[source, cypher]
397399
----

modules/ROOT/pages/authentication-authorization/property-based-access-control.adoc

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ CREATE ROLE regularUsers;
1212
[[property-based-access-control]]
1313
= Property-based access control
1414

15-
Property-based access control grants permissions to users to read node properties based on property/value conditions.
15+
Property-based access control grants or denies permission to read or traverse nodes or relationships based on property/value conditions.
1616
Each property-based privilege can only be restricted by a single property.
17-
For information about read privileges and their syntax, see xref:authentication-authorization/privileges-reads.adoc[Read privileges].
17+
For information about and syntax for these privileges, see xref:authentication-authorization/privileges-reads.adoc[Read privileges].
1818

1919
[IMPORTANT]
2020
====
@@ -25,28 +25,32 @@ Users who can change this property can affect the granted property-based privile
2525

2626
== Syntax
2727

28-
To specify the property/value conditions of the read privilege, you can use the following syntax:
28+
To specify the property/value conditions of the privilege, you can use the following syntax:
2929

3030
[source, syntax, role="noheader"]
3131
----
3232
{GRANT | DENY | REVOKE [GRANT | DENY]}
3333
[IMMUTABLE]
34-
{MATCH | READ | TRAVERSE}
34+
{MATCH | READ | TRAVERSE}
3535
ON { HOME GRAPH | GRAPH[S] { * | name[, ...] } }
3636
[
3737
ELEMENT[S] { * | label-or-rel-type[, ...] }
3838
| NODE[S] { * | label[, ...] }
3939
| RELATIONSHIP[S] { * | rel-type[, ...] }
4040
| FOR {
41-
42-
([var][:label["|" ...]] "{" property: value "}")
43-
| (var[:label["|" ...]])
44-
WHERE [NOT] var.property { { = | <> | > | >= | < | <= } value | IS NULL | IS NOT NULL | IN { "["[value[, ...]]"]" | listParam } }
45-
| (var[:label["|" ...]]
46-
WHERE [NOT] var.property { { = | <> | > | >= | < | <= } value | IS NULL | IS NOT NULL | IN { "["[value[, ...]]"]" | listParam } } )
47-
}
48-
49-
{TO | FROM} role[, ...]
41+
([var][:label["|" ...]] "{" property: value "}")
42+
| (var[:label["|" ...]])
43+
WHERE [NOT] var.property { { = | <> | > | >= | < | <= } value | IS NULL | IS NOT NULL | IN { "["[value[, ...]]"]" | listParam } }
44+
| (var[:label["|" ...]]
45+
WHERE [NOT] var.property { { = | <> | > | >= | < | <= } value | IS NULL | IS NOT NULL | IN { "["[value[, ...]]"]" | listParam } } )
46+
| ()[<]-"["[var][:type["|" ...]] "{" property: value "}" "]"-[>]()
47+
| ()[<]-"["var[:type["|" ...]]"]"-[>]()
48+
WHERE [NOT] var.property { { = | <> | > | >= | < | <= } value | IS NULL | IS NOT NULL | IN { "["[value[, ...]]"]" | listParam } }
49+
| ()[<]-"["var[:type["|" ...]]
50+
WHERE [NOT] var.property { { = | <> | > | >= | < | <= } value | IS NULL | IS NOT NULL | IN { "["[value[, ...]]"]" | listParam } } "]"-[>]()
51+
}
52+
]
53+
{TO | FROM} role[, ...]
5054
----
5155

5256

@@ -57,7 +61,7 @@ See xref:authentication-authorization/limitations.adoc#property-based-access-con
5761

5862
When having property rules, the following factors can worsen the impact on performance:
5963

60-
* The number of properties on the nodes concerned (more properties = greater performance impact).
64+
* The number of properties on the nodes and relationships concerned (more properties = greater performance impact).
6165
* The number of property-based privileges (more property-based privileges = greater performance impact).
6266
* The type of the privilege: `TRAVERSE` property-based privileges have greater performance impact than `READ` property-based privileges.
6367
* The type of storage medium in operation. The impact of the property-based privileges on performance is considerably amplified by accessing disc storage.
@@ -81,7 +85,7 @@ GRANT privilege-name ON GRAPH graph-name FOR pattern TO role-name
8185
The user role does not need to have `READ` privilege for the property used by the property-based privilege.
8286
====
8387

84-
=== Grant a property-based privilege on a specific property using its value
88+
=== Grant a property-based privilege on a specific property using the value of another property
8589

8690
The following example shows how to grant permission to `READ` the `address` property on `Email` or `Website` nodes with domain `exampledomain.com` to role `regularUsers`:
8791

@@ -97,6 +101,12 @@ Alternatively, you can use the following syntax:
97101
GRANT READ { address } ON GRAPH * FOR (:Email|Website {domain: 'exampledomain.com'}) TO regularUsers
98102
----
99103

104+
The following example shows how to grant permission to `READ` the `since` property on `OWNS` relationships having `classification` equal to `UNCLASSIFIED` to role `regularUsers`:
105+
106+
[source, syntax, role="noheader"]
107+
----
108+
GRANT READ { since } ON GRAPH * FOR ()-[o:OWNS]-() WHERE o.classification = 'UNCLASSIFIED' TO regularUsers
109+
----
100110

101111
=== Grant a property-based privilege using `NULL`
102112

@@ -109,20 +119,22 @@ GRANT TRAVERSE ON GRAPH * FOR (n:Email) WHERE n.classification IS NULL TO regula
109119

110120
=== Deny a property-based privilege using a comparison operator
111121

112-
The following example shows how to deny permission to `READ` and `TRAVERSE` nodes where the property `classification` is different from `UNCLASSIFIED` to role `regularUsers`:
122+
The following example shows how to deny permission to `READ` and `TRAVERSE` nodes and relationships where the property `classification` is different from `UNCLASSIFIED` to role `regularUsers`:
113123

114124
[source, syntax, role="noheader"]
115125
----
116126
DENY MATCH {*} ON GRAPH * FOR (n) WHERE n.classification <> 'UNCLASSIFIED' TO regularUsers
127+
DENY MATCH {*} ON GRAPH * FOR ()-[r]-() WHERE r.classification <> 'UNCLASSIFIED' TO regularUsers
117128
----
118129

119130
=== Grant a property-based privilege on all properties using a property value
120131

121-
The following example shows how to grant permission to `READ` all properties on nodes where the property `securityLevel` is higher than `3` to role `regularUsers`:
132+
The following example shows how to grant permission to `READ` all properties on nodes and relationships where the property `securityLevel` is higher than `3` to role `regularUsers`:
122133

123134
[source, syntax, role="noheader"]
124135
----
125136
GRANT READ {*} ON GRAPH * FOR (n) WHERE n.securityLevel > 3 TO regularUsers
137+
GRANT READ {*} ON GRAPH * FOR ()-[r]-() WHERE r.securityLevel > 3 TO regularUsers
126138
----
127139

128140
[NOTE]
@@ -132,22 +144,24 @@ The role `regularUsers` does not need to have `READ` privilege for the property
132144

133145
=== Deny a property-based privilege using a list of values
134146

135-
The following example shows how to deny permission to `READ` all properties on nodes where the property `classification` is not included in the list of `[UNCLASSIFIED, PUBLIC]`:
147+
The following example shows how to deny permission to `READ` all properties on nodes and relationships where the property `classification` is not included in the list of `[UNCLASSIFIED, PUBLIC]`:
136148

137149
[source, syntax, role="noheader"]
138150
----
139151
DENY READ {*} ON GRAPH * FOR (n) WHERE NOT n.classification IN ['UNCLASSIFIED', 'PUBLIC'] TO regularUsers
152+
DENY READ {*} ON GRAPH * FOR ()-[r]-() WHERE NOT r.classification IN ['UNCLASSIFIED', 'PUBLIC'] TO regularUsers
140153
----
141154

142155
// The last two examples were added in 5.26.
143156

144157
=== Grant a property-based privilege using temporal value
145158

146-
The following example shows how to grant permission to `READ` all properties on nodes where the property `createdAt` is later than the current date:
159+
The following example shows how to grant permission to `READ` all properties on nodes and relationships where the property `createdAt` is later than the current date:
147160

148161
[source, syntax, role="noheader"]
149162
----
150163
GRANT READ {*} ON GRAPH * FOR (n) WHERE n.createdAt > date() TO regularUsers
164+
GRANT READ {*} ON GRAPH * FOR ()-[r]-() WHERE r.createdAt > date() TO regularUsers
151165
----
152166

153167
[NOTE]
@@ -174,6 +188,7 @@ SHOW ROLE regularUsers PRIVILEGES AS REVOKE COMMANDS
174188
|===
175189
|command
176190
|"REVOKE GRANT READ {*} ON GRAPH * FOR (n) WHERE n.createdAt > date('2024-10-25') FROM `regularUsers`"
177-
a|Rows: 1
191+
|"REVOKE GRANT READ {*} ON GRAPH * FOR ()-[r]-() WHERE r.createdAt > date('2024-10-25') FROM `regularUsers`"
192+
a|Rows: 2
178193
|===
179194

modules/ROOT/pages/backup-restore/online-backup.adoc

Lines changed: 160 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,12 @@ For more information, see xref:backup-restore/online-backup.adoc#online-backup-c
6464

6565
[source,role=noheader]
6666
----
67-
neo4j-admin database backup [-h] [--expand-commands] [--verbose]
67+
neo4j-admin database backup [-h] [--expand-commands] [--prefer-diff-as-parent] [--verbose]
6868
[--compress[=true|false]] [--keep-failed[=true|false]]
69-
[--parallel-recovery[=true|false]]
70-
[--additional-config=<file>]
71-
[--include-metadata=none|all|users|roles]
72-
[--inspect-path=<path>] [--pagecache=<size>] [--temp-path=<path>]
73-
[--to-path=<path>] [--type=<type>] [--from=<host:port>[,<host:
74-
port>...]]... [<database>...]
69+
[--parallel-recovery[=true|false]] [--additional-config=<file>]
70+
[--include-metadata=none|all|users|roles] [--inspect-path=<path>]
71+
[--pagecache=<size>] [--temp-path=<path>] [--to-path=<path>]
72+
[--type=<type>] [--from=<host:port>[,<host:port>...]]... [<database>...]
7573
----
7674

7775
=== Description
@@ -162,6 +160,10 @@ It is recommended to use `SHOW USERS`, `SHOW ROLES`, and `SHOW ROLE $role PRIVIL
162160
Note: this is an EXPERIMENTAL option. Consult Neo4j support before use.
163161
|false
164162

163+
|--prefer-diff-as-parent
164+
|label:new[Introduced in 2025.04] When performing a differential backup, prefer the latest non-empty differential backup as the parent instead of the latest backup.
165+
|false
166+
165167
|--temp-path=<path>
166168
|Provide a path to a temporary empty directory for storing backup files until the command is completed. The files will be deleted once the command is finished.
167169
|
@@ -457,3 +459,154 @@ bin/neo4j-admin database backup --to-path=azb://myStorageAccount/myContainer/myD
457459
----
458460
======
459461
=====
462+
463+
464+
[role=label--new-2025.04]
465+
[[diff-backup-as-parent]]
466+
=== Perform a differential backup using the `--prefer-diff-as-parent` option
467+
468+
By default, a differential backup (`--type=DIFF`) uses the *most recent non-empty* backup -- whether full or differential -- in the directory as its parent.
469+
470+
The `--prefer-diff-as-parent` option changes this behavior and forces the backup job to use the *latest differential* backup as the parent, even if a newer full backup exists.
471+
472+
This approach allows you to maintain a chain of differential backups for all transactions and restore to any point in time.
473+
Without this option, the transactions between the last full backup and a previous differential backup cannot be backed up as individual transactions.
474+
475+
To use the `--prefer-diff-as-parent` option, set it to `true`.
476+
477+
The following examples cover different scenarios for using the `--prefer-diff-as-parent` option.
478+
479+
[.tabbed-example]
480+
=====
481+
[role=include-with-Chain-with-full-and-differential-backups]
482+
======
483+
484+
Let's assume that you write 10 transactions to the `neo4j` database every hour, except from 12:30 to 13:30, when you do not write any transactions.
485+
486+
There is a backup job that takes a backup every hour and a full backup every four hours.
487+
An empty backup has no transactions, meaning that both the lower transaction ID and the upper transaction ID are zero.
488+
489+
Imagine you have the following backup chain:
490+
491+
[cols="h,e,m,h,h"]
492+
|===
493+
|Timestamp | Backup name | Backup type | Lower Transaction ID | Upper Transaction ID
494+
495+
| 10:30
496+
| backup1
497+
| FULL
498+
| 1
499+
| 10
500+
501+
| 11:30
502+
| backup2
503+
| DIFF
504+
| 11
505+
| 20
506+
507+
| 12:30
508+
| backup3
509+
| DIFF
510+
| 21
511+
| 30
512+
513+
| 13:30
514+
| backup4
515+
| DIFF
516+
| 0
517+
| 0
518+
519+
| 14:30
520+
| backup5
521+
| FULL
522+
| 1
523+
| 40
524+
525+
|===
526+
527+
At 15:30, you execute the following backup command:
528+
529+
[source,shell]
530+
----
531+
neo4j-admin database backup --from=<address:port> --to-path=<targetPath> --type=DIFF neo4j
532+
----
533+
534+
The result would be:
535+
536+
[cols="h,e,m,h,h"]
537+
|===
538+
| 15:30
539+
| backup6
540+
| DIFF
541+
| 41
542+
| 50
543+
|===
544+
545+
The result means you have chosen `backup5` as the parent for your differential `backup6` since the `backup5` is the *latest non-empty* backup.
546+
547+
However, if you execute the following command with the `--prefer-diff-as-parent` option:
548+
549+
[source,shell]
550+
----
551+
neo4j-admin database backup --from=<address:port> --to-path=<targetPath> --type=DIFF --prefer-diff-as-parent neo4j
552+
----
553+
554+
The result would be:
555+
556+
[cols="h,e,m,h,h"]
557+
|===
558+
| 15:30
559+
| backup6
560+
| DIFF
561+
| 31
562+
| 50
563+
|===
564+
565+
In this case, the `backup3` is selected as the parent since it is the *latest non-empty differential* backup.
566+
567+
======
568+
[role=include-with-Chain-with-only-full-backups]
569+
======
570+
571+
Let's assume that you write 10 transactions to the `neo4j` database every hour and trigger an hourly full backup.
572+
573+
[cols="h,e,m,h,h"]
574+
|===
575+
|Timestamp | Backup name | Backup type | Lower Transaction ID | Upper Transaction ID
576+
577+
| 10:30
578+
| backup1
579+
| FULL
580+
| 1
581+
| 10
582+
583+
| 11:30
584+
| backup2
585+
| FULL
586+
| 11
587+
| 20
588+
|===
589+
590+
In this case, there is no differential backup.
591+
Therefore, the `--prefer-diff-as-parent` option has no effect and the behaviour is the same as the default one.
592+
593+
[source,shell]
594+
----
595+
neo4j-admin database backup \
596+
--from=<address:port> --to-path=<targetPath> \
597+
--type=DIFF --prefer-diff-as-parent \
598+
neo4j
599+
----
600+
601+
The result would be (with or without the `--prefer-diff-as-parent` option):
602+
[cols="h,e,m,h,h"]
603+
|===
604+
| 12:30
605+
| backup3
606+
| DIFF
607+
| 21
608+
| 30
609+
|===
610+
611+
======
612+
=====

modules/ROOT/pages/backup-restore/restore-backup.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ For more information, see xref:clustering/databases.adoc#cluster-seed[Designated
300300

301301
If you have backed up a database with the option `--include-metadata`, you can manually restore the users and roles metadata.
302302

303-
From the _<NEO4J_HOME>_ 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[][Cypher Shell]:
303+
From the _<NEO4J_HOME>_ 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[]:
304304

305305
*Using `cat` (UNIX)*
306306
[source, shell, role=nocopy noplay]

0 commit comments

Comments
 (0)