Skip to content

Commit afd944a

Browse files
authored
Merge pull request #6556 from opsmill/stable
Merge stable into develop
2 parents 73428e4 + abb7771 commit afd944a

19 files changed

+1040
-73
lines changed

backend/infrahub/core/schema/schema_branch.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2022,7 +2022,11 @@ def add_relationships_to_template(self, node: NodeSchema | GenericSchema) -> Non
20222022
)
20232023

20242024
parent_hfid = f"{relationship.name}__template_name__value"
2025-
if relationship.kind == RelationshipKind.PARENT and parent_hfid not in template_schema.human_friendly_id:
2025+
if (
2026+
not isinstance(template_schema, GenericSchema)
2027+
and relationship.kind == RelationshipKind.PARENT
2028+
and parent_hfid not in template_schema.human_friendly_id
2029+
):
20262030
template_schema.human_friendly_id = [parent_hfid] + template_schema.human_friendly_id
20272031
template_schema.uniqueness_constraints[0].append(relationship.name)
20282032

@@ -2058,7 +2062,6 @@ def generate_object_template_from_node(
20582062
include_in_menu=False,
20592063
display_labels=["template_name__value"],
20602064
human_friendly_id=["template_name__value"],
2061-
uniqueness_constraints=[["template_name__value"]],
20622065
attributes=[template_name_attr],
20632066
)
20642067

@@ -2077,7 +2080,6 @@ def generate_object_template_from_node(
20772080
human_friendly_id=["template_name__value"],
20782081
uniqueness_constraints=[["template_name__value"]],
20792082
inherit_from=[InfrahubKind.LINEAGESOURCE, InfrahubKind.NODE, core_template_schema.kind],
2080-
default_filter="template_name__value",
20812083
attributes=[template_name_attr],
20822084
relationships=[
20832085
RelationshipSchema(

changelog/6478.fixed.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Remove uniqueness constraint on generic templates to support upsert mutations

docs/docs/guides/database-backup.mdx

Lines changed: 257 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
title: Database backup and restore
33
---
44

5-
# Database backup and restore examples
5+
import EnterpriseBadge from '@site/src/components/EnterpriseBadge';
6+
7+
# Standalone database backup and restore examples
68

79
This is a guide on how to backup and restore your database using an Infrahub command line tool.
810
Please [see this topic](../topics/database-backup) for the requirements for using the tool and an explanation of how it works.
@@ -42,4 +44,257 @@ In this example, I am running the backup command on the same machine that is run
4244
python -m utilities.db_backup neo4j restore /infrahub_backups --database-cypher-port=9876
4345
```
4446

45-
In this example, I am restoring `.backup` files that exist in the `/infrahub_backups` directory and my Infrahub database container uses a non-standard port for cypher access: `9876` instead of `7687`.
47+
In this example, I am restoring `.backup` files that exist in the `/infrahub_backups` directory and my Infrahub database container uses a non-standard port for cypher access: `9876` instead of `7687`.
48+
49+
# Cluster Database backup and restore examples
50+
51+
<EnterpriseBadge />
52+
53+
## Cluster topology
54+
55+
| Node | Role |
56+
|------------------|----------|
57+
| `database` | Leader |
58+
| `database-core2` | Follower |
59+
| `database-core3` | Follower |
60+
61+
## Context
62+
63+
We are going to back up the Neo4j database from `database-core2` and restore it on `database-core3`, after having dropped the Neo4j database cluster-wide.
64+
65+
:::caution Important
66+
Always run backup/restore commands as the `neo4j` user inside the container to avoid permission issues with the data files.
67+
:::
68+
69+
## Step 1: Create backup from database-core2
70+
71+
```bash
72+
docker exec -it -u neo4j infrahub-database-core2-1 bash
73+
mkdir -p backups
74+
neo4j-admin database backup --to-path=backups/
75+
ls backups
76+
# Output should include:
77+
# neo4j-2025-03-24T19-57-18.backup
78+
```
79+
80+
## Step 2: Copy the backup to database-core3
81+
82+
```bash
83+
docker cp infrahub-database-core2-1:/var/lib/neo4j/backups/neo4j-2025-03-24T19-57-18.backup \
84+
infrahub-database-core3-1:/var/lib/neo4j/neo4j-2025-03-24T19-57-18.backup
85+
```
86+
87+
## Step 3: drop the Neo4j database across the cluster
88+
89+
Connect to any node
90+
91+
```bash
92+
cypher-shell -d system -u neo4j
93+
DROP DATABASE neo4j;
94+
SHOW SERVERS;
95+
```
96+
97+
<center>
98+
![drop database](../media/guides/database_backup_restore_step3.png)
99+
</center>
100+
101+
## Step 4: Clean residual data on database-core3
102+
103+
Connect to the container:
104+
105+
```bash
106+
docker exec -it -u neo4j infrahub-database-core3-1 bash
107+
```
108+
109+
Remove any existing data to avoid corruption:
110+
111+
```bash
112+
rm -rf /data/databases/neo4j
113+
rm -rf /data/transactions/neo4j
114+
```
115+
116+
Then restart the container to ensure a clean state:
117+
118+
```bash
119+
docker restart infrahub-database-core3-1
120+
```
121+
122+
## Step 5: Restore the backup on database-core3
123+
124+
Reconnect to the container:
125+
126+
```bash
127+
docker exec -it -u neo4j infrahub-database-core3-1 bash
128+
```
129+
130+
Run the restore command:
131+
132+
```bash
133+
neo4j-admin database restore \
134+
--from-path=/var/lib/neo4j/neo4j-2025-03-24T19-57-18.backup neo4j
135+
```
136+
137+
<center>
138+
![Restore database](../media/guides/database_backup_restore_step3.png)
139+
</center>
140+
141+
## Step 6: Identify the seed instance id
142+
143+
Connect via Cypher shell (on the system database):
144+
145+
```bash
146+
cypher-shell -d system -u neo4j
147+
```
148+
149+
Run:
150+
151+
```bash
152+
SHOW SERVERS;
153+
```
154+
155+
⚠️ **Note** :
156+
> Find the `serverId` corresponding to infrahub-database-core3-1.
157+
>> For example: d05fce79-e63e-485a-9ce7-1abbf9d18fce.
158+
159+
<center>
160+
![Seed database](../media/guides/database_backup_restore_step5.png)
161+
</center>
162+
163+
## Step 7: recreate the Neo4j database from the seed
164+
165+
Run the following Cypher command:
166+
167+
```bash
168+
CREATE DATABASE neo4j
169+
TOPOLOGY 3 PRIMARIES
170+
OPTIONS {
171+
existingData: 'use',
172+
existingDataSeedInstance: 'd05fce79-e63e-485a-9ce7-1abbf9d18fce'
173+
};
174+
```
175+
176+
<center>
177+
![Choose seed database](../media/guides/database_backup_restore_step7.png)
178+
</center>
179+
180+
## Step 8: Verify cluster sync
181+
182+
Check that the database is coming online:
183+
184+
```bash
185+
SHOW DATABASES;
186+
```
187+
188+
<center>
189+
![Online database](../media/guides/database_backup_restore_step8_1.png)
190+
</center>
191+
192+
Then validate cluster sync status:
193+
194+
```bash
195+
SHOW SERVERS;
196+
```
197+
198+
<center>
199+
![Status sync servers](../media/guides/database_backup_restore_step8_2.png)
200+
</center>
201+
202+
All nodes should eventually show the Neo4j database as online.
203+
204+
## 📝 Notes
205+
206+
- If any node shows as **dirty** or **offline**, check the logs and ensure that the file `/data/databases/neo4j/neostore` exists.
207+
- Restoring the database on a single node does **not** automatically register it with the cluster.
208+
You **must** run the `CREATE DATABASE ... OPTIONS { existingData: 'use' }` command to register the restored data properly.
209+
210+
# Restore a database cluster backup on a standalone instance (for debug)
211+
212+
## Context
213+
214+
We are taking a backup from a Neo4j cluster and restoring it on a standalone local Neo4j instance (non-clustered), for the purpose of debugging and data analysis in a safe, isolated environment.
215+
216+
## Step 1: Backup from a cluster node <EnterpriseBadge />
217+
218+
The backup was created from a cluster node (either follower or leader) using:
219+
220+
```bash
221+
neo4j-admin database backup --to-path=backups/
222+
# Resulting file: neo4j-2025-03-24T19-57-18.backup
223+
```
224+
225+
## Step 2: Copy the backup to database
226+
227+
```bash
228+
docker cp neo4j-2025-03-24T19-57-18.backup \
229+
infrahub-database-1:/var/lib/neo4j/neo4j-2025-03-24T19-57-18.backup
230+
```
231+
232+
## Step 3: prepare the local Neo4j instance
233+
234+
Connect to the container:
235+
236+
```bash
237+
docker exec -it -u neo4j infrahub-database-1 bash
238+
```
239+
240+
Clean any existing Neo4j database (optional but recommended):
241+
242+
```bash
243+
rm -rf /data/databases/neo4j
244+
rm -rf /data/transactions/neo4j
245+
```
246+
247+
Drop the Neo4j Database
248+
249+
```bash
250+
cypher-shell -d system -u neo4j
251+
DROP DATABASE neo4j;
252+
SHOW SERVERS;
253+
```
254+
255+
<center>
256+
![Choose seed database](../media/guides/database_backup_restore_step7.png)
257+
</center>
258+
259+
## Step 4. Restore the backup
260+
261+
Run the restore command from the directory where the backup file is located:
262+
263+
```bash
264+
neo4j-admin database restore \
265+
--from-path=/var/lib/neo4j/neo4j-2025-03-24T19-57-18.backup neo4j
266+
```
267+
268+
## Step 5: recreate the Neo4j database
269+
270+
Run the following Cypher command:
271+
272+
```bash
273+
CREATE DATABASE neo4j
274+
```
275+
276+
## Step 6: Verify the status
277+
278+
Check that the database is coming online:
279+
280+
```bash
281+
SHOW DATABASES;
282+
```
283+
284+
<center>
285+
![Choose seed database](../media/guides/database_backup_restore_standalone_step6_1.png)
286+
</center>
287+
288+
Then validate database status:
289+
290+
```bash
291+
SHOW SERVERS;
292+
```
293+
294+
<center>
295+
![Choose seed database](../media/guides/database_backup_restore_standalone_step6_2.png)
296+
</center>
297+
298+
## 📝 Notes
299+
300+
- This process *restores only data* — not cluster roles, replication, or configuration.
38 KB
Loading
25.3 KB
Loading
16.9 KB
Loading
25.3 KB
Loading
114 KB
Loading
26.2 KB
Loading
17.8 KB
Loading

0 commit comments

Comments
 (0)