Guide MariaDB / MySQL
mysqldump / mariadb-dump : sauvegarder et restaurer une base MariaDB ou MySQL
Les options à mettre systématiquement, les commandes pour exporter une base, quelques tables ou tout le serveur, la restauration, et les erreurs qu'on rencontre tous un jour. Un guide d'usage, pensé pour la production.
La commande à retenir
Si vous ne devez garder qu'une ligne, c'est celle-ci. Elle produit un dump cohérent d'une base InnoDB sans bloquer les écritures, avec les procédures stockées et les événements, en limitant les risques de corruption des données binaires et des caractères accentués.
mariadb-dump --single-transaction --routines --events \
--default-character-set=utf8mb4 --hex-blob \
mydb > mydb-$(date +%F).sqlSur MariaDB, utilisez mariadb-dump : l'ancien nom mysqldump est déprécié depuis MariaDB 11.0 et absent de l'image Docker officielle, sa présence dépend donc des paquets installés. Sur MySQL, remplacez mariadb-dump par mysqldump et mariadb par mysql. La différence entre les deux binaires est expliquée dans mariadb-dump vs mydumper.
Les options qui comptent
--single-transaction
Ouvre une transaction en lecture cohérente : les tables InnoDB sont exportées telles qu'elles étaient au démarrage du dump, sans verrou. Aucun ALTER TABLE, CREATE TABLE, DROP TABLE, RENAME TABLE ou TRUNCATE TABLE ne doit tourner pendant ce temps. Les tables MyISAM ou Aria ne sont pas couvertes : elles ne sont ni verrouillées ni cohérentes, il leur faut une stratégie de verrouillage explicite.
--routines --events
Procédures, fonctions et événements planifiés ne sont pas exportés par défaut. Les triggers, eux, le sont. Un dump sans ces options restaure les tables mais pas toujours l'application.
--hex-blob
Écrit les colonnes binaires (BLOB, BINARY, VARBINARY, BIT…) en hexadécimal. Évite les corruptions quand le fichier passe par un éditeur, un changement d'encodage ou un transfert mal configuré.
--default-character-set=utf8mb4
Force l'encodage de la connexion. Sans lui, un client configuré autrement peut transformer les emojis et certains caractères en points d'interrogation, sans erreur visible.
--quick
Lit les lignes une par une au lieu de charger la table en mémoire. Déjà actif par défaut via --opt : inutile de l'ajouter, mais ne le désactivez pas.
--master-data=2 --gtid (MariaDB) / --source-data=2 (MySQL 8.0.26+)
Écrit en commentaire la position binlog (et le GTID sur MariaDB) au moment du dump. Indispensable pour monter un réplica ou faire une restauration à un instant précis avec les binlogs. Combinée à --single-transaction, elle pose un verrou global au démarrage, normalement bref, mais qui attend la fin des requêtes longues en cours : pendant cette attente, toutes les écritures sont bloquées.
Exporter : les cas courants
Une base
mariadb-dump --single-transaction --routines --events mydb > mydb.sqlQuelques tables d'une base
mariadb-dump --single-transaction mydb customers orders > customers-orders.sqlLe schéma seul, sans les données
mariadb-dump --no-data --routines --events mydb > mydb-schema.sqlToutes les bases du serveur
mariadb-dump --single-transaction --routines --events --all-databases > all.sqlAvec les coordonnées de réplication (MariaDB)
# MariaDB: binlog position + GTID written as a header comment
mariadb-dump --single-transaction --master-data=2 --gtid --all-databases > all.sqlAvec les coordonnées de réplication (MySQL)
# MySQL 8.0.26+: --source-data replaces --master-data
mysqldump --single-transaction --source-data=2 --all-databases > all.sqlAvec --databases ou --all-databases, le dump contient les CREATE DATABASE et USE : il se restaure sans préciser de base. Avec un nom de base seul, il faut créer la base cible et la nommer à la restauration.
Compresser et envoyer ailleurs
Un dump SQL se compresse très bien. Compressez à la volée plutôt qu'après coup : le fichier non compressé n'occupe jamais le disque du serveur.
Compression zstd à la volée
mariadb-dump --single-transaction --routines --events mydb \
| zstd -T0 > mydb-$(date +%F).sql.zstDirectement vers un serveur de sauvegarde, sans fichier local
mariadb-dump --single-transaction --routines --events mydb \
| zstd -T0 | ssh backup@srv-backup "cat > /backups/mydb-$(date +%F).sql.zst"Copie d'une base vers un autre serveur, en un seul flux
mariadb-dump --single-transaction --routines --events --databases mydb \
| ssh admin@new-server "mariadb"Restaurer un dump
Restauration simple (la base cible doit exister)
mariadb mydb < mydb.sqlDepuis un fichier compressé
zstd -dc mydb-2026-09-28.sql.zst | mariadb mydb
# or, for a gzip file:
zcat mydb.sql.gz | mariadb mydbUne seule base depuis un dump --all-databases
# Filters on the current database (USE mydb): fine for standard dumps,
# not a strict isolation (a statement naming another database still runs)
mariadb --one-database mydb < all.sqlUne seule table, via une base temporaire
# Restore the whole dump into a scratch database (never into production),
# then re-export only the table you need
mariadb -e "CREATE DATABASE mydb_restore"
mariadb mydb_restore < mydb.sql
mariadb-dump --single-transaction mydb_restore customers > customers.sqlNe rejouez jamais un dump directement en production pour récupérer une table : son DROP TABLE écrase la table actuelle. Restaurez dans une base temporaire, puis recopiez les lignes utiles. Extraire la table du fichier avec sed est tentant mais peu fiable (en-tête perdu, routines embarquées si c'est la dernière table). Si vous restaurez souvent des tables isolées, dumpez-les séparément ou passez à mydumper, qui écrit un fichier par table.
Accélérer un import
Le dump désactive déjà les contrôles d'unicité et de clés étrangères dans son en-tête : inutile de le refaire à la main. Ce qui ralentit vraiment un import, c'est le rejeu mono-thread et la reconstruction des index.
- Relâcher temporairement la durabilité avec
innodb_flush_log_at_trx_commit = 2, et la remettre à 1 juste après. À ne faire que sur un serveur où une coupure pendant l'import n'a pas de conséquence : au pire, on relance l'import. - Dimensionner
innodb_buffer_pool_sizeet la taille du redo log pour la charge d'écriture de l'import, pas pour la charge habituelle. - Si le serveur cible est un primaire avec des réplicas et que l'import ne doit pas être répliqué,
SET sql_log_bin = 0dans la session d'import. Dans le cas contraire, vérifiez l'en-tête du dump : un dump MySQL avec GTID contient lui-mêmeSET @@SESSION.sql_log_bin=0, à éviter avec--set-gtid-purged=OFFsi l'import doit être répliqué. - Quand la restauration devient trop longue pour votre objectif de reprise, le vrai levier est de changer d'outil : restauration parallèle avec mydumper / myloader, ou sauvegarde physique avec mariabackup.
-- For the duration of the import only, then back to 1
SET GLOBAL innodb_flush_log_at_trx_commit = 2;
-- ... import ...
SET GLOBAL innodb_flush_log_at_trx_commit = 1;Les erreurs fréquentes
ERROR at line 1: Unknown command '\-'
Depuis MariaDB 10.5.25, 10.6.18, 10.11.8 et 11.4.2 (correctif de sécurité de mai 2024), mariadb-dump écrit en première ligne /*!999999\- enable the sandbox mode */. Un client MariaDB plus ancien ou le client mysql de MySQL refusent cette ligne. Restaurez avec un client MariaDB récent, ou retirez la ligne : tail -n +2 dump.sql | mysql base.
Unknown table 'COLUMN_STATISTICS' in information_schema (1109)
Vous utilisez le mysqldump de MySQL 8 contre un serveur MariaDB (ou un MySQL ancien). Utilisez le client MariaDB, ou ajoutez --column-statistics=0.
Access denied; you need (at least one of) the PROCESS privilege(s)
Depuis MySQL 8.0.21, mysqldump a besoin du privilège PROCESS pour exporter les tablespaces. Ajoutez --no-tablespaces si vous n'en avez pas besoin (cas le plus fréquent), ou accordez le privilège au compte de sauvegarde.
Warning: A partial dump from a server that has GTIDs…
Sur MySQL avec GTID, le dump inclut un SET @@GLOBAL.gtid_purged qui couvre tout le serveur, même pour un dump partiel. Pour une simple copie de données vers un serveur qui n'est pas un réplica, utilisez --set-gtid-purged=OFF.
The user specified as a definer ('x'@'y') does not exist (1449)
Les vues, triggers et procédures gardent leur DEFINER d'origine. Créez ce compte sur le serveur cible, ou retirez les clauses DEFINER du dump avant de le rejouer (commande ci-dessous). Ce sed est purement textuel : il modifierait aussi une donnée contenant ce motif, et les objets recréés appartiendront au compte qui les restaure.
Got a packet bigger than 'max_allowed_packet' bytes (1153)
Une instruction du dump (souvent un INSERT de plusieurs lignes, ou une ligne avec un gros BLOB) dépasse la taille de paquet acceptée. Augmentez max_allowed_packet côté serveur et côté client (mariadb --max-allowed-packet=512M).
Retirer les clauses DEFINER d'un dump
sed -E 's/DEFINER=`[^`]+`@`[^`]+`//g' mydb.sql > mydb-no-definer.sqlAutomatiser : un script de sauvegarde avec rétention
Une base par fichier, compression à la volée, purge des dumps de 14 jours et plus, uniquement si toutes les sauvegardes ont réussi. Les identifiants sont dans un fichier d'options lisible par root seul, jamais sur la ligne de commande (visible dans la liste des processus).
# /root/.my.cnf
[client]
user=backup
password=********#!/usr/bin/env bash
# /usr/local/bin/backup-mariadb.sh — credentials read from /root/.my.cnf (chmod 600)
set -euo pipefail
DEST=/backups/mariadb
DATE=$(date +%F-%H%M)
mkdir -p "$DEST"
# List the databases first: stop if the query fails or returns nothing
DBS=$(mariadb -N -B -e "SHOW DATABASES" \
| grep -Ev '^(information_schema|performance_schema|sys)$')
[ -n "$DBS" ] || { echo "no database to dump" >&2; exit 1; }
while IFS= read -r DB; do
OUT="$DEST/$DB-$DATE.sql.zst"
if ! mariadb-dump --single-transaction --routines --events \
--default-character-set=utf8mb4 --hex-blob "$DB" \
| zstd -T0 -q > "$OUT"; then
rm -f "$OUT"; echo "dump failed: $DB" >&2; exit 1
fi
done <<< "$DBS"
# Only reached when every dump succeeded.
# -mtime +13 = files 14 full days old or more
find "$DEST" -name '*.sql.zst' -mtime +13 -deleteset -o pipefail est essentiel : sans lui, un dump qui échoue au milieu passe inaperçu, parce que le code retour est celui de zstd, qui lui a réussi. Côté privilèges, le compte de sauvegarde a besoin de SELECT, SHOW VIEW, TRIGGER, EVENT et LOCK TABLES (TRIGGER et EVENT permettent aussi de modifier ces objets : ce n'est pas un compte en pure lecture), de SELECT sur mysql.proc pour --routines sur MariaDB, et de droits supplémentaires selon les options : RELOAD et BINLOG MONITOR (MariaDB) ou REPLICATION CLIENT (MySQL) pour --master-data, PROCESS sur MySQL 8.0.21+ (ou --no-tablespaces), RELOAD ou FLUSH_TABLES sur MySQL 8.0.32+ avec GTID et --single-transaction.
Et gardez une copie hors du serveur : un dump stocké sur le disque de la base disparaît avec elle.
Tester la restauration, et savoir combien de temps elle prend
Un dump qui n'a jamais été rechargé n'est pas une sauvegarde. Restaurez régulièrement sur une instance isolée, comparez le nombre de lignes des tables principales, lancez quelques requêtes de l'application. Vous saurez si le fichier est exploitable, et surtout combien de temps il faut pour le remettre en ligne.
Ce temps grandit vite avec la taille de la base, parce que chaque INSERT est rejoué et chaque index reconstruit. Nous donnons des ordres de grandeur par taille, et expliquons quand passer à la sauvegarde physique, dans mysqldump vs mariabackup : temps de restauration réels.
Questions fréquentes
Comment exporter une base MySQL ou MariaDB en ligne de commande ?
mariadb-dump --single-transaction --routines --events nom_base > nom_base.sql (ou mysqldump sur MySQL). --single-transaction garantit un export cohérent des tables InnoDB sans bloquer les écritures.
Comment importer un dump SQL ?
mariadb nom_base < nom_base.sql (ou mysql sur MySQL), la base cible devant exister. Pour un fichier compressé : zcat fichier.sql.gz | mariadb nom_base.
mysqldump bloque-t-il la base pendant l'export ?
Pas avec --single-transaction sur des tables InnoDB : les écritures continuent. Sans cette option, --lock-tables (actif par défaut) verrouille les tables base par base. Avec --single-transaction, les tables MyISAM ne sont pas verrouillées, mais leur cohérence n'est pas garantie.
Pourquoi mes procédures stockées ne sont pas dans le dump ?
Les procédures, fonctions et événements ne sont pas exportés par défaut. Ajoutez --routines et --events. Les triggers, eux, sont inclus par défaut.
Peut-on restaurer une seule base depuis un dump de tout le serveur ?
Oui, avec mariadb --one-database nom_base < all.sql : le client ne rejoue que les ordres exécutés quand la base courante (USE) est nom_base. Suffisant pour un dump standard, mais ce n'est pas une isolation stricte.
Pages liées
- mysqldump vs mariabackup : temps de restauration réels
- Envoyer ses dumps vers Proxmox Backup Server : méthode testée et chiffres mesurés
- mariadb-dump vs mydumper / myloader : quel outil de dump ?
- Fin de vie de MySQL 8.0 : passer en 8.4 ou migrer vers MariaDB ?
- Outils DBA MariaDB / MySQL : ceux que nous utilisons et ceux à connaître
Vos dumps se restaurent-ils vraiment ?
Un audit MariaDB inclut une revue de votre stratégie de sauvegarde et un test de restauration mesuré.
Démarrez votre projet MariaDB infogéré
Discutons de vos besoins en bases de données. Notre équipe DBA vous conseille sur l'architecture optimale pour votre cas d'usage.
RDEM Systems SAS — SIREN 820 338 671 — 5 B rue des Noyers, 95300 Pontoise