## Migration de MySQL 5.7.34 vers 8.4 et transition vers l’encodage UTF-8

### Prérequis obligatoires

Avant de lancer l'installation, assurez-vous que votre environnement respecte toutes les conditions requises. Ce POC a été réalisé en sauvegardant les données existantes afin de prévenir toute perte ou corruption en cas d'interruption ou d'erreur pendant le processus.

#### Condition nécessaire pour lancer le POC :

Logiciel impérativement besoin :

* **Git** installé
* **Docker Desktop** installé et fonctionnel
* **Docker Compose** disponible (inclus avec Docker Desktop)

Sur l’environnement configuré et testé :

* ✅ **Windows 11 25H2** avec WSL 2 (Ubuntu24-04 recommandé)
* ✅ **MacOS** (Devrait fonctionner après quelques ajustements)

### I. Migration MySQL

1. Lancez vos conteneurs actuels pour récupérer une sauvegarde. Pour cela, récupérez le nom du conteneur où MySQL 5.7.34 est en cours d’exécution en utilisant la commande suivante :

```powershell
docker ps
```

2. Vous allez obtenir une liste dans ce format. Dans notre cas, le conteneur concerné est nommé `media-manager-db`. Assurez-vous de sa présence. S’il est absent, tentez de le redémarrer à l’aide des commandes `make down` puis `make up`:

```powershell
CONTAINER ID   IMAGE                    COMMAND                  CREATED       STATUS       PORTS                                                                                                                                                                                                                 NAMES
ba87d43e8093   3580d6f07765             "/usr/local/bin/dock…"   4 hours ago   Up 3 hours   0.0.0.0:80->80/tcp, \[::]:80->80/tcp, 0.0.0.0:443->443/tcp, \[::]:443->443/tcp, 0.0.0.0:8080->8080/tcp, \[::]:8080->8080/tcp, 0.0.0.0:8484->8484/tcp, \[::]:8484->8484/tcp, 0.0.0.0:8585->8585/tcp, \[::]:8585->8585/tcp   media\_manager-webserver
ee6c74a4d25c   44ecb3fa1985             "docker-entrypoint.s…"   4 hours ago   Up 3 hours                                                                                                                                                                                                                         media\_manager-grunt
aaeb05a6ab70   mysql:test            "docker-entrypoint.s…"   4 hours ago   Up 3 hours   0.0.0.0:3307->3306/tcp, \[::]:3307->3306/tcp                                                                                                                                                                           media\_manager-db-slave
32214ade3ba3   redis:6.0.7-alpine       "docker-entrypoint.s…"   4 hours ago   Up 3 hours   0.0.0.0:6379->6379/tcp, \[::]:6379->6379/tcp                                                                                                                                                                           media\_manager-redis
bcfafd1dab29   mysql:5.7.34               "docker-entrypoint.s…"   4 hours ago   Up 3 hours   0.0.0.0:3306->3306/tcp, \[::]:3309->3306/tcp                                                                                                                                                                           media\_manager-db 
bd6beda4f83c   mailhog/mailhog:latest   "MailHog"                4 hours ago   Up 3 hours   0.0.0.0:1025->1025/tcp, \[::]:1025->1025/tcp, 0.0.0.0:8025->8025/tcp, \[::]:8025->8025/tcp                                                                                                                              media\_manager-mailhog
```

3. Commande pour sauvegarder les données des bases de données.  Seules les bases **non gérées automatiquement par MySQL** seront récupérées. Les tables système comme `mysql`, `sys` ou `performance\_schema` **ne peuvent pas être récupérées** en raison de leur incompatibilité lors de la migration de **MySQL 5.7 vers MySQL 8.4**.

```powershell
docker exec media\_manager-db sh -c 'exec mysqldump -uroot -p"$MYSQL\_ROOT\_PASSWORD" --databases licence\_106 licence\_108 licence\_110 licence\_111 licence\_112 licence\_125 licence\_141 licence\_142 licence\_143 licence\_153 licence\_154  licence\_155 licence\_156 licence\_157 licence\_158 licence\_159 licence\_160 licence\_161 licence\_162 licence\_163 licence\_164 licence\_176 licence\_177 licence\_178 licence\_179 licence\_180 licence\_181 licence\_182 licence\_183 licence\_184  licence\_185 licence\_186 licence\_187 licence\_188 licence\_189 licence\_190 licence\_191 licence\_192 licence\_193 licence\_194 licence\_3 licence\_44 licence\_68 licence\_80 licence\_87 licence\_88 licence\_90 licence\_91 licence\_98  media\_manager streamup\_bd\_modele --single-transaction --quick --lock-tables=false' > backup\_user.sql
```

4. Créez un nouveau volume vierge, sans contenu existant ; il servira à héberger MySQL 8.4. :

```
docker volume create <nom\_du\_volume>
```

5. Vérifiez que le volume a bien été créé :

```
docker volume inspect <nom\_du\_volume>
```

6. Récupérez l’image officielle depuis Docker Hub :

```
docker pull mysql:8.4
```

7. Vérifiez que l’image a bien été téléchargée (`pull`) :

```
docker image ls                           
```

8. Modifiez le fichier `docker-compose.yaml`.  
Si certains volumes semblent manquer, c’est normal : nous voulons d’abord lancer le conteneur **vide** pour vérifier qu’aucune erreur ne se produit.

```
  db:
    container\_name: media\_manager-db
    image: mysql:8.4
    ports:
      - '3309:3306'
    volumes:
      - mysql:/var/lib/mysql
    environment:
      MYSQL\_ROOT\_PASSWORD: 'root'
    networks:
      - shared
```

9. Supprimez tous les conteneurs existants du service **media\_manager**. Vous pouvez réaliser cette opération soit depuis l’interface Docker Desktop, soit en utilisant la commande suivante :

```
make down 
make stop
docker rm -f $(docker ps -a -q --filter "name=media\_manager") # ou via l'interface Docker Desktop 
```

10. Premier démarrage du conteneur avec **MySQL 8.4** :

```
make build
```

11. Vérifiez les logs du conteneur pour confirmer qu’il a démarré correctement.

```
docker logs -f media\_manager-db 
# On peut consulter directement sur l'interface Docker Desktop 
```

12. (ERREUR) : Si votre conteneur s'arrête quelques secondes après son démarrage,  
cela indique généralement un problème de **droits d’écriture**.  
Dans ce cas, vérifiez que votre fichier `docker-compose.yaml` est correctement configuré.

```
2025-11-04 09:12:44+00:00 \[Note] \[Entrypoint]: Entrypoint script for MySQL Server 8.4.0-1.el9 started. 
2025-11-04 09:12:44+00:00 \[Note] \[Entrypoint]: Switching to dedicated user 'mysql' 
2025-11-04 09:12:44+00:00 \[Note] \[Entrypoint]: Entrypoint script for MySQL Server 8.4.0-1.el9 started. '/var/lib/mysql/mysql.sock' -> '/var/run/mysqld/mysqld.sock'
```

13. Si vous rencontrez cette erreur, suivez les étapes indiquées sur la page StackOverflow suivante :  
[Erreur lors de l'installation DB AzerothCore Docker](https://stackoverflow.com/questions/77344634/azerothcore-docker-install-db-fails-with-upgrade-is-not-supported-after-a-cras)

```
\[ERROR] \[MY-012526] \[InnoDB] Upgrade is not supported after a crash or shutdown with innodb\_fast\_shutdown = 2. This redo log was created with MySQL 8.4.0, and it appears logically non empty. Please follow the instructions at http://dev.mysql.com/doc/refman/8.4/en/upgrading.html
\[ERROR] \[MY-012930] \[InnoDB] Plugin initialization aborted with error Generic error.
\[ERROR] \[MY-010020] \[Server] Failed to initialize DD Storage Engine
\[ERROR] \[MY-010020] \[Server] Data Dictionary initialization failed.
\[ERROR] \[MY-010119] \[Server] Aborting
```

14. Si votre conteneur reste actif après le démarrage, c’est une excellente nouvelle : votre conteneur fonctionne correctement en **MySQL 8.4.0**. Vous devriez voir le message : `Ready for Connections`.

```
2025-11-04 09:18:38+00:00 \[Note] \[Entrypoint]: Entrypoint script for MySQL Server 8.4.0-1.el9 started.
2025-11-04 09:18:38+00:00 \[Note] \[Entrypoint]: Switching to dedicated user 'mysql'
2025-11-04 09:18:38+00:00 \[Note] \[Entrypoint]: Entrypoint script for MySQL Server 8.4.0-1.el9 started.
'/var/lib/mysql/mysql.sock' -> '/var/run/mysqld/mysqld.sock'
2025-11-04T09:18:39.432547Z 0 \[Warning] \[MY-011068] \[Server] The syntax '--skip-host-cache' is deprecated and will be removed in a future release. Please use SET GLOBAL host\_cache\_size=0 instead.
2025-11-04T09:18:39.434982Z 0 \[System] \[MY-010116] \[Server] /usr/sbin/mysqld (mysqld 8.4.0) starting as process 1
2025-11-04T09:18:39.447334Z 1 \[System] \[MY-013576] \[InnoDB] InnoDB initialization has started.
2025-11-04T09:18:39.741757Z 1 \[System] \[MY-013577] \[InnoDB] InnoDB initialization has ended.
2025-11-04T09:18:40.041309Z 0 \[Warning] \[MY-010068] \[Server] CA certificate ca.pem is self signed.
2025-11-04T09:18:40.041361Z 0 \[System] \[MY-013602] \[Server] Channel mysql\_main configured to support TLS. Encrypted connections are now supported for this channel.
2025-11-04T09:18:40.045597Z 0 \[Warning] \[MY-011810] \[Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
2025-11-04T09:18:40.084231Z 0 \[System] \[MY-011323] \[Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock
2025-11-04T09:18:40.084328Z 0 \[System] \[MY-010931] \[Server] /usr/sbin/mysqld: ready for connections. Version: '8.4.0'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server - GPL.
```

15. Nous allons maintenant restaurer les données à partir du dump créé précédemment. Pour ce faire, copiez le fichier SQL dans le volume Docker approprié

```
docker cp backup\_user.sql media\_manager-db:/tmp/backup\_user.sql0
```

16. Entrez dans le conteneur et restaurez le dump de la base de données :

```
docker exec -it media\_manager-db bash

# Une fois rentré :
= bash5.1# = mysql -u root -p

# Puis : 
= SOURCE /tmp/backup.sql;

# la copie des données est lancé
```

17. Une fois que les données ont été correctement copiées, nous allons vérifier qu’aucune donnée corrompue n’a été créée. Pour cela, reconstruisez le conteneur afin de vous assurer que tout fonctionne correctement.

```
make build
```

18. Pour convertir les tables de **MyISAM** en **InnoDB**, entrez à nouveau dans le conteneur.

```
docker exec -it media\_manager-db bash
```

19. Ouvrez MySQL dans le conteneur (Attention n'oubliez pas d’inclure les paramètres `-p` et `-s` !)

```
mysql -u root -p -s
```

20. Saisissez la commande suivante, qui générera les instructions `ALTER TABLE` :

```
SELECT CONCAT('ALTER TABLE `', TABLE_SCHEMA,'`.`',TABLE_NAME, '` ENGINE = InnoDB;') FROM information_schema.TABLES WHERE ENGINE='MyISAM' AND TABLE_SCHEMA NOT IN('mysql','information_schema','performance_schema');
```

21. Elle renvoie une longue liste similaire à celle-ci :

```
ALTER TABLE `licence\_98`.`stats\_prerolls\_views\_daily` ENGINE = InnoDB;
ALTER TABLE `licence\_98`.`stats\_sites\_views\_archive` ENGINE = InnoDB;
ALTER TABLE `licence\_98`.`stats\_sites\_views\_daily` ENGINE = InnoDB;
ALTER TABLE `licence\_98`.`stats\_tracked\_links\_clicks\_archive` ENGINE = InnoDB;
ALTER TABLE `licence\_98`.`stats\_tracked\_links\_clicks\_daily` ENGINE = InnoDB;
(etc ...)
```

22. Copiez tout le contenu affiché, puis collez-le pour exécuter l'opération complète.

```
mysql> ALTER TABLE `streamup\_bd\_modele`.`breakout\_rooms\_users\_logs` ENGINE = InnoDB;
mysql> ALTER TABLE `streamup\_bd\_modele`.`categories` ENGINE = InnoDB;
mysql> ALTER TABLE `streamup\_bd\_modele`.`categories\_congres\_categories` ENGINE = InnoDB;
E `streamup\_bd\_modele` ...
```

23. Vérifiez que les tables ont bien été converties en **InnoDB**. Choisissez une licence au hasard :

```
mysql> use licence\_3
mysql> SHOW CREATE TABLE users;
```

24. La commande devrait vous renvoyer un résultat similaire, où l'on constate que **Engine = InnoDB**.

> Les instructions ont été récupérées depuis les sites suivants :  
> - \[Convertir toutes les tables MyISAM en InnoDB](https://connaissances.fournier38.fr/entry/Convertir%20toutes%20les%20tables%20MyISAM%20en%20InnoDB)  
> - \[MySQL: Querying all MyISAM databases](https://dba.stackexchange.com/questions/50028/mysql-command-querying-all-myisam-database/50030#50030)

```
Table   Create Table
users   CREATE TABLE `users` (\\n  `ID\_user` int unsigned NOT NULL AUTO\_INCREMENT,\\n  
`ID\_service` int unsigned NOT NULL DEFAULT '0',\\n  `ID\_societe` int unsigned DEFAULT '0',\\n
`user\_dtcrea` timestamp NOT NULL DEFAULT CURRENT\_TIMESTAMP,\\n  `user\_dtlastcnx` timestamp NOT
NULL DEFAULT '0000-00-00 00:00:00',\\n  `user\_type` enum('normal','contributeur','moderateur',
'synergie\_master','licence\_master','exhibitor','exhibitor\_chat','faculty') NOT NULL DEFAULT 
'normal',\\n  `user\_pseudo` varchar(100) NOT NULL DEFAULT '',\\n  `user\_guid` varchar(200) NOT 
NULL DEFAULT '',\\n  `user\_mail` varchar(255) DEFAULT NULL,\\n  `user\_status` enum('A','V','S')
 NOT NULL DEFAULT 'V',\\n  `user\_count\_login\_attempt` tinyint unsigned NOT NULL DEFAULT '0',
\\n  `user\_oauth\_provider` enum('none','facebook','twitter','api','MyKey4') NOT NULL DEFAULT
'none',\\n  `user\_oauth\_token\_secret` varchar(100) NOT NULL,\\n  `user\_oauth\_token` varchar
(100) NOT NULL,\\n  `user\_oauth\_id` varchar(100) NOT NULL DEFAULT '',\\n  `user\_pwd` varchar
(100) NOT NULL DEFAULT '',\\n  `user\_chat\_banned` tinyint NOT NULL DEFAULT '0',\\n  
`user\_chat\_enabled` int NOT NULL DEFAULT '1',\\n  `user\_meetings\_enabled` enum('0','1') NOT 
NULL DEFAULT '1',\\n  `user\_displayname\_interactivity\_enabled` enum('0','1') NOT NULL DEFAULT '1',\\n  PRIMARY KEY (`ID\_user`),\\n  KEY `ID\_service` (`ID\_service`),\\n  KEY `user\_pseudo` 
(`user\_pseudo`),\\n  KEY `user\_mail` (`user\_mail`),\\n  KEY `user\_oauth\_provider` 
(`user\_oauth\_provider`),\\n  KEY `user\_dtcrea` (`user\_dtcrea`),\\n  KEY `user\_type` 
(`user\_type`),\\n  KEY `user\_oauth\_id` (`user\_oauth\_id`),\\n  KEY `ID\_societe` (`ID\_societe`),
\\n  KEY `user\_status` (`user\_status`)\\n) ENGINE=InnoDB AUTO\_INCREMENT=57278 DEFAULT 
CHARSET=latin1
```

25. Conversion des tables UTF-8 en utf8mb4 :  
Exécutez la commande suivante pour générer un fichier SQL qui convertira toutes les tables de votre base de données en `utf8mb4` :

```
#bash 5.1 > mysql -u USER -p -N -e "SELECT CONCAT(
    'ALTER TABLE \`', TABLE_SCHEMA, '\`.\`', TABLE_NAME,
    '\` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'
)
FROM information_schema.TABLES
WHERE TABLE_SCHEMA NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys')
  AND TABLE_TYPE = 'BASE TABLE';" > convert_utf8mb4.sql 
```

26. Vérifiez le contenu du fichier :

```
cat convert\_utfmb4.sql
```

27. Lancez l'exécution du fichier SQL suivant pour mettre à jour la base de données :

```
mysql -u USER -p < convert\_utf8mb4.sql
```

28. Conversion de la base de données en utf8mb4 :
Exécutez la commande suivante pour générer un fichier SQL qui convertira tout vos base de données en `utf8mb4` :

```
SELECT CONCAT('ALTER DATABASE `', SCHEMA_NAME,'` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;')
FROM information_schema.SCHEMATA
WHERE SCHEMA_NAME NOT IN ('mysql','information_schema','performance_schema','sys');
CONCAT('ALTER DATABASE `', SCHEMA_NAME,'` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;')
```

29. Elle renvoie également une longue liste similaire à celle-ci :

```
ALTER DATABASE `licence\_106` CHARACTER SET utf8mb4 COLLATE utf8mb4\_unicode\_ci;
ALTER DATABASE `licence\_108` CHARACTER SET utf8mb4 COLLATE utf8mb4\_unicode\_ci;
ALTER DATABASE `licence\_110` CHARACTER SET utf8mb4 COLLATE utf8mb4\_unicode\_ci;
ALTER DATABASE `licence\_111` CHARACTER SET utf8mb4 COLLATE utf8mb4\_unicode\_ci;
```

30. Copiez tout le contenu affiché, puis collez-le pour exécuter l'opération complète.

```
mysql> ALTER DATABASE `licence\_106` CHARACTER SET utf8mb4 COLLATE utf8mb4\_unicode\_ci;
mysql> ALTER DATABASE `licence\_108` CHARACTER SET utf8mb4 COLLATE utf8mb4\_unicode\_ci;
mysql> ALTER DATABASE `licence\_110` CHARACTER SET utf8mb4 COLLATE utf8mb4\_unicode\_ci; .... 
```

23. Vérifiez que les bases de données ont bien été converties en **utf8mb4**. Choisissez une licence au hasard :

```
mysql> use licence\_3
mysql> SHOW CREATE DATABASE licence\_68;
```

Il faut s’assurer que l’encodage est bien utf8mb4 :

```
Database        Create Database
licence\_68      CREATE DATABASE `licence\_68` /\*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4\_unicode\_ci \*/ /\*!80016 DEFAULT ENCRYPTION='N' \*/
```



28. Une fois les données mises à jour, revenez dans le fichier `docker-compose.yml` et ajoutez les lignes suivantes :

```
  db:
    container\_name: media\_manager-db
    #    platform: linux/amd64 #Mac M1 compatibility
    image: mysql:8.4
    ports:
      - '3309:3306'
    volumes:
      - mysql:/var/lib/mysql
      - ./docker/mysql/conf.d:/etc/mysql/conf.d
      - ./docker/mysql/script:/tmp/mysql/script
      - ./docker/mysql/import:/tmp/mysql/import
    command: >
      bash -c "
      chmod 644 /etc/mysql/conf.d/\*.cnf
      \&\& /entrypoint.sh mysqld --server-id=1 --log-bin=mysql-bin --binlog-format=ROW --binlog-ignore-db=mysql --binlog-ignore-db=information\_schema --binlog-ignore-db=performance\_schema
      "
    environment:
      TZ: "Europe/Paris"
      MYSQL\_ROOT\_PASSWORD: 'root'
      MYSQL\_USER: 'user'
      MYSQL\_PASSWORD: 'password'
    networks:
      - shared
```

29. Modifiez le fichier `mysqld.cnf`, qui est initialement prévu pour MySQL 5.  
Ce fichier se trouve dans le chemin suivant : `docker/mysql/conf.d`.  
Une fois localisé, remplacez-le par le fichier suivant :

```
\[mysqld]
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
datadir         = /var/lib/mysql
log-error       = /var/log/mysql/error.log
symbolic-links  = 0

# Désactivation des modes SQL stricts pour compatibilité application
sql\_mode = NO\_ENGINE\_SUBSTITUTION

# Optimisation mémoire et connexions
max\_connections = 5000
max\_connect\_errors = 500
connect\_timeout = 20
wait\_timeout = 28800
interactive\_timeout = 28800
max\_allowed\_packet = 64M
thread\_cache\_size = 128

# Buffers (à ajuster selon RAM)
sort\_buffer\_size = 4M
read\_buffer\_size = 2M
read\_rnd\_buffer\_size = 8M
join\_buffer\_size = 2M

# Tables temporaires
tmp\_table\_size = 128M
max\_heap\_table\_size = 128M

# InnoDB (le moteur par défaut)
innodb\_buffer\_pool\_size = 1G
innodb\_redo\_log\_capacity = 268435456
innodb\_flush\_log\_at\_trx\_commit = 1
innodb\_file\_per\_table = 1
innodb\_flush\_method = O\_DIRECT

# MyISAM (si encore utilisé)
key\_buffer\_size = 128M
myisam\_sort\_buffer\_size = 64M
myisam\_recover\_options = BACKUP

# Journalisation requêtes lentes
slow\_query\_log = 1
slow\_query\_log\_file = /var/log/mysql/mysql-slow.log
long\_query\_time = 8

# Réplication (désactive le démarrage automatique du slave)
skip_replica_start

# Réduit les résolutions DNS inutiles
skip-name-resolve

# Empêche le démarrage si fichiers corrompus
innodb\_strict\_mode = 1
```

30. Une fois toutes ces étapes accomplies, votre base de données sera en **MySQL 8.4** et les données en **UTF-8**.
En revanche, le projet n’est pas encore entièrement en UTF-8, ce qui peut provoquer des erreurs lors du démarrage.



1. Si vous souhaitez tester la plateforme en UTF-8, je vous conseille de faire un `pull` et de basculer sur la branche suivante :

```
git checkout feature/STREAMUP-3820 
make build 
```

### Accès au projet

Si toutes les étapes ont été respectées à la lettre, la plateforme devrait fonctionner correctement, sans erreur.
Pour accéder au projet, utilisez le lien suivant :

```
🔗 https://default.prod.stream-up.local/
```

