Christian Renner (ch12r)

Große MySQL-Dumps zeilenweise splitten und importieren

Dieser Post soll darstellen, wie man einen MySQL-Dump zeilenweise splittet bzw. nur bestimmte Teile extrahiert, um nur Teile der Datenbank weiderherzustellen bzw. den Import zeitlich aufzuteilen. Er ist vor allem für mich als Gedankenstütze gedacht, könnte aber auch für andere interessant sein.

Erstellt man mittels mysqldump ein Backup der Datenbank, verwendet man wohl so was ähnliches, wie folgt:

mysqldump -h HOST -u USER DBNAME -p > FILENAME.sql

Als Ergebnis erhält man ein MySQL-Skript, mit welchem man mittels mysql die komplette Datenbank wieder herstellen kann und zwar wie folgt:

mysql -h HOST -u USER DBNAME -p < FILENAME.sql

Import zerlegt

So weit - so gut. Das dürfte für die Meisten nichts Neues sein. Handelt es sich nun jedoch bei FILENAME.sql um einen recht großen Dump, muss man diesen eventuell mit split zerlegen. Das könnte man zum Beispiel mit einem der folgenden Anweisungen erledigen:

#Erzeugt Dateien mit jeweils 1000 Zeilen Länge
split -l 1000 FILENAME.sql
#Erzeugt Dateien mit jeweils 1 MB Größe
split -b 1M FILENAME.sql

Import nach Maß

Um nun nur eine bestimmte Tabelle des Dumps zu importieren, macht man sich die Struktur des dump-Files zu eigen. Dieses liegt in der folgenden wiederkehrenden Form vor:

  • Tabellenkommentar
  • CREATE TABLE - Anweisung
  • Zeilenkommentar
  • INSERT - Anweisungen

Jeder Tabellenkommentar sieht wie folgt aus:

--
-- Table structure for table `TABELLENNAME`
--

Nun kann man sich von grep die Zeilennummern ausgeben lassen, in denen "Table structure for table" steht:

grep -n 'Table structure for table' FILENAME.sql
# Ergibt folgende Ausgabe:
# 19:-- Table structure for table `table1`
# 44:-- Table structure for table `table2`
# 447:-- Table structure for table `table3`
# 544:-- Table structure for table `table4`
# 625:-- Table structure for table `table5`

Die letzte Zeile einer Tabellensequenz, heißt bei mir immer "UNLOCK TABLES;". Somit können wir die Länge der letzten Tabelle bestimmen:

grep -n 'UNLOCK TABLES;' FILENAME.sql
# Ergibt folgende Ausgabe:
# 41:UNLOCK TABLES;
# 444:UNLOCK TABLES;
# 541:UNLOCK TABLES;
# 622:UNLOCK TABLES;
# 674:UNLOCK TABLES;

Die Nummer der letzten Zeile bekommt man mit:

grep -n 'Dump completed' FILENAME.sql
# Ergibt folgende Ausgabe:
# 686:Dump completed

Möchte man nur bestimmte Zeilennummern des Dumps importieren, kann man diesen mit sed erstellen:

#Erzeugt eine Datei mit den Zeilen 43 bis 445 des Dumps (table3):
sed -n '43,445 p' < FILENAME.sql > FILENAME_part.sql

Zu beachten gilt:
Am Anfang der FILENAME.sql befinden sich Anweisungen, die die Datenbankverbindung für den Import konfigurieren. Unter Anderem wird hier die Zeichenkodierung der Verbindung gesetzt. Am Ende des Datenbankskriptes (nach der letzten Tabellensequenz) werden diese Parameter wieder zurückgesetzt.

Im Folgenden wollen wir sowohl den Header als auch den Footer an den Tabellendump kleben:

# Header extrahieren:
sed -n '1,17 p' < FILENAME.sql > header.sql
# Tabelle (table3) extrahieren:
sed -n '43,445 p' < FILENAME.sql > FILENAME_part.sql
# Footer extrahieren:
sed -n '675,686 p' < FILENAME.sql > footer.sql
# Zusammenführen der Dateien:
cat header.sql FILENAME_part.sql footer.sql > table3.sql
# Import:
mysql -h HOST -u USER DBNAME -p < table3.sql
This entry was posted in Development and tagged , , , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

One Comment

  1. Frank
    Posted 20. February 2013 at 18:18 | Permalink

    Klasse Inspiration, Vielen Dank.
    Man unterschätzt immer wieder, wie mächtig doch die Shell ist.

Post a Comment

Your email is never published nor shared.

You may use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="">