Conditions préalables pour l'utilisation de gh-ost
L'outil gh-ost se distingue par son approche "sans trigger" pour effectuer des migrations de schémas en ligne. Avant toute exécution sur MySQL (5.6, 5.7 ou 8.0), votre environnement doit impérativement respecter les critères suivants :
| Critère de vérification | Exigence technique | Note de compatibilité |
|---|---|---|
| Format du Binlog | Doit être configuré en ROW. |
Obligatoire pour permettre l'extraction précise des modifications. |
| Binlog Row Image | Doit être réglé sur FULL. |
Essentiel pour reconstruire les données sur la table fantôme. |
| Index requis | Clé primaire ou Index Unique non nul. | gh-ost utilise ces clés pour segmenter la copie des données par "chunks". |
| Contraintes de structure | Aucune clé étrangère (FK) ni trigger. | L'outil refuse l'exécution si ces éléments sont présents (voir section architecture). |
| Encodage | UTF8 ou UTF8MB4 recommandés. | Une attention particulière est requise pour les anciens jeux de caractères. |
Modèles de commandes pour les déploiements courants
1. Exécution directe sur le Master (Instance isolée)
Ce scénario s'applique aux bases de données sans réplication active. Il est crucial de limiter l'impact sur les performances puisque toutes les opérations s'effectuent sur le nœud d'écriture.
nohup gh-ost \
--user="admin_db" \
--host="10.10.20.50" \
--password='MonMotDePasseSecurise' \
--database="inventory_prod" \
--table="order_history" \
--alter="ADD COLUMN delivery_status TINYINT DEFAULT 0, ADD INDEX idx_status (delivery_status)" \
--allow-on-master \
--execute \
--postpone-cut-over-flag-file="/tmp/ghost_switch.lock" \
--panic-flag-file="/tmp/ghost_abort.panic" \
--max-load="Threads_running=25,Threads_connected=400" \
--critical-load="Threads_running=80" \
--chunk-size=1500 \
--dml-batch-size=20 \
--serve-socket-file="/tmp/gh-ost_inv.sock" \
--timestamp-old-table \
--verbose \
> /var/log/mysql/gh-ost_migration_$(date +%F).log 2>&1 &
2. Architecture Maître-Esclave avec contrôle de latence
Ici, gh-ost modifie le Master tout en surveillant le délai de réplication sur les esclaves pour éviter de casser la synchronisation métier.
nohup gh-ost \
--user="ghost_svc" --password='StrongPassword' \
--host="master-db-01" \
--database="erp_system" --table="client_assets" \
--alter="MODIFY COLUMN description TEXT" \
--execute \
--throttle-control-replicas="10.10.20.51:3306,10.10.20.52:3306" \
--max-lag-millis=2000 \
--postpone-cut-over-flag-file="/tmp/hold_rename.flag" \
--initially-drop-ghost-table \
--serve-socket-file="/tmp/gh-ost_erp.sock" \
--verbose \
> /var/log/gh-ost_replica_aware.log 2>&1 &
3. Exécution déportée sur un Replica (Haute disponibilité)
Pour les tables volumineuses, il est préférable de lire les données depuis un esclave pour décharger les I/O du maître. La migration s'appliquera toutefois in fine sur le maître.
gh-ost \
--user="admin" --password='Password' \
--host="slave-db-01" \
--database="analytics" --table="user_events" \
--alter="ADD COLUMN session_id VARCHAR(64)" \
--migrate-on-replica \
--assume-master-host="master-db-01:3306" \
--execute \
--serve-socket-file="/tmp/gh-ost_analytics.sock"
Intercations en cours de processus (Contrôle via Socket)
L'un des avantages majeurs de gh-ost est sa capacité à être piloté dynamiquement sans arrêter le processus.
- Vérifier l'état d'avancement :
echo "status" | nc -U /tmp/gh-ost_inv.sock - Suspendre la copie des données :
echo "sup" | nc -U /tmp/gh-ost_inv.sock - Modifier la taille des blocs dynamiquement :
echo "chunk-size=500" | nc -U /tmp/gh-ost_inv.sock - Finaliser la migration (Cut-over) :
rm -f /tmp/ghost_switch.lock
Analyse des paramètres critiques
| Option | Description Technique | Conseil d'expert |
|---|---|---|
--postpone-cut-over-flag-file |
Empêche le renommage final de la table tant que le fichier existe. | Indispensable pour synchroniser la bascule finale lors d'une fenêtre de maintainance. |
--max-load |
Seuil de suspension temporaire basé sur les métriques MySQL. | Réglez-le juste au-dessus de votre charge nominale pour éviter les pics de latence. |
--critical-load |
Seuil d'arrêt d'urgence (Panic). | Le dernier rempart pour protéger l'intégrité de la production en cas de surcharge. |
--initially-drop-ghost-table |
Supprime toute table fantôme résiduelle d'une tentative précédente. | Évite les erreurs de démarrage si un job précédent a échoué. |
Gestion des risques et erreurs fréquentes
Problème de syntaxe Shell : L'utilisation de commentaires # à l'intérieur d'une commande multi-ligne avec des backslashes \ provoque l'échec de la commande. Assurez-vous que le caractère \ est le tout dernier caractère de chaque ligne.
Authentification et Nohup : Lors de l'exécution avec nohup, les variables d'environnement comme $MYSQL_PWD peuvent ne pas être transmises. Il est recommandé d'utiliser l'argument --password entouré de guillemets simples pour protéger les caractères spéciaux.
Nettoyage post-migration : Par défaut, gh-ost conserve l'ancienne table sous un nom de type _table_del. Il est conseillé de ne pas utiliser --ok-to-drop-table immédiatement afin de disposer d'une sauvegarde physique en cas de régression applicative constatée après la mise à jour.
Pourquoi les triggers et clés étrangères sont-ils proscrits ?
Le moteur de gh-ost repose sur l'application asynchrone des journaux binaires (Binlogs) sur une table miroir.
- Conflit de Triggers : Si la table source possède déjà des triggers, gh-ost ne peut pas les répliquer sur la table fantôme car cela pourrait entraîner une double exécution de la logique métier lors de l'application des binlogs.
- Incohérence des Clés Étrangères : MySQL lie les contraintes de clés étrangères aux noms de tables ou aux identifiants internes. Lors de l'opération de
RENAME TABLE, les contraintes risquent soit de pointer vers l'ancienne table (désormais obsolète), soit de bloquer le renommage par sécurité d'intégrité référentielle.