mysqldump para um tar.gz

88

Geralmente, após despejar um banco de dados MySQL com o mysqldumpcomando, eu imediatamente tar / gzip o arquivo resultante. Estou procurando uma maneira de fazer isso em um comando:

Então a partir disso:

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

Para algo assim:

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

Ou ainda melhor (já que geralmente estou scp'ing o arquivo de despejo em outro servidor):

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

Estou executando o bash no debian.

pygorex1
fonte

Respostas:

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

Você não pode usar o tar em um pipe como este e nem precisa dele, pois está produzindo apenas um único arquivo. O tar só é útil se você tiver vários arquivos.

James
fonte
6
Você está certo sobre não precisar de alcatrão, mas você pode usá-lo no oleoduto, se precisar, commysqldump | tar cf - | gzip -c | ssh ... 'cat > file.tgz'
Darren Chamberlain
Isso realmente funciona? Tenho certeza de que o tar precisa de uma lista de nomes de arquivos para trabalhar.
James
2
Atualizei isso para funcionar localmente (não em um servidor ssh remoto) e uso um nome dinâmico com base na data, graças ao pôster e resposta originais! mysqldump --opt <database> | gzip -c | cat > $(date +%Y-%m-%d-%H.%M.%S).sql.gz
precisa saber é o seguinte
4
@electblake: você não precisa usar 'cat' se for local. Justgzip -c > $(date +%Y-%m-%d-%H.%M.%S).sql.gz
James
Apenas por diversão, você pode usar em netcatvez de canalizar para o ssh. Você economizará um pouco na sobrecarga de criptografia do ssh, se estiver sendo transferida por uma rede segura (ou se você não se importa com segurança). Hoje em dia você também pode considerar usar em xzvez de gzip.
James
45

Se você estiver executando isso localmente, use o seguinte comando para fazer backup do seu banco de dados e compactá-lo usando gzip:

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

(Editar: chave -c fixa)

Dax
fonte
2
Sim, esta é a solução mais simples. Eu também uso.
Roman Snitko
2
Provavelmente deveria ser gzip -c, certo?
Pilsetnieks
legal ... mas como redireciono o stderr neste comando? Se eu anexar 2> / dev / null, ele não funcionará mais. E 2> / dev / null antes do pipe também não funciona.
Nelson Teixeira
mysqldump -u nome_do_usuário -p (senhaPrompt) nome_do seu Banco de Dados 2> / var / log / dump-errors | gzip -v> output.gz
undefine
estou usando como mysqldump -u root -p nome do banco de dados - rotinas | gzip -v> myfile.sql.gz ... eu recebo uma parte .gz arquivo que não im capaz de baixar
Sushivam
18

Use um pipe nomeado.

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

Eu uso o tempo todo, é incrível.

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

Jon Haddad
fonte
6
James faz a mesma coisa em 1 linha.
Jon Haddad
15
..mas aprender sobre pipes nomeados vale a pena :-)
Tomasz Zieliński
mkfifo mysql_pipe; gzip -9 -c < mysql_pipe > name_of_dump.gz &; mysqldump database > mysql_pipe; rm mysql_pipelá, uma linha. É claro que eu mantinha o cachimbo por perto e o usava sempre.
D34dh0r53
15

Eu escrevi um script rápido para sugar um banco de dados mysql remoto. Ele usa compressão mysql, compressão gzip e ssh. Sugou um banco de dados com vários GB a uma taxa incrível.

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

Um benefício colateral é que ele não requer espaço livre no servidor de banco de dados de origem, para que você possa usá-lo para fazer backup de um banco de dados em um servidor com zero espaço em disco livre antes de remover os dados.

Espero que ajude alguém.

Tony Dillon
fonte
Eu criei um script de shell simples: #! / Bin / bash if [-z "$ 1"]; então ecoa "Uso: $ {0} [host] [usuário] [banco de dados] [outputFile]" exit else HOST = $ 1 fi se [-z "$ 2"]; em seguida, ecoa "Uso: $ {0} $ {1} [usuário] [banco de dados] [outputFile]" exit else USER = $ 2 fi se [-z "$ 3"]; em seguida, ecoa "Uso: $ {0} $ {1} $ {2} [banco de dados] [outputFile]" exit else DB = $ 3 fi se [-z "$ 4"]; então OUTFILE = "$ {DB} .sql.gz" else OUTFILE = $ 4 fi COMANDO = "ssh -C $ {USUÁRIO} @ $ {HOST} \" mysqldump --opt $ {DB} | gzip -9 -c \ "> $ {OUTFILE}" ssh -C $ {USER} @ $ {HOST} "mysqldump --opt $ {DB} | gzip -9 -c"> $ {OUTFILE}
Tony Dillon
Duas dessas compressões são inúteis: A opção mysqldump compacta os dados no processo do servidor e descompacta imediatamente novamente (se o mysqldump for executado no próprio servidor DB). A opção -C para ssh ativa a compactação gzip, que desperdiçará mais ciclos de CPU porque os dados já foram compactados nesse ponto.
MattW.
5

Use pve monitore a taxa!

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

Ou, se você souber o tamanho (3 GB), obtenha uma estimativa precisa:

mysqldump prod_db -h dbslave | pv -s 3g | gzip -c > prod_2012_08_20.dump.tgz
New Alexandria
fonte
4

Tente o seguinte:

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

Por favor, não que eu não seja nada bom nessas coisas, eu apenas combinei duas opções na Web em uma.

Pode muito bem ser melhor de alguma outra maneira, mas essa é uma linha que funciona para mim.

No entanto, ele precisa ssh.keysser instalado e aceito, se você quiser usá-lo em scripts crontabou similares.

Charlie Candergart
fonte
1
Bem-vindo ao ServerFault. Parece perfeitamente razoável para mim.
pintainhos
2

Você pode fazer como:

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

por exemplo

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

Min He
fonte
1

Eu tenho trabalhado neste script bash abaixo que tenta reunir todos os bons conselhos que eu vi quando se trata de despejar / restaurar com o mysql. É direcionado para operações remotas.

Apenas reconfigure os vars e experimente. :)

Os recursos são:

  • você pode passar uma lista de tabelas para despejar (despejo seletivo)
  • você pode ser solicitado a fornecer senhas (MySQL / SSH) ou defini-las em variáveis
  • transmissão de rede é compactada com gzip
  • você pode optar por salvar o dump compactado em gzip no servidor remoto
  • você pode reimportar o dump para o servidor remoto on-the-fly (sem arquivos temporários no servidor local / remoto)
  • você tem um feedback visual do que está acontecendo (graças ao eco e ao pv)
  • você pode definir variáveis ​​mysql antes e depois do processo de despejo

O que precisa ser aprimorado:

  • você precisa passar uma lista de tabelas (não é possível despejar todas as tabelas)
  • A senha do MySQL é a mesma para origem e destino
  • você precisa conceder privilégios manualmente (parece que o MySQL não deixa isso remotamente)
  • você precisa ter o sshpass instalado
  • algumas tabelas compactadas enormes do innodb demoram a despejar (pode ser culpa do mysqldump)

Compartilho esse script aqui, esperando que possa ser melhorado pela comunidade. (melhor visualizado com o nano ou outro editor que colore o código)

--------------------------------- corte aqui --------------- -------------------

#!/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
fonte
0

Você também pode armazenar sua senha em um arquivo de configuração e usar esta opção --defaults-extra-file:

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

O arquivo de configuração pode ficar assim:

[mysqldump]
host = localhost
user = username
password = "password"
linstar
fonte