mysqldump do tar.gz

88

Zwykle po zrzuceniu bazy danych MySQL mysqldump polecenia natychmiast tar / gzip wynikowy plik. Szukam sposobu, aby to zrobić za pomocą jednego polecenia:

Więc z tego:

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

Do czegoś takiego:

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

Lub nawet lepiej (ponieważ zwykle scp'uję plik zrzutu na inny serwer):

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

Używam bash na Debianie.

pygorex1
źródło

Odpowiedzi:

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

Nie możesz używać tar w potoku takim jak ten, i tak go nie potrzebujesz, ponieważ wyprowadzasz tylko jeden plik. tar jest użyteczny tylko wtedy, gdy masz wiele plików.

James
źródło
6
Masz rację, że nie potrzebujesz smoły, ale możesz ją wykorzystać w przygotowaniu, jeśli to zrobisz, zmysqldump | tar cf - | gzip -c | ssh ... 'cat > file.tgz'
Darren Chamberlain
Czy to naprawdę działa? Jestem prawie pewien, że tar potrzebuje listy nazw plików do pracy.
James
2
Zaktualizowałem to, aby działało lokalnie (nie na zdalnym serwerze ssh) oh, i używam dynamicznej nazwy opartej na dacie, dzięki oryginalnemu plakatowi i odpowiedzi. mysqldump --opt <database> | gzip -c | cat > $(date +%Y-%m-%d-%H.%M.%S).sql.gz
electblake
4
@electblake: nie musisz używać „cat”, jeśli jest lokalny. Tylkogzip -c > $(date +%Y-%m-%d-%H.%M.%S).sql.gz
James
Dla zabawy możesz użyć netcatzamiast sipowania. Możesz trochę zaoszczędzić na kosztach szyfrowania ssh, jeśli są one przesyłane przez bezpieczną sieć (lub nie martwisz się o bezpieczeństwo). W dzisiejszych czasach możesz również rozważyć użycie xzzamiast gzip.
James
45

Jeśli uruchamiasz to lokalnie, po prostu użyj następującego polecenia, aby wykonać kopię zapasową bazy danych i skompresować ją za pomocą gzip:

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

(Edycja: klawisz fixed-c)

Dax
źródło
2
Tak, to najprostsze rozwiązanie. Ja też tego używam.
Roman Snitko,
2
Prawdopodobnie powinno być gzip -c, prawda?
pilsetnieks
fajnie ... ale jak przekierować stderr w tym poleceniu? Jeśli dołączę 2> / dev / null, to już nie będzie działać. I 2> / dev / null przed potokiem też nie działa.
Nelson Teixeira,
mysqldump -u nazwa_użytkownika -p (hasłoPrompt) twoja_bazy_danych 2> / var / log / dump-error | gzip -v> output.gz
undefine
używam jak mysqldump -u root -p nazwa bazy danych - procedury | gzip -v> myfile.sql.gz ... dostaję plik .gz części, którego nie mogę pobrać
Sushivam
18

Użyj nazwanego potoku.

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

Używam go cały czas, jest niesamowity.

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

Jon Haddad
źródło
6
James robi to samo w 1 linii.
Jon Haddad
15
.. ale warto poznać nazwane rury :-)
Tomasz Zieliński
mkfifo mysql_pipe; gzip -9 -c < mysql_pipe > name_of_dump.gz &; mysqldump database > mysql_pipe; rm mysql_pipetam, jedna linia. Oczywiście zatrzymałbym fajkę i używałbym jej za każdym razem.
d34dh0r53
15

Napisałem szybki skrypt do wyssania zdalnej bazy danych mysql. Wykorzystuje kompresję mysql, gzip i kompresję ssh. W niesamowitym tempie wyssałem bazę danych o pojemności wielu GB.

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

Dodatkową korzyścią jest to, że nie wymaga wolnego miejsca na źródłowym serwerze bazy danych, więc można go użyć do wykonania kopii zapasowej bazy danych na serwerze z zerowym wolnym miejscem na dysku przed przystąpieniem do czyszczenia danych.

Mam nadzieję, że to komuś pomoże.

Tony Dillon
źródło
Stworzyłem prosty skrypt powłoki: #! / Bin / bash if [-z "$ 1"]; następnie echo „Użycie: $ {0} [host] [użytkownik] [baza danych] [plik wyjściowy]” exit else HOST = $ 1 fi, jeśli [-z "$ 2"]; następnie echo „Użycie: $ {0} $ {1} [użytkownik] [baza danych] [outputFile]" exit else USER = 2 $ fi, jeśli [-z "3 $"; następnie echo „Zastosowanie: $ {0} $ {1} $ {2} [baza danych] [plik wyjściowy]" exit else DB = 3 $ fi, jeśli [-z "4 $"; następnie OUTFILE = "$ {DB} .sql.gz" else 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
Dwie z tych kompresji są bezużyteczne: Opcja mysqldump kompresuje dane w procesie serwera i natychmiast dekompresuje ponownie (jeśli mysqldump jest uruchamiany na samym serwerze DB). Opcja -C polecenia ssh aktywuje kompresję gzip, co spowoduje marnowanie kolejnych cykli procesora, ponieważ dane są już w tym momencie zgzipowane.
MattW.
5

Używaj pvi monitoruj tempo!

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

Lub, jeśli znasz rozmiar (3 GB), uzyskaj dokładne oszacowanie:

mysqldump prod_db -h dbslave | pv -s 3g | gzip -c > prod_2012_08_20.dump.tgz
Nowa Aleksandria
źródło
4

Spróbuj tego:

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

Proszę, nie jestem w żaden sposób dobry w tych sprawach, po prostu połączyłem 2 opcje w sieci w jedną.

Może być lepiej w inny sposób, ale jest to jedna linijka, która działa dla mnie.

Jednak wymaga ssh.keysinstalacji i akceptacji, jeśli chcesz używać go w skryptach crontablub w podobny sposób.

Charlie Candergart
źródło
1
Witamy w ServerFault. Dla mnie wygląda to całkowicie rozsądnie.
pisklęta
2

Możesz zrobić jak:

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

na przykład

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

Min
źródło
1

Pracowałem nad tym skryptem bash poniżej, który próbuje zebrać wszystkie dobre porady, które widziałem, jeśli chodzi o zrzut / przywracanie z mysql. Jest ukierunkowany na operacje zdalne.

Po prostu ponownie skonfiguruj vars i spróbuj. :)

Funkcje to:

  • możesz przekazać listę tabel do zrzutu (zrzut selektywny)
  • możesz zostać zapytany o hasło (MySQL / SSH) lub ustawić je w zmiennych
  • transmisja sieciowa jest zgzipowana
  • możesz zdecydować się na zapisanie zrzutu gzipped na zdalnym serwerze
  • możesz ponownie importować zrzut na zdalny serwer w locie (bez plików tymczasowych na lokalnym / zdalnym serwerze)
  • masz wizualną informację zwrotną o tym, co się dzieje (dzięki echu i PV)
  • możesz ustawić zmienne mysql przed i po procesie zrzutu

Co wymaga poprawy:

  • musisz przekazać listę tabel (nie mogę zrzucić wszystkich tabel)
  • Hasło MySQL jest takie samo dla źródła i celu
  • musisz UDZIELIĆ UPRAWNIEŃ (wygląda na to, że MySQL nie pozwala na to zdalnie)
  • musisz mieć zainstalowany sshpass
  • niektóre skompresowane tabele innodb wolno się zrzutu (może to być wina mysqldump)

Udostępniam ten skrypt tutaj, mając nadzieję, że może on zostać ulepszony przez społeczność. (najlepiej oglądać w nano lub innym edytorze, który koloruje kod)

--------------------------------- przetnij tutaj --------------- -------------------

#!/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
źródło
0

Możesz również zapisać swoje hasło w pliku konfiguracyjnym i użyć tej opcji - domyślny plik-dodatkowy:

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

Plik konfiguracyjny może wyglądać następująco:

[mysqldump]
host = localhost
user = username
password = "password"
linstar
źródło