Wie kann ich den Fortschritt eines Imports einer großen .sql-Datei überwachen?

204

Ich importiere 7 GB foobar.sql, um eine Tabelle in einer lokalen Datenbank wiederherzustellen.

$ mysql -h localhost -u root 'my_data' < foobar.sql

$ mysql --version
/usr/local/mysql/bin/mysql  Ver 14.12 Distrib 5.0.96, for apple-darwin9.8.0 (i386) using readline 5.1

Wie kann ich den Fortschritt überwachen?

qazwsx
quelle
1
Die Antworten auf diese Frage zeigen, dass dies ein klarer Mangel des MySQL-Clients ist
William Entriken

Antworten:

267

Wenn Sie nur eine Sicherungsdatei von der CLI unter * nix importieren, z

mysql -uxxx -pxxx dbname < /sqlfile.sql

Installieren Sie dann zunächst den Pipe Viewer auf Ihrem Betriebssystem, und versuchen Sie es dann in etwa so:

pv sqlfile.sql | mysql -uxxx -pxxxx dbname

Das zeigt einen Fortschrittsbalken, während das Programm läuft.

Es ist sehr nützlich und Sie können es auch verwenden, um eine Schätzung für den Fortschritt von mysqldump zu erhalten.

pv gibt das aus sqlfile.sqlund übergibt es an mysql (wegen des Pipe-Operators). Während des Dumpings wird der Fortschritt angezeigt. Das coole daran ist, dass mysql die Daten nur so schnell nimmt, wie es sie verarbeiten kann, damit pv den Fortschritt des Imports anzeigen kann. Ich habe keine Beweise. Aber es scheint so. Ich denke, es wird ein Puffer verwendet, aber ich denke, mysqldass er irgendwann keine Daten mehr liest, wenn er noch in Bearbeitung ist.

Pipe Viewer-Screenshot

rauben
quelle
1
Ich würde vermuten, dass mysql einen Puffer hat, in den einige Daten gepiped werden können, ohne vollständig "verarbeitet" zu werden (dh wenn es fehlerfrei ist, hat pv möglicherweise leicht übermeldet, was tatsächlich hereinkommt). Aber im Allgemeinen funktionieren Rohre so. Dies ist der gleiche Grund, warum Sie sudo hd /dev/sda1 | lessIhre gesamte Systempartition im Arbeitsspeicher haben können.
Snapfractalpop
2
@snapfractalpop pvist in vielen Fällen nicht besonders genau, da die Verarbeitung einiger SQL- Blöcke mehr Zeit in Anspruch nimmt als anderer. Eine Zeile, bei der es sich um eine einfache Einfügung handelt, wird viel schneller ausgeführt als eine Zeile, die bei einem Index für eine Tabelle erstellt wird, die beispielsweise bereits viele Zeilen enthält. Aber eine ungefähre Vorstellung vom Fortschritt der Ausgabe sollte hilfreich sein, es sei denn, der von verwendete Lesepuffer mysqlist besonders groß (für eine 7-GB-Eingabe müsste der Puffer sehr groß sein, um pvdie Ausgabe überhaupt nicht nützlich zu machen).
David Spillett
1
@ DavidSpillett in der Tat. Ihr Kommentar spiegelt mein Gefühl wider. Grundsätzlich ist pv roh, aber effektiv. Am besten gefällt mir, wie allgemein es ist. Das ist die Schönheit von Unix-Pipes (danke McIlroy).
Snapfractalpop
1
@rob Das ist ein großartiger Typ. Könntest du auch ein Beispiel geben mysqldump?
Josue Alexander Ibarra
Sehr schöne Lösung! Wenn das Passwort manuell ist, wartet pv nicht darauf, dass es seinen Fortschritt anzeigt
Pierre de LESPINAY
26

Wenn Sie den Import bereits gestartet haben, können Sie diesen Befehl in einem anderen Fenster ausführen, um die aktuelle Größe Ihrer Datenbanken anzuzeigen. Dies kann hilfreich sein, wenn Sie die Gesamtgröße der zu importierenden SQL-Datei kennen.

SELECT table_schema "Data Base Name", sum( data_length + index_length ) / 1024 / 1024 "Data Base Size in MiB" 
FROM information_schema.TABLES GROUP BY table_schema;  

Gutschrift auf: http://forums.mysql.com/read.php?108,201578,201578


Die MySQL 8.0-Referenz besagt Folgendes zur Genauigkeit:

DATA_LENGTH

Bei MyISAM ist DATA_LENGTH die Länge der Datendatei in Byte.

Bei InnoDB ist DATA_LENGTH die ungefähre Größe des für den Clustered-Index zugewiesenen Speichers in Byte. Dies ist insbesondere die Größe des Clustered-Index in Seiten multipliziert mit der InnoDB-Seitengröße.

 

INDEX_LENGTH

Bei MyISAM ist INDEX_LENGTH die Länge der Indexdatei in Byte.

INDEX_LENGTH ist für InnoDB die ungefähre Größe des für nicht gruppierte Indizes zugewiesenen Speichers in Byte. Insbesondere ist dies die Summe der nicht gruppierten Indexgrößen in Seiten multipliziert mit der InnoDB-Seitengröße.

Josh Grinberg
quelle
Mein Tisch ist jetzt bei 12 GiB nach den Befehlen aus dieser Antwort und noch zu importieren. Meine Sqldump-Datei ist nur 5 GiB. Ich wäre an einer Erklärung für diese Diskrepanz interessiert
Lucidbrot
17

Wenn Sie einen mysqldump einer einzelnen Datenbank ausführen, werden alle Tabellen in alphabetischer Reihenfolge gesichert.

Natürlich würde das Neuladen des mysqldump in eine Datenbank auch in alphabetischer Reihenfolge erfolgen.

Sie könnten einfach eine SHOW-PROZESSLISTE erstellen. und finde heraus, welche DB-Verbindung den mysqldump ausführt. Wenn der Dump neu geladen wird, verschwindet die DB-Verbindung.

Wenn Sie wissen möchten, welche Tabellen sich im Dumpfile befinden, führen Sie dies mit foobar.sql aus

cat foobar.sql | grep "^CREATE TABLE" | awk '{print $3}'

UPDATE 2012-05-02 13:53 EDT

Entschuldigung, dass Sie nicht bemerkt haben, dass es nur einen Tisch gibt.

Wenn es sich bei der Tabelle um MyISAM handelt, ist die Überwachung nur aus Sicht des Betriebssystems möglich. Der Grund? Die Tabelle ist während des gesamten Neuladens schreibgeschützt. Was suchst du? Die Größe der .MYDund .MYIDateien. Natürlich müssen Sie das mit der Tabellengröße vergleichen, die zuvor auf dem anderen DB-Server, von dem Sie importiert haben, vorhanden war.

Wenn die Tabelle InnoDB ist und Sie innodb_file_per_table aktiviert haben, ist die einzige Möglichkeit zur Überwachung die Sicht des Betriebssystems. Der Grund? Die Tabelle ist während des gesamten Neuladens schreibgeschützt. Was suchst du? Die Größe der .ibdDatei. Natürlich müssen Sie das mit der Tabellengröße vergleichen, die zuvor auf dem anderen DB-Server, von dem Sie importiert haben, vorhanden war.

Wenn die Tabelle InnoDB ist und Sie innodb_file_per_table deaktiviert haben, kann nicht einmal die Sicht des Betriebssystems helfen.

UPDATE 2012-05-02 13:56 EDT

Ich habe letztes Jahr so ​​etwas angesprochen: Wie erhalte ich% Fortschritt für "Typ db.sql | mysql"?

UPDATE 2012-05-02 14:09 EDT

Da ein Standard-mysqldump die Tabelle folgendermaßen schreibsperrt:

LOCK TABLES `a` WRITE;
/*!40000 ALTER TABLE `a` DISABLE KEYS */;
INSERT INTO `a` VALUES (123),(451),(199),(0),(23);
/*!40000 ALTER TABLE `a` ENABLE KEYS */;
UNLOCK TABLES;

Dann gibt es keine Möglichkeit, mit mysql einen Fortschritt zu erzielen, bis die Tabellensperre aufgehoben wird.

Wenn Sie aus dem Dumpfile bekommen LOCK TABLESund UNLOCK TABLESkommentieren können ...

  • Wenn die Tabelle MyISAM ist, funktioniert SELECT COUNT (*)
  • Wenn die Tabelle InnoDB ist, würde SELECT COUNT (*) den Ladevorgang wahrscheinlich verlangsamen / anhalten, bis die Zählung abgeschlossen ist
RolandoMySQLDBA
quelle
Das hat funktioniert. Vielen Dank. Eine letzte Frage ist, ob Sie aus Erfahrung wissen, ob die Importzeit in Bezug auf die Dateigröße und die Dateigröße ungefähr linear ist . .MYD.MYI
qazwsx
1
Das Nachladen der Tabelle erfolgt linear. Indexwiederherstellungen sind linear. Vor Jahren war es nicht so, wie ich es als Frage an MySQL gewagt habe ( lists.mysql.com/mysql/202489 ) und ich erwähnte es in DBA StackExchange ( dba.stackexchange.com/a/2697/877 )
RolandoMySQLDBA
8

Alle 2 Sekunden sehen Sie, wie die Prozesse ausgeführt werden.

watch 'echo "show processlist;" | mysql -uuser -ppassword';

Wenn Sie es weniger häufig möchten, fügen Sie hinzu, -n xwobei x die Anzahl der Sekunden ist. 5 Sekunden wären:

watch -n 5 'echo "show processlist;" | mysql -uuser -ppassword';
Marcelo Luiz Onhate
quelle
Können Sie eine Beispielausgabe posten? Zeigt es nur den Prozess an oder zeigt es wirklich den Fortschritt des Imports an, nach dem ich wirklich gefragt habe?
Qazwsx
Das ist so ein hilfreicher Code. Thankyou
Narayan
6

Wenn Sie nur prüfen möchten, ob es blockiert ist, können Sie eine Abfrage durchführen

show processlist; 

und sehen, was ausgeführt wird.

SCL
quelle
5

Als Lösung für jemanden, der pv nicht zur Arbeit bringen kann oder für den pv Lügen erzählt. Sie können die Größe der Datei ibdata1 in / var / lib / mysql überwachen, die die Daten enthält. Dies führt dazu, dass die Dateigröße in Ihrem Quellserver (oder in etwa) gleich ist.

Wenn es viele Tabellen gibt, können Sie sie auch einzeln in / var / lib / mysql / <Datenbankname> anzeigen.

Ich habe diese Tatsache kürzlich ausgenutzt, als eine Langzeitdatenbank über einen Zeitraum von drei oder vier Jahren eine Protokolldatei von etwa 20 G erstellt hatte. Ich bemerkte, dass die Übertragung Ewigkeiten in Anspruch nahm und verwendete diese Technik, um den Fortschritt zu überwachen.

Ich denke, dass es höchst unwahrscheinlich ist, dass der Tag beginnt, an dem eine Datenbank nicht irgendwo eine Datei enthält. In der Zwischenzeit können Sie die Datei überwachen, um den Fortschritt der Übertragung zu verfolgen. Die von mir vorgeschlagene Methode konnte in der einen oder anderen Form durchgeführt werden, seit die erste SQL-Datenbank geschrieben wurde. Ich hätte nie gedacht, dass es irgendeine "offizielle" Technik ist, auf die ein manueller Jockey zurückgreifen kann. Es wird ein allgemeiner Kenntnisstand in Bezug auf Computer im Allgemeinen und Unix im Besonderen vorausgesetzt.

nerak99
quelle
2

Wenn Ihre Datenbank ansonsten leise ist (dh keine anderen Benutzer aktiv sind) und Sie nur Lese- / Schreibaktivitäten sehen möchten, warum nicht einfach so etwas tun:

mysqladmin -h<host>-uroot -p<yourpass> extended -r -i 10 |grep 'row'

Sie sehen die Anzahl der Lese- / Schreib- / Einfüge- / Warte- / Aktualisierungsvorgänge.

Wenn Sie zum Beispiel einfügen, sehen Sie etwas wie:

Innodb_rows_inserted                          | 28958 

Wobei 28958 die Anzahl der Zeilen ist, die für Ihr Intervall eingefügt wurden (10 Sekunden in meinem Fall).

user113373
quelle
1

Für jemanden, der nach dem Pipe-Viewer-Beispiel sucht mysqldump, würden Sie einfach Folgendes tun:

mysqldump -hxxx -uxxx -p dbname | pv -W > dump.sql

Das -WFlag weist pv einfach an, auf das erste Byte zu warten, bevor der Fortschritt angezeigt wird (nach der Eingabeaufforderung).

Mauricio Trajano
quelle
0

Sie können einen Import im Ordner \ Msql \ Data [DB-Name] überwachen.

Hotcronchy
quelle
0

Ok, noch ein Workaround. Dies kann jedoch die schlechteste und ungenaueste Option sein.

Das heißt, hier ist meine Lösung für Windows:

Öffnen Sie den Task-Manager durch Drücken von

CTRL + SHIFT + ESC

Kopieren Sie die Datenträgergeschwindigkeit "mysqld.exe"

e.g. 11mb/s

Stecken Sie das in einen Taschenrechner wie diesen: https://techinternets.com/copy_calc?do

Schätzen Sie die ETA. Mein Fall war:

Speed: 8 MB/s
Size: 4.9 GB
0 Hours, 11 Minutes and 29 Seconds

Ergebnisse:

Beg -> 11:19
ETA -> 11:31
End -> 11:39
Daniel
quelle
-1

Ich bin so überrascht, dass niemand 'mysql -v' als Option gepostet hat. Wenn es hängen bleibt, stoppt die Ausgabe.

dtc
quelle
3
"Überwachung des Fortschritts" bedeutet im Allgemeinen, zu versuchen, abzuschätzen, wie weit der Prozess fortgeschritten ist oder wann er abgeschlossen werden würde, was mysql -vnicht sinnvoll ist. Wenn Sie 7 GB Daten auf das Terminal übertragen, wird die Wiederherstellung erheblich verlangsamt.
Mustaccio
Ich verstehe, danke für die Erklärung. das ist wahr, die Ausgabe von 7 GB wäre nicht gut, um in das Terminal auszugeben. Ich denke, ich benutze -v nur für einen kleinen lokalen Testfall, bei dem meine Datenbank einfach hängen bleibt.
dtc
2
Dieser Vorschlag hat mir geholfen, ein Problem zu lokalisieren, wie unpraktisch es auch für die Verwendung mit großen Dateien sein mag. (Meins war klein).
Casey Perkins