Kann ich eine einzelne Tabelle aus einer vollständigen mysql mysqldump-Datei wiederherstellen?

194

Ich habe eine mysqldump-Sicherung meiner mysql-Datenbank, die aus all unseren Tabellen besteht und ungefähr 440 Megabyte groß ist. Ich möchte den Inhalt nur einer der Tabellen aus dem mysqldump wiederherstellen. Ist das möglich? Theoretisch könnte ich einfach den Abschnitt ausschneiden, der die gewünschte Tabelle neu erstellt, aber ich weiß nicht einmal, wie ich ein Textdokument dieser Größe effektiv bearbeiten kann.

Mobius
quelle
2
FWIW, Sie könnten auch mydumper verwenden . Dadurch wird ein logischer Speicherauszug wie mysqldump erstellt, es werden jedoch separate Dateien pro Tabelle ausgegeben, und es kann sowohl das Dumping als auch das Laden von Multithreads ausgeführt werden, sodass weniger Zeit erforderlich ist.
Bill Karwin

Antworten:

289

Sie können versuchen, sed zu verwenden, um nur die gewünschte Tabelle zu extrahieren.

mytableAngenommen , der Name Ihrer Tabelle lautet und die Datei mysql.dump ist die Datei, die Ihren riesigen Speicherauszug enthält:

$ sed -n -e '/CREATE TABLE.*`mytable`/,/CREATE TABLE/p' mysql.dump > mytable.dump

Dadurch wird in die Datei kopiert, mytable.dumpwas sich zwischen CREATE TABLE mytableund CREATE TABLEder nächsten Tabelle befindet, die der nächsten Tabelle entspricht.

Sie können dann die Datei anpassen, die mytable.dumpdie Struktur der Tabelle mytableund die Daten (eine Liste von INSERT) enthält.

uloBasEI
quelle
5
Das ist noch schöner als meine Antwort, da es sich auch um die CREATE TABLE kümmert, aber Sie sollten mit den Backquotes suchen, um keine weitere Tabelle mit dem Namen "thisismytabletoo" zu erhalten.
JCCyC
1
Wahr. Ich war mir nicht sicher, ob die Tabellennamen in allen MySQL-Dumps immer von Backquote umgeben sind oder ob "CREATE TABLE mytable" auch möglich sein könnte. Wir können den ersten regulären Ausdruck leicht anpassen, wenn wir wissen, wie der Speicherauszug aussieht. Ein zweites Problem könnte sein, wenn die Tabelle mytable nicht eindeutig ist (eine in der Datenbank db1 und eine andere in der Datenbank db2). Beide werden in die Datei mytable.dump exportiert. Wenn die Tabelle nicht eindeutig ist, können wir denselben Befehl sed verwenden, zuerst mit CREATE DATABASE, um nur die richtige Datenbank zu extrahieren. Verwenden Sie dann den Befehl sed mit CREATE TABLE.
uloBasEI
13
Süss! Denken Sie daran, DROP TABLE oben hinzuzufügen und DROP TABLE [nächste Tabelle] unten in der Datei zu entfernen.
Nathan
20
Um DROP TABLE nicht hinzuzufügen / zu entfernen, ist es sinnvoller, nach Table structure for tableKommentaren zu suchen, anstatt nach CREATE TABLE. Dadurch wird sichergestellt, dass die nächste Tabelle nicht gelöscht wird, wenn vergessen wird, die Anweisung DROP TABLE zu entfernen, und Piping für die Wiederherstellung von Tabellen mit nur einem Befehl (gzip | sed | mysql) ermöglicht. Diese Lösung hängt jedoch von der Kommentarsyntax von mysqldump ab (ich weiß nicht, wie Standard sie ist).
Olexa
12
Mit Olexas Modifikation ist es perfekt: sed -n -e '/ Tabellenstruktur für. * `Mytable /, / Tabellenstruktur für / p' full.sql> mytable.sql
deeenes
120

Ich habe eine modifizierte Version des Befehls sed von uloBasEI verwendet. Es enthält den vorhergehenden DROP-Befehl und liest, bis MySQL fertig ist, um Daten in Ihre Tabelle zu speichern (UNLOCK). Hat für mich (re) importiert wp_users in eine Reihe von Wordpress-Sites.

sed -n -e '/DROP TABLE.*`mytable`/,/UNLOCK TABLES/p' mydump.sql > tabledump.sql
Bryn
quelle
3
Dies ist tatsächlich eine viel bessere Lösung als die oben als Antwort gewählte. Ich kann nicht glauben, dass es nicht mehr positive Stimmen bekommen hat.
Rich
9
Ich schlage vor, dem Tabellennamen mindestens Backtick-Anführungszeichen hinzuzufügen: um `mytable`zu vermeiden, dass Tabellen übereinstimmen, mytable2und so weiter, wie es in meinem Fall der Fall war.
Bartekbrak
3
Du hast gerade meinen Arsch gerettet
Gabriel Alack
1
@ user706420 Hmm, bist du sicher, dass dein Terminal nicht schuld war? sedsollte die Codierung nicht stören ...
Bryn
6
Für diejenigen mit SQL-Dateien, die das nicht enthalten DROP TABLE(mein MySQL-Speicherauszug hatte dies nicht), möchten Sie möglicherweise sed -n -e '/-- Table structure for table ``<Table Name>/,/UNLOCK TABLES/p' <SQL File> > table.sql Folgendes verwenden: Dies verwendet die Tabellenkommentare, die vor jeder Tabelle in einem MySQl-Speicherauszug bereitgestellt werden, und stellt sicher, dass Zeilen wie /*!40101 SET @saved_cs_client = @@character_set_client */;eingeschlossen werden.
Hamx0r
50

Dies kann einfacher gemacht werden? So habe ich es gemacht:

Erstellen Sie eine temporäre Datenbank (z. B. Wiederherstellen):

mysqladmin -u root -p create restore

Stellen Sie den vollständigen Speicherauszug in der temporären Datenbank wieder her:

mysql -u root -p restore <fulldump.sql

Speichern Sie die Tabelle, die Sie wiederherstellen möchten:

mysqldump stellt mytable> mytable.sql wieder her

Importieren Sie die Tabelle in eine andere Datenbank:

mysql -u root -p database <mytable.sql

Martijn Kools
quelle
2
Das brauchen die meisten Menschen.
Sjas
2
Gemäß diesem Bearbeitungsvorschlag sollten Sie den Parameter "--one-database" hinzufügen, um sicherzustellen, dass Sie nur eine Datenbank wiederherstellen und nicht alles andere zerstören.
SL Barth - Wiedereinsetzung Monica
7
Für wirklich große Datenbanken kann es sehr seltsam sein - 150 GB Daten für eine Tabelle mit 100 MB wiederherzustellen.
Enyby
Ich habe dies nur ohne "--one-database" ausgeführt und es wurden immer noch Tabellen zusammengeführt. Meine vorhandenen Tabellen wurden nicht entfernt.
Qasim
1
Sehr schlechte Praxis! Ich hatte nur wenige DBs im Dump und versuchte, nur einen wiederherzustellen, löschte alle anderen.
AndreyP
11

Eine einfache Lösung wäre, einfach einen Speicherauszug nur der Tabelle zu erstellen, die Sie separat wiederherstellen möchten. Sie können den Befehl mysqldump verwenden, um dies mit der folgenden Syntax zu tun:

mysqldump -u [user] -p[password] [database] [table] > [output_file_name].sql

Importieren Sie es dann wie gewohnt und es wird nur die ausgegebene Tabelle importiert.

Brom558
quelle
9

Auf die eine oder andere Weise muss jeder Prozess, der dies tut, den gesamten Text des Dumps durchlaufen und ihn auf irgendeine Weise analysieren. Ich würde nur danach greifen

INSERT INTO `the_table_i_want`

und leiten Sie die Ausgabe in MySQL. Schauen Sie sich vorher den ersten Tisch in der Müllkippe an, um sicherzustellen, dass Sie den INSERT richtig einsetzen.

Bearbeiten: OK, diesmal die richtige Formatierung.

JCCyC
quelle
Ich bin dumm, nicht sofort daran zu denken, es zu packen. Grep rettet jeden Tag meinen Speck, wie es scheint. Die anderen beiden Vorschläge waren ebenfalls knallhart und genau das, was ich ohne die Wunder von grep getan hätte. Danke euch allen!
Mobius
6
Wenn du denkst, du liebst grep, wenn du awk lernst, wirst du sein glücklicher Sexsklave: en.wikipedia.org/wiki/Awk
JCCyC
7

Sie sollten den Befehl @bryn versuchen, aber ansonsten extrahieren Sie mit dem Trennzeichen `` auch die Tabellen mit einem Präfix oder einem Suffix. Dies ist, was ich normalerweise mache:

sed -n -e '/DROP TABLE.*`mytable`/,/UNLOCK TABLES/p' dump.sql > mytable.sql

Zu Testzwecken möchten Sie möglicherweise den Tabellennamen vor dem Import ändern:

sed -n -e 's/`mytable`/`mytable_restored`/g' mytable.sql > mytable_restored.sql

Zum Importieren können Sie dann den Befehl mysql verwenden:

mysql -u root -p'password' mydatabase < mytable_restore.sql
Maxime Biette
quelle
6
  1. Backup

    $ mysqldump -A | gzip > mysqldump-A.gz
  2. Stellen Sie eine einzelne Tabelle wieder her

    $ mysql -e "truncate TABLE_NAME" DB_NAME
    $ zgrep ^"INSERT INTO \`TABLE_NAME" mysqldump-A.gz | mysql DB_NAME
y.tk.
quelle
4

Eine Möglichkeit, damit umzugehen, besteht darin, eine temporäre Datenbank wiederherzustellen und nur diese Tabelle aus der temporären Datenbank zu sichern. Verwenden Sie dann das neue Skript.

Tim Hoolihan
quelle
3
sed -n -e '/-- Table structure for table `my_table_name`/,/UNLOCK TABLES/p' database_file.sql > table_file.sql

Dies ist eine bessere Lösung als einige der oben genannten, da nicht alle SQL-Dumps eine DROP TABLEAnweisung enthalten . Dieser wird funktionieren alle Arten von Dumps.

Weston Ganger
quelle
2

Dies kann auch helfen.

# mysqldump -u root -p database0 > /tmp/database0.sql
# mysql -u root -p -e 'create database database0_bkp'
# mysql -u root -p database0_bkp < /tmp/database0.sql
# mysql -u root -p database0 -e 'insert into database0.table_you_want select * from database0_bkp.table_you_want'
Pjl
quelle
2

Die Tabelle sollte sowohl im Speicherauszug als auch in der Datenbank dieselbe Struktur aufweisen.

`zgrep -a ^"INSERT INTO \`table_name" DbDump-backup.sql.tar.gz | mysql -u<user> -p<password> database_name`

oder

`zgrep -a ^"INSERT INTO \`table_name" DbDump-backup.sql | mysql -u<user> -p<password> database_name`
Neminath
quelle
1

Die meisten modernen Texteditoren sollten in der Lage sein, eine Textdatei dieser Größe zu verarbeiten, wenn Ihr System dies zulässt.

Jedenfalls musste ich das einmal sehr schnell machen und ich hatte keine Zeit, irgendwelche Werkzeuge zu finden. Ich habe eine neue MySQL-Instanz eingerichtet, das gesamte Backup importiert und dann nur die gewünschte Tabelle ausgespuckt.

Dann habe ich diese Tabelle in die Hauptdatenbank importiert.

Es war langweilig, aber ziemlich einfach. Viel Glück.

Bryan Migliorisi
quelle
1

Sie können den vi-Editor verwenden. Art:

vi -o mysql.dump mytable.dump

um sowohl den gesamten Speicherauszug mysql.dumpals auch eine neue Datei zu öffnen mytable.dump. Suchen Sie die entsprechende Einfügung in eine Zeile, indem Sie drücken, /und geben Sie dann eine Phrase ein, zum Beispiel: "Einfügen in" mytable "". Kopieren Sie diese Zeile dann mit yy. Wechseln Sie bis ctrl+wdahin zur nächsten Datei down arrow keyund fügen Sie die kopierte Zeile mit ein pp. Speichern Sie schließlich die neue Datei durch Eingabe :wqund ganz vi Editor von :q.

Beachten Sie, dass wenn Sie die Daten abgeladen haben mehrere Einsätze verwenden Sie (yank) alle auf einmal mit kopieren , Nyyin dem Ndie Anzahl der Zeilen kopiert werden.

Ich habe es mit einer Datei von 920 MB Größe gemacht.

mtoloo
quelle
0

Holen Sie sich einen anständigen Texteditor wie Notepad ++ oder Vim (wenn Sie bereits damit vertraut sind). Suchen Sie nach dem Tabellennamen, und Sie sollten in der Lage sein, nur die Befehle CREATE, ALTER und INSERT für diese Tabelle hervorzuheben. Es ist möglicherweise einfacher, mit der Tastatur als mit der Maus zu navigieren. Und ich würde sicherstellen, dass Sie sich auf einem Computer mit viel RAM befinden, damit es kein Problem gibt, die gesamte Datei auf einmal zu laden. Sobald Sie die benötigten Zeilen markiert und kopiert haben, ist es eine gute Idee, nur den kopierten Teil in einer eigenen Sicherungsdatei zu sichern und ihn dann in MySQL zu importieren.

Cameron
quelle
1
Dies ist selbst für Anfänger sehr einfach und verständlich. Ich weiß nicht, warum dies abgelehnt wird.
Karl Johan Vallner
0

Die SQL-Blöcke werden mit "Tabellenstruktur für Tabelle my_table" und "Daten für Tabelle sichern" blockiert my_table.

Sie können eine Windows-Befehlszeile wie folgt verwenden, um die Zeilennummern für die verschiedenen Abschnitte abzurufen. Passen Sie die gesuchte Zeichenfolge nach Bedarf an.

find / n "für Tabelle` "sql.txt

Folgendes wird zurückgegeben:

---------- SQL.TXT

[4384] - Tabellenstruktur für Tabelle my_table

[4500] - Daten für Tabelle sichern my_table

[4514] - Tabellenstruktur für Tabelle some_other_table

... etc.

Das bringt dir die Zeilennummern, die du brauchst ... jetzt, wenn ich nur wüsste, wie man sie benutzt ... Nachforschungen.

Kuyenda
quelle
0

Die zuvor erwähnten "sed" -Lösungen sind nett, aber wie erwähnt nicht 100% sicher

  • Möglicherweise haben Sie INSERT-Befehle mit Daten, die Folgendes enthalten: ... CREATE TABLE ... (was auch immer) ... mytable ...

  • oder sogar die genaue Zeichenfolge "CREATE TABLE` mytable`; " wenn Sie zum Beispiel DML-Befehle speichern!

(und wenn die Tabelle riesig ist, möchten Sie das nicht manuell überprüfen)

Ich würde die genaue Syntax der verwendeten Dump-Version überprüfen und eine restriktivere Mustersuche durchführen:

Vermeiden Sie ". *" Und verwenden Sie "^", um sicherzustellen, dass wir am Anfang der Zeile beginnen. Und ich würde es vorziehen, den ersten "DROP" zu nehmen.

Alles in allem funktioniert das besser für mich:

sed -n -e '/^DROP TABLE IF EXISTS \`mytable\`;/,/^UNLOCK TABLES;/p' mysql.dump > mytable.dump
phil_w
quelle