background success stories

MySQL 8.0.21, une révolution du dump !

MySQL propose depuis de nombreuses années un outil pour réaliser des dumps logiques, le fameux mysqldump que tout le monde connait. Malheureusement trop souvent utilisé à tord et notamment avec de trop grosses volumétries pour cet outil qui n’a pas réellement évolué depuis longtemps. Il est monothreadé, les exports sont longs et les imports encore plus.

Connaissez vous MySQLPump avec un P ?

Avec MySQL 5.7 un nouvel est outil est sortit, mysqlPump, une variante multithread avec des nouveaux filtres, cependant lors de la sortie, une indication a été donnée de ne pas l’utiliser tout de suite car il n’était pas fonctionnelle à 100% (et nous avons vécu ses défauts avec un de nos clients). Les problèmes rencontrés ont été corrigés dans les patchs suivants, sauf erreur de ma part. Mais il n’a pas percé et il est aujourd’hui un inconnu, alors qu’il est toujours présent en version 8.0. Son nom semble être un clin d’œil à l’outil de dump Oracle, EXP et son évolution EXPDP pour Export Data Pump, le fameux P.

Le nouvel outil fait partit du package util() de l’outil MySQL Shell. De nouveaux outils sont ajoutés régulièrement à l’intérieur au fil des versions.

Cet outil est multithreadé et compresse par défaut les dumps.

Le dump se lance simplement avec la commande suivante en mode Javascript, util.dumpInstance(‘nomdudump’)

[root@localhost ~]# mysqlsh root@localhost

MySQL localhost:33060+ ssl JS - util.dumpInstance('/tmp/testdump')
Acquiring global read lock
All transactions have been started
Locking instance for backup
Global read lock has been released
Writing global DDL files
Writing users DDL
Preparing data dump for table `testdump`.`mytable`
Data dump for table `testdump`.`mytable` will be chunked using column `id`
Running data dump using 4 threads.
NOTE: Progress information uses estimated values and may not be accurate.
Writing DDL for schema `testdump`
Writing DDL for table `testdump`.`mytable`
Data dump for table `testdump`.`mytable` will be written to 1 file
1 thds dumping - 100% (1 rows / ~1 rows), 0.00 rows/s, 0.00 B/s uncompressed, 0.00 B/s compressed
Duration: 00:00:00s
Schemas dumped: 1
Tables dumped: 1
Uncompressed data size: 2 bytes
Compressed data size: 0 bytes
Compression ratio: 2.0
Rows written: 1
Bytes written: 0 bytes
Average uncompressed throughput: 2.00 B/s
Average compressed throughput: 0.00 B/s

La progression est aussi affichée pendant le dump. Le résultat n’est pas un simple fichier mais plutôt un répertoire contenant plusieurs fichiers. Dans notre exemple il n’y a qu’une base testdump et une table mytable à l’intérieur. Dans le même esprit un outil est présent pour dumper précisément des schémas et non toute l’instance.

[root@localhost ~]# ls /tmp/testdump/
@.done.json  @.post.sql  testdump.json                 testdump@mytable@@0.tsv.zst.idx  testdump@mytable.sql  @.users.sql
@.json       @.sql       testdump@mytable@@0.tsv.zst  testdump@mytable.json            testdump.sql

On retrouve à l’intérieur les fichiers avec du JSON et du SQL. L’ensemble correspond à un seul dump. Sans rentrer dans les détails, pour améliorer les temps d’export et d’import il est préférable de travailleur sur plusieurs fichiers et que chaque élément soit séparé (ou sous un référentiel dans les en têtes de fichier comme un dump Oracle expdp).

À l’avenir il sera peut être possible d’avoir un seul fichier en sortie, mais vous pouvez aussi faire un tar du répertoire.

Pour le chargement il est lui aussi optimisé, avec du parallélisme et de nombreuses options.

La syntaxe de la commande est util.loadDump(‘dumpname’, {option})

MySQL localhost:33060+ ssl JS - util.loadDump("/tmp/testdump", {dryRun: true})
ERROR: The 'local_infile' global system variable must be set to ON in the target server, after the server is verified to be trusted.

Comme on peut le voir le chargement est bloqué pour des raisons de sécurité, vous ne pouvez pas le charger directement il est nécessaire d’activer l’option LOCAL_INFILE (en mode SQL). Ce paramètre peut être définit juste pour l’import et ensuite désactivé.

L’option {dryRun} permet de voir ce qui va être chargé, la liste des tables/bases etc. sans l’exécuter.

Activation du paramètre Local_infile :

MySQL  localhost:33060+ ssl  JS - \sql
Switching to SQL mode... Commands end with ;
MySQL  localhost:33060+ ssl  SQL - set persist local_infile=0;
Query OK, 0 rows affected (0.0006 sec)
 MySQL  localhost:33060+ ssl  JS -  util.loadDump("/tmp/testdump", {dryRun:true})
Loading DDL and Data from '/tmp/testdump' using 4 threads.
dryRun enabled, no changes will be made.
Target is MySQL 8.0.21. Dump was produced from MySQL 8.0.21
Checking for pre-existing objects...
Executing common preamble SQL
Executing DDL script for schema `testdump`
Executing DDL script for `testdump`.`mytable`
Executing common postamble SQL

No data loaded.
0 warnings were reported during the load.

Le dump de test ne contient que la base testdump et la table mytable à l’intérieur. Maintenant sans le dryRun:

 MySQL  localhost:33060+ ssl  JS -  util.loadDump("/tmp/testdump")
Loading DDL and Data from '/tmp/testdump' using 4 threads.
Target is MySQL 8.0.21. Dump was produced from MySQL 8.0.21
Checking for pre-existing objects...
Executing common preamble SQL
Executing DDL script for schema `testdump`
Executing DDL script for `testdump`.`mytable2`
[Worker000] testdump@mytable2@@0.tsv.zst: Records: 1  Deleted: 0  Skipped: 0  Warnings: 0
Executing common postamble SQL

1 chunks (1 rows, 2 bytes) for 1 tables in 1 schemas were loaded in 1 sec (avg throughput 2.00 B/s)
0 warnings were reported during the load.

Le dump a bien été chargé, nous avons bien récupéré notre table avec ses enregistrement :

 MySQL  localhost:33060+ ssl  SQL - select * from testdump.mytable;
+----+
| id |
+----+
|  1 |
+----+
1 row in set (0.0005 sec)

L’utilisation de ces outils est très simple. Ils servent aussi pour MySQL Database Service sur le cloud Oracle, de nombreuses options sont intégrées qui y sont associées.

Pour plus d’informations n’hésitez pas à consulter la documentation officielle :

https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-shell-utilities-dump-instance-schema.html

https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-shell-utilities-load-dump.html