MySQL InnoDB Cluster: "Schlüsselmomente" beim Import

titelbild-key-moments

Dieser Beitrag bezieht sich auf ein Problem eines unserer Kunden, welches beim Import einer Datenbank in ein neues InnoDB Cluster entstanden ist.

Unser Kunde ist dabei, seine bestehende (veraltete) MySQL-5.5-Single-Instanz-Datenbank zu migrieren. Die Zielumgebung soll dabei aus einem Drei-Knoten-InnoDB-Cluster bestehen.

Problembeschreibung

Um die neue Umgebung zu testen, sollte ein relativ aktueller Datenbestand von der aktuellen produktiven Umgebung auf die neue Zielarchitektur importiert werden. Das Backup wurde auf der alten Umgebung „traditionell" mit einem „mysqldump" erstellt, ließ sich auf den neuen Cluster aber nicht einspielen. Zumindest berichtete unser Kunde, dass der Import der relativ kleinen DB (< 5 GB) auch nach Stunden nicht zum Ende kam.

In einer gemeinsam Remote-Session haben wir diesen Vorgang (Import) erneut gestartet und das Verhalten analysiert. Relativ schnell war zu sehen, dass der Import der ersten Tabelle nicht durchlief.

Die Analyse

Zu erkennen war, dass die Daten (mehrere Millionen Zeilen) zwar noch in den Cluster geladen wurden, die Import-Session dann aber mehrere Minuten (der Kunde berichtete aus seinen Versuchen von Stunden) mit dem Aktivieren der Indizes eben dieser Tabelle beschäftigt war.

Um den Import-Vorgang eines mysqldump-Files besser zu verstehen, muss man wissen, dass der Import einer Tabelle aus den folgenden grundlegenden Prozessschritten besteht (siehe auch Beispiel-Code aus einem unserer Dumpfiles):

  1. Löschen einer möglicherweise noch bestehenden Tabelle
  2. Anlegen der Tabelle / Struktur
  3. Sperren der Tabelle / Unterbindung von Zugriffen
  4. Deaktivierung der Indizes
  5. Laden der Daten
  6. Aktivieren der Indizes 
DROP TABLE IF EXISTS `manufacturer`;
…
CREATE TABLE `manufacturer` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
…
--
-- Dumping data for table `manufacturer`
--
LOCK TABLES `manufacturer` WRITE;
/*!40000 ALTER TABLE `manufacturer` DISABLE KEYS */;
INSERT INTO `manufacturer` VALUES (1,'VW'),(2,'BMW');
/*!40000 ALTER TABLE `manufacturer` ENABLE KEYS */;
UNLOCK TABLES;
 

Das Deaktivieren und Aktivieren der Indizes soll den Ladevorgang beschleunigen. Die Indizes müssen so nur einmal am Ende aufgebaut und nicht während des Ladevorgangs der Daten permanent gepflegt werden.

Das Problem

Zur Lösung des Problems muss man weiterhin wissen, dass ein InnoDB Cluster bestimmte Voraussetzungen an das Datenmodell stellt. So müssen beispielsweise alle Tabellen der DB über die Engine InnoDB verwaltet werden (ok, das Produkt heißt ja auch InnoDB Cluster ;-) ). Eine weitere Anforderung ist die, dass alle Tabellen über einen Primary Key verfügen müssen, da dieser für eine performante Verarbeitung von Transaktionen im Cluster benötigt wird. Das Deaktivieren von Indizes ist aus diesem Grund nicht erlaubt.

Versucht man beispielsweise die Indizes in einem Cluster auf einer Tabelle zu deaktivieren, so kommt es zu einer Warnung:

MySQL  localhost:3306 ssl  car  SQL > alter table manufacturer disable keys;
Query OK, 0 rows affected, 1 warning (0.0317 sec)
Note (code 1031): Table storage engine for 'manufacturer' doesn't have this option 

Auf der speziellen Version des Kunden (und wir konnten dieses Verhalten in unserem Labor nicht reproduzieren) verhielt sich die DB äußerst merkwürdig. Das Deaktivieren der Indizes (zumindest das Kommando wurde akzeptiert und eine Warnung generiert) und das Laden der Daten lief durch. Beim Aktivieren der Indizes passierte hingegen gar nichts mehr. Die Session lief nicht weiter, es wurde aber auch kein Fehler oder keine Warnung generiert. Irgendwann lief die Session auf einen Timeout (Variable „wait_timeout") und der Import wurde angebrochen.
Dieses Verhalten ist natürlich etwas merkwürdig.

Auf einem unserer internen Testsysteme, welches zumindest auf dem gleichen Minor-Release lief, wurden beide Anweisungen (Deaktivierung und Aktivierung der Indizes) mit einer Warnung quittiert. Der Import-Prozess lief jedoch erwartungsgemäß bis zum Ende durch.

Die Lösung

Um das Problem zu lösen und da die Datenmenge und die Import-Zeiten keine kritische Größe darstellten, haben wir an dem Backup-Prozess gefeilt. Um die problematischen Statements loszuwerden, haben wir beim Backup den zusätzlichen Parameter „--skip-disable-keys" aufgenommen. Dieser sorgt dafür, dass um den eigentlichen Ladevorgang die Indizes weder deaktiviert noch aktiviert werden. Damit konnte der Kunde die DB dann erfolgreich auf dem neuen Cluster importieren und seine weiteren Tests durchführen.

Fazit

Auch wenn der Fehler an dieser Stelle relativ einfach zu erklären war (Indizes sind essentiell für den Cluster), war das Verhalten dieses Systems mehr als merkwürdig und konnte nicht auf den ersten Blick erkannt werden. Gerade bei komplexeren Lösungen wie Clustern denkt man schnell in sehr komplexen Zusammenhängen:

  • zu klein dimensionierte Speicherbereiche (die Tabelle des Kunden hatte x Mio. Datensätze)
  • Problem in der Kommunikation der Knoten (Latenzen, Cluster-Variablen/-Konfiguration)
  • ….

Oftmals hilft hier ein Schritt zurück und die Draufsicht eines noch unbeteiligten DBAs, um auch einfache Lösungen wieder in den Blick zu bekommen.

By accepting you will be accessing a service provided by a third-party external to https://blog.ordix.de/