Temporärer SSH-Tunnel für Sicherungszwecke

11

Ich möchte ein Shell-Skript schreiben (derzeit mit Bash), um den Inhalt mehrerer MySQL-Schemas auf einem Remote-Server automatisch zu sichern. Der Remote-Server ist gesperrt, um nur den SSH-Zugriff zuzulassen. Daher muss ich einen SSH-Tunnel erstellen, bevor ich mit mysqldumpden verschiedenen Schemas arbeiten kann.

Ich kann einen Tunnel ohne Probleme erstellen, möchte ihn jedoch nach Abschluss des Datenbank-Dumps automatisch schließen können.

Derzeit macht mein Skript Folgendes:

/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

Wenn die Verbindung 600 Sekunden lang offen gehalten wird. Wenn jedoch einer der ersten Speicherauszüge länger dauert, wird die Verbindung geschlossen, bevor die anderen Speicherauszüge abgeschlossen sind. Ich möchte für jede Schemasicherung separate Dateien behalten (daher wird --databasesmysqldump vorerst vermieden).

Irgendwelche Vorschläge?

BenM
quelle

Antworten:

29

Sie müssen sich nicht um all das Tunneln kümmern :-).

Lassen Sie einfach mysqldump seine Daten über die SSH-Verbindung streamen:

ssh usr@host mysqldump -u dbuser -ppasswd my-database-name >dumpfile
sleske
quelle
1
+1 für das Ausweichen aus dem Problem. Dies setzt voraus, dass mysqldump auf dem Remote-Host verfügbar ist, und ich glaube, dass das Kennwort in der Prozessliste des Remote-Servers angezeigt wird. Wenn diese Dinge jedoch kein Problem darstellen, klingt dies nach einer viel besseren Lösung.
Mark
3
Als Antwort auf den Markierungskommentar "Markieren Sie den 6. Juli 09 um 16:34 Uhr" zum Kennwort in der Prozessliste des Remoteservers (ich habe nicht genug Ruf, um einen Kommentar hinzuzufügen): Sie können eine .my.cnf-Datei in der Startseite des Benutzers erstellen Verzeichnis auf dem Remote-Server und geben Sie dort das Passwort an: [client] password = "secret" Dann verwenden Sie einfach mysqldump (hier mit Komprimierung, um die Datenübertragung zu beschleunigen):$ ssh user@host "mysqldump foobar | gzip -9" | gzip -d > foobar.sql
Thomas Schuster
5

Fügen Sie die Option -N, die Option -f und den Schlafmodus 600 hinzu. Dadurch wird der Tunnel geöffnet, ohne ihn im Hintergrund auszuführen. Anschließend können Sie den Befehl mit & ausführen, die PID abrufen und den SSH-Prozess beenden, sobald die Jobs abgeschlossen sind.

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

(Ich habe dies mit Bash getestet - möglicherweise müssen Sie die Dinge für eine andere Shell ändern.)

Kennzeichen
quelle
4

Als geringfügige Abweichung von Sleskes Vorschlag können Sie die mysqldump-Ausgabe vor der Übertragung durch gzip leiten, um sie zu komprimieren:

ssh SSH-USER@SERVER mysqldump -u DB-USER -pDB-PASSWORD DB-NAME | gzip -c > DB-NAME.sql.gz
eethann
quelle
Ich vermute, dass dieser Befehl erst nach der Übertragung komprimiert wird. Möglicherweise müssen Sie das Bit "mysql ... | gzip" zitieren, damit die Pipe aus der Ferne ausgewertet wird
The Mighty Chris
3

Wie Sleske sagte, warum sollte man sich in diesem speziellen Fall die Mühe machen? Es gibt jedoch eine Lösung zur Steuerung eines SSH-Tunnels im allgemeinen Fall: Verwenden Sie eine Named Pipe. Erstellen Sie zuerst das Rohr wie folgt:

ssh -l remoteuser 208.77.188.166 mkfifo /tmp/PIPO

Dann schreiben Sie (Blockieren in die Pipe) in Ihr SSH, um den Tunnel zu erstellen:

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

Wenn Sie den Tunnel schließen möchten, lesen Sie einfach die Leitung:

ssh -l remoteuser 208.77.188.166 cat /tmp/PIPO

Et voilà!

Wazoox
quelle
2

So würde ich es schreiben,

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

Wo das Skript ist,

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

Schließlich kann das Archiv scpmit einem anderen Befehl zurückgesetzt werden.
Ja, ich habe weder Rohr noch Tunnel.

nik
quelle