Cambio de esquema en línea sin triggers con gh-ost
MySQLOperaciones en líneaComando
# 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.postponeQué hace
Construye una tabla ghost y copia las filas; aplica los cambios concurrentes leyendo el binlog en lugar de usar triggers. El throttling, la pausa y el momento del cut-over se controlan en tiempo de ejecución mediante el socket o archivos flag.
Cuándo usarlo
En tablas grandes con muchas escrituras donde la sobrecarga de los triggers es inaceptable y quiere elegir usted mismo el momento del cut-over (p. ej., una ventana de poco tráfico).
Precaución
Requiere binlog_format=ROW y binlog_row_image=FULL; la réplica a la que se conecta necesita log_replica_updates=ON. El usuario necesita SUPER o REPLICATION CLIENT / REPLICATION SLAVE más ALL sobre la tabla. No se admiten tablas con foreign keys (padre o hija). Tras el cut-over la tabla antigua queda como _<table>_del; elimínela manualmente una vez verificada (--ok-to-drop-table la elimina automáticamente). Las versiones de gh-ost anteriores a 1.1.8 usan SHOW SLAVE STATUS y se detienen con el error 1064 en MySQL 8.4; el soporte de 8.4 llegó en 1.1.8. gh-ost crea por sí mismo el archivo indicado en --postpone-cut-over-flag-file; el cut-over no se produce hasta que se elimina el archivo.