Je ne sais pas si cela est vrai, mais je me souviens avoir lu si vous exécutez la commande suivante sous linux
mysqldump -u username -p database_name > backup_db.sql
pendant la lecture et l'écriture dans une base de données, le vidage peut contenir des erreurs.
Existe-t-il des options particulières dans la commande mysqldump
pour vous assurer que cela se fait en toute sécurité sur un système en direct? Je suis d'accord avec la lecture/écriture désactivée pour nos utilisateurs pendant quelques secondes (la base de données <50 Mo)
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 et fonctions stockées
--triggers
vide tous les déclencheurs pour chaque table qui les a
Vous devrez imposer un verrou de lecture global, 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
Essaie !!!
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 86400 secondes (que 24 heures) juste pour obtenir l'ID de processus et tuer à l'extérieur, essayons de définir un délai d'expiration 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.
--single-transaction
option, comme mentionné dans une autre réponse.--lock-tables
.Voir le documentation officielle ici
La suggestion de la documentation officielle mysql est que vous devriez avoir une base de données maître "M1" et une base de données esclave "S1" qui est décrite dans "Scénario 2: Sauvegarde avec un esclave en lecture seule" Sauvegarde d'un maître ou Esclave en le rendant en lecture seule
Vous devez définir la base de données esclave en lecture seule et effectuer e
Voici comment je l'ai fait. Il 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 !"
La commande Shell sleep
sert uniquement à s'assurer que la tâche en 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 cela devrait toujours être bien. Augmentez-le à 30 secondes et essayez d'insérer des valeurs 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 les options mysqldump
--single-transaction
et --lock-tables
:
mysqldump
pendant la même période de verrouillage. 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 avec SHOW MASTER STATUS;
à l'état exact du vidage que vous avez créé (avant de déverrouiller la base de données), pour pouvoir créer un esclave de réplication.Si vous souhaitez le faire pour MyISAM ou des tables mixtes sans aucun temps d'arrêt du verrouillage des tables, vous pouvez configurer une base de données esclave et prendre vos instantanés à partir de là. La configuration de la base de données esclave, malheureusement, entraîne un certain temps d'arrêt pour exporter la base de données en direct, mais une fois qu'elle est en cours d'exécution, vous devriez pouvoir verrouiller ses tables et exporter en utilisant les méthodes décrites par d'autres. Lorsque cela se produit, il sera en retard sur le maître, mais n'empêchera pas le maître de mettre à jour ses tables et rattrapera son retard dès que la sauvegarde sera terminée.
si vous avez une très grande table MYISAM et que vous devez vider la table sans verrou et éviter une charge de serveur élevée, vous pouvez utiliser le script suivant.
#!/bin/sh
my_user="user"
my_password="password"
my_db="vpn"
my_table="traffic"
my_step=100000
read -p "Dumping table ${my_db}.${my_table} to ${my_table}.sql?" yn
case $yn in
[Yy]* ) break;;
* ) echo "User cancel."; exit;;
esac
my_count=$(mysql $my_db -u $my_user -p$my_password -se "SELECT count(*) FROM $my_table")
my_count=$(($my_count + 0))
if [ ! $my_count ]
then
echo "No records found"
exit
fi
echo "Records in table ${my_db}.${my_table}: ${my_count}"
echo "" > $my_table.sql
max_progress=60
for (( limit=0; limit<=$my_count; limit+=$my_step )); do
progress=$((max_progress * ( limit + my_step) / my_count))
echo -ne "Dumping ["
for ((i=0; i<$progress; i ++)); do
echo -ne "#"
done
for ((; i<$max_progress; i ++)); do
echo -ne "."
done
mysqldump -u $my_user -p$my_password --complete-insert --no-create-info --opt --where="1 limit $limit , $my_step" $my_db $my_table >> $my_table.sql
echo "" >> $my_table.sql
echo -ne "] $((100 * ( limit + my_step ) / my_count)) %"
echo -ne "\r"
sleep 1
done
echo -ne "\n"