Я хотел бы написать сценарий оболочки (в настоящее время использующий bash) для автоматического резервного копирования содержимого нескольких схем MySQL на удаленном сервере. Удаленный сервер заблокирован, чтобы разрешить доступ только по SSH, поэтому мне нужно создать туннель SSH перед запуском mysqldump
против различных схем.
Я могу создать туннель без каких-либо проблем, однако я хотел бы иметь возможность автоматически закрывать его после завершения дампа базы данных.
В настоящее время мой скрипт делает это:
/usr/bin/ssh -T -f -L 4444:127.0.0.1:3306 -l remoteuser 208.77.188.166 sleep 600
/usr/bin/mysqldump --compress -h 127.0.0.1 -P 4444 -u user -ppassword db1 | gzip > /root/backups/snapshot/db1.sql.gz
/usr/bin/mysqldump --compress -h 127.0.0.1 -P 4444 -u user -ppassword db2 | gzip > /root/backups/snapshot/db2.sql.gz
/usr/bin/mysqldump --compress -h 127.0.0.1 -P 4444 -u user -ppassword db3 | gzip > /root/backups/snapshot/db3.sql.gz
Если соединение остается открытым в течение 600 секунд, очевидно, однако, что если один из первых дампов занимает больше времени, то соединение закрывается до завершения других дампов. Я хотел бы сохранить отдельные файлы для каждой резервной копии схемы (чтобы избежать --databases
mysqldump на данный момент).
Какие-либо предложения?
Вам не нужно возиться со всем этим туннелированием :-).
Просто позвольте mysqldump передавать свои данные через соединение SSH:
ssh usr@host mysqldump -u dbuser -ppasswd my-database-name >dumpfile
Добавьте параметр -N, параметр -f и режим сна 600, это откроет туннель, не запуская его в фоновом режиме. Затем вы можете запустить команду с помощью &, получить PID, а затем убить процесс ssh после завершения заданий.
/usr/bin/ssh -T -L 4444:127.0.0.1:3306 -l remoteuser 208.77.188.166 &
PID=$!
do_stuff
kill $PID
(Я тестировал это с помощью bash - вам может потребоваться что-то изменить для другой оболочки)
Небольшое изменение предложения sleske, вы можете передать вывод mysqldump через gzip для сжатия перед передачей:
ssh SSH-USER@SERVER mysqldump -u DB-USER -pDB-PASSWORD DB-NAME | gzip -c > DB-NAME.sql.gz
Как сказал Слеске, зачем беспокоиться в данном конкретном случае? Однако есть решение для управления туннелем ssh в общем случае: использовать именованный канал. Сначала создайте такую трубу:
ssh -l remoteuser 208.77.188.166 mkfifo /tmp/PIPO
Затем вы пишете (блокировка канала) в своем ssh, чтобы создать туннель:
/usr/bin/ssh -T -f -L 4444:127.0.0.1:3306 -l remoteuser 208.77.188.166 "echo T > /tmp/PIPO"
Если вы хотите закрыть туннель, просто прочтите трубу:
ssh -l remoteuser 208.77.188.166 cat /tmp/PIPO
И вуаля!
Вот как я бы это написал,
scp backup-db.sh remoteuser@208.77.188.166:/root/backups/
ssh remoteuser@208.77.188.166 exec /root/backups/backup-db.sh
Где сценарий,
#!/bin/sh
# backup-db.sh
DUMPARGS=--compress -h 127.0.0.1 -P 4444 -u user -ppassword
BACKUP_PATH=/root/backups/snapshot
/usr/bin/mysqldump $DUMPARGS db1 | bzip2 > $BACKUP_PATH/db1.sql.bz2
/usr/bin/mysqldump $DUMPARGS db2 | bzip2 > $BACKUP_PATH/db2.sql.bz2
/usr/bin/mysqldump $DUMPARGS db3 | bzip2 > $BACKUP_PATH/db3.sql.bz2
Наконец, архив можно scp
ed вернулся с другой командой.
Да, я не трубу и не туннель.