Triggerlose Online-Schemaänderung mit gh-ost
MySQLOnline-OperationenBefehl
# Connects to a replica and reads its binlog; postpones cut-over until the flag file is removed
gh-ost --host=db2 --port=3306 --user=ghost --password='Gh0st#2024' \
--database=shop --table=orders \
--alter="ADD COLUMN channel VARCHAR(20) NULL, ADD INDEX ix_channel (channel)" \
--max-load=Threads_running=50 --critical-load=Threads_running=200 --max-lag-millis=1500 \
--exact-rowcount --concurrent-rowcount --default-retries=120 \
--postpone-cut-over-flag-file=/tmp/ghost.postpone --panic-flag-file=/tmp/ghost.panic \
--serve-socket-file=/tmp/gh-ost.shop.orders.sock --ssl --ssl-allow-insecure --execute
# While running: status / throttle / cut-over
echo status | nc -U /tmp/gh-ost.shop.orders.sock
echo throttle | nc -U /tmp/gh-ost.shop.orders.sock
rm /tmp/ghost.postponeWas es tut
Baut eine Ghost-Tabelle auf und kopiert Zeilen; wendet parallele Änderungen an, indem es das Binlog liest statt Trigger zu nutzen. Drosselung, Pausieren und Zeitpunkt des Cut-overs werden zur Laufzeit über den Socket oder Flag-Dateien gesteuert.
Wann einsetzen
Bei großen, schreibintensiven Tabellen, bei denen Trigger-Overhead inakzeptabel ist und du den Zeitpunkt des Cut-overs (z. B. ein Fenster mit wenig Verkehr) selbst wählen willst.
Vorsicht
Erfordert binlog_format=ROW und binlog_row_image=FULL; die Replica, mit der es sich verbindet, braucht log_replica_updates=ON. Der Benutzer braucht SUPER oder REPLICATION CLIENT / REPLICATION SLAVE plus ALL auf der Tabelle. Tabellen mit Foreign Keys (Parent oder Child) werden nicht unterstützt. Nach dem Cut-over bleibt die alte Tabelle als _<table>_del zurück; nach der Prüfung manuell löschen (--ok-to-drop-table löscht sie automatisch). gh-ost-Releases vor 1.1.8 nutzen SHOW SLAVE STATUS und stoppen unter MySQL 8.4 mit Fehler 1064; Unterstützung für 8.4 kam mit 1.1.8. gh-ost legt die in --postpone-cut-over-flag-file angegebene Datei selbst an; der Cut-over erfolgt erst, wenn die Datei entfernt wird.