PHP 8.0 / MariaDB 10.3: mysqli_store_result() schlägt fehl, wenn zu viele Parameter/-werte ("Commands out of sync; you can't run this command now")

  • PHP

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von Marcus Gräfe.

    PHP 8.0 / MariaDB 10.3: mysqli_store_result() schlägt fehl, wenn zu viele Parameter/-werte ("Commands out of sync; you can't run this command now")

    Ich habe derzeit nachfolgendes Problem in einer PHP-8.0-Anwendung in Verbindung mit MariaDB 10.3 (unter Ubuntu 20). Das Problem tritt nicht auf unter Windows 10 mit MariaDB 10.5 (und auch PHP 8.0). Ich vermute derzeit, dass es evtl. irgendeine Einstellung von PHP und/oder MariaDB ist und kein im PHP-Code (oder in der SQL-Anweisung) behebbarer Fehler. Aber wer weiß ...

    Mein abgespeckter PHP-Code (inkl. SQL):

    PHP-Quellcode

    1. // 2 Tabellen: daten (Felder: nummer, kunden_id), kunden (Felder: id, name)
    2. // [...] mysqli-Datenbankverbindung wird korrekt aufgebaut, steckt in Objekt $db [...]
    3. $stm = $db->prepare('
    4. SELECT d.nummer, k.name
    5. FROM daten d
    6. LEFT JOIN kunden k ON k.id = d.kunden_id
    7. WHERE k.id IN (?, ?, ?, ?, ?)
    8. ORDER BY k.name, d.nummer
    9. ')
    10. $stm->bind_param('iiiii', 1, 2, 3, 4, 5);
    11. $stm->execute(); // keine Exception und Ergebnis ist "true"
    12. $stm->store_result(); // <== hier tritt der Fehler auf: Commands out of sync; you can't run this command now
    13. // [...] $stm->bind_result [...] $stm->fetch() [...]

    Dieser Code funktioniert erst mal einwandfrei. Aber nur bis WHERE k.id IN (?, ?, ?, ?, ?) und bind_param('iiiii', 1, 2, 3, 4, 5) jeweils eine große Anzahl an Werten beinhaltet. Hunderte sind möglich, aber bei Tausenden kommt der genannte Fehler. Aber nur auf dem Linux-System. Nehme ich die WHERE-Bedingung ganz raus, so klappt es, auch wenn es (in meinem Fall) 35.000 Datensätze sind. Die Anzahl der Daten ist also kein Problem, sondern offenbar die Anzahl der Parameter.

    Hat jemand eine Idee? Sämtliche Suchergebnisse im Netz bzgl. der konkreten Fehlermeldung führen zu Lösungen, die in meinem Fall nicht zutreffen. Nämlich dass mehrere SQL-Anweisungen parallel ausgeführt werden, mehr als ein Result-Set ankommt oder man eine neue Abfrage startet, ohne die alte komplett abgerufen zu haben oder aus dem Speicher entfernt hat. Sämtliche mysqli-spezifischen Anweisungen in der ganzen PHP-Datei sind oben aufgelistet, mehr habe ich nicht. D. h. da kann nichts reinpfuschen.

    EDIT: In der MariaDB-Konfiguration steht max_allowed_packet = 16M. Das wäre die einzige Einstellung, die mir hier einfallen würde. 16M sollte ausreichen, aber auch 32M oder 1G lösen das Problem nicht. Laut phpMyAdmin wird diese Einstellung aber durchaus übernommen.
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Marcus Gräfe“ ()

    Hi,

    @Marcus Gräfe ich konnte dazu auch nix finden was du nicht schon gefunden hast, mich würde hier allerdings interessieren, ob der Fehler noch auftritt wenn du es mal mit PDO probierst - hast du die Möglichkeit?

    //EDIT: Von mysqli hab ich nicht allzuviel Ahnung tbh, aber das mysqli object selbst hat auch eine store_result() Methode, muss vielleicht die aufgerufen werden anstatt der des mysqli_stmt Objekts .. idk


    Link :thumbup:
    Hello World

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „Link“ ()

    Muss ich morgen mal schauen, ob ich, zumindest den einen Part testweise, auf PDO umstellen kann. Die ganze Anwendung sicher nicht, die ist zu umfangreich.
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum

    Link schrieb:

    das mysqli object selbst hat auch eine store_result() Methode, muss vielleicht die aufgerufen werden anstatt der des mysqli_stmt Objekts

    Nein, das sind zwei verschiedene Dinge. Ich habe ein Prepared-Statement, daher muss ich das store_result damit/davon benutzen. Das andere wäre nur für "normale" Queries. Übrigens kann ich das store_result auch weglassen und der Fehler kommt trotzdem (z. B. beim fetch). Es ist also nicht speziell die Anweisung, sondern jede Art von Zugriff auf das Ergebnis der Abfrage führt zum Fehler.

    Den PDO-Test mache ich jetzt. Allerdings wäre das nur interessant zu wissen, keine Lösung. Denn die Anwendung ist in einem Stadium, wo ich nicht die Zugriffsart mal eben umstellen kann. Zudem läuft es ja auf bestimmten Systemen und auch mit weniger Parameterwerten. Also am Ende evtl. einfach nur ein Bug in MariaDB 10.3.

    EDIT: Ich habe zunächst noch einen anderen Test gemacht. Ich habe unter Windows auch MariaDB 10.3 installiert. Dort gab es zunächst den Fehler, dass max_allowed_packet zu klein ist. Nachdem ich den Wert dort erhöht hatte, ging es. Letztendlich geht es somit unter Windows unter 10.3, 10.4 und 10.5 (auf einem System .3 und .5, auf einem anderen .4) und es geht nicht auf 2 Systemen unter Linux mit 10.3.

    Und ich habe festgestellt, dass nach dem execute so wirklich gar kein Befehl akzeptiert wird. Noch nicht einmal sowas wie result_metadata(), mit welchem ich an Informationen kommen wollte, die mir bei der Fehlersuche helfen. Alle Ausgabemöglichkeiten von Fehlern geben nichts aus, auch der SQL-State ist "0000" ("success").

    EDIT #2:

    Link schrieb:

    ob der Fehler noch auftritt wenn du es mal mit PDO probierst

    Habe ich nun gemacht. Es gibt jetzt gar keine Fehlermeldung, sondern es kommen beim fetch einfach keine Daten, sondern nur false. Die PDO-Verbindung ist auf ATTR_ERRMODE = ERRMODE_EXCEPTION (ERRMODE_WARNING auch getestet). PDO an sich geht aber, also mit wenigen Parametern geht's wie zuvor und es kommen Daten.

    EDIT #3: Korrektur, die Rückgabe false kommt bereits beim execute! Das war ohne PDO nicht so. Aber errorCode() und errorInfo() melden keine Fehler, eine Exception kommt auch nicht.
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Marcus Gräfe“ ()

    Ich habe es endlich nach stundenlanger Recherche und Rumprobieren rausgefunden.

    In der Konfiguration von MariaDB muss die Option in_predicate_conversion_threshold vom Standardwert 1.000 hochgesetzt werden. In meinem Fall waren über 10.000 nötig, ich habe zur Sicherheit 100.000 genommen. Also in_predicate_conversion_threshold = 100000.

    Über das Problem wurde hier berichtet: github.com/georgringer/news/is…4#issuecomment-1061919612

    EDIT: Ist nicht ganz richtig gewesen. Es gibt in MariaDB 10.3.34 (nur exakt diese Version) einen Bug. in_predicate_conversion_threshold = 0 behebt diesen. In allen anderen Versionen kann man den Wert auf dem Standardwert 1.000 lassen. Eingeführt wurde die Variable aber erst mit 10.3.18.

    Über den Bug wird hier berichtet: bugs.launchpad.net/ubuntu/+source/mariadb-10.3/+bug/1964622

    Was die Variable bewirkt steht hier: mariadb.com/kb/en/conversion-o…edicates-into-subqueries/
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Marcus Gräfe“ ()