Zugriff verweigert; Sie benötigen (mindestens eines) der SUPER-Berechtigung (en) für diesen Vorgang


89

Also versuche ich, eine SQL-Datei in rds (1G MEM, 1 CPU) zu importieren. Die SQL-Datei ist wie 1.4G

mysql -h xxxx.rds.amazonaws.com -u Benutzer -ppass --max-allow-packet = 33554432 db <db.sql

Es blieb hängen bei:

ERROR 1227 (42000) at line 374: Access denied; you need (at least one of) the SUPER privilege(s) for this operation

Der tatsächliche SQL-Inhalt ist:

/*!50003 CREATE*/ /*!50017 DEFINER=`another_user`@`1.2.3.4`*/ /*!50003 TRIGGER `change_log_BINS` BEFORE INSERT ON `change_log` FOR EACH ROW
IF (NEW.created_at IS NULL OR NEW.created_at = '00-00-00 00:00:00' OR NEW.created_at = '') THEN
        SET NEW.created_at = NOW();
END IF */;;

another_user ist in rds nicht vorhanden, also mache ich:

GRANT ALL PRIVILEGES ON db.* TO another_user@'localhost';

Immer noch kein Glück.

Antworten:


167

Entfernen Sie entweder die DEFINER=..Anweisung aus Ihrer sqldump-Datei oder ersetzen Sie die Benutzerwerte durch CURRENT_USER.

Der von RDS bereitgestellte MySQL-Server erlaubt keine DEFINERSyntax für einen anderen Benutzer (meiner Erfahrung nach).

Sie können ein sedSkript verwenden, um sie aus der Datei zu entfernen:

sed 's/\sDEFINER=`[^`]*`@`[^`]*`//g' -i oldfile.sql

3
Du hast Recht. Der Grund, warum dies nicht funktioniert, besteht darin, dass die Angabe eines anderen Benutzers, DEFINERwenn der angemeldete Benutzer nicht über die SUPERBerechtigung verfügt (die selbst in RDS nicht zulässig ist), eine willkürliche Eskalation von Berechtigungen ermöglichen würde - gespeicherte Programme werden mit den Anmeldeinformationen und Berechtigungen ihrer Benutzer ausgeführt DEFINER(im Gegensatz zu denen des anrufenden Benutzers - dessen INVOKER), standardmäßig. Auch bei Serverfehler .
Michael - sqlbot

Mann du bist ein Lebensretter. Mein Hosting-Unternehmen hat mir beim Export eine beschädigte Datenbank mitgeteilt und nichts, was zur Wiederherstellung getan werden könnte. Perfekte Lösung.
Woody

4
Aus irgendeinem Grund musste ich * anstelle von + verwenden:sed 's/\sDEFINER=`[^`]*`@`[^`]*`//' -i oldfile.sql
Berend de Boer

Danke @BerenddeBoer
Awolad Hossain

1
@ WonderLand Sie können versuchen, awkdie etwas schneller sein könnte alssed
hjpotter92

35

Wenn Ihre Dump-Datei nicht vorhanden ist DEFINER, stellen Sie sicher, dass diese Zeilen auch entfernt werden, wenn sie vorhanden sind, oder kommentiert werden mit --:

Am Anfang:

-- SET @@SESSION.SQL_LOG_BIN= 0;
-- SET @@GLOBAL.GTID_PURGED=/*!80000 '+'*/ '';

Am Ende:

-- SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN;

12
Sie können dies verhindern, indem Sie --set-gtid-purged=OFFIhrem mysqldumpBefehl hinzufügen . Gefunden hier: stackoverflow.com/a/56251925
Illya Moskvin

13

Ein weiterer nützlicher Trick besteht darin, mysqldump mit der Option --set-gtid-purged = OFF aufzurufen, bei der die folgenden Zeilen nicht in die Ausgabedatei geschrieben werden:

SET @@SESSION.SQL_LOG_BIN= 0;
SET @@GLOBAL.GTID_PURGED=/*!80000 '+'*/ '';
SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN;

Ich bin mir nicht sicher über den DEFINER.


Vielen Dank! Es hat mir bei RDS geholfen
Victor

Vielen Dank. In meinem Fall lief ich SET @@GLOBAL.GTID_MODE = OFF;in MySql Workbench auf der exportierenden Seite aus der Quellendatenbank
Byron Wong

8

Nur ein zusätzliches MacOS-Update für hjpotter92.

Um seddas Muster in MacOS zu erkennen, müssen Sie vor dem =Zeichen einen Backslash einfügen, wie folgt :

sed -i old 's/\DEFINER\=`[^`]*`@`[^`]*`//g' file.sql

funktioniert ab 2020 mit MariaDB 10.4 unter macOS Catalina
Wayne

4

Problem : Sie versuchen, Daten (mithilfe der mysqldump-Datei) in Ihre mysql-Datenbank zu importieren, aber anscheinend haben Sie keine Berechtigung, diesen Vorgang auszuführen.

Lösung : Angenommen, Ihre Daten werden in Ihrer MySQL-Datenbank migriert, gesetzt und aktualisiert. Erstellen Sie mit mysqldump einen Snapshot und exportieren Sie ihn in eine Datei

mysqldump -u [username] -p [databaseName] --set-gtid-purged=OFF > [filename].sql

Aus der MySQL-Dokumentation:

GTID - Eine globale Transaktionskennung (GTID) ist eine eindeutige Kennung, die für jede auf dem Ursprungsserver (Master) festgeschriebene Transaktion erstellt und zugeordnet wird. Diese Kennung ist nicht nur für den Server eindeutig, von dem sie stammt, sondern für alle Server in einem bestimmten Replikationssetup. Es gibt eine 1: 1-Zuordnung zwischen allen Transaktionen und allen GTIDs.

--set-gtid-purged = OFF SET @@ GLOBAL.gtid_purged wird der Ausgabe nicht hinzugefügt, und SET @@ SESSION.sql_log_bin = 0 wird der Ausgabe nicht hinzugefügt. Verwenden Sie für einen Server, auf dem GTIDs nicht verwendet werden, diese Option oder AUTO. Verwenden Sie diese Option nur für einen Server, auf dem GTIDs verwendet werden, wenn Sie sicher sind, dass der erforderliche GTID-Satz bereits in gtid_purged auf dem Zielserver vorhanden ist und nicht geändert werden sollte, oder wenn Sie fehlende GTIDs manuell identifizieren und hinzufügen möchten.

Stellen Sie anschließend mit dem Benutzer root eine Verbindung zu Ihrer MySQL her, erteilen Sie Berechtigungen, leeren Sie sie und überprüfen Sie, ob Ihre Benutzerrechte korrekt aktualisiert wurden.

mysql -u root -p
UPDATE mysql.user SET Super_Priv='Y' WHERE user='johnDoe' AND host='%';
FLUSH PRIVILEGES;
mysql> SHOW GRANTS FOR 'johnDoe';
+------------------------------------------------------------------+
| Grants for johnDoe                                               |
+------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `johnDoe`                                  |
| GRANT ALL PRIVILEGES ON `db1`.* TO `johnDoe`                     |
+------------------------------------------------------------------+

Laden Sie nun die Daten neu und der Vorgang sollte zulässig sein .

mysql -h [host] -u [user] -p[pass] [db_name] < [mysql_dump_name].sql

3

.sql.gzEntfernen Sie zum Importieren der Datenbankdatei im Format den Definierer und importieren Sie ihn mit dem folgenden Befehl

zcat path_to_db_to_import.sql.gz | sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' | mysql -u user -p new_db_name
  1. Exportieren Sie zuvor die Datenbank im Format .sql.gz mit dem folgenden Befehl.

    mysqldump -u user -p old_db | gzip -9 > path_to_db_exported.sql.gz;

  2. Importieren Sie die exportierte Datenbank und entfernen Sie den Definierer mit dem folgenden Befehl.

    zcat path_to_db_exported.sql.gz | sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' | mysql -u user -p new_db


2

Stellen Sie beim Wiederherstellen der Sicherung sicher, dass Sie denselben Benutzernamen für den alten und den neuen verwenden.


2

Vollständige Lösung

Alle oben genannten Lösungen sind in Ordnung. Und hier werde ich alle Lösungen kombinieren, damit es für alle Situationen funktioniert.

  1. DEFINER behoben

Für Linux und Mac

sed -i old 's/\DEFINER\=`[^`]*`@`[^`]*`//g' file.sql


Öffnen Sie für Windows Atom oder Notepad ++ Ihre Dump-SQL-Datei mit Atom oder Notepad ++, drücken Sie Strg + F,
suchen Sie das Wort DEFINER und entfernen Sie die Zeile DEFINER = admin@% (oder für Sie möglicherweise etwas anders) von überall und speichern Sie die Datei.
Wie zum Beispiel
vor dem Entfernen dieser Zeile: CREATE DEFINER = admin@ %PROCEDUREMyProcedure
Nach dem Entfernen dieser Zeile: CREATE PROCEDUREMyProcedure

  1. Entfernen Sie die 3 Zeilen. Entfernen Sie alle diese 3 Zeilen aus der Speicherauszugsdatei. Sie können den Befehl sed verwenden oder die Datei im Atom-Editor öffnen, nach jeder Zeile suchen und dann die Zeile entfernen.
    Beispiel: Öffnen Sie Dump2020.sql in Atom, drücken Sie Strg + F, suchen Sie nach SET @@ SESSION.SQL_LOG_BIN = 0 und entfernen Sie diese Zeile.
SET @@SESSION.SQL_LOG_BIN= 0;
SET @@GLOBAL.GTID_PURGED=/*!80000 '+'*/ '';
SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN;
  1. Es gibt ein Problem mit Ihrer generierten Datei. Möglicherweise tritt ein Problem auf, wenn Ihre generierte Datei dump.sql nicht ordnungsgemäß ist. Aber hier werde ich nicht erklären, wie man eine Dump-Datei generiert. Aber du kannst mich fragen ( _ )

0

Ich habe kommentiert, dass alle Zeilen SETin der *.sqlDatei beginnen und es hat funktioniert.


0

* Die Antwort gilt möglicherweise nur für MacOS *

Beim Versuch, eine SQL-Datei in einen Docker-Container zu importieren, wurde die folgende Fehlermeldung angezeigt:

Zugriff verweigert; Sie benötigen (mindestens eines) der SUPER-Berechtigung (en) für diesen Vorgang

Während ich einige der anderen Vorschläge ausprobierte, erhielt ich auf meinem MacOS (osx) den folgenden Fehler.

sed: RE-Fehler: Unzulässige Bytesequenz

Schließlich hat der folgende Befehl aus dieser Ressource mein Problem "Zugriff verweigert" behoben.

LC_ALL=C sed -i old 's/\DEFINER\=`[^`]*`@`[^`]*`//g' fileName.sql

So konnte ich in die Docker-Datenbank importieren mit:

docker exec -i dockerContainerName mysql -uuser -ppassword table < importFile.sql

Hoffe das hilft! :) :)


0

Auf der Serverseite muss der Serverparameter "log_bin_trust_function_creators" auf "on" gesetzt werden. Diese finden Sie leicht auf der linken Seite Klinge, wenn es azurblaue Maria db ist.


-1

Erklärung

DEFINER = username@ `%

ist ein Problem in Ihrem Backup-Dump.

Die Lösung, die Sie umgehen können, besteht darin, alle Einträge aus der SQL-Dump-Datei zu entfernen und Daten aus der GCP-Konsole zu importieren.

cat DUMP_FILE_NAME.sql | sed -e 's / DEFINER = <username>@ %// g'> NEW-CLEANED-DUMP.sql

Versuchen Sie, eine neue Datei zu importieren (NEW-CLEANED-DUMP.sql).

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.