getsentry / getsentry/self-hosted
IntegrityError UniqueViolation when restoring a backup. I'd like to restore a partial backup onto a completely clean installation of Sentry but I keep getting a duplicate key value error when restoring the backup..
- Dominant language
- Shell
- Stars
- 9.6k
- Forks
- 2k
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 12
Description
### Self-Hosted Version
24.6.0
### CPU Architecture
x86_64
### Docker Version
27.0.3
### Docker Compose Version
2.28.1
### Steps to Reproduce
These are the steps I took:
1. Updated Sentry to version 24.6.0
2. Created a partial backup using `./scripts/backup.sh global`
3. Completely reset Docker and deleted any remaining Docker directories/files
4. Reinstalled Docker
5. Ran `./install.sh` from my Sentry directory (24.6.0)
At this point I tried running the restore but encountered an error.
I then tried running `docker compose up -d` and let it finish and tried running the restore but encountered another error.
I then tried logging in to Sentry and then running the restore but it still fails.
The documentation site states:
```We strongly recommended that you restore your backup on the same version of Sentry on a fresh install (empty database but migrations are run)```
So I assume this means that the restore should be run after `./install.sh` completes.
**But I'm unsure as to what migrations are or when they are run.** Is this at the end of the install script? Is this after I call 'docker compose up -d`? Or is this after logging into the Sentry portal?
When exactly am I supposed to trigger the restore?
### Expected Result
Expected a successful restore.
### Actual Result
This is the restore log I see after a **COMPLETELY FRESH INSTALL**. This is after `./install.sh` completes and after running `docker compose up -d` and waiting about 5 minutes.
```
sentryroot@AZURE-SENTRY:~/sentry$ ./scripts/restore.sh global
▶ Initializing Docker Compose ...
▶ Detecting Docker platform
Detected Docker platform is linux/amd64
▶ Setting up error handling ...
#0 building with "default" instance using docker driver
#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 292B done
#1 DONE 0.0s
#2 [internal] load metadata for docker.io/library/debian:bookworm-slim
#2 DONE 0.4s
#3 [internal] load .dockerignore
#3 transferring context: 2B done
#3 DONE 0.0s
#4 [1/2] FROM docker.io/library/debian:bookworm-slim@sha256:f528891ab1aa484bf7233dbcc84f3c806c3e427571d75510a9d74bb5ec535b33
#4 DONE 0.0s
#5 [2/2] RUN set -x && apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends jq && apt-get clean && rm -rf /var/lib/apt/lists/*
#5 CACHED
#6 exporting to image
#6 exporting layers done
#6 writing image sha256:fa67d561b504496dc6088bdfa5d62323c1b4a335ede13d8f57728f7811b56e8b done
#6 naming to docker.io/library/sentry-self-hosted-jq-local done
#6 DONE 0.0s
latest: Pulling from getsentry/sentry-cli
Digest: sha256:a0a7d8066341778703d68a74623f30e264b6c1e42e88064a6dd08fbced42eceb
Status: Image is up to date for getsentry/sentry-cli:latest
docker.io/getsentry/sentry-cli:latest
Container sentry-self-hosted-smtp-1 Running
Container sentry-self-hosted-symbolicator-1 Running
Container sentry-self-hosted-memcached-1 Running
Container sentry-self-hosted-redis-1 Running
Container sentry-self-hosted-clickhouse-1 Running
Container sentry-self-hosted-zookeeper-1 Running
Container sentry-self-hosted-postgres-1 Running
Container sentry-self-hosted-kafka-1 Running
Container sentry-self-hosted-vroom-1 Running
Container sentry-self-hosted-snuba-outcomes-billing-consumer-1 Running
Container sentry-self-hosted-snuba-transactions-consumer-1 Running
Container sentry-self-hosted-snuba-replacer-1 Running
Container sentry-self-hosted-snuba-errors-consumer-1 Running
Container sentry-self-hosted-snuba-outcomes-consumer-1 Running
Container sentry-self-hosted-snuba-subscription-consumer-events-1 Running
Container sentry-self-hosted-snuba-api-1 Running
Container sentry-self-hosted-snuba-subscription-consumer-transactions-1 Running
Container sentry-self-hosted-zookeeper-1 Waiting
Container sentry-self-hosted-zookeeper-1 Healthy
Container sentry-self-hosted-kafka-1 Waiting
Container sentry-self-hosted-redis-1 Waiting
Container sentry-self-hosted-kafka-1 Waiting
Container sentry-self-hosted-kafka-1 Waiting
Container sentry-self-hosted-redis-1 Waiting
Container sentry-self-hosted-kafka-1 Waiting
Container sentry-self-hosted-kafka-1 Waiting
Container sentry-self-hosted-redis-1 Waiting
Container sentry-self-hosted-redis-1 Waiting
Container sentry-self-hosted-clickhouse-1 Waiting
Container sentry-self-hosted-redis-1 Waiting
Container sentry-self-hosted-clickhouse-1 Waiting
Container sentry-self-hosted-clickhouse-1 Waiting
Container sentry-self-hosted-kafka-1 Waiting
Container sentry-self-hosted-redis-1 Waiting
Container sentry-self-hosted-clickhouse-1 Waiting
Container sentry-self-hosted-redis-1 Waiting
Container sentry-self-hosted-kafka-1 Waiting
Container sentry-self-hosted-redis-1 Waiting
Container sentry-self-hosted-clickhouse-1 Waiting
Container sentry-self-hosted-clickhouse-1 Waiting
Container sentry-self-hosted-clickhouse-1 Waiting
Container sentry-self-hosted-kafka-1 Waiting
Container sentry-self-hosted-clickhouse-1 Waiting
Container sentry-self-hosted-kafka-1 Waiting
Container sentry-self-hosted-redis-1 Healthy
Container sentry-self-hosted-clickhouse-1 Healthy
Container sentry-self-hosted-redis-1 Healthy
Container sentry-self-hosted-clickhouse-1 Healthy
Container sentry-self-hosted-kafka-1 Healthy
Container sentry-self-hosted-clickhouse-1 Healthy
Container sentry-self-hosted-kafka-1 Healthy
Container sentry-self-hosted-redis-1 Healthy
Container sentry-self-hosted-kafka-1 Healthy
Container sentry-self-hosted-clickhouse-1 Healthy
Container sentry-self-hosted-redis-1 Healthy
Container sentry-self-hosted-redis-1 Healthy
Container sentry-self-hosted-clickhouse-1 Healthy
Container sentry-self-hosted-kafka-1 Healthy
Container sentry-self-hosted-kafka-1 Healthy
Container sentry-self-hosted-kafka-1 Healthy
Container sentry-self-hosted-clickhouse-1 Healthy
Container sentry-self-hosted-clickhouse-1 Healthy
Container sentry-self-hosted-redis-1 Healthy
Container sentry-self-hosted-redis-1 Healthy
Container sentry-self-hosted-kafka-1 Healthy
Container sentry-self-hosted-kafka-1 Healthy
Container sentry-self-hosted-kafka-1 Healthy
Container sentry-self-hosted-clickhouse-1 Healthy
Container sentry-self-hosted-redis-1 Healthy
Updating certificates in /etc/ssl/certs...
0 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
done.
Proceeding with this operation will irrecoverably delete all existing
low-volume data - are you sure want to continue? [y/n]: y
16:01:53 [INFO] sentry.backup.imports: import_by_model.request_import (model_name='sentry.integration' import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:53 [INFO] sentry.services.hybrid_cloud.import_export.impl: import_by_model.successfully_imported (model_name=NormalizedModelName: sentry.integration import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:53 [INFO] sentry.backup.imports: import_by_model.request_import (model_name='sentry.option' import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:53 [INFO] sentry.services.hybrid_cloud.import_export.impl: import_by_model.successfully_imported (model_name=NormalizedModelName: sentry.option import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:53 [INFO] sentry.backup.imports: import_by_model.request_import (model_name='sentry.organization' import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:53 [INFO] sentry.services.hybrid_cloud.import_export.impl: import_by_model.successfully_imported (model_name=NormalizedModelName: sentry.organization import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:53 [INFO] sentry.backup.imports: import_by_model.request_import (model_name='sentry.organizationintegration' import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:53 [INFO] sentry.services.hybrid_cloud.import_export.impl: import_by_model.successfully_imported (model_name=NormalizedModelName: sentry.organizationintegration import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:53 [INFO] sentry.backup.imports: import_by_model.request_import (model_name='sentry.organizationoption' import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:53 [INFO] sentry.services.hybrid_cloud.import_export.impl: import_by_model.successfully_imported (model_name=NormalizedModelName: sentry.organizationoption import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:53 [INFO] sentry.backup.imports: import_by_model.request_import (model_name='sentry.relay' import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:53 [INFO] sentry.services.hybrid_cloud.import_export.impl: import_by_model.successfully_imported (model_name=NormalizedModelName: sentry.relay import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:53 [INFO] sentry.backup.imports: import_by_model.request_import (model_name='sentry.relayusage' import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:53 [INFO] sentry.services.hybrid_cloud.import_export.impl: import_by_model.successfully_imported (model_name=NormalizedModelName: sentry.relayusage import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:53 [INFO] sentry.backup.imports: import_by_model.request_import (model_name='sentry.repository' import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:53 [INFO] sentry.services.hybrid_cloud.import_export.impl: import_by_model.successfully_imported (model_name=NormalizedModelName: sentry.repository import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:53 [INFO] sentry.backup.imports: import_by_model.request_import (model_name='sentry.team' import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:53 [INFO] sentry.services.hybrid_cloud.import_export.impl: import_by_model.successfully_imported (model_name=NormalizedModelName: sentry.team import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:53 [INFO] sentry.backup.imports: import_by_model.request_import (model_name='sentry.user' import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:53 [INFO] sentry.services.hybrid_cloud.import_export.impl: import_by_model.successfully_imported (model_name=NormalizedModelName: sentry.user import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:53 [INFO] sentry.backup.imports: import_by_model.request_import (model_name='sentry.userip' import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:54 [INFO] sentry.services.hybrid_cloud.import_export.impl: import_by_model.successfully_imported (model_name=NormalizedModelName: sentry.userip import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:54 [INFO] sentry.backup.imports: import_by_model.request_import (model_name='sentry.userip' import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=21)
16:01:54 [INFO] sentry.services.hybrid_cloud.import_export.impl: import_by_model.successfully_imported (model_name=NormalizedModelName: sentry.userip import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=21)
16:01:54 [INFO] sentry.backup.imports: import_by_model.request_import (model_name='sentry.userrole' import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:54 [INFO] sentry.services.hybrid_cloud.import_export.impl: import_by_model.successfully_imported (model_name=NormalizedModelName: sentry.userrole import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:54 [INFO] sentry.backup.imports: import_by_model.request_import (model_name='sentry.userroleuser' import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:54 [INFO] sentry.services.hybrid_cloud.import_export.impl: import_by_model.successfully_imported (model_name=NormalizedModelName: sentry.userroleuser import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:54 [INFO] sentry.backup.imports: import_by_model.request_import (model_name='sentry.recentsearch' import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:54 [INFO] sentry.services.hybrid_cloud.import_export.impl: import_by_model.successfully_imported (model_name=NormalizedModelName: sentry.recentsearch import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:54 [INFO] sentry.backup.imports: import_by_model.request_import (model_name='sentry.recentsearch' import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=21)
16:01:54 [INFO] sentry.services.hybrid_cloud.import_export.impl: import_by_model.successfully_imported (model_name=NormalizedModelName: sentry.recentsearch import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=21)
16:01:54 [INFO] sentry.backup.imports: import_by_model.request_import (model_name='sentry.recentsearch' import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=41)
16:01:54 [INFO] sentry.services.hybrid_cloud.import_export.impl: import_by_model.successfully_imported (model_name=NormalizedModelName: sentry.recentsearch import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=41)
16:01:54 [INFO] sentry.backup.imports: import_by_model.request_import (model_name='sentry.recentsearch' import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=61)
16:01:54 [INFO] sentry.services.hybrid_cloud.import_export.impl: import_by_model.successfully_imported (model_name=NormalizedModelName: sentry.recentsearch import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=61)
16:01:54 [INFO] sentry.backup.imports: import_by_model.request_import (model_name='sentry.recentsearch' import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=81)
16:01:54 [INFO] sentry.services.hybrid_cloud.import_export.impl: import_by_model.successfully_imported (model_name=NormalizedModelName: sentry.recentsearch import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=81)
16:01:54 [INFO] sentry.backup.imports: import_by_model.request_import (model_name='sentry.project' import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:54 [INFO] sentry.services.hybrid_cloud.import_export.impl: import_by_model.successfully_imported (model_name=NormalizedModelName: sentry.project import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:54 [INFO] sentry.backup.imports: import_by_model.request_import (model_name='sentry.organizationmember' import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:54 [INFO] sentry.services.hybrid_cloud.import_export.impl: import_by_model.successfully_imported (model_name=NormalizedModelName: sentry.organizationmember import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
16:01:54 [INFO] sentry.backup.imports: import_by_model.request_import (model_name='sentry.environment' import_uuid='3dfcd12abb8d474ab48232d555a64338' min_ordinal=1)
RpcImportError(
kind: IntegrityError,
on: InstanceID(model: 'sentry.environment'),
reason: UniqueViolation('duplicate key value violates unique constraint "sentry_environment_organization_id_name_95a37dc7_uniq"\nDETAIL: Key (organization_id, name)=(1, Production) already exists.\n')
SQL: INSERT INTO "sentry_environment" ("organization_id", "name", "date_added") VALUES (%s, %s, %s) RETURNING "sentry_environment"."id"
)
>> Are you restoring from a backup of the same version of Sentry?
>> Are you restoring onto a clean database?
>> If so then this IntegrityError might be our fault, you can open an issue here:
>> https://github.com/getsentry/sentry/issues/new/choose
RpcImportError(
kind: IntegrityError,
on: InstanceID(model: 'sentry.environment'),
reason: UniqueViolation('duplicate key value violates unique constraint "sentry_environment_organization_id_name_95a37dc7_uniq"\nDETAIL: Key (organization_id, name)=(1, Production) already exists.\n')
SQL: INSERT INTO "sentry_environment" ("organization_id", "name", "date_added") VALUES (%s, %s, %s) RETURNING "sentry_environment"."id"
)
Traceback (most recent call last):
File "/.venv/bin/sentry", line 4, in
raise SystemExit(main())
^^^^^^
File "/usr/src/sentry/src/sentry/runner/main.py", line 148, in main
func(**kwargs)
File "/.venv/lib/python3.11/site-packages/click/core.py", line 1157, in __call__
return self.main(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.venv/lib/python3.11/site-packages/click/core.py", line 1078, in main
rv = self.invoke(ctx)
^^^^^^^^^^^^^^^^
File "/.venv/lib/python3.11/site-packages/click/core.py", line 1688, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.venv/lib/python3.11/site-packages/click/core.py", line 1688, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.venv/lib/python3.11/site-packages/click/core.py", line 1434, in invoke
return ctx.invoke(self.callback, **ctx.params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.venv/lib/python3.11/site-packages/click/core.py", line 783, in invoke
return __callback(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.venv/lib/python3.11/site-packages/click/decorators.py", line 33, in new_func
return f(get_current_context(), *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/sentry/src/sentry/runner/decorators.py", line 35, in inner
return ctx.invoke(f, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.venv/lib/python3.11/site-packages/click/core.py", line 783, in invoke
return __callback(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/sentry/src/sentry/runner/commands/backup.py", line 898, in import_global
import_in_global_scope(
File "/usr/src/sentry/src/sentry/backup/imports.py", line 598, in import_in_global_scope
return _import(
^^^^^^^^
File "/usr/src/sentry/src/sentry/backup/imports.py", line 474, in _import
do_writes(pk_map)
File "/usr/src/sentry/src/sentry/backup/imports.py", line 403, in do_writes
do_write(import_write_context, pk_map, model_name, json_data, offset)
File "/usr/src/sentry/src/sentry/backup/imports.py", line 334, in do_write
raise ImportingError(result)
sentry.backup.imports.ImportingError: is_err=True kind='IntegrityError' on=InstanceID(model='sentry.environment', ordinal=None) left_pk=None right_pk=None reason='UniqueViolation(\'duplicate key value violates unique constraint "sentry_environment_organization_id_name_95a37dc7_uniq"\\nDETAIL: Key (organization_id, name)=(1, Production) already exists.\\n\')\nSQL: INSERT INTO "sentry_environment" ("organization_id", "name", "date_added") VALUES (%s, %s, %s) RETURNING "sentry_environment"."id"'
cat: sentry_restore: No such file or directory
cat: global_log-2024-07-15_16-01-41.txt: No such file or directory
```
### Event ID
_No response_
Contributor guide
Research direction
Start with ./scripts/restore.sh and ./scripts/backup.sh, then review install.sh and the documented docker compose up -d sequence. Reproduce the restore on the reported clean 24.6.0 installation and inspect where migrations and the duplicate-key failure occur. Done means the partial global backup restores successfully without the IntegrityError.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- docker, docker-compose, postgresql, shell
- Domain
- databases, devops
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100