Contao Konferenz & College 2019 in Duisburg - JETZT TICKET SICHERN!
Ergebnis 1 bis 2 von 2

Thema: AUTO_INCREMENT-"Fehler" bis MySQL Version 5.7

  1. #1
    Contao-Nutzer
    Registriert seit
    08.10.2018.
    Beiträge
    9

    Standard AUTO_INCREMENT-"Fehler" bis MySQL Version 5.7

    Hallo Community,

    bin nicht ganz sicher, in welches Forum dieser Beitrag gehört, ansonsten gerne verschieben.
    Evtl. kann man es auch trennen in 2 Diskussionen (Problembehebung + AUTO_INCREMENT-Fehler)...

    TLDR;
    Problem: Gelöschte IDs werden in Datenbank neu verwendet, Problem liegt in Funktionsweise des AUTO_INCREMENTS. Dieses wird bei Serverneustart mit erstem freien Wert belegt, anstatt dem tatsächlich gespeicherten Wert.
    ENDE TLDR;

    ich bin in der Contao-Installation eines unserer Kunden (durch dessen Hinweis) auf einen seltsamen und evtl. tiefgreifenden Fehler gestoßen, der MySQL-Datenbanken bis Version 5.7 betrifft.

    Zugegeben, es betrifft in diesem Fall hauptsächlich EFG (evtl. sollte dieser Thread auch dorthin verschoben werden), allerdings vermute ich, dass die Auswirkungen weitere Erweiterungen, wenn nichts sogar auch den Contao-Core selbst betreffen könnten.

    AUSGANGSSITUATION:
    Bei Abschicken eines Formulars wird ein Teilnehmer als einzelner Datensatz in die Formular-Datenbank-Tabelle #1 (tl_form_details) eingetragen, verlinkt mit verschiedenen Einträgen in Tabelle #2, welche verschiedene Details (Name, Datum+Uhrzeit, E-Mail, etc.pp.) enthalten. Der Datensatz in Tabelle #1 hat, selbstverständlich eine ID, welche via AUTO_INCREMENT automatisch hochgezählt wird. Jetzt wurde diese ID mMn zweckentfremdet und als Alias für das Backend angegeben, sodass unser Kunde der Einfachheit halber diese ID als Teilnehmer-ID verwendet hat.

    PROBLEM:
    Wenn ein Teilnehmer gelöscht wird, wird im Normalfall ein neuer Eintrag (über das Formular) mit der nächsthöheren ID angelegt. Es passierte jetzt jedoch scheinbar zufällig, dass alte IDs neu vergeben wurden, wodurch bspw. zwischen Teilnehmern #530 und #531 auf einmal der Teilnehmer #210 auftauchte, diese hatten sich jedoch zeitlich nacheinander angemeldet.

    RECHERCHE & VERMUTUNG:
    Bei der Fehlersuche stieß ich (über einen Freund, der mehr von Datenbanken versteht als ich) auf folgenden Artikel:
    Kamil from DeSmart: Be Careful With MySQL's auto_increment
    mit einer weiteren Verlinkung in diesem Artikel auf folgende Seite:
    MySQL 8.0 Reference Manual - AUTO_INCREMENT Handling in InnoDB
    Daraus ließ sich für mich schließen, dass dieser "Fehler" (von MySQL als Feature ausgezeichnet) vermutlich nicht nur mich betrifft, sondern potentiell auch andere.
    Das tieferliegende Problem scheint in meinem Fall gewesen zu sein, dass 1. der Webhoster einen Server-Neustart veranlasst hat, wodurch MySQL den auto_increment-Wert durch den Algorithmus
    Code:
    SELECT MAX(ai_col) FROM t FOR UPDATE;
    auf den ersten verfügbaren Wert gesetzt hat und 2. MySQL laut Hoster auf 5.6 steht, was durchaus sinnig ist, allerdings ist seit April 2018 Version 8.0 verfügbar, in welcher ein Fix für die (falsche) Initialisierung des AUTO_INCREMENT-Wertes nach Serverneustart besteht.

    MOTIVATION:
    Warum ich diese umfangreichen Informationen hier poste und nicht einfach nur mein Problem schildere? Ich möchte die Aufmerksamkeit erhöhen für dieses Verhalten der InnoDB-Datenbanken (und anscheinend auch anderer, denn die bei mir betroffene Datenbank läuft unter MyISAM), und mögliche Implikationen im Zusammenhang mit Contao und Contao-Erweiterungen aufzeigen.

    FRAGEN:
    Habt ihr dieses Problem schonmal gehabt? Seid ihr ganz ruhig und denkt, dass ist alles schon okay so? Habt ihr evtl. eine Lösung für mich, durch die ich das Updaten von MySQL auf Version 8.0 umgehen kann? Kann ich ohne Probleme auf MySQL 8.0 updaten (lassen, durch den Hoster) oder geht mir dadurch die ganze Webseite flöten?
    Ich bin kein Datenbank-Spezialist, daher bin ich nicht ganz sicher, ob dieser Beitrag über meine Lösungssuche hinaus sinnbringend ist, aber es wäre prima, wenn ich zumindest in meinem Fall eine Lösung finden könnte...
    Auch Lösungen, die die Datenbank umgehen, sind gut, durch das Alter von EFG und der Verwendung eines Multipage-Formulars ist in diesem Fall aber z.B. eine Lösung über einen PHP-Counter schwierig(/nicht möglich?).

    LG
    Mathis

  2. #2
    Contao-Urgestein
    Registriert seit
    22.10.2013.
    Beiträge
    7.997
    User beschenken
    Wunschliste

    Standard

    Führt die "komische" Initialisierung beim Serverneustart dazu, dass doppelte IDs erzeugt werden können? Kann ich mir schwer vorstellen, denn das wäre sehr schnell unangenehm aufgefallen und schnell gefixt worden. Also scheint auch mit dieser Initialisierung eine Autoincrement-Spalte eindeutige Werte zu haben und somit als primary key tauglich zu sein. Ich nenne die Initialisierung deswegen mal "komisch" oder "unerwartet" und nicht "fehlerhaft".

    Das Problem, das dieses Verhalten bei dem Kunden verursacht habe ich allerdings aus dem Beitrag nicht verstanden. Was MySQL da macht oder gemacht hat (genau genommen tut es das immer noch in ganz speziellen Fällen) ist, dass beim Neustart des MySQL-Servers der höchste Wert der Autoincrement Spalte ermittelt um den Wert für das Autoinkrement zu setzen. Bei einem INSERT wird der Wert dann eben um 1 erhöht. Das steht so im Manual und wird auch von Kamil so beschrieben. Also jedenfalls habe ich beim drüberlesen nirgends etwas gefunden, dass hier Lückenwerte benutzt werden oder was auch immer. MAX(ai_col) ist der höchste Wert der Spalte, nicht der erste (niedrigste) freie Wert. Es sollte also zumindest laut Manual kein freier "Lückenwert" verwendet werden. Was bei Kamil das Problem war ist, dass hier sein "Archiv" und die tatsächliche Tabelle nicht mehr konsistent waren, weil er sich darauf verlassen hatte, dass es niemals zwei verschiedene Einträge mit dem selben Autoincrement-Wert geben kann. Das kann allerdings passieren, wenn die zuletzt eingetragenen Spalten vor dem Neustart gelöscht werden. Im Archiv sind die noch drin, was dann eben zur Inkonsistenz führt. Ob man das jetzt als einen Fehler in Kamils Design oder als einen Bug in MySQL betrachtet, das liegt "im Auge des Betrachters", wie man so schön sagt. Ich kann mir jedenfalls nicht vorstellen, dass das erwartete Verhalten eine zugesicherte Eigenschaft von MySQL war, die man dann beim Serverneustart seitens der Entwickler außer Kraft gesetzt und das dann auch noch als Feature verkauft hat. Schliesslich ist es ja immer noch keine zugesicherte Eigenschaft, in ganz pathologischen Fällen bei Neustart nach einem Servercrash kann das ja immer noch passieren, nur eben nicht mehr bei einem ganz normalen Neustart. Man darf sich also schlicht niemals darauf verlassen - sonst ist man eben unter Umständen verlassen.

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

Lesezeichen

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •