mysqldump đến một tar.gz


88

Thông thường sau khi kết xuất cơ sở dữ liệu MySQL bằng mysqldumplệnh I ngay lập tức tar / gzip tệp kết quả. Tôi đang tìm cách để làm điều này trong một lệnh:

Vì vậy, từ đây:

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

Để một cái gì đó như thế này:

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

Hoặc thậm chí tốt hơn (vì tôi thường quét tệp kết xuất sang máy chủ khác):

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

Tôi đang chạy bash trên debian.

Câu trả lời:


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

Bạn không thể sử dụng tar trong một đường ống như thế này và dù sao bạn cũng không cần nó, vì bạn chỉ xuất ra một tệp duy nhất. tar chỉ hữu ích nếu bạn có nhiều tập tin.


6
Bạn đúng về việc không cần tar, nhưng bạn có thể sử dụng nó trong đường ống nếu bạn đã làm, vớimysqldump | tar cf - | gzip -c | ssh ... 'cat > file.tgz'
Darren Chamberlain

Điều đó thực sự làm việc? Tôi khá chắc chắn tar cần một danh sách tên tập tin để làm việc.
James

2
Tôi đã cập nhật cái này để làm việc cục bộ (không phải trên máy chủ ssh từ xa) oh, và tôi sử dụng một tên động dựa trên ngày, nhờ vào poster và người trả lời ban đầu! mysqldump --opt <database> | gzip -c | cat > $(date +%Y-%m-%d-%H.%M.%S).sql.gz
electblake

4
@electblake: bạn không cần phải sử dụng 'mèo' nếu là địa phương. Chỉ cầngzip -c > $(date +%Y-%m-%d-%H.%M.%S).sql.gz
James

Chỉ để cho vui, bạn có thể sử dụng netcatthay vì đường ống đến ssh. Bạn sẽ tiết kiệm một chút cho chi phí mã hóa của ssh, nếu nó được chuyển qua mạng an toàn (hoặc bạn không quan tâm đến bảo mật). Ngày nay bạn cũng có thể cân nhắc sử dụng xzthay vì gzip.
James

45

Nếu bạn đang chạy cục bộ này, chỉ cần sử dụng lệnh sau để sao lưu cơ sở dữ liệu của bạn và nén nó bằng gzip:

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

(Chỉnh sửa: phím -c cố định)


2
Vâng, đây là giải pháp đơn giản nhất. Tôi cũng dùng nó
Roman Snitko

2
Có lẽ nên như vậy gzip -c, phải không?
pilsetnieks

tốt ... nhưng làm thế nào để tôi chuyển hướng stderr trong lệnh này? Nếu tôi thêm 2> / dev / null thì nó không hoạt động nữa. Và 2> / dev / null trước khi đường ống cũng không hoạt động.
Nelson Teixeira

mysqldump -u userName -p (passwordPrompt) yourDatabaseName 2> / var / log / dump-error | gzip -v> output.gz
xác định

tôi đang sử dụng như mysqldump -u root -p databasename --routines | gzip -v> myfile.sql.gz ... tôi nhận được một phần .gz mà tôi không thể tải xuống
Sushivam

18

Sử dụng một đường ống được đặt tên.

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

Tôi sử dụng nó mọi lúc, thật tuyệt vời.

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


6
James làm điều tương tự trong 1 dòng.
Jon Haddad

15
..nhưng tìm hiểu về các đường ống được đặt tên là đáng giá :-)
Tomasz Zieliński

mkfifo mysql_pipe; gzip -9 -c < mysql_pipe > name_of_dump.gz &; mysqldump database > mysql_pipe; rm mysql_pipeở đó, một dòng. Tất nhiên tôi sẽ giữ đường ống xung quanh và sử dụng nó mỗi lần.
d34dh0r53

15

Tôi đã viết một kịch bản nhanh để hút một cơ sở dữ liệu mysql từ xa. Nó sử dụng nén mysql, gzip và ssh nén. Hút một cơ sở dữ liệu nhiều GB với tốc độ đáng kinh ngạc.

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

Một lợi ích phụ là nó không yêu cầu không gian trống trên máy chủ cơ sở dữ liệu nguồn, vì vậy bạn có thể sử dụng nó để sao lưu cơ sở dữ liệu trên máy chủ có không gian đĩa trống bằng không trước khi tiến hành cắt xén dữ liệu của bạn.

Hy vọng nó sẽ giúp được ai đó.


Tôi đã tạo một tập lệnh shell đơn giản: #! / Bin / bash nếu [-z "$ 1"]; sau đó lặp lại "Cách sử dụng: $ {0} [máy chủ] [người dùng] [cơ sở dữ liệu] [outputFile]" thoát khác HOST = $ 1 fi nếu [-z "$ 2"]; sau đó lặp lại "Cách sử dụng: $ {0} $ {1} [người dùng] [cơ sở dữ liệu] [outputFile]" thoát khác USER = $ 2 fi nếu [-z "$ 3"]; sau đó lặp lại "Cách sử dụng: $ {0} $ {1} $ {2} [cơ sở dữ liệu] [outputFile]" thoát khác DB = $ 3 fi nếu [-z "$ 4"]; sau đó OUTFILE = "$ {DB} .sql.gz" khác OUTFILE = $ 4 fi ĐIỀU = "ssh -C $ {USER} @ $ {HOST} \" mysqldump --opt $ {DB} | gzip -9 -c \ "> $ {OUTFILE}" ssh -C $ {USER} @ $ {HOST} "mysqldump --opt $ {DB} | gzip -9 -c"> $ {OUTFILE}
Tony Dillon

Hai trong số các lần nén đó là vô ích: Tùy chọn mysqldump nén dữ liệu trong quy trình máy chủ và ngay lập tức giải nén lại (nếu mysqldump chạy trên chính máy chủ DB). Tùy chọn -C để ssh kích hoạt nén gzip, điều này sẽ làm lãng phí thêm chu kỳ CPU vì dữ liệu đã được nén vào thời điểm đó.
MattW.

5

Sử dụng pvvà theo dõi tỷ lệ!

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

Hoặc, nếu bạn biết kích thước (3 GB), hãy ước tính chính xác:

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

4

Thử đi:

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

Xin lưu ý rằng tôi không giỏi trong những điều này, tôi chỉ kết hợp 2 tùy chọn trên web thành một.

Nó có thể rất tốt theo một cách khác nhưng đây là một lớp lót phù hợp với tôi.

Tuy nhiên, nó đòi hỏi ssh.keysphải được cài đặt và chấp nhận nếu bạn muốn sử dụng nó trong các tập lệnh hoặc crontabhoặc tương tự.


1
Chào mừng bạn đến với ServerFault. Nó trông hoàn toàn hợp lý với tôi.
gà con

2

Bạn có thể làm như:

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

ví dụ

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


1

Tôi đã làm việc với tập lệnh bash bên dưới này để cố gắng kết hợp tất cả các lời khuyên tốt mà tôi đã thấy khi nói đến kết xuất / khôi phục với mysql. Nó được nhắm mục tiêu vào các hoạt động từ xa.

Chỉ cần điều chỉnh lại vars và thử nó. :)

Các tính năng là:

  • bạn có thể chuyển một danh sách các bảng để kết xuất (kết xuất có chọn lọc)
  • bạn có thể được nhắc nhập mật khẩu (MySQL / SSH) hoặc đặt chúng trong các biến
  • truyền mạng được nén
  • bạn có thể chọn lưu kết xuất được nén vào máy chủ từ xa
  • bạn có thể nhập lại kết xuất vào máy chủ từ xa một cách nhanh chóng (không có tệp tạm thời trên máy chủ cục bộ / từ xa)
  • bạn có phản hồi trực quan về những gì đang xảy ra (nhờ echo và pv)
  • bạn có thể đặt các biến mysql trước và sau quá trình kết xuất

Những gì cần cải thiện:

  • bạn cần phải vượt qua một danh sách các bảng (không thể kết xuất tất cả các bảng)
  • Mật khẩu MySQL giống nhau cho nguồn và đích
  • bạn cần phải CẤP RIÊNG TƯ theo cách thủ công (có vẻ như MySQL không cho phép làm điều đó một cách đơn giản)
  • bạn cần phải cài đặt sshpass
  • một số bảng nén khổng lồ của innodb bị chậm đổ (có thể là lỗi của mysqldump)

Tôi chia sẻ kịch bản này ở đây với hy vọng nó có thể được cải thiện bởi cộng đồng. (được xem tốt nhất với nano hoặc trình chỉnh sửa khác tô màu mã)

--------------------------------- cắt ở đây --------------- -------------------

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

Bạn cũng có thể lưu trữ mật khẩu của mình trong một tệp cấu hình và sử dụng tùy chọn này --defaults-Extra-file:

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

Các tập tin cấu hình có thể trông như thế này:

[mysqldump]
host = localhost
user = username
password = "password"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.