Migrer une base PrestaShop de MySQL 5.7 vers MySQL 8 n’est pas un simple apt upgrade. Entre les changements de dictionnaire de données, d’authentification, de collations et d’optimiseur, l’écart fonctionnel est réel. Les lignes ci‑dessous sont écrites pour des stacks e‑commerce typiques PrestaShop 1.7.8 / 8.x / 9.x sous PHP 8.1 à 8.3, avec connecteurs PDO/MySQLi (mysqlnd) — c’est le contexte le plus fréquent en 2026.
Table des matières :
- Cadre technique : ce qui change réellement entre MySQL 5.7 et 8.0 (impact direct sur PrestaShop)
- Préparer la migration : audit du schéma, du SQL et de la configuration
- Mettre en place un staging fidèle : données, anonymisation et parité d’infra
- Procédure de migration : dump/restore vs réplication, cutover et rollback
- Tests de charge et de non‑régression : méthodologie, outils et KPI exploitables
- Points de durcissement post‑migration : tuning, compat SQL et sécurité d’exploitation
Cadre technique : ce qui change réellement entre MySQL 5.7 et 8.0 (impact direct sur PrestaShop)
MySQL 5.7 est EOL depuis longtemps (fin des correctifs publics), donc l’enjeu n’est pas « gagner 3% de perf », mais arrêter d’exécuter un moteur non patché. Côté PrestaShop, la compatibilité applicative est globalement bonne (requêtes standard InnoDB), mais les modules tiers et le SQL legacy peuvent casser sur des détails : GROUP BY non conforme, colonnes implicites, dépendance à une collation spécifique, etc. Les problèmes apparaissent rarement sur la page d’accueil : ils sortent sur le tunnel de commande, la recherche, les exports, les batchs cron.
Concrètement, voici les catégories de changements qui reviennent le plus souvent en migration PrestaShop (et qu’on peut pré-tester avant le cutover) :
- Authentification / drivers : clients PHP, outils d’admin, ETL, scripts CRON historiques.
- Collations et tri : un
ORDER BYpeut produire un ordre différent si vous changez de collation par défaut (utile à savoir pour des exports « comparés » ou des flux marketplace). - SQL strict / compat : certains environnements 5.7 ont désactivé des modes stricts (ou les ont modifiés), et des requêtes “tolérées” deviennent rejetées ou changent de résultat.
- Optimiseur : plans différents (parfois meilleurs, parfois pires) sur des requêtes longues, surtout celles avec beaucoup de jointures et de filtres optionnels (facettes, recherche, statistiques BO).
Deux changements de MySQL 8 reviennent en post‑mortem de migration. Le premier, l’authentification :
“cachingsha2password is the default authentication plugin in MySQL 8.0.” — MySQL 8.0 Reference Manual, Authentication Plugins
Si votre stack PHP/clients est vieille (libmysqlclient ancien, outils d’admin, connecteurs d’ETL), la connexion peut échouer. Sur un serveur e‑commerce, l’impact est immédiat : back-office KO, connecteurs ERP/PIM qui ne poussent plus les stocks, scripts de facturation en échec, etc. Anticipez en listant tous les consommateurs de la base (pas seulement PrestaShop).
Le second, le stockage des métadonnées :
“MySQL 8.0 uses a transactional data dictionary.” — MySQL 8.0 Reference Manual, Data Dictionary
Ça implique des changements d’outillage (certaines manipulations directes des tables système, ou des scripts de maintenance hérités, ne sont plus valides).
Enfin, MySQL 8.0 modifie des comportements par défaut qui impactent PrestaShop sans toucher une ligne de PHP : collations UTF‑8 modernes (utf8mb4_0900_ai_ci), optimiseur plus agressif (plans différents), histogrammes, EXPLAIN ANALYZE, et un sql_mode souvent plus strict selon votre ancien paramétrage. Le résultat typique : mêmes requêtes, mais plan d’exécution différent ⇒ latences p95 qui bougent, ou index qui ne sont plus choisis.
Mini-scénario typique (vu sur des boutiques FR/EU) : la navigation catégorie est OK, mais dès qu’un visiteur combine 4–6 filtres (taille + couleur + marque + prix), une requête bascule d’un plan “index range” vers un plan avec table temporaire volumineuse. En prod, ça se traduit par une hausse des temps de réponse sur mobile et un taux d’abandon en hausse — alors que « l’app n’a pas changé ». D’où l’importance d’un staging fidèle et de tests sous charge.
Préparer la migration : audit du schéma, du SQL et de la configuration
Avant de choisir une procédure, faites un audit de ce que vous migrez réellement. Sur PrestaShop, la base « métier » est souvent polluée par : tables de modules supprimés, index redondants, collation mixte table par table, et colonnes surdimensionnées. Une migration 5.7→8.0 est un bon moment pour geler le périmètre : liste des modules actifs, batchs cron, intégrations ERP/PIM, jobs de synchronisation, scripts internes. Si vous n’avez pas de visibilité sur les requêtes lentes et les plans, commencez par l’inventaire (voir l’article interne : Audit MySQL/MariaDB : optimiser les requêtes lentes e‑commerce).
Le contrôle le plus rentable (et trop souvent ignoré) est l’upgrade checker officiel via MySQL Shell. Sur un serveur MySQL 5.7 (idéalement patché au dernier 5.7.x), exécutez :
# Pré-requis : mysqlsh installé sur une machine ayant accès au MySQL 5.7
mysqlsh --uri admin@mysql57:3306 -- \
-e "util.checkForServerUpgrade({\"targetVersion\":\"8.0\"})"
Ce rapport remonte les incompatibilités fréquentes : collations obsolètes, tables MyISAM qui traînent, triggers/événements problématiques, mots réservés utilisés comme identifiants, etc.
Pour compléter (et rendre l’audit “opérationnel”), voici une checklist rapide utile en contexte PrestaShop — elle évite la majorité des surprises au moment du restore ou des premiers tests applicatifs :
| Contrôle rapide | Pourquoi c’est utile en PrestaShop | Comment l’obtenir |
|---|---|---|
@@character_set_server / @@collation_server |
Éviter les mélanges utf8/utf8mb4 et les tris inattendus sur recherche / BO |
SELECT @@character_set_server, @@collation_server; |
| Collations hétérogènes par table | Des jointures peuvent devenir plus coûteuses, ou provoquer des conversions implicites | requêtes sur information_schema.TABLES / COLUMNS |
@@sql_mode (et différences avec prod) |
Certains modules “tolèrent” un mode plus permissif et cassent en strict | SELECT @@sql_mode; |
| Tables non InnoDB résiduelles | MyISAM/Memory “historique” = risques de locks, crash recovery, etc. | SELECT ENGINE, COUNT(*) FROM information_schema.TABLES ... GROUP BY ENGINE; |
| Mots réservés / identifiants borderline | Un module peut avoir créé une colonne/table au nom risqué | rapport checkForServerUpgrade |
| Paramètres InnoDB et limites OS | La perf post-migration dépend autant de l’I/O que de la version | doc + SHOW VARIABLES + OS (ulimit) |
Complétez par des checks pragmatiques : comparer @@sql_mode, @@character_set_server, @@collation_server, @@innodb_file_format (hérité), et l’encodage effectif des tables (information_schema.TABLES). Le but est de supprimer les « surprises » le jour du cutover.
Côté configuration, MySQL 8 a des defaults différents et certains paramètres changent de sens ou deviennent inutiles. Sur un serveur e‑commerce, documentez au minimum : taille du innodb_buffer_pool_size, innodb_flush_log_at_trx_commit, sync_binlog, max_connections, tmp_table_size/max_heap_table_size, binlog_format (ROW est attendu pour réplication/CDC), et les limites OS (ulimit, I/O scheduler). Si votre tuning 5.7 est du copier‑coller de blog 2017, attendez-vous à des régressions.
Point souvent oublié en migration “réelle” : alignez aussi la chaîne d’outils. Exemples : version de mysqldump utilisée par votre outil de backup, scripts d’export CSV, connecteur BI, jobs de purge. L’objectif n’est pas d’être “parfait”, mais de savoir ce qui doit être validé avant la bascule, surtout si vous avez une contrainte de fenêtre courte (nuit / dimanche) ou des pics saisonniers (soldes, Black Friday, opérations TV).
Pour éviter les angles morts sécurité (TLS, privilèges, comptes applicatifs), appuyez-vous aussi sur : Sécurité MySQL : pare-feu, TLS, privilèges minimaux et audit.
Mettre en place un staging fidèle : données, anonymisation et parité d’infra
Le staging doit être structurellement identique à la prod, sinon vos tests ne valent rien. « Identique » veut dire : même version de MySQL (8.0.x précise), mêmes options mysqld, même taille de disque et même type de stockage (NVMe vs réseau), même version de PHP, même reverse‑proxy, même Redis/Varnish si présent. Pour PrestaShop, la moindre divergence sur le cache (OPcache, Redis) peut masquer une régression SQL. Si vous cherchez un modèle reproductible, l’approche Docker est un bon point de départ (article interne : Staging PrestaShop : créer un environnement Docker fidèle à la production).
La donnée staging doit être proche de la prod, mais conforme RGPD. La stratégie courante : dump prod → restore staging → anonymisation (clients, adresses, emails, téléphones, tokens) → re‑génération des index de recherche si vous en avez (facettes, moteurs externes). Pour PrestaShop, attention aux tables ps_customer, ps_address, ps_orders, ps_order_payment, mais aussi aux tables de modules (marketing automation, support, tracking). Ne vous contentez pas de “changer les emails” : neutralisez aussi les webhooks sortants et les clés API.
Exemples très concrets de pièges (et donc de contrôles à ajouter à votre runbook de staging) :
- Emails transactionnels : si votre staging appelle un SMTP réel, vous pouvez envoyer de “fausses” confirmations de commande. Prévoir un SMTP de test (MailHog / Mailpit) ou une règle de blocage au niveau MTA.
- Webhooks / API sortantes : certains modules poussent des événements commande vers des URLs externes (ERP, CRM, tracking). Désactivez ou remplacez les endpoints.
- Paiements : forcer les modes sandbox et vérifier qu’aucun token prod n’est présent en staging (PayPal/Stripe/Adyen selon les cas).
- Données sensibles dans les logs : si vous collectez des logs applicatifs, ne dupliquez pas un pipeline prod vers des outils non conformes (accès, rétention).
Enfin, imposez de la parité sur les workloads. Les migrations MySQL échouent rarement sur un SELECT 1; elles échouent sous charge, quand InnoDB swap, quand les temp tables explosent, ou quand un plan de requête change. Le staging doit pouvoir exécuter : imports produits, navigation catégorie + facettes, ajout panier, calcul taxes, création commande, webservice/API, et tâches cron. Si votre prod a des crawlers agressifs (SEO, marketplaces), simulez-les : ils changent la distribution des lectures et la contention.
Astuce pratique : avant même les tests de charge, mesurez un baseline sur MySQL 5.7 (prod ou pré-prod) avec quelques KPI comparables (latence p95 sur 5–10 requêtes critiques, durée d’un import produit de référence, temps d’ouverture d’une page catégorie “lourde”). C’est cette “photo” qui permet de dire objectivement si MySQL 8 améliore, dégrade, ou ne change rien — et d’éviter les discussions subjectives le jour J.
Procédure de migration : dump/restore vs réplication, cutover et rollback
Deux stratégies réalistes existent pour une migration MySQL 5.7 vers 8.0 sur une boutique PrestaShop : (1) in‑place upgrade ou (2) side‑by‑side (nouveau serveur) avec bascule. En e‑commerce, l’in‑place est tentant (moins d’infra), mais c’est le meilleur moyen de se retrouver sans rollback propre si l’upgrade échoue ou si la perf chute après redémarrage. La stratégie side‑by‑side est généralement plus maîtrisable : vous validez MySQL 8 avec une copie complète de données, puis vous basculez proprement.
Pour aider à choisir, voici une comparaison “terrain” :
| Approche | Avantages | Risques / limites | Quand c’est un bon choix |
|---|---|---|---|
| In‑place upgrade | Peu d’infra supplémentaire, simple sur le papier | Rollback difficile (et souvent long), stress opérationnel élevé | Petites boutiques, fenêtre longue, plan de secours très clair |
| Dump/restore side‑by‑side | Robuste, reproductible, facile à rejouer en staging | Downtime lié au dump/restore si pas de réplication | Bases petites/moyennes, ou fenêtre de maintenance acceptable |
| Réplication/CDC vers MySQL 8 | Downtime minimal, validations continues | Mise en place plus technique, discipline sur le cutover | Boutique à fort CA, fenêtre courte, exigence “quasi zéro coupure” |
Pour un dataset moyen, le dump/restore reste robuste si on le fait correctement. Exemple de dump cohérent (InnoDB) :
mysqldump -h mysql57 -u backup -p \
--single-transaction --routines --triggers --events \
--set-gtid-purged=OFF --hex-blob --default-character-set=utf8mb4 \
prestashop | gzip > prestashop.sql.gz
zcat prestashop.sql.gz | mysql -h mysql80 -u restore -p prestashop
Bonnes pratiques qui évitent des “restores surprises” :
- Restaurer d’abord sur un MySQL 8 de staging, puis seulement sur la cible de prod : vous validez que le dump est correct et que les scripts post-restore (users/grants, events) passent.
- Capturer les warnings lors de l’import (ils sont souvent ignorés) : ils pointent des conversions de charset/collation, des champs tronqués, ou des soucis de définition.
- Prévoir un temps de rebuild applicatif : cache, index de recherche, tables de facettes, etc.
Pour les grosses bases (plusieurs dizaines/centaines de Go), préférez mydumper/myloader (parallélisation) ou une sauvegarde physique type Percona XtraBackup (si votre distribution/contrat l’autorise). Si votre contrainte est le downtime minimal, mettez en place une réplication (ou un mécanisme CDC) vers MySQL 8, faites tourner le staging sur le replica, puis planifiez un cutover avec gel des écritures.
Le cutover doit être écrit comme un runbook, avec un rollback explicite. Une séquence éprouvée : (a) activer maintenance PrestaShop (bloquer checkout), (b) attendre la vidange des workers/queues, (c) verrouiller les écritures (ou arrêter l’app), (d) rattraper le delta (réplication), (e) basculer DNS/endpoint/secret DB, (f) smoke tests ciblés (connexion BO, ajout panier, commande), (g) réouverture.
Pour rendre le runbook réellement exploitable, ajoutez systématiquement :
- Des critères Go/No-Go (ex. “smoke tests OK + p95 < baseline + pas d’erreurs SQL dans les logs app”).
- Une limite de temps (ex. “si non conforme à T+30 min, rollback”).
- Un responsable de décision (unique) et un canal de communication (chat + conf).
- Un plan de gel des changements (pas de déploiement module/thème en parallèle de la migration DB).
Le rollback n’est pas “on verra” : c’est “on rebascule sur MySQL 5.7 + réouverture” tant que le delta d’écritures est maîtrisé (d’où l’intérêt de garder MySQL 5.7 en lecture seule et d’avoir un point de restauration). Si vous cherchez une logique similaire sur d’autres briques, l’article Hébergement PrestaShop géré : migration sans coupure, staging et maintenance décrit bien l’approche « runbook + bascule + fenêtre » (même si le sujet dépasse MySQL).
Tests de charge et de non‑régression : méthodologie, outils et KPI exploitables
Les tests doivent répondre à deux questions : (1) est‑ce que ça marche ? et (2) est‑ce que ça tient la charge ? Pour (1), définissez une batterie de tests fonctionnels centrés sur les parcours qui tapent la base : login, création compte, recherche, facettes, panier, checkout, BO (listing commandes/clients), webservice/API, cron (relances, imports). Pour éviter un “ça marche sur mon navigateur”, automatisez : Playwright/Cypress côté UI, et tests API sur endpoints critiques. Sur PrestaShop, les modules sont la source #1 de SQL borderline : testez les modules réellement installés, pas un PrestaShop nu.
Pour (2), ne vous limitez pas à sysbench (même s’il est utile). Combinez un benchmark synthétique (capacité brute) et un replay applicatif (profil réel). Exemple sysbench OLTP :
sysbench oltp_read_write \
--mysql-host=mysql80 --mysql-user=bench --mysql-password=*** \
--mysql-db=prestashop \
--tables=20 --table-size=200000 \
--threads=64 --time=300 run
Ensuite, faites un test applicatif via k6/Gatling/Locust en simulant des scénarios PrestaShop (browse→add-to-cart→checkout) et du trafic bot (crawl catégories + combinaisons de filtres). Si votre boutique utilise la recherche à facettes, c’est un bon endroit pour trouver les régressions (voir : Recherche à facettes PrestaShop : configurer ps_facetedsearch et filtres combinés).
Un point qui fait gagner du temps : définir vos scénarios de charge avec un ratio réaliste lecture/écriture. En e‑commerce, on observe souvent un profil très majoritairement lecture (navigation), avec des pics d’écriture sur le checkout, les mises à jour de panier, les logs, et les imports. Si votre test ne fait que du read, vous ne testez pas les verrous, les flush, ni les comportements “pire cas” du tunnel.
Les KPI à suivre doivent être actionnables, pas décoratifs. Côté MySQL : QPS, latence p50/p95/p99 par type (SELECT/UPDATE), temps d’attente InnoDB (mutex/lock), InnoDB_buffer_pool_reads (cache miss), IOPS, fsync/s, taille et création de temp tables, et top requêtes (digest). Côté application : TTFB p95, taux d’erreur 5xx, temps checkout, timeouts PHP-FPM, et saturation CPU/RAM.
Une manière simple de rendre ces KPI “utilisables” est de les relier à des décisions. Exemple :
- Si
Created_tmp_disk_tablesexplose pendant les tests facettes : revoir index/requête, et vérifiertmp_table_size/max_heap_table_size(sans masquer un problème structurel). - Si p95 checkout augmente mais QPS DB reste stable : suspecter contention/locks (panier/stock) ou latence fsync (binlog/redo).
- Si CPU DB baisse mais TTFB augmente : suspecter côté PHP/app (cache, réseau, DNS), pas seulement MySQL.
Pour l’observabilité en temps réel (staging et prod), Netdata fait le job rapidement ; voir Netdata collecteurs : supervision temps réel Kubernetes, Docker et AWS et, côté intégrations, comment brancher Prometheus, SNMP et StatsD dans Netdata.
Points de durcissement post‑migration : tuning, compat SQL et sécurité d’exploitation
Après la bascule, la priorité est de stabiliser les plans et d’éviter les “optimisations” à l’aveugle. MySQL 8 offre des outils de diagnostic plus précis : EXPLAIN ANALYZE, performance_schema mieux exploitable, et la possibilité de tester des index sans risque via les invisible indexes. Exemple : rendre un index invisible pour vérifier si l’optimiseur en dépend vraiment (utile quand vous suspectez un index redondant) :
ALTER TABLE ps_product ADD INDEX idx_tmp (reference) INVISIBLE;
-- tester sous charge
ALTER TABLE ps_product ALTER INDEX idx_tmp VISIBLE;
Sur PrestaShop, la perf DB est surtout une question de latence I/O et de contention, pas de “feature” MySQL magique. Vérifiez que innodb_buffer_pool_size est dimensionné (souvent 60–75% de la RAM sur serveur dédié DB), que innodb_flush_method est cohérent avec votre stockage, et que la journalisation binaire (si activée) n’explose pas vos fsync. Lisez vos slow logs, comparez avant/après et corrigez les vraies requêtes lentes (l’article PrestaShop performance : optimiser cache, images WebP et base MySQL donne un cadre utile côté stack globale, pas seulement DB).
Côté compat SQL, gardez une règle : corriger le SQL applicatif plutôt que “dé-durcir” MySQL. Si vous changez sql_mode pour faire passer un module, documentez-le et mettez-le dans la dette technique (avec une date de traitement). C’est particulièrement vrai en e‑commerce où des requêtes incorrectes finissent par casser sur un upgrade futur (ou pire : produire des résultats silencieusement faux).
Enfin, durcissez l’exploitation : TLS côté MySQL, comptes applicatifs à privilèges minimaux, rotation des secrets, et règles réseau (pas de MySQL exposé). Ne laissez pas default_authentication_plugin=mysql_native_password “temporaire” pendant 18 mois : migrez les clients vers un support correct de MySQL 8, et alignez vos outils (backup, migration, monitoring) sur la réalité post‑5.7.
Dans beaucoup de migrations, une approche pragmatique consiste à :
1) valider que tous les clients (PHP-FPM, CLI, ETL, outils) se connectent en MySQL 8,
2) puis basculer progressivement les comptes applicatifs vers caching_sha2_password (au lieu de le forcer globalement).
Pour les références externes (à lire avant de toucher la prod) :
- Sysbench (outil de bench) : GitHub — sysbench
Une migration MySQL 5.7→8 réussie, sur PrestaShop, c’est rarement une histoire de “commande magique”. C’est un enchaînement discipliné : check upgrade + staging fidèle + runbook cutover + tests de charge + observabilité, avec un rollback crédible. Si un de ces blocs manque, vous ne migrez pas : vous pariez.




