Toutes les données sont InnoDB
Voici ce qui vous donnera un instantané exact des données :
mysqldump -uuser -ppass --single-transaction --routines --triggers --all-databases > backup_db.sql
--single-transaction
produit un point de contrôle qui permet au vidage de capturer toutes les données avant le point de contrôle lors de la réception des modifications entrantes. Ces modifications entrantes ne font pas partie du vidage. Cela garantit le même point dans le temps pour toutes les tables.
--routines
vide toutes les procédures stockées et les fonctions stockées
--triggers
vide tous les déclencheurs pour chaque table qui en a
Toutes les données sont MyISAM ou un mélange d'InnoDB/MyISAM
Vous devrez imposer un verrou global en lecture, effectuer le mysqldump et libérer le verrou global
mysql -uuser -ppass -Ae"FLUSH TABLES WITH READ LOCK; SELECT SLEEP(86400)" &
sleep 5
mysql -uuser -ppass -ANe"SHOW PROCESSLIST" | grep "SELECT SLEEP(86400)" > /tmp/proclist.txt
SLEEP_ID=`cat /tmp/proclist.txt | awk '{print $1}'`
echo "KILL ${SLEEP_ID};" > /tmp/kill_sleep.sql
mysqldump -uuser -ppass --single-transaction --routines --triggers --all-databases > backup_db.sql
mysql -uuser -ppass -A < /tmp/kill_sleep.sql
Essayez-le !!!
MISE À JOUR 2012-06-22 08:12 EDT
Puisque vous avez <50 Mo de données totales, j'ai une autre option. Au lieu de lancer une commande SLEEP en arrière-plan pour maintenir le verrou de lecture global pendant 86 400 secondes (ces 24 heures) juste pour obtenir l'ID de processus et le tuer à l'extérieur, essayons de définir un délai d'attente de 5 secondes dans mysql plutôt que dans le système d'exploitation :
SLEEP_TIMEOUT=5
SQLSTMT="FLUSH TABLES WITH READ LOCK; SELECT SLEEP(${SLEEP_TIMEOUT})"
mysql -uuser -ppass -Ae"${SQLSTMT}" &
mysqldump -uuser -ppass --single-transaction --routines --triggers --all-databases > backup_db.sql
Il s'agit d'une approche plus propre et plus simple pour les très petites bases de données.
- Pour les tables InnoDB, vous devez utiliser le
--single-transaction
option, comme mentionné dans une autre réponse. - Pour MyISAM il y a
--lock-tables
.
Voir la documentation officielle ici
Voici comment je l'ai fait. Cela devrait fonctionner dans tous les cas car il utilise FLUSH TABLES WITH READ LOCK
.
#!/bin/bash
DB=example
DUMP_FILE=export.sql
# Lock the database and sleep in background task
mysql -uroot -proot $DB -e "FLUSH TABLES WITH READ LOCK; DO SLEEP(3600);" &
sleep 3
# Export the database while it is locked
mysqldump -uroot -proot --opt $DB > $DUMP_FILE
# When finished, kill the previous background task to unlock
kill $! 2>/dev/null
wait $! 2>/dev/null
echo "Finished export, and unlocked !"
Le shell sleep
commande est juste pour s'assurer que la tâche d'arrière-plan exécutant la commande de verrouillage mysql est exécutée avant le démarrage de mysqldump. Vous pouvez le réduire à 1 seconde et tout devrait bien se passer. Augmentez-le à 30 secondes et essayez d'insérer une valeur dans n'importe quelle table d'un autre client pendant ces 30 secondes, vous verrez qu'il est verrouillé.
Il y a 2 avantages à utiliser ce verrouillage manuel en arrière-plan, au lieu d'utiliser le mysqldump
choix --single-transaction
et --lock-tables
:
- Cela verrouille tout, si vous avez mélangé des tables MyISAM/InnoDB.
- Vous pouvez exécuter d'autres commandes en plus du
mysqldump
pendant la même période de fermeture. C'est utile, par exemple, lors de la configuration de la réplication sur un nœud maître, car vous devez obtenir la position du journal binaire avecSHOW MASTER STATUS;
à l'état exact du dump que vous avez créé (avant de déverrouiller la base de données), pour pouvoir créer un esclave de réplication.