MariaDB Bugfix sorgt für ein bisschen Ärger

Ein kleiner selbstverursachter Logikfehler bei Datenbankstrukturen macht kleinen Webanwendungen grade ein bisschen Stress. Damit Ihr damit keinen Stress habt, eine kurze Erklärung zum Thema und wie man das behebt und vermeidet.

MariaDB Update

Bis vor kurzem hatten wir auf den Servern noch die MariaDB 10.1.33 laufen, jetzt die 10.2.21 . Beim Wechsel von 10.1 auf  10.2 haben die Devs von MariaDB den globalen SQL-Modus umgestellt, daß er jetzt eher failed, statt tolerant zu sein.

Eine Beispieltabelle:

beispiel

#NameTypKollationAttributeNullStandardKommentareExtra
1 int(11) Neinkein(e)AUTO_INCREMENT
2 int(11) Nein2
3 text utf8_general_ciNein
4 int(11) Neinkein(e)

Jetzt führen wir diesen Insert aus:

INSERT INTO beispiel SET id=NULL, test = 3, name=“Fritz“, counter = 0;

Klappt. Kein Fehler. Nächster Insert :

INSERT INTO beispiel SET name=“Hans“, counter = 0;

Klappt.Tabelle sieht jetzt so aus :

testnamecounterid
3Fritz01
2Hans02

Nun der Insert hier:

INSERT INTO beispiel SET id=NULL, test=9,name=“Killer“;

und schon kommt die Meldung:

ERROR 1364 (HY000): Field ‚counter‘ doesn’t have a default value

Vollkommen zurecht, weil ich im Insert der Datenbank durch Auslassung gesagt habe, nimm den Defaultwert für das ausgelassene Feld.  Da es keinen Defaultwert für das Feld gibt, kann die Datenbank den auch nicht benutzen.

Jetzt ist das aber in MariaDB 10.1 noch möglich gewesen. Das lag daran, daß sich mit 10.2.4 die Defaults des Servermode geändert haben und der Modus „STRICT_TRANS_TABLES“ jetzt aktiv ist, wenn die  Webanwendung das nicht selbst anders haben will. Beweis:

MariaDB [msctest]> INSERT INTO beispiel SET id=NULL, test=9,name=“Killer“;
ERROR 1364 (HY000): Field ‚counter‘ doesn’t have a default value
MariaDB [msctest]> SELECT @@SQL_MODE;
+——————————————————————————————-+
| @@SQL_MODE |
+——————————————————————————————-+
| STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+——————————————————————————————-+
1 row in set (0.00 sec)

MariaDB [msctest]> set sql_mode = „ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION“;
Query OK, 0 rows affected (0.00 sec)

MariaDB [msctest]> INSERT INTO beispiel SET id=NULL, test=9,name=“Killer“;
Query OK, 1 row affected, 1 warning (0.00 sec)

Jetzt die spannende Frage, mit was die Datenbank den Wert aufgefüllt hat, von dem Sie nicht weiß, wie der aussehen müßte:

idtestnamecounter
13Fritz0
22Hans0
59Killer0

Mit „0“ , was bei einem INT ja auch naheliegend ist.

Klare Ansage

Bevor jetzt jemand den MariaDB Entwicklern die Schuld dafür geben will, daß die eigene Webseite nicht mehr so funktioniert: selbst Schuld!

Ihr habt von vornherein einen Logikbug in Eurer Datenbankstruktur + Weblogik gehabt, sich darüber zu beschweren ist heuchlerisch. Da die Webanwendung sich selbst den Modus setzen kann, mit dem die Datenbank mit Ihr arbeiten soll, hätte man das ja auch mal selbst explizit so setzen können, wie man es braucht. Defaults können sich ändern, damit muß man rechnen.

Abhilfe schaffen

  1. Datenbankstruktur so ändern, daß ein Default vorhanden ist.
  2. Im Insert keine Felder auslassen, sondern explizit setzen.
  3. vor der Anwendung set sql_mode = „ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION“;  absetzen, dann hat man wieder das alte Verhalten

Viel Spaß jetzt damit 🙂