Der Umstieg auf InnoDB

  • Beitrags-Autor:
  • Beitrags-Kategorie:Software & Co.
  • Lesedauer:4 min Lesezeit

Man hört hier und da, InnoDB als Storage Engine für MySQL wäre besser. Nur was bedeutet besser? Schneller? Speicher schohnender?

Der größte Vorteil von InnoDB (übernommen von Oracle, aber GPL 2 lizensiert) sind die sog. row-locks, die nur eine einzige Zeile einer Datenbanktabelle sperren, statt gleich die ganze Tabelle unzugänglich zu machen. Transactions kann man auch mit MyISAM haben (nur eben ohne row-lock). Ich weiß zwar nicht genau, ob MyISAM auch ACID transactions gerantiert, aber ich kann mir kaum vorstellen, dass es nicht so ist.

Der Weg zu InnoDB kann manchmal richtig hard sein… Man muss vieles beachten: von I/O im Betriebssystem bis hin zu Überprüfung aller Skripte, die auf MySQL zugreifen.

Wenn man an eine Umstellung auf InnoDB denkt, muss man als erstes sehr kritisch mit sich selbst umgehen. Ist meine Datenbank-Architektur überhaupt auf einem Level, den man die 3. Normalform nennt? Oder schreibe ich in die Spalten jeden Sch..ss und versuche mit „%etwas%“ eine Information heruaszufinden? Sind die Zeilen-Werte möglichst eindeutig und als Relationen zwischen verschiedenen Tabellen zu benutzten? Oder ist alles in einer Monstertabelle? Sind nur die nötigen Indexe angelegt oder lässt man einfach alles indexieren? Sollte ich nicht besser Sphinx betreiben, statt in FULLTEXT-Indexen herumzukramen?

By the way: FULLTEXT gibt es in InnoDB nicht. Also löschen! Danach – oder noch besser zuvor – die Skripte nach „MATCH … AGAINST“ durchsuchen. Diese SQL-Statements benötigen die Volltext-Indexe. Und wo wir gerade dabei sind, unsere Skripte anzuschauen: gibt es da eine Möglichkeit, gleich nach der Auswahl der Datenbank ein einfaches SQL „BEGIN“ und am Ende des Ablaufs ein SQL „COMMIT“ abzusetzen? Wenn man „SET AUTOCOMMIT=0“ benutzt (noch vor „BEGIN“), kann MySQL erst einmal unsere „Wünsche“ auf den Wunschzettel schreiben, so tun, als hätte sie es erfüllt, und erst am Ende (bei „COMMIT“) Alles in einem Rutsch ausführen oder (bei „ROLLBACK“) zurücknehmen. Mit AUTOCOMMIT gibt es keinen Wunschzettel… Alles wird direkt in die Tabellen reingeschrieben! Vorteil gegenüber MyISAM ist gleich NULL! Vor allem bei unvorhersehbaren Updates (z.B. 2x Update von denselben Zeilen auf dieselben Werte) würde unser Wunsch-Update mit BEGIN-COMMIT nur einmal in die Datenbank geschrieben… und das spart Zeit!

Man sollte sich unbedingt die Beschreibung von Beschränkungen in InnoDB als Bett-Lektüre zu Gemüte führen. Vor allem die Abschnitte über schwachsinnige COUNT’s ohne WHERE Bedingungen, die 2 GB Grenze bei Dateien (wohl eher Vergangenheit wie Linuxkernel 2.4 und ext2), das AUTO_INCREMENT und Tabellen-LOCK’s. Dass eine Tabelle nicht mehr als 1000 Spalten haben sollte oder eine Zeile die 4GB-Grenze nicht überschreiten darf ist ja wohl klar (keine Monstertabelen!). Auch VARCHAR-Spalten dürfen zusammen nicht mehr als 65535 Zeichen haben (das entspricht z.B. 256 Spalten a 256 Zeichen).

Wenn das alles einigermaßen zutrifft, kann man sich der Einrichtung von InnoDB in my.cnf bzw. my.ini zuwenden. Der erste und entscheidende Wert für InnoDB ist: „innodb_buffer_pool_size„. Man sollte ihn wie folgt berechnen

key_buffer + (max_connections * (sort_buffer_size+read_buffer_size+binlog_cache_size)) +
max_connections * 2

bedeutet: 1024+ (256*(2)) + 256*2 = 2048 also 2048 MB RAM sollte für InnoDB von MySQL freigehalten werden, wenn man den key_buffer so hoch und die maximale Zahl der Verbindungen mit 256 beziffert (eher selten anzutreffen). Hier stoßen wir auf die erste Grenze: 2 GB RAM für ein userprocess – das ist viel (bei 32 bit). Wenn man noch höher gehen will, sollte man mehr als 4 GB RAM haben, und CONFIG_X86_4G=y, CONFIG_HIGHMEM64G=y, CONFIG_HIGHMEM=y, CONFIG_X86_PAE=y, CONFIG_HIGHMEM64G=y in den kernel einkompilieren. Vor allem 32 bit Systeme können schnell abstürzen, wenn der Speicher nicht reicht! Die 64-Bitter sehen das etwas entspannter. Man sollte innodb_buffer_pool_size hoch ansetzen: 50, allerhöchstens aber 80% des verfügbaren RAM (wenn ausser MySQL sonst auf dem Rechner nichts läuft). Mit innodb_additional_mem_pool_size kann man noch etwas Puffer einräumen – aber nicht zu viel! Farhan Mashraqi empfiehlt 10 MB.

Als nächstes sind die Log-Dateien dran. innodb_log_file_size entscheidet unter anderem, wie oft wirklich in die Tabelle geschrieben wird. Ist sie groß (so groß wie innodb_buffer_pool_size, aber kleiner als 4 GB) kann das der MySQL bei Zugriffs-Spitzen etwas Spielraum einräumen.