Migration hangs when --attempt-instant-ddl succeeds
Los mantenedores suelen responder en 10 días
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 30/100
Línea de trabajo
Start with Migrate() in go/logic/migrator.go, where the instant-DDL branch returns without reading ghostTableMigrated, then follow onChangelogStateEvent and notifyListeners to see where listenersMutex is held during the blocking send. The binlog side is shouldDecodeRowsEvent in the event streamer, reached through BinlogSyncer.Close() in finalCleanup. Done means the instant-DDL success path returns without hanging, with a test covering that short-circuit.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Overview
A migration run with --attempt-instant-ddl against a server that can apply the
ALTER instantly applies it, logs Success! table ... migrated instantly, and then
never returns. gh-ost hangs until it is killed.
Reproduced on master (dd44453f) and on v1.1.11.
Why
Migrate() short-circuits on the instant-DDL path: on success it calls
finalCleanup(), runs the OnSuccess hook and returns, so it never reads
<-mgtr.ghostTableMigrated.
Three goroutines then form a cycle:
-
The changelog listener parks on the
GhostTableMigratedsend in
onChangelogStateEvent.ghostTableMigratedis unbuffered and the
instant-DDL path never reads it, so the send blocks. It is wrapped in
base.SendWithContext, which only unblocks on context cancellation — and
nothing cancels the context here, precisely becauseMigrate()has not
returned. The listener is invoked fromnotifyListeners, which holds
listenersMutexacross the synchronous call, so the mutex stays held for as
long as the send is parked. -
The binlog parser goroutine (go-mysql's
BinlogSyncer.onStream) calls
EventsStreamer.shouldDecodeRowsEventthroughRowsEventDecodeFuncand
blocks taking that samelistenersMutex. -
BinlogSyncer.Close(), reached fromfinalCleanup()→
EventsStreamer.Close(), ends inb.wg.Wait()and waits for that parser
goroutine, which is never coming back.
Step 2 is what makes the cycle reachable. shouldDecodeRowsEvent was introduced
by #1699 ("Don't parse binlog events of unrelated tables", first released in
v1.1.11); it put listenersMutex on the binlog parser's goroutine, so a listener
parked while holding that mutex now stalls the parser directly, and with it
BinlogSyncer.Close().
--attempt-instant-ddl defaults to off and the short-circuit has no test
coverage, which is presumably why this has not been reported before. We hit it in
a downstream consumer that passes the flag for every migration, where every ALTER
MySQL could apply instantly hung.
Reproduction
Any instant-applicable ALTER on MySQL 8.0 with the flag set, e.g.
gh-ost --host=... --database=test --table=testing \
--alter='ADD COLUMN author varchar(255)' \
--attempt-instant-ddl --allow-on-master --execute
The column is added, Success! ... migrated instantly is logged, and the process
does not exit.
Fix
PR to follow: scope listenersMutex to the listener lookup in notifyListeners,
and give ghostTableMigrated a one-slot buffer.
- Lenguaje dominante
- Go
- Estrellas
- 13.6k
- Forks
- 1.4k
- Merge medio
- 9 d 19 h
- PR fusionados (30 d)
- 1
Preparar el entorno
- Incluye un Dockerfile o un archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de github/gh-ost
-
`--resume` without `--execute` drops the ghost table it correctly skipped alteringPosiblemente ocupada @ajm188 la tomó hace 55 días. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 86/100
Los mantenedores suelen responder en 10 días
-
[Suggestion] Apply simple validation to alter commandPosiblemente ocupada @drkemp187 la tomó hace 106 días. Abiertoenhancement good first issue
Dificultad 2/5 1-3 horas Aptitud para principiantes 64/100
github/gh-ost#1431 · 4 comentarios ·
Los mantenedores suelen responder en 10 días
-
Dificultad 4/5 3-5 días Aptitud para principiantes 42/100
Los mantenedores suelen responder en 10 días
-
Atomic cut-over always fails on MySQL 9.1+: information_schema.processlist errors out (3854) while another session runs a non-BMP utf8mb4 statementPosiblemente ocupada Un pull request vinculado a esta issue está abierto o ya se fusionó. Abierto
Dificultad 4/5 3-5 días Aptitud para principiantes 52/100
github/gh-ost#1780 · 1 comentario ·
Los mantenedores suelen responder en 10 días
-
Dificultad 4/5 3-5 días Aptitud para principiantes 68/100
Los mantenedores suelen responder en 10 días
Todos los issues de github/gh-ost
Issues similares
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 85/100
prime-radiant-inc/evener#6325 ·
Los mantenedores suelen responder en 1 día
-
team:library-maintainers
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
padok-team/burrito#1208 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
bazel-contrib/rules_go#4784 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
betterleaks/betterleaks#484 ·
Los mantenedores suelen responder en 1 día