Jörg: Fatal error: Uncaught mysqli_sql_exception: The user specified as a definer (''...@'...') does not exist in...

Hallo,

ich nutze seit graumer Zeit das von Raketenskripter aka Raketenwilli geschriebene Script, um nächtlich meine Datenbanken zu sichern. Danke nochmal für das tolle Script! 👍

Das Script läuft tadellos und damit ich im Falle des Falles hieraus gezogen Backups schnell und unkompliziert einspielen kann, habe ich mir eine bequeme Api geschrieben, die das vorzüglich macht. Der Konsolenbefehl lautet dann:

Konsolenbefehl zum Einspielen der Datenbank

/bin/gunzip -c /mein/pfad/zum/dump/2023-05-02/2023-05-02_01:59:01_myDB.sql.gz | grep -vP "^USE \`myDB\`;$" | /usr/bin/mysql -u myDB-kopie -p'myPass!' -h localhost -B myDB-kopie

Nun habe ich die Api dahin gehend erweitert, mir auch einen Shellbefehl zu generieren, der mir ein beliebiges Backup in meine lokale Xamppinstallation einspielt, auch das funktioniert eingentlich sehr gut. Die DB wird anstandslos eingespielt.

/bin/gunzip -c /home/thatsMe/import_db/2023-05-02/2023-05-02_01:59:01_myDB.sql.gz | grep -vP "^USE \`myDB\`;$" | /mnt/d/myXampp8/mysql/bin/mysql -u root -p -h localhost myDBname

Klappt hervorragend, die DB wird eingespielt.

Aber beim Arbeiten mit der DB wird folgedender Fehler erzeugt:

Fatal error: Uncaught mysqli_sql_exception: The user specified as a definer ('...'@'....de') does not exist in D:\myXampp8\htdocs\testverz\script.php:601

Wo setze ich an?
Kann ich diesen User aus der *.sql.gz mit einem weiteren Konsolenbefehl nicht zuvor löschen oder ersetzen?

Jörg

  1. Hallo Jörg,

    du hast den User rausgepunktet.

    Nehmen wir mal an, da hätte

    as a definer ('foo'@'example.org') does
    

    gestanden.

    Würde es denn den User foo@example.org geben? Irgendwie muss er ja an diese Definer-ID herangekommen sein und ich kann mir vorstellen, dass da im Script Hochkommas sind, wo keine hingehören und sie dann in der DB landen, statt nur Strings zu begrenzen.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Hallo Rolf,

      Nehmen wir mal an, da hätte

      as a definer ('foo'@'example.org') does
      

      gestanden.

      Würde es denn den User foo@example.org geben? Irgendwie muss er ja an diese Definer-ID herangekommen sein und ich kann mir vorstellen, dass da im Script Hochkommas sind, wo keine hingehören und sie dann in der DB landen, statt nur Strings zu begrenzen.

      Den User würde es auf dem Produktivserver geben, aber natürlich in meinem XAMPP nicht.

      Daher würde ich gerne den Dump so bearbeiten, dass es den User dort im Dump auch nicht mehr gibt, bevor ich ihn in mein XAMPP importiere.

      Jörg

    2. Ich habe gerade mal meine Trigger entfernt und schopn lässt sich mit den Daten arbeiten.

      Es muss also an den Triggern liegen, aber inwiefern?

      Sind die auf einen DB-User registriert?

      Und wenn ja, wie reagiere ich darauf?

      Jörg

      1. Sind die auf einen DB-User registriert?

        Habe gerade mal einen Dump geöffnet und die Trigger sind dort so vermerkt:

        DELIMITER ;;
        /*!50003 CREATE*/ /*!50017 DEFINER=`DB555555`@`server%.example.com`*/ /*!50003 TRIGGER `myTriggerName` AFTER INSERT ON `tableA`
         FOR EACH ROW BEGIN
            INSERT INTO ... 
            SET 
            ...
            Erstelldatum = now();
            
        END */;;
        DELIMITER ;
        
      2. Es muss also an den Triggern liegen, aber inwiefern?

        Naja. Wie es scheint liegt es aber an den Daten im Dump.

        Wenn Du auf dem Zielserver Benutzer nicht willst, die Du auf dem Quellserver hast, die dann aber in Triggern als creator werden (woran Rechte hängen), dann geht das notwendig in die Hose.

        Lösung:

        Jage den Dump durch etwas wie sed. Ersetze dabei den creator des Triggers durch einen existierenden user:

        Test: (Datei: test.txt)

        Holla.
        Da steht 'foo'@'bar.de' drin. Wirklich 'foo'@'bar.de'.
        

        Aktion

        $ sed -e "s/'foo'@'bar.de'/'bar'@'foo.org'/g" test.txt > text.neu;
        

        Ausgabe:

        $ cat text.neu
        
        Holla.
        Da steht 'bar'@'foo.org' drin. Wirklich 'bar'@'foo.org'.
        
        1. Hallo Raketenwilli,

          Es muss also an den Triggern liegen, aber inwiefern?

          Naja. Wie es scheint liegt es aber an den Daten im Dump.

          Ja klar, stimmt.
          Es liegt daran, dass die Trigger in meinem XAMPP automatisch auf root@localhost als Definer angelegt werden.
          keine Ahnung, wo mysql abspeichert, dass die eigentlich auf einen anderen Definer laufen sollten.

          Wenn Du auf dem Zielserver Benutzer nicht willst, die Du auf dem Quellserver hast, die dann aber in Triggern als creator werden (woran Rechte hängen), dann geht das notwendig in die Hose.

          Verstehe.

          Lösung:

          Jage den Dump durch etwas wie sed. Ersetze dabei den creator des Triggers durch einen existierenden user:

          Test: (Datei: test.txt)

          Holla.
          Da steht 'foo'@'bar.de' drin. Wirklich 'foo'@'bar.de'.
          

          Aktion

          $ sed -e "s/'foo'@'bar.de'/'bar'@'foo.org'/g" test.txt > text.neu;
          

          Ja, genau an sowas dachte ich, danke! 👍

          Kann ich auch den gepackten dump gleich durch sed jagen und danach, wenn erfolgreich, gleich importieren, also so in der Art?

          gunzip -c /home/thatsMe/import_db/2023-05-02/2023-05-02_01:59:01_myDB.sql.gz | sed -e "s/'foo'@'bar.de'/'bar'@'foo.org'/g" | gzip > /home/thatsMe/import_db/2023-05-02/2023-05-02_01:59:01_myDB_neu.sql.gz && /mnt/d/myXampp8/mysql/bin/mysql -u root -p -h localhost myDBname < /home/thatsMe/import_db/2023-05-02/2023-05-02_01:59:01_myDB_neu.sql.gz
          

          Jörg

          1. Kann ich auch den gepackten dump gleich durch sed jagen und danach, wenn erfolgreich, gleich importieren, also so in der Art?

            gunzip -c /home/thatsMe/import_db/2023-05-02/2023-05-02_01:59:01_myDB.sql.gz | sed -e "s/'foo'@'bar.de'/'bar'@'foo.org'/g" | gzip > /home/thatsMe/import_db/2023-05-02/2023-05-02_01:59:01_myDB_neu.sql.gz && /mnt/d/myXampp8/mysql/bin/mysql -u root -p -h localhost myDBname < /home/thatsMe/import_db/2023-05-02/2023-05-02_01:59:01_myDB_neu.sql.gz
            

            Oder in meinem Fall:

            gunzip -c /home/thatsMe/import_db/2023-05-02/2023-05-02_01:59:01_myDB.sql.gz | sed -E "s/DEFINER=\`[^`]+\`@\`example\.com\`/DEFINER=\`root\`@\`localhost\`/g" > /home/thatsMe/import_db/2023-05-02/2023-05-02_01:59:01_myDB_neu.sql && \
            gzip /home/thatsMe/import_db/2023-05-02/2023-05-02_01:59:01_myDB_neu.sql && \
            /mnt/d/myXampp8/mysql/bin/mysql -u root -p -h localhost myDBname < /home/thatsMe/import_db/2023-05-02/2023-05-02_01:59:01_myDB_neu.sql.gz
            

            oder vielleicht auch direkt ohne den Zwischenschritt des Speicherns in einer neuen Datei?

            gunzip -c /home/thatsMe/import_db/2023-05-02/2023-05-02_01:59:01_myDB.sql.gz | sed -E "s/DEFINER=\`[^`]+\`@\`example\.com\`/DEFINER=\`root\`@\`localhost\`/g" | mysql -u root -p -h localhost myDBname
            

            Passt das?
            Und lieber in einem Schritt oder mit Zwischenschritt?

            Jörg

            1. gunzip -c /home/thatsMe/import_db/2023-05-02/2023-05-02_01:59:01_myDB.sql.gz | sed -E "s/DEFINER=\`[^`]+\`@\`example\.com\`/DEFINER=\`root\`@\`localhost\`/g" | mysql -u root -p -h localhost myDBname
              

              Bei sed stürzt mein Linux ab, ich vermute mal, dass es an Arbeitsspeicher fehlt oder die Datei einfach mit fast einem GB zu groß ist.

              Mit awk geht es aber:

              gunzip -c /mein/pfad/zum/dump/test.sql.gz | awk '{gsub(/DEFINER=`[^`]+`@`example\.com`/, "DEFINER=`root`@`localhost`")}1' | grep -vP "^USE \`myDB\`;$" | /mnt/d/xampp8/mysql/bin/mysql.exe -u root -p -h localhost myDBname
              

              Danke für die Hilfe und Gruß,

              Jörg

              1. Danke für die Hilfe

                Bitte. Gern geschehen. (Und entschuldige mein Mittagschläfchen…)

                1. Danke für die Hilfe

                  Bitte. Gern geschehen. (Und entschuldige mein Mittagschläfchen…)

                  Gar kein Problem, Du hast mich auf die richtige Fährte gebracht, da ist dann ein Mittagsschläfchen nicht mehr als verdient. 😉

                  Jörg

  2. Hello Jörg,

    bevor Du dir über die Skripte Gedanken machst, solltest Du dir nochnals über die Rahmenbedingungen klar werden.

    • was wird gefordert?
      -- dynamische Sicherung ggf. auch während des Betriebs?
      -- Vollsicherung mit Offtime des Datenbankservers
    • wie kann ich das erreichen?
    • welche Nachteile hat welche Lösung?
    • Wie unterstützt mich das Datenbanksystem dabei?
    • Wie unterstützen mich das Filesystem und das Betriebssystem dabei?
    • Wo wird gesichert?
      -- im LAN
      -- Über das WAN, also z. B. bei mir zuhause?
    • Wie hoch ist die Busgeschwindigkeit zwischen lokalen Permanentspeichern?
    • Wie hoch ist die Transfergeschwindigkeit im LAN oder WAN (Internet)?

    Ich beschäftige mich seit ca. 20 Jahren mit diesen Aufgabenstellungen und poste hier öfter Beschreibungen meiner (wenigen) Problemfälle bzw. Museumshosts. Das wird dann von einigen Mitlesern oft so verstanden, als wären da keine neuen Erkenntnisse. Leider sind erfahrungsgemäß die meisten Hosts älter (manchmal bewahrt einen das aber auch vor neuen Lücken).

    Fastix aka Rakete* unterstützt mich seitdem wirklich gut mit innovativen Ideen und diversen Lösungen.

    Allerdings kann auch er nicht raten, welche Möglichkeiten Du außer den beschriebenen noch hättest, um deiner Aufgabenstellung im Detail gerecht werden zu können.

    Die Fragen von

    • möglicher Offtime
    • mittlerer Übertragungskapatzität (egal ob lokal oder per WAN/GAN)

    sind also immer als erstes zu klären.

    Glück Auf
    Tom vom Berg

    --
    Es gibt soviel Sonne, nutzen wir sie.
    www.Solar-Harz.de
    S☼nnige Grüße aus dem Oberharz
    1. Hallo Tom,

      immer auf dem Boden bleiben.
      Es wird nächtlich ein Dump jeder DB gesichert.

      Es geht nur ums Wiedereinlesen und das nicht auf dem server, denn das klappt ganz vorzüglich.

      Es geht nur darum, dass ich ab und an gerne zum lokalen testen eine DB auf mein XAMPP einspielen möchte. Habe ich bisher über Einspielen auf dem server und anschließendem Kopieren der DB auf mein XAMPP gemacht. Klappt.

      Aber bequemer wäre es natürlich, den S`Dump ohne Umweg gleich ins XAMPP zu importieren, der befehl dafür liegt vor und funktioniert auch vorzüglich.

      Lediglich kann ich mit den Daten nicht arbeiten, weil die "userbehaftet" sind und es diesen User verstädlicherweise auf meinem XAMPP nicht gibt.

      Es geht bei meiner Frage also wirklich lediglich darum, den Dump nachträglich vom User abzutrennen.

      Jörg

      bevor Du dir über die Skripte Gedanken machst, solltest Du dir nochnals über die Rahmenbedingungen klar werden.

      • was wird gefordert?
        -- dynamische Sicherung ggf. auch während des Betriebs?
        -- Vollsicherung mit Offtime des Datenbankservers
      • wie kann ich das erreichen?
      • welche Nachteile hat welche Lösung?
      • Wie unterstützt mich das Datenbanksystem dabei?
      • Wie unterstützen mich das Filesystem und das Betriebssystem dabei?
      • Wo wird gesichert?
        -- im LAN
        -- Über das WAN, also z. B. bei mir zuhause?
      • Wie hoch ist die Busgeschwindigkeit zwischen lokalen Permanentspeichern?
      • Wie hoch ist die Transfergeschwindigkeit im LAN oder WAN (Internet)?

      Ich beschäftige mich seit ca. 20 Jahren mit diesen Aufgabenstellungen und poste hier öfter Beschreibungen meiner (wenigen) Problemfälle bzw. Museumshosts. Das wird dann von einigen Mitlesern oft so verstanden, als wären da keine neuen. Leider sind werfahrungsgemäß die meisten Hosts älter (manchmal bewahrt einen das aber auch vor neuen Lücken).

      Fastix aka Rakete* unterstützt mich seitdem wirklich gut mit innovativen Ideen und diversen Lösungen.

      Allerdings kann auch er nicht raten, welche Möglichkeiten Du außer den beschriebenen noch hättest, um deiner Aufgabenstellung im Detail gerecht werden zu können.

      Die Fragen von

      • möglicher Offtime
      • mittlerer Übertragungskapatzität (egal ob lokal oder per WAN/GAN)

      sind also immer als erstes zu klären.

      1. Hello Jörg,

        immer auf dem Boden bleiben.

        Ok, ich bin draußen.

        Du darfst aber gerne später nochmal nachfragen, wenn Du erkannt hast, dass Du viel zu tief einsetzt.

        Glück Auf
        Tom vom Berg

        --
        Es gibt soviel Sonne, nutzen wir sie.
        www.Solar-Harz.de
        S☼nnige Grüße aus dem Oberharz
        1. immer auf dem Boden bleiben.

          Ok, ich bin draußen.

          Einverstanden. 👍

  3. Lieber Jörg,

    wenn ich einen gezippten SQL-Dump auf meinem localhost einspielen will, verwende ich das hier:

    unzip -p Downloads/meine_db.sql.zip | mysql -u root -p meine_db
    

    Zur Erklärung: Nach dem Entpacken wird der Inhalt mit dem Pipe-Symbol an ein anderes Programm weiter gereicht, in diesem Fall das Kommandozeilen-Programm mysql. Dieses erhält mit dem -u-Schalter einen Benutzernamen (hier root) und mit dem -p-Schalter die Aufforderung, das Passwort einzufordern, welches ich dann eintippen muss.

    Wenn Du das Eintippen des Passwortes wegautomatisieren willst, weil Du die Backups automatisch einspielen willst, dann braucht es dafür Tricks mit echo und so.

    Liebe Grüße

    Felix Riesterer