mysqldump à un tar.gz

88

Habituellement, après avoir sauvegardé une base de données MySQL avec la mysqldumpcommande, j'ai immédiatement tar / gzip le fichier résultant. Je cherche un moyen de faire cela en une seule commande:

Donc de ceci:

mysqldump dbname -u root -p > dbname.sql
tar czvf dbname.sql.tgz dbname.sql
rm dbname.sql

Pour quelque chose comme ça:

mysqldump dbname -u root -p > some wizardry > dbname.sql.tgz

Ou même mieux (puisque je transfère habituellement le fichier de vidage sur un autre serveur):

mysqldump dbname -u root -p > send dbname.sql.tgz to user@host

Je cours bash sur debian.

Pygorex1
la source

Réponses:

102
mysqldump --opt <database> | gzip -c | ssh user@wherever 'cat > /tmp/yourfile.sql.gz'

Vous ne pouvez pas utiliser tar dans un tuyau comme celui-ci, et vous n'en avez de toute façon pas besoin, car vous ne sortez qu'un seul fichier. tar n'est utile que si vous avez plusieurs fichiers.

James
la source
6
Vous avez raison de ne pas avoir besoin de goudron, mais vous pouvez l'utiliser dans le pipeline si vous en aviez eu besoin avecmysqldump | tar cf - | gzip -c | ssh ... 'cat > file.tgz'
Darren Chamberlain le
Est-ce que ça marche vraiment? Je suis presque sûr que tar a besoin d'une liste de noms de fichiers sur lesquels travailler.
James
2
J'ai mis à jour cela pour qu'il fonctionne localement (pas sur un serveur ssh distant) oh, et j'utilise un nom dynamique basé sur la date, grâce à l'affiche et au répondeur d'origine! mysqldump --opt <database> | gzip -c | cat > $(date +%Y-%m-%d-%H.%M.%S).sql.gz
Electblake
4
@electblake: vous n'avez pas besoin d'utiliser 'cat' si c'est local. Justgzip -c > $(date +%Y-%m-%d-%H.%M.%S).sql.gz
James
Juste pour le plaisir, vous pourriez utiliser netcatau lieu de piping to ssh. Vous économiserez un peu sur la surcharge de cryptage de SSH, si celle-ci est transférée sur un réseau sécurisé (ou si vous ne vous souciez pas de la sécurité). De nos jours, vous pouvez également envisager d'utiliser xzau lieu de gzip.
James
45

Si vous utilisez ceci localement, utilisez la commande suivante pour sauvegarder votre base de données et compressez-la à l'aide de gzip:

mysqldump -u userName -p (passwordPrompt) yourDatabaseName | gzip -c > output.gz 

(Edit: clé -c fixe)

Dax
la source
2
Oui, c'est la solution la plus simple. Je l'utilise aussi.
Roman Snitko
2
Cela devrait probablement être gzip -c, non?
pilsetnieks
sympa ... mais comment puis-je rediriger stderr dans cette commande? Si j'ajoute 2> / dev / null, cela ne fonctionne plus. Et 2> / dev / null before pipe ne fonctionne pas non plus.
Nelson Teixeira
mysqldump -u nom_utilisateur -p (mot_de_passe_votre_base_de_données 2> / var / log / dump-errors | gzip -v> output.gz
undefine
im en utilisant comme mysqldump -u racine -p nom_base_données --routines | gzip -v> myfile.sql.gz ... je reçois un fichier .gz qui ne peut pas être téléchargé
Sushivam
18

Utilisez un tuyau nommé.

mkfifo mysql_pipe
gzip -9 -c < mysql_pipe > name_of_dump.gz &
mysqldump database > mysql_pipe 
rm mysql_pipe

Je l'utilise tout le temps, c'est génial.

http://en.wikipedia.org/wiki/Named_pipe

Jon Haddad
la source
6
James fait la même chose en 1 ligne.
Jon Haddad
15
..mais apprendre sur les pipes nommées en vaut la peine :-)
Tomasz Zieliński
mkfifo mysql_pipe; gzip -9 -c < mysql_pipe > name_of_dump.gz &; mysqldump database > mysql_pipe; rm mysql_pipelà, une ligne. Bien sûr, je garderais le tuyau et l’utiliserais à chaque fois.
d34dh0r53
15

J'ai écrit un script rapide pour aspirer une base de données mysql distante. Il utilise la compression mysql, gzip et ssh. Aspiré une base de données multi Go à un rythme incroyable.

    ssh -C user@host "mysqldump --opt --compress database <table> | gzip -9 -c" > outputfile.sql.gz

Un autre avantage est qu'il ne nécessite aucun espace libre sur le serveur de base de données source. Vous pouvez donc l'utiliser pour sauvegarder une base de données sur un serveur sans espace disque libre avant de procéder à l'élagage de vos données.

J'espère que ça aide quelqu'un.

Tony Dillon
la source
J'ai créé un script shell simple: #! / Bin / bash if [-z "$ 1"]; then echo "Utilisation: $ {0} [hôte] [utilisateur] [base de données] [fichier de sortie]" quitte par ailleurs HOST = $ 1 fi if [-z "$ 2"]; then echo "Utilisation: $ {0} $ {1} [utilisateur] [base de données] [fichier de sortie]" quitte par ailleurs USER = $ 2 fi if [-z "$ 3"]; then echo "Utilisation: $ {0} $ {1} $ {2} [base de données] [fichier de sortie]" exit DB = $ 3 fi if [-z "$ 4"]; then OUTFILE = "$ {DB} .sql.gz" sinon OUTFILE = $ 4 fi COMMAND = "ssh -C $ {USER} @ $ {HOST} \" mysqldump --opt $ {DB} | gzip -9 -c \ "> $ {OUTFILE}" ssh -C $ {USER} @ $ {HOST} "mysqldump --opt $ {DB} | gzip -9 -c"> $ {OUTFILE}
Tony Dillon
Deux de ces compressions sont inutiles: L'option de mysqldump compresse les données dans le processus du serveur et se décompresse immédiatement de nouveau (si mysqldump est exécuté sur le serveur de base de données lui-même). L'option -C de ssh active la compression gzip, ce qui gaspille d'autres cycles de la CPU car les données sont déjà gzippées à ce stade.
Matt.
5

Utilisez pvet surveillez le taux!

mysqldump prod_db -h dbslave | pv | gzip -c > prod_2012_08_20.dump.tgz

Ou, si vous connaissez la taille (3 Go), obtenez une estimation précise:

mysqldump prod_db -h dbslave | pv -s 3g | gzip -c > prod_2012_08_20.dump.tgz
Nouvelle Alexandrie
la source
4

Essaye ça:

mysqldump --all-databases --password=dbpassword | gzip -c | ssh user@servername "cat >/tmp/filename_of_your_choice.gz"

S'il vous plaît, pas que je ne suis en aucune façon bon à ces choses, je viens de combiner 2 options sur le Web en une seule.

Cela pourrait très bien être mieux d’une autre manière, mais c’est un modèle unique qui fonctionne pour moi.

Toutefois, il doit ssh.keysêtre installé et accepté si vous souhaitez l’utiliser dans des scripts crontabou similaires.

Charlie Candergart
la source
1
Bienvenue sur ServerFault. Cela me semble parfaitement raisonnable.
poussins
2

Vous pouvez faire comme:

mysqldump --add-drop-table -h dbhost -u dbuser -p dbname (tablename tablename ... ) | gzip -c > wp.sql.gz

par exemple

mysqldump --add-drop-table -h localhost -u root -p wordpress | gzip -c > wp.sql.gz

Min He
la source
1

J'ai travaillé sur ce script bash ci-dessous qui tente de rassembler tous les bons conseils que j'ai vus en matière de vidage / restauration avec mysql. Il est destiné aux opérations à distance.

Il suffit de reconfigurer les serveurs et d’essayer. :)

Les caractéristiques sont:

  • vous pouvez passer une liste de tables à dump (dump sélectif)
  • vous pouvez être invité à entrer des mots de passe (MySQL / SSH) ou à les définir dans des variables
  • la transmission réseau est gzippée
  • vous pouvez choisir de sauvegarder le dump compressé sur un serveur distant
  • vous pouvez réimporter le dump sur le serveur distant à la volée (pas de fichiers temporaires sur le serveur local / distant)
  • vous avez un retour visuel de ce qui se passe (grâce à echo et pv)
  • vous pouvez définir des variables mysql avant et après le processus de vidage

Ce qui a besoin d'amélioration:

  • vous devez passer une liste de tables (vous ne pouvez pas vider toutes les tables)
  • Le mot de passe MySQL est le même pour la source et la cible
  • vous devez attribuer manuellement PRIVILEGES (on dirait que MySQL ne le laisse pas faire à distance)
  • vous devez avoir installé sshpass
  • Certaines tables compressées innodb sont lentes à dump (peut être la faute de mysqldump)

Je partage ce script ici en espérant qu'il puisse être amélioré par la communauté. (mieux visualisé avec nano ou un autre éditeur qui colore le code)

--------------------------------- couper ici --------------- -------------------

#!/bin/bash
#set -x

#REQUIRED VARS
SOURCE_USER=root   #MySQL user
SOURCE_HOST=localhost
SOURCE_PASSWORD=yourmysqlpass  #optional
SOURCE_DBNAME=yourdbname
TARGET_HOST=192.168.1.2
TARGET_DBNAME=yourdbname
TARGET_SSHUSER=root
TARGET_SSHPASSWORD=yoursshpass  #optional
TABLES='table1 table2 table3 table4'
TARGET_DIR="/data/dumpfiles"
EXEC_ACTION_TEXT[0]='Reimport TABLES directly into remote MySQL database'
EXEC_ACTION_TEXT[1]='Backup gzipped data to TARGED_DIR on remote TARGET_HOST'
EXEC_ACTION=0

#print config
echo "---------------------------------"
echo " SOURCE_USER:    $SOURCE_USER (MySQL)"
if [ "SOURCE_PASSWORD" != "" ]; then
echo " SOURCE_PASSWORD:<present>        "; else
echo " SOURCE_PASSWORD:<to be asked>    "
fi
echo " SOURCE_HOST:    $SOURCE_HOST     "
echo " SOURCE_DBNAME:  $SOURCE_DBNAME   "
echo " TARGET_HOST:    $TARGET_HOST     "
echo " TARGET_DBNAME:  $TARGET_DBNAME   "
echo " TARGET_SSHUSER: $TARGET_SSHUSER  "
if [ "TARGET_SSHPASSWORD" != "" ]; then
echo " TARGET_SSHPASS: <present>     "; else
echo " TARGET_SSHPASS: <to be asked>    "
fi
echo " TABLES:         $TABLES          "
echo " EXEC_ACTION:    $EXEC_ACTION - ${EXEC_ACTION_TEXT[$EXEC_ACTION]}"
echo " TARGET_DIR:     $TARGET_DIR (only for action 1)"
echo "---------------------------------"
echo "PRESS <ENTER> to continue...";  read;  echo

#read the mysql password from command-line (SOURCE and TARGET uses the same password)
if [ "$SOURCE_PASSWORD" == "" ]; then
     echo -n "Type $SOURCE_USER password for MySQL servers: "; read -s SOURCE_PASSWORD; echo
fi
echo "Creating database $TARGET_DBNAME on $TARGET_HOST if not exists ... "
mysql \
--user=$SOURCE_USER \
--password=$SOURCE_PASSWORD \
--host=$TARGET_HOST \
--execute "create database if not exists $TARGET_DBNAME;"

echo '--------------------------------------------------------------------------------------'
echo "**** ATTENTION ****: execute this command on mysql server at  $TARGET_HOST :"
echo "GRANT ALL PRIVILEGES ON $TARGET_DBNAME.* TO '$SOURCE_USER'@'%' IDENTIFIED BY 'yourpass';"
echo '--------------------------------------------------------------------------------------'
echo "PRESS <ENTER> to continue...";  read;  echo

#read the password from command-line
if [ "$TARGET_SSHPASSWORD" == "" ]; then
     echo -n "Type the password for remote SSH Server (TARGET) ['$TARGET_SSHUSER'@'$TARGET_HOST']: "; read -s TARGET_SSHPASSWORD; echo
fi

for thistable in $TABLES
do
     case "$EXEC_ACTION" in
         0)
         thisaction="gunzip | mysql --user=$SOURCE_USER --password=$SOURCE_PASSWORD -D $TARGET_DBNAME"
         endmessage='remote reimporting has finished'
         ;;
         1)
         thisaction="cat > $TARGET_DIR/`date +%Y.%m.%d`-"$thistable".gz"
         endmessage="$thisaction has finished"
         ;;
         *)   echo "EXEC_ACTION=$EXEC_ACTION not supported" && exit 1
     esac

     echo "---------------------------------------------------------------------"
     echo "-- table $thistable"
     echo "---------------------------------------------------------------------"
     (
       echo -n "-- setting variables... " > /dev/stderr  #talk to user via stderr
       echo "SET AUTOCOMMIT=0; SET UNIQUE_CHECKS=0; SET FOREIGN_KEY_CHECKS=0;"
       echo -n "starting mysqldump... " > /dev/stderr
       mysqldump --opt --user=$SOURCE_USER --password=$SOURCE_PASSWORD --host=$SOURCE_HOST $SOURCE_DBNAME $thistable
       echo -n "done mysqldump, reseting variables... " > /dev/stderr
       echo "SET FOREIGN_KEY_CHECKS=1; SET UNIQUE_CHECKS=1; SET AUTOCOMMIT=1;"
       echo -n "commiting... " > /dev/stderr
       echo "COMMIT;"
       echo "done!" > /dev/stderr
     ) | \
     gzip -c -2 | \
     pv | \
     sshpass -p $TARGET_SSHPASSWORD ssh $TARGET_SSHUSER'@'$TARGET_HOST $thisaction
     echo $endmessage ' with exit status '$?
done
Fernando Fabreti
la source
0

Vous pouvez également stocker votre mot de passe dans un fichier de configuration et utiliser cette option --defaults-extra-file:

mysqldump --defaults-extra-file=mysqldump.cnf DataBaseName | gzip -c > DBOutputName.sql.gz

Le fichier de configuration peut ressembler à ceci:

[mysqldump]
host = localhost
user = username
password = "password"
linstar
la source