Laden...

MySQL zu MSSQL konvertieren (1,5TB)

Erstellt von manullino vor 5 Jahren Letzter Beitrag vor 5 Jahren 3.045 Views
manullino Themenstarter:in
371 Beiträge seit 2008
vor 5 Jahren
MySQL zu MSSQL konvertieren (1,5TB)

verwendetes Datenbanksystem: <MySQL, MSSQL>

Hallo zusammen,

ich bin gerade dabei eine Datenbank mit 1,5TB von MySQL nach MSSQL zu konvertieren.
Ich verwende dazu SQL Scripts im SQL Management Studio und einen Link (MySQL) Server wie hier angegeben. Für jede Tabelle verwende ich ein Script.

https://www.codeproject.com/Articles/29106/Migrate-MySQL-to-Microsoft-SQL-Server

Meine Test Umgebung ist:
MySQL 5.6.20
MSSQL 2017 (Developer)
Windows Server 2012R mit 8GB RAM. (etwa 4 GB stehen zur Verfügung)

Beide Datenbanken sind auf dieser Maschine lokal installiert.

Bei kleinen Tabelle oder wenn ich das MySQL Select Statement auf eine gewisse Anzahl begrenze (z.B. 1.000 oder 10.000) funktioniert die Konvertierung schnell. Erweitere ich aber die Anzahl die Sätze wird es sehr langsam.

Ich habe ein paar Test gemacht, u. A.:
10.000 Datensätze benötigen etwa 10x so lange wie 1.000 und 1.000 etwa 10x so lange wie 100.
Bei 100.000 trifft das leider nicht zu. (Diese Tabelle hat eine Größe von 8GB und 1.3 Mio. Datensätze)

Ich habe das Gefühl, dass sobald die Größe (In MB) der Datensätze die Größe meines Arbeitsspeichers überschreitet, diese Problem eintrifft.

Kann das jemand bestätigen? Bin für jeden Tipp dankbar!
Grüße,
Manullino

3.511 Beiträge seit 2005
vor 5 Jahren

Moin,

deaktiviere alle Constraints und droppe im Vorfeld alle Indizes. Nach dem Import alles wieder aktivieren und Indizes erstellen. Das dürfte einiges bringen.

[Edit]: Auf der MSSQL Seite natürlich 😃

Gruß
Khalid

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

manullino Themenstarter:in
371 Beiträge seit 2008
vor 5 Jahren

Halllo Khalid,

vielen Dank fuer den Tipp, das werde ich gleich testen!

Mittlerweile ist der Test mit den 100.000 Records auch fertig. Es hat sage und schreibe 13,5h gedauert.
10.000 Records dauerten nur 20Min.

Was auch interessant ist, die Tablle mit 100.000 Records hat in MSSQL eine Datengroesse von 15,3GB, der Index ist 5GB gross. Die komplette Tabelle mit 1,3Mio Records hat in MYSQL aber nur 8GB.

Irgendwas scheint da nicht ganz zu passen?!

Gruesse,
Manullino

T
2.224 Beiträge seit 2008
vor 5 Jahren

Das Problem dürfte auch das Select Into sein.
Da hier jeder Datensatz einzeln mit Insert Into importiert wird, ist dies bei großen Datenbanken, wie bei dieser, ungemein langsam.
Hier würde es sich schon anbieten mit einem Tool die Daten mit Bulk Insert zu importieren, was die Performance schon beim schreiben ungemein erhöhen dürfte.

Ich würde hier nur die Datenstrukturen der MySQL DB in die MS SQL DB übertragen und die Daten einfach per DataTable und SqlBulkCopy importieren.
Das dürfte enorm viel Zeit beim kopieren sparen.

Nachtrag:
@manullino
Wird vermutlich an den Einstellungen der DB liegen.
Je nachdem wie die Einstellungen zum Wachstum der DB sind, wird eben mehr Platz reserviert als benötigt wird um nicht bei jedem Insert mehr Platz reservieren zu müssen was die DB enorm verlangsamen würde.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

manullino Themenstarter:in
371 Beiträge seit 2008
vor 5 Jahren

Hallo zusammen,

ich importiere gerade 5 Mio. Datensaetze in 100.000er Schritten.
(Select aus MYSQL, Insert into im MSSQL)

Pro Durchgang dauert das ganze unglaubliche 11 Minuten.
Also der Import startete, lag die Dauer bei 4 Minuten.

Je groesser die Tabelle ist, desto langsamer wird der import.
Index oder Primary Key ist/sind keine vorhanden.

Ich habe festgestellt, dass die Schreibrate bei nur 3BM/s liegt.
RAM liegt bei 60% Auslastung, und die CPU hat so gut wie nichts zu tun.

Die beiden Datenbanken sind auf getrennten HDDs. (keine SSDs!)
Kopiere ich eine Datei im Explorer, liegt die Schreibrate deutlich ueber den 3MB/s.

Im Resource Monitor ist die Queue Length der HDD waehrend des INSERT INTO ganz am Anschlag.

Wie kann ich den SQL Server dazu bewegen, in INSERT INTO schneller zu machen? 😉

Sorry fuer den Doppelpost!

Dachte ich mach einen Thread auf, da ich das Problem nun mehr eingegrenzt und besser beschrieben haben.

Was mir nicht in den Kopf will, dass ein Insert Into abhängig von der vorhandenen Datenmenge langsamer wird, auch wenn kein Index oder Trigger definiert sind und die Hardware noch deutlich mehr Resourcen zur Verfuegung stellen koennte.

Das wurde Quasi bedeuten, dass eine Tabelle mit Mio. von Records, keine Sinn macht?!

T
2.224 Beiträge seit 2008
vor 5 Jahren

@manullino
Wie sind den die Einstellungen der DB Server und der Datenbank?
Wenn z.B. deine DB alle X MB wächst, dann ist deine DB z.B. immer wieder mit Speicherreservieren und dann mit Daten schreiben beschäftigt.

Wenn du die Default Einstellungen hast, wächst die DB und das Transaktionslog z.B. alle 10% was gerade am Anfang häufig dazu führt, dass die DB neuen Speicherplatz reservieren muss.
Und je nachdem wie das Transaktionslog eingestellt ist, wir auch jeder Eintrag erst dort und dann in die Datendatei geschrieben.

Und je nachdem wie die Resourcen des DB Server sind, verändert sich ebenfalls die Situation.
Hat er nur sehr wenig RAM den er nutzen kann, dann müssen häufiger Daten geschrieben/gelesen werden.

Wenn du auch mal mit SqlBulkCopy einen Test machen würdest, könntest du auch prüfen ob dies dein Problem löst.
Bei größeren Datenmengen, wie in deinem Fall, würde ich nie ein Select mit Insert Into machen sondern die Daten aus der Ursprungsdatenbank lesen und per Bulk Insert importieren.
Dann dürfte deine DB unter Volllast schreiben und die Daten um einen beachtlichen Faktor importieren.
Gerade dafür gibt es ja Bulk Insert.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

3.511 Beiträge seit 2005
vor 5 Jahren

Hast du denn schon mal den "klassischen" Weg über Kommandozeilen-Tools gemacht? Oder direkt im SQL Server den mySql Server als Linked Server angegeben?

Beiden dürfte immens schneller sein, als ein eigenes Programm welches die Daten migriert. Für Kommandozeile kann man bcp verwenden. Hier müsste man auf der mySql ein Dump in eine CSV Datei machen und diese per bcp wieder importieren.

Oder halt die mySql ODBC Treiber auf dem SQL Server installieren und dann per Linked Server migrieren.

Gruß
Khalid

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

manullino Themenstarter:in
371 Beiträge seit 2008
vor 5 Jahren

Hallo Khalid,

wie in meinem ersten Post geschrieben, arbeite ich mit Scripts und Linked Server. Ein eigenes Programm zu verwenden, war der Vorschlag von T-Virus.

@T-Virus:
Autogrowth steht auf ein 1GB und die TransactionLogs habe ich auf "SIMPLE" gestellt.
Gibt es noch weitere Parameter die man verbessern kann?

Vielen Dank,
Manullino

T
2.224 Beiträge seit 2008
vor 5 Jahren

@manullino
Klingt erst einmal in soweit korrekt.
Der Ansatz mit den Linked Server dürfte aber schon das Problem sein.
Du hast selbst geschrieben, dass es Probleme macht, sobald du mehr Daten lesen willst als du RAM hat.

Wie sieht dein System bzw. der Server dann aus?
Ist dort dann der RAM Verbrauch am Limit?
Muss eines der Systeme swappen?

Gerade hier wäre dann dein Hauptproblem, was ich eben mit einem einfachen Tool lösen würde.
Dazu muss man bloss einen DataReader auf die MySQL Datenbank öffnen und diesen an SqlBulkCopy mitgeben.
Dann kann SqlBulkCopy die Daten aus dem DataReader lesen, wenn die Tabellen auf beiden Datenbanken den gleichen Aufbau haben.

Kann man in wenigen Minuten zusammen bauen samt Timeout etc.
Da würdest du dir mehr Zeit sparen als noch ewig und drei Tage nach einer Lösung per Linked Server oder Script zu suchen.
Und dann Bulk Copy wäre es auch schneller als dein Select Into Ansatz.

Ebenfalls würde mich auch interessieren, warum du einen Developer SQL Server verwendest.
Sind das Testdaten oder wieso hast du deinen Standard/Enterprise Server?
Ich hoffe nur, du nutzt diesen nicht als produktiv System.
Mal davon abgesehen, dass Microsoft im Developer Server auch deine Daten auslesen darf, steht in der Lizenz des Developer Server.
Deshalb hoffe ich, dass du dir das gut überlegt hast.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

3.511 Beiträge seit 2005
vor 5 Jahren

wie in meinem ersten Post geschrieben, arbeite ich mit Scripts und Linked Server

Ups 😃

Dann verstehe ich es nicht ganz. Habe mal kurz ein Test gefahren

  • Quelle mySQL (4 CPU, 8 GB RAM, SSD)
    • Tabelle mit > 100mio Rows (davon aber nur ca. 4,5 mio selektiert)
  • Ziel MS SQL Express (2 CPU, 8 GB RAM, SSD)
    • Über Linked Server zum mySql

Ausgeführt über "SELECT * INTO Test FROM OPENQUERY(TEST_MYSQL, 'SELECT * FROM xxxx')"

Ergebnis: 4,5 mio Rows in 55min (wobei ich das schon erschreckend langsam finde, aber kann an den limitierten Testkisten liegen).

[Edit]:
Die Tabelle hat ca. 40 Spalten. Eingefügte Datenmenge sind knapp unter 1 GB. Bei den Daten handelt es sich um Laufdaten nach Datum.

Dein Bottleneck muss irgendwas anderes sein.

OK, gerade nochmal gelesen, dass du nur HDDs hast. Ich hingegen habe den Test auf SSDs gemacht. Aber selbst eine HDD liefert bei weitem mehr als 3 MB/s

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

manullino Themenstarter:in
371 Beiträge seit 2008
vor 5 Jahren

Mittlerweile ist die MSSQL auch auf eine SSD, was das Ganze schon ungemein schneller macht.
Das Problem, dass es immer langsamer wird, bleibt aber bestehen.

Meinen MYSQL Datenbank ist auch 1,5TB, daher hinkt der Verleich evtl. ein bisschen... 😉

@T-Virus
Vielen Dank fuer den Hinweis, aber es ist nur eine Test Umgebung.

Einer der Tabellen enthaelt 500GB an Daten, da werde ich den Bulk Insert versuchen / anwenden.

Gruesse,
Manullino

T
2.224 Beiträge seit 2008
vor 5 Jahren

@manullino
Hast du den mal meine Tipps oben geprüft?
Also ob deine Kiste oder der Server swappen muss.
Den wenn die Daten in einem Rutsch durchlaufen, würde es genau daran hängen.
Dann wäre aber auch dein aktueller Ansatz keine Option.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.