Túnel SSH temporário para fins de backup

11

Eu gostaria de escrever um script de shell (atualmente usando o bash) para fazer backup automático do conteúdo de vários esquemas do MySQL em um servidor remoto. O servidor remoto está bloqueado para permitir apenas o acesso SSH, então eu tenho que criar um túnel SSH antes de executar mysqldumpnos vários esquemas.

Posso criar um túnel sem nenhum problema, mas gostaria de poder fechá-lo automaticamente após a conclusão do dump do banco de dados.

Atualmente, meu script está fazendo isso:

/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

Onde a conexão é mantida aberta por 600 segundos, obviamente, se um dos primeiros despejos demorar mais que isso, a conexão será fechada antes que os outros despejos sejam concluídos. Eu gostaria de reter arquivos separados para cada backup do esquema (para evitar o --databasesmysqldump por enquanto).

Alguma sugestão?

BenM
fonte

Respostas:

29

Você não precisa se preocupar com todo esse tunelamento :-).

Apenas deixe o mysqldump transmitir seus dados usando a conexão SSH:

ssh usr@host mysqldump -u dbuser -ppasswd my-database-name >dumpfile
sleske
fonte
1
+1 por evitar o problema. Isso requer que o mysqldump esteja disponível no host remoto e acredito que mostre a senha na lista de processos do servidor remoto, mas assumindo que essas coisas não são um problema, isso soa como uma solução muito melhor.
Mark
3
Em resposta às marcas do comentário "Mark 6 de julho de 2009 às 16:34" sobre a senha na lista de processos do servidor remoto (não tenho reputação suficiente para adicionar um comentário): Você pode criar um arquivo .my.cnf na página inicial dos usuários diretório no servidor remoto e especifique a senha: [client] password = "secret" Em seguida, basta usar o mysqldump (aqui com compactação para acelerar a transferência de dados):$ ssh user@host "mysqldump foobar | gzip -9" | gzip -d > foobar.sql
Thomas Schuster
5

Adicione a opção -N, a opção -f e o sleep 600, isso abrirá o túnel sem executá-lo em segundo plano. Em seguida, você pode executar o comando com &, obter o PID e interromper o processo ssh após a conclusão dos trabalhos.

/usr/bin/ssh -T -L 4444:127.0.0.1:3306 -l remoteuser 208.77.188.166 &
PID=$!
do_stuff
kill $PID

(Eu testei isso com o bash - pode ser necessário mudar as coisas para um shell diferente)

Marca
fonte
4

Uma pequena variação na sugestão de sleske, você pode canalizar a saída do mysqldump através do gzip para compactar antes da transferência:

ssh SSH-USER@SERVER mysqldump -u DB-USER -pDB-PASSWORD DB-NAME | gzip -c > DB-NAME.sql.gz
eethann
fonte
Eu suspeito que este comando não faz compressa até depois da transferência, você pode precisar de citar o "mysql ... | gzip" pouco para que o tubo fica avaliada remotamente
The Mighty Chris
3

Como disse sleske, por que se preocupar nesse caso em particular? No entanto, existe uma solução para controlar um túnel ssh no caso geral: use um pipe nomeado. Primeiro, crie o pipe assim:

ssh -l remoteuser 208.77.188.166 mkfifo /tmp/PIPO

Então você escreve (bloqueando o pipe) no seu ssh para criar o túnel:

/usr/bin/ssh -T -f -L 4444:127.0.0.1:3306 -l remoteuser 208.77.188.166 "echo T > /tmp/PIPO"

Quando você quiser fechar o túnel, basta ler o pipe:

ssh -l remoteuser 208.77.188.166 cat /tmp/PIPO

Et voilà!

wazoox
fonte
2

É assim que eu escreveria,

scp backup-db.sh [email protected]:/root/backups/
ssh [email protected] exec /root/backups/backup-db.sh

Onde está o script,

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

Finalmente, o arquivo morto pode ser scpeditado novamente com outro comando.
Sim, eu não cano ou túnel.

nik
fonte