Ich habe eine Symfony-Anwendung mit einer InnoDB-Datenbank von ~ 2 GB mit 57 Tabellen. Der Großteil der Datenbankgröße befindet sich in einer einzelnen Tabelle (~ 1,2 GB). Ich verwende derzeit mysqldump, um die Datenbank jede Nacht zu sichern.
Aufgrund meiner Comcast-Verbindung tritt häufig eine Zeitüberschreitung auf, wenn ich einen Dump manuell ausführe, bevor der Dump abgeschlossen ist, sodass ich den Dump erneut ausführen muss. [Ich führe derzeit einen Cron aus, der den Dump jeden Abend ausführt. Dies ist nur für Dumps, die ich manuell ausführe.]
Gibt es eine Möglichkeit, die Speicherauszüge für das Problem mit dem Verbindungszeitlimit zu beschleunigen, aber auch die Zeit zu begrenzen, in der der Server mit diesem Prozess beschäftigt ist?
Übrigens arbeite ich derzeit daran, die Größe der gesamten Datenbank zu reduzieren, um dieses Problem zu beheben.
Der größte Engpass im Dump wie diesem ist die Laufwerks-E/A. Sie lesen eine Menge Daten und schreiben sie erneut. Sie können dies auf verschiedene Arten beschleunigen:
gzip
oder ähnliches weiter. Dies reduziert den Schreibaufwand (reduzieren Sie also die Gesamtlast IO und die Kopfbewegung) auf Kosten einer gewissen CPU-Zeit (für die Sie möglicherweise viel Zeit zur Verfügung haben) diese Zeiten sowieso).--quick
verwenden, um die Auswirkungen der Sicherung großer Tabellen auf RAM) zu verringern.Möglicherweise beheben Sie jedoch das falsche Problem: Es ist möglicherweise einfacher, die Verbindungsabbrüche zu beheben (obwohl die Reduzierung der durch Ihre Sicherungen verursachten E/A-Belastung dazu beiträgt, die Auswirkungen auf andere Benutzer zu verringern, lohnt es sich trotzdem, dies zu versuchen). Könnten Sie Ihre manuellen Sicherungen über Bildschirm (oder ähnliche Tools wie tmux ) ausführen? Auf diese Weise können Sie, wenn Ihre Verbindung zum Server unterbrochen wird, die Verbindung einfach wiederherstellen und erneut mit der Sitzung screen
verbinden, ohne dass Prozesse unterbrochen werden.
Wenn Sie die Daten direkt über die Verbindung senden (dh Sie führen mysqldump auf Ihrem lokalen Computer für eine entfernte Datenbank aus, sodass der Speicherauszug lokal angezeigt wird), sollten Sie den Speicherauszug möglicherweise zuerst auf dem Server ausführen, nach Bedarf komprimieren und dann übertragen die Daten über das Netzwerk mit einem Tool (z. B. rsync
), das Teilübertragungen unterstützt, sodass Sie die Übertragung fortsetzen können (anstatt sie neu zu starten), wenn ein Verbindungsabbruch sie unterbricht.
Als Teil Ihrer "Reduzierung der Größe der Gesamtdatenbank zur Behebung dieses Problems" würde ich vermuten, dass sich ein großer Teil Ihrer Daten nicht ändert. Möglicherweise können Sie einen großen Teil der 1,2 GB von dieser Haupttabelle in eine andere verschieben und diesen von denjenigen entfernen, die vom Aufruf mysqldump
kopiert wurden. Sie müssen diese Daten nicht jedes Mal sichern, wenn sie sich nie ändern. Das Aufteilen von Daten zwischen Tabellen und Datenbanken auf diese Weise wird normalerweise als Datenpartitionierung bezeichnet und ermöglicht es Ihnen auch, die Daten- und E/A-Last auf mehrere Laufwerke zu verteilen. High-End-Datenbanken unterstützen die automatische Partitionierung. In MySQL müssen Sie dies jedoch wahrscheinlich manuell tun und Ihre Datenzugriffsschicht ändern, um dies zu berücksichtigen.
Abweichend vom Thema für diese Site (daher sollten Sie sich wahrscheinlich an ServerFault oder SuperUser wenden, um zu fragen, ob Sie weitere Details benötigen): Wenn Sie aufgrund von Inaktivität scheinbar Verbindungen verlieren, überprüfen Sie die Optionen auf Ihrem SSH-Server und SSH-Client Stellen Sie sicher, dass Keep-Alive-Pakete aktiviert sind und häufig genug gesendet werden. Wenn Sie sehen, dass die Verbindung unterbrochen wird, auch wenn die Verbindung aktiv ist, können Sie auch versuchen, OpenVPN oder ähnliches zum Umbrechen der Verbindung zu verwenden. Es sollte ein kurzes Löschen behandelt werden, sogar ein vollständiges Löschen, wenn Ihre gesamte Verbindung einige Sekunden lang unterbrochen ist, z Server nicht bemerken.
EINBLICK IN BACKUPS MIT mysqldump
IMHO Backups zu machen ist eher eine Kunstform geworden, wenn man genau weiß, wie man es angeht
Sie haben Optionen
Option 1: mysqldump eine ganze mysql-Instanz
Dies ist die einfachste, das Kinderspiel !!!
mysqldump -h... -u... -p... --hex-blob --routines --triggers --all-databases | gzip > MySQLData.sql.gz
Alles in einer Datei geschrieben: Tabellenstrukturen, Indizes, Trigger, gespeicherte Prozeduren, Benutzer, verschlüsselte Passwörter. Andere mysqldump-Optionen können auch verschiedene Arten von INSERT-Befehlen, Protokolldateien und Positionskoordinaten aus Binärprotokollen, Datenbankerstellungsoptionen, Teildaten (Option --where) usw. exportieren.
Option 2: mysqldump separate Datenbanken in separate Datendateien
Beginnen Sie mit der Erstellung einer Liste von Datenbanken (2 Techniken, um dies zu tun)
Technik 1
mysql -h... -u... -p... -A --skip-column-names -e"SELECT schema_name FROM information_schema.schemata WHERE schema_name NOT IN ('information_schema','mysql')" > ListOfDatabases.txt
Technik 2
mysql -h... -u... -p... -A --skip-column-names -e"SELECT DISTINCT table_schema FROM information_schema.tables WHERE table_schema NOT IN ('information_schema','mysql')" > ListOfDatabases.txt
Technik 1 ist der schnellste Weg. Technik 2 ist die sicherste und sicherste. Technik 2 ist besser, da Benutzer manchmal Ordner für allgemeine Zwecke in/var/lib/mysql (Datenverzeichnis) erstellen, die nicht datenbankbezogen sind. Das Informationsschema würde den Ordner als Datenbank in der Tabelle information_schema.schemata registrieren. Technik 2 würde Ordner umgehen, die keine MySQL-Daten enthalten.
Sobald Sie die Liste der Datenbanken zusammengestellt haben, können Sie die Liste durchlaufen und sie mysqldumpen, auch parallel, wenn dies gewünscht wird.
for DB in `cat ListOfDatabases.txt`
do
mysqldump -h... -u... -p... --hex-blob --routines --triggers ${DB} | gzip > ${DB}.sql.gz &
done
wait
Wenn zu viele Datenbanken gleichzeitig gestartet werden können, sichern Sie sie jeweils 10 Mal parallel:
COMMIT_COUNT=0
COMMIT_LIMIT=10
for DB in `cat ListOfDatabases.txt`
do
mysqldump -h... -u... -p... --hex-blob --routines --triggers ${DB} | gzip > ${DB}.sql.gz &
(( COMMIT_COUNT++ ))
if [ ${COMMIT_COUNT} -eq ${COMMIT_LIMIT} ]
then
COMMIT_COUNT=0
wait
fi
done
if [ ${COMMIT_COUNT} -gt 0 ]
then
wait
fi
Option 3: mysqldump separate Tabellen in separate Datendateien
Erstellen Sie zunächst eine Liste mit Tabellen
mysql -h... -u... -p... -A --skip-column-names -e"SELECT CONCAT(table_schema,'.',table_name) FROM information_schema.tables WHERE table_schema NOT IN ('information_schema','mysql')" > ListOfTables.txt
Speichern Sie dann alle Tabellen in 10er-Gruppen
COMMIT_COUNT=0
COMMIT_LIMIT=10
for DBTB in `cat ListOfTables.txt`
do
DB=`echo ${DBTB} | sed 's/\./ /g' | awk '{print $1}'`
TB=`echo ${DBTB} | sed 's/\./ /g' | awk '{print $2}'`
mysqldump -h... -u... -p... --hex-blob --triggers ${DB} ${TB} | gzip > ${DB}_${TB}.sql.gz &
(( COMMIT_COUNT++ ))
if [ ${COMMIT_COUNT} -eq ${COMMIT_LIMIT} ]
then
COMMIT_COUNT=0
wait
fi
done
if [ ${COMMIT_COUNT} -gt 0 ]
then
wait
fi
Option 4: BENUTZEN SIE IHRE IMAGINATION
Probieren Sie Variationen der oben genannten Optionen sowie Techniken für saubere Schnappschüsse aus
Beispiele
[~ # ~] Einschränkung [~ # ~]
Nur Option 1 bringt alles. Der Nachteil ist, dass auf diese Weise erstellte mysqldumps nur in dieselbe Majot-Release-Version von mysql neu geladen werden können, mit der der mysqldump generiert wurde. Mit anderen Worten, ein mysqldump aus einer MySQL 5.0-Datenbank kann nicht in 5.1 oder 5.5 geladen werden. Der Grund ? Das MySQL-Schema unterscheidet sich grundlegend zwischen den Hauptversionen.
In den Optionen 2 und 3 werden Benutzernamen und Kennwörter nicht gespeichert.
Hier ist die allgemeine Methode zum Speichern der SQL-Zuschüsse für Benutzer, die lesbar und portabler ist
mysql -h... -u... -p... --skip-column-names -A -e"SELECT CONCAT('SHOW GRANTS FOR ''',user,'''@''',Host,''';') FROM mysql.user WHERE user<>''" | mysql -h... -u... -p... --skip-column-names -A | sed 's/$/;/g' > MySQLGrants.sql
Option 3 speichert die gespeicherten Prozeduren nicht, sodass Sie Folgendes tun können
mysqldump -h... -u... -p... --no-data --no-create-info --routines > MySQLStoredProcedures.sql &
Ein weiterer Punkt, der beachtet werden sollte, betrifft InnoDB. Wenn Sie über einen großen InnoDB-Pufferpool verfügen, ist es sinnvoll, diesen so gut wie möglich zu leeren, bevor Sie Sicherungen durchführen. Andernfalls verbringt MySQL die Zeit damit, Tabellen mit übrig gebliebenen schmutzigen Seiten aus dem Pufferpool zu leeren. Folgendes schlage ich vor:
Führen Sie diesen SQL-Befehl ca. 1 Stunde vor dem Ausführen der Sicherung aus
SET GLOBAL innodb_max_dirty_pages_pct = 0;
In MySQL 5.5 ist standardmäßig innodb_max_dirty_pages_pct 75. In MySQL 5.1 und zurück ist standardmäßig innodb_max_dirty_pages_pct 90. Wenn Sie innodb_max_dirty_pages_pct auf 0 setzen, wird das Löschen schmutziger Seiten auf die Festplatte beschleunigt. Dies verhindert oder verringert zumindest die Auswirkungen der Bereinigung unvollständiger zweiphasiger Festschreibungen von InnoDB-Daten, bevor ein mysqldump für InnoDB-Tabellen ausgeführt wird.
FINAL Word ON mysqldump
Die meisten Leute scheuen mysqldump zugunsten anderer Tools und diese Tools sind in der Tat gut.
Solche Werkzeuge umfassen
Wenn Sie den Geist eines echten MySQL-DBA haben, können Sie mysqldump annehmen und die vollständige Meisterschaft darüber erlangen, die erreicht werden kann. Mögen alle Ihre Backups Ihre Fähigkeiten als MySQL-DBA widerspiegeln .
Schauen Sie sich MySQL Replication Master to Slave an. Sie können die Datenbank des Masters auf einen anderen Datenbankserver mit derselben Datenbank klonen. Dies schließt die Master- und Slave-Identitäten ein. Slave erstellt selbst die exakte Kopie des Master-Datenbankservers und/oder seiner Datenbanken. Es kann eine Eins-Eins, Eins-Viele, Viele-Eins-Beziehung zwischen Master (s) und Slave (s) geben.
Der Slave liest kontinuierlich das Binärprotokoll am Master (das Bin-Protokoll speichert die auf dem Master-Datenbankserver geschriebenen Abfragen) und erhält Eingaben an seinen Slave-Datenbankserver. (Dies bedeutet, dass Ihre Master-Datenbank überhaupt nicht betroffen ist.)
Die gute Nachricht ist, dass Ihr MySQL-Server nicht zu stark beeinträchtigt wird, da Sie keine Ausfallzeiten oder langsamen Abfrageantworten bemerken. Wir verwenden es für 10-Gbit-Datenbanken und es funktioniert wie ein Zauber ohne Ausfallzeiten.
Plan A: Siehe auch Xtrabackup von Percona. Dies ermöglicht eine Online-Sicherung von InnoDB ohne nennenswerte Sperrung.
Plan B: Ein Slave kann gestoppt werden, und Sie können eine konsistente Sicherung auf verschiedene Arten durchführen (Dateien kopieren, mysqldump, xtrabackup usw.).
Plan C: LVM-Schnappschuss. Nach einigen kryptischen Einstellungen beträgt die Ausfallzeit für eine Sicherung weniger als eine Minute, unabhängig von der Größe der Datenbank. Sie stoppen mysqld, erstellen den Snapshot, starten mysqld neu und kopieren den Snapshot. Der letzte Schritt kann lange dauern, aber MySQL ist nicht ausgefallen.
Plan D: Momentaufnahme eines Slaves - keine Ausfallzeit.
Ein paar Admin-Punkte zuerst: Stellen Sie eine Verbindung zu einem FTP her oder sind Sie eingeschaltet und es stirbt? Wenn ssh, verwenden Sie unbedingt screen, damit Sie nach dem Comcast-Absturz fortfahren können. Wenn ftp, dann stellen Sie sicher, dass Sie es/tar vor dem Senden komprimieren.
Versuchen Sie auch den Parameter --opt oder --quick
--opt Diese Option aktiviert eine Reihe zusätzlicher Optionen, um die Speicherauszugs- und Neuladevorgänge effizienter zu gestalten. Dies entspricht insbesondere der gemeinsamen Verwendung der Optionen --add-drop-table, --add-locks, --all, --quick, --extended-insert, --lock-tables und --disable-keys. Beachten Sie, dass diese Option die Ausgabe weniger portabel macht und von anderen Datenbanksystemen weniger wahrscheinlich verstanden wird.
--quick Diese Option weist mysqldump an, beim Lesen jeder Zeile vom Server eine Dump-Ausgabe zu schreiben, was für große Tabellen nützlich sein kann. Standardmäßig liest mysqldump alle Zeilen aus einer Tabelle in den Speicher, bevor die Ausgabe geschrieben wird. Für große Tabellen erfordert dies viel Speicher, was möglicherweise dazu führt, dass der Speicherauszug fehlschlägt.
Ich hatte auch Probleme mit Timeouts während des Dumps großer Datenbanken. Ich habe es endlich gelöst, indem ich einzelne Befehle für jede Tabelle in der Datenbank gesendet und alles an eine Datei wie diese angehängt habe:
TABLES=`mysql -u $USER -p$PWD -Bse 'show tables' $DB`
for TABLE in $TABLES
do
mysqldump -u $USER -p$PWD $DB $TABLE >> dump.sql
done
Ich denke, die Frage ist, wie man schneller aus den von mysqldump erstellten Dump-Dateien wiederherstellt, nicht mit einer anderen Sicherungslösung.
Sie können dies unter anderem tun, indem Sie Gruppen von Tabellen in Ihrem Schema erstellen und für jede Gruppe einen separaten DB-Benutzer erstellen. Anschließend können Sie mithilfe der MySQL-Berechtigungen nicht zulassen, dass Tabellen mit allen bis auf einen DB-Benutzer eingefügt werden.
Dies ist eine bewährte, schnelle, fast parallele Technik, aber nicht 100% sicher, wie lange die Wiederherstellung von großen Dumps wie 500G oder so dauern wird. Aber meiner bescheidenen Meinung nach braucht man etwas Paralleles. Überprüfen Sie den Link unten für ein Beispiel.
[Schnelle, parallele Wiederherstellung von SQL-Dumps (mysqldump) für MySQL] [1]
"Schnelle, parallele Wiederherstellung von SQL-Dumps (mysqldump) für MySQL"