MySQL Galera Cluster: Specified key was too long; max key length is 767 bytes

Der Grund diese Meldung ist, dass bei MySQL die Gesamtzahl aller UNIQUE/PRIMARY keys 767 Bytes nicht überschreiten darf, wobei bei utf8 drei- und bei utf8mb4 vier Bytes pro Zeichen kommen. Somit dürfte die Gesamtzahl aller UNIQUE/PRIMARY keys 191 Zeichen (767 / 4) pro Tabelle nicht überschreiten.

Dies wäre eigentlich auch bei normalen MySQL Installationen der Fall, im „standalone“-Modus wird jedoch diese Vorgabe nicht forciert, wobei Galera dies tut und DB-Importe, welche sich nicht an die MySQL-Spezifikation halten strikte ablehnt.

Achtung vor Workarounds
Im Internet kursieren Meldungen, wonach man

SET innodb_strict_mode=0;

setzen soll.
Dies hat jedoch in einem Galera-Cluster so fatale folgen, dass der ganze Cluster gekillt wird und sollte also NIE in einem Galera-Cluster zur Anwendung kommen. Stattdessen sollte, wie nachfolgend erklört das Schema nachhaltig so angepasst werden, dass es den MySQL-Spezifikationen entspricht.

Hat man beispielsweise eine Tabellendefinition, welche wie folgt aussieht:

CREATE TABLE `tabelle1` (
  `userid` int(10) NOT NULL,
  `username` varchar(255) NOT NULL,
  `firstname` varchar(255) NOT NULL,
  `lastname` varchar(255) NOT NULL DEFAULT 0,
  `address` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`userid`,`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

In diesem Beispiel wird der PRIMARY KEY aus ‚userid‘ und ‚username‘ gebildet. Diese Zwei Werte dürfen also nicht über 767 Bytes kommen.

Da jedoch beim charset „utf8mb4“ 4 Bytes pro Zeichen verwendet werden kommen wir da auf: 10 Zeichen + 255 Zeichen * 4 Bytes = 1060 Bytes total.

Die Lösung hier ist ganz einfach: In dem wir das Feld ‚username‘ von 255 Zeichen auf 150 Zeichen runter setzen sieht die Rechnung schon anders aus:
10 Zeichen + 150 Zeichen * 4 Bytes = 640 Bytes total
Damit dürfte dann einem erfolgreichen import nichts mehr im Wege stehen.

Schlechtes Datenbank-Design vermeiden
Das vorige Beispiel ist eigentlich an sich schon schlechtes Datenbank-Design, denn ein Primärschlüssel sollte niemals aus einem Text-String bestehen.
Die bessere Lösung wäre hier also, die die Datenbank so zu designen, dass der Primärschlüssel auch nur aus numerischen IDs besteht und dann wird man vermutlich auch nie an die erwähnte Grenze stossen.

Referenzen

Published by

Steven Varco

Steven ist ein Redhat RHCE-Zertifizierter Linux-Crack und ist seit über 18 Jahren sowohl beruflich wie auch privat auf Linux spezialisiert. In seinem Keller steht ein Server Rack mit diversen ESX und Linux Servern.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.