mysqldump на tar.gz


88

Обычно после сброса базы данных MySQL с помощью mysqldumpкоманды я немедленно выполняю tar / gzip результирующего файла. Я ищу способ сделать это в одной команде:

Итак, из этого:

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

Чтобы что-то вроде этого:

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

Или даже лучше (поскольку я обычно копирую файл дампа на другой сервер):

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

Я использую bash на Debian.

Ответы:


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

Вы не можете использовать tar в таком канале, и он вам все равно не нужен, поскольку вы выводите только один файл. tar полезен только если у вас есть несколько файлов.


6
Вы правы , не нуждаясь деготь, но вы можете использовать его в трубопроводе , если вы сделали, сmysqldump | tar cf - | gzip -c | ssh ... 'cat > file.tgz'
Даррен Чемберлен

Это на самом деле работает? Я уверен, что tar нужен список имен файлов для работы.
Джеймс

2
Я обновил это, чтобы работать локально (не на удаленном ssh-сервере), и я использую динамическое имя, основанное на дате, благодаря оригинальному постеру и ответчику! mysqldump --opt <database> | gzip -c | cat > $(date +%Y-%m-%d-%H.%M.%S).sql.gz
Electblake

4
@electblake: вам не нужно использовать 'cat', если он локальный. Простоgzip -c > $(date +%Y-%m-%d-%H.%M.%S).sql.gz
Джеймс

Просто для удовольствия, вы можете использовать netcatвместо пайпинга ssh. Вы немного сэкономите на издержках шифрования ssh, если он передается по защищенной сети (или вас не волнует безопасность). В настоящее время вы также можете рассмотреть возможность использования xzвместо gzip.
Джеймс

45

Если вы выполняете это локально, просто используйте следующую команду для резервного копирования вашей базы данных и архивирования ее с помощью gzip:

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

(Изменить: исправлен ключ -c)


2
Да, это самое простое решение. Я тоже этим пользуюсь.
Роман Снитко

2
Наверное, должно быть gzip -c, верно?
pilsetnieks

хорошо ... но как мне перенаправить stderr в этой команде? Если я добавлю 2> / dev / null, он больше не будет работать. И 2> / dev / null до pipe тоже не работает.
Нельсон Тейшейра

mysqldump -u userName -p (passwordPrompt) yourDatabaseName 2> / var / log / dump-errors | GZIP -v> output.gz
Undefine

я использую как mysqldump -u root -p имя_базы данных --routines | gzip -v> myfile.sql.gz ... я получаю часть файла .gz, который я не могу скачать
Сушивам

18

Используйте именованную трубу.

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

Я использую это все время, это круто.

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


6
Джеймс делает то же самое в 1 строке.
Джон Хаддад

15
... но изучение именованных каналов того стоит :-)
Томаш Зелиньски

mkfifo mysql_pipe; gzip -9 -c < mysql_pipe > name_of_dump.gz &; mysqldump database > mysql_pipe; rm mysql_pipeтам одна строка. Конечно, я бы держал трубку и использовал ее каждый раз.
d34dh0r53

15

Я написал быстрый скрипт для удаления удаленной базы данных MySQL. Он использует сжатие mysql, gzip и ssh. Всасывал базу данных в несколько ГБ с невероятной скоростью.

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

Дополнительным преимуществом является то, что для него не требуется свободного места на исходном сервере баз данных, поэтому вы можете использовать его для резервного копирования базы данных на сервере с нулевым свободным дисковым пространством, прежде чем приступать к удалению данных.

Надеюсь, это кому-нибудь поможет.


Я создал простой сценарий оболочки: #! / Bin / bash if [-z "$ 1"]; затем выведите «Usage: $ {0} [host] [user] [database] [outputFile]» exit else HOST = $ 1 fi if [-z "$ 2"]; затем выведите «Usage: $ {0} $ {1} [user] [database] [outputFile]» exit else USER = $ 2 fi if [-z "$ 3"]; затем выведите «Usage: $ {0} $ {1} $ {2} [database] [outputFile]» exit else DB = $ 3 fi if [-z "$ 4"]; then 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}
Тони Диллон

Два из этих сжатий бесполезны: опция mysqldump сжимает данные в процессе сервера и немедленно снова распаковывается (если mysqldump запускается на самом сервере БД). Опция -C для ssh активирует сжатие gzip, что приводит к потере дополнительных циклов ЦП, поскольку данные уже сжаты в этот момент.
MattW.

5

Используйте pvи следите за скоростью!

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

Или, если вы знаете размер (3 ГБ), получите точную оценку:

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

4

Попробуй это:

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

Пожалуйста, заметьте, что я ни в чем не разбираюсь, я просто объединил 2 варианта в Интернете в один.

Вполне может быть, лучше чем-то другим, но это одна строка, которая мне подходит.

Однако его необходимо ssh.keysустановить и принять, если вы хотите использовать его в сценариях crontabили тому подобное.


1
Добро пожаловать в ServerFault. Это выглядит вполне разумно для меня.
цыплята

2

Вы можете сделать как:

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

например

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


1

Я работал над этим bash-скриптом ниже, который пытается собрать воедино все полезные советы, которые я видел, когда дело доходит до дампа / восстановления с помощью mysql. Он ориентирован на удаленные операции.

Просто перенастройте Vars и попробуйте. :)

Особенности:

  • Вы можете передать список таблиц для дампа (выборочный дамп)
  • вам могут быть предложены пароли (MySQL / SSH) или установить их в переменных
  • передача по сети происходит
  • Вы можете сохранить GZIP-дамп на удаленном сервере.
  • вы можете импортировать дамп на удаленный сервер на лету (нет временных файлов на локальном / удаленном сервере)
  • у вас есть визуальная обратная связь о том, что происходит (благодаря echo и pv)
  • Вы можете установить переменные mysql до и после процесса дампа

Что нуждается в улучшении:

  • вам нужно передать список таблиц (не могу сбросить все таблицы)
  • Пароль MySQL одинаков для исходного и целевого
  • вам нужно выдавать привилегии вручную (похоже, MySQL не позволяет делать это remotelly)
  • вам нужно установить sshpass
  • некоторые огромные сжатые таблицы innodb медленно сбрасываются (возможно, ошибка mysqldump)

Я делюсь этим сценарием здесь, надеясь, что он может быть улучшен сообществом. (лучше всего смотреть с нано или другим редактором, который раскрашивает код)

--------------------------------- отрезать здесь --------------- -------------------

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

0

Вы также можете сохранить свой пароль в конфигурационном файле и использовать эту опцию --defaults-extra-file:

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

Файл конфигурации может выглядеть так:

[mysqldump]
host = localhost
user = username
password = "password"
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.