[Bug][SonarQube] Migration 20230927145127 is not re-runnable: fails with "constraint _tool_sonarqube_file_metrics_pkey does not exist" after an interrupted run
I maintainer di solito rispondono entro 3 giorni
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 35/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Ferma
- Stack tecnologico
- go, mysql, postgresql
- Ambito
- backend, data-engineering, database
Direzione di ricerca
Read backend/plugins/sonarqube/models/migrationscripts/20230927_modify_file_metrics_key_length.go and backend/core/migration/migrator.go to understand the migration steps and when history is recorded. The issue links open PR #9242, which may already be addressing the work. Done means rerunning after the primary key has been dropped succeeds on PostgreSQL and MySQL, with the expected primary key restored; the issue describes an e2e regression test for both cases.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Search before asking
- I had searched in the issues and found no similar issues.
What happened
Reported in apache/devlake-helm-chart#381 (DevLake v1.0.3-beta15, PostgreSQL 18, official Helm chart, external
DB_URL). DevLake panics at startup during migration:
modify _tool_sonarqube_file_metrics file_metrics_key from varchar(191) to varchar(500)
ERROR: constraint "_tool_sonarqube_file_metrics_pkey" of relation "_tool_sonarqube_file_metrics" does not exist (SQLSTATE 42704)
The failing statement is the first step of migration 20230927145127
(backend/plugins/sonarqube/models/migrationscripts/20230927_modify_file_metrics_key_length.go). Up() does:
- Drop the primary key without checking that it exists:
- MySQL:
ALTER TABLE _tool_sonarqube_file_metrics DROP PRIMARY KEY - otherwise (PostgreSQL):
ALTER TABLE _tool_sonarqube_file_metrics DROP CONSTRAINT _tool_sonarqube_file_metrics_pkey
- MySQL:
migrationhelper.ChangeColumnsType(rename / add / copy / drop column)ALTER TABLE _tool_sonarqube_file_metrics ADD PRIMARY KEY (connection_id, file_metrics_key)
migrator.Execute() (backend/core/migration/migrator.go) runs scripts one by one, not in a transaction, and
writes the _devlake_migration_history row only after Up() succeeds. If the process stops after step 1 but
before the history row is written, the next startup runs the script again. Step 1 then fails because the
primary key is already gone, and every later startup fails the same way:
1st start: DROP pkey OK ──▶ interrupted / failed ──▶ no history row
2nd start: script re-runs ──▶ DROP pkey fails: constraint does not exist ──▶ panic
MySQL is affected too. The helm-chart report is about PostgreSQL, but while investigating it I found
that the MySQL branch has the same problem. MySQL has no IF EXISTS form of DROP PRIMARY KEY, so after the
same kind of interruption the re-run fails with:
Error 1091 (42000): Can't DROP 'PRIMARY'; check that column/key exists
I confirmed this on MySQL 8 with the same simulated interruption (see below).
The second error in that report (migration 20260701000000 dropping
idx__tool_sonarqube_issue_code_blocks_component) was already fixed by #9012 (closes #9011, see also #9033),
included since v1.0.3-beta16. It is out of scope here.
What do you expect to happen
Migration 20230927145127 should be safe to re-run. If the primary key is already gone, it should skip the drop
and still end with PRIMARY KEY (connection_id, file_metrics_key), so DevLake can start.
How to reproduce
A truly fresh database does not trigger this. With PostgreSQL 18 and the official
apache/devlake:v1.0.3-beta15 image (all plugins, FORCE_MIGRATION=true), 20230927145127 succeeds and the
primary key exists. Only the already-fixed 20260701000000 error shows up.
To reproduce, simulate a run that was interrupted right after the drop:
-
Start DevLake once against PostgreSQL so that migration
20230927145127has run. -
Run:
ALTER TABLE _tool_sonarqube_file_metrics DROP CONSTRAINT _tool_sonarqube_file_metrics_pkey; DELETE FROM _devlake_migration_history WHERE script_version = 20230927145127; -
Restart DevLake with
FORCE_MIGRATION=true. -
Migration fails with the same
constraint "_tool_sonarqube_file_metrics_pkey" ... does not exist (SQLSTATE 42704)
error and the server panics.
On MySQL, use ALTER TABLE _tool_sonarqube_file_metrics DROP PRIMARY KEY; in step 2. Step 4 then fails with
Error 1091 (42000): Can't DROP 'PRIMARY'; check that column/key exists.
Anything else
Possible trigger in the Helm setup (a hypothesis, not confirmed)
- With
FORCE_MIGRATION,CreateAndRunApiServer(backend/server/api/api.go) runs
services.InitExecuteMigration()beforeRunApiServerstarts listening. - The chart's default lake
livenessProbeishttpGet /pingwithinitialDelaySeconds: 30,periodSeconds: 5,
failureThreshold: 5. A slow migration against a remote database can get the pod killed and restarted in the
middle of it. - The panic from the
20260701000000error also causes CrashLoop restarts.
Any interruption while this script is running leaves the table without a primary key.
Proposed fix (PR to follow)
Make the script idempotent on both databases by dropping the primary key only if it exists:
- PostgreSQL:
ALTER TABLE ... DROP CONSTRAINT IF EXISTS _tool_sonarqube_file_metrics_pkey - MySQL: check
information_schema.table_constraintsfor an existing primary key beforeDROP PRIMARY KEY
The normal path is unchanged. The PR adds an e2e regression test that covers the normal run and a re-run
without the primary key. It fails without the fix on both MySQL 8 and PostgreSQL 18, and passes with it.
The script has not changed since #6157 and #6196 (2023).
Version
v1.0.3-beta15 (the script is unchanged on main at ee0079ab3)
Are you willing to submit PR?
- Yes I am willing to submit a PR!
Code of Conduct
- I agree to follow this project's Code of Conduct
- Lingua principale
- Go
- Stelle
- 3.2k
- Fork
- 824
- Merge medio
- 2g 22h
- PR unite (30g)
- 45
Preparare l'ambiente
Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Nessuna guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di apache/devlake
-
Difficoltà 4/5 1-2 giorni Idoneità per principianti 56/100
I maintainer di solito rispondono entro 3 giorni
-
[Bug][GitHub] Closed (unmarked) Pull Requests are re-fetched on every runForse già presa @dvecy l’ha presa oggi. Apertatype/bug
Difficoltà 3/5 1-2 giorni Idoneità per principianti 64/100
I maintainer di solito rispondono entro 3 giorni
-
[Bug][Blueprint] Scheduled run fails silently when plan generation errorsForse già presa @jcamargos l’ha presa 2 giorni fa. Aperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 25/100
I maintainer di solito rispondono entro 3 giorni
-
Difficoltà 3/5 Mezza giornata Idoneità per principianti 62/100
I maintainer di solito rispondono entro 3 giorni
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 42/100
I maintainer di solito rispondono entro 3 giorni
Tutte le issue di apache/devlake
Issue simili
-
area/gateway kind/bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
vllm-project/aibrix#3226 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
I maintainer di solito rispondono entro 1 giorno
-
gencrl: serial numbers that fail to parse are added to the CRL as 0 or a partial valueForse già presa @sebxt l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
cloudflare/cfssl#1460 ·
I maintainer di solito rispondono entro 2 giorni
-
bug
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 75/100
ironcore-dev/cloud-hypervisor-provider#210 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
OpenTollGate/tollgate-module-basic-go#1027 ·
I maintainer di solito rispondono entro 1 giorno