Accesso negato; è necessario (almeno uno dei) privilegi SUPER per questa operazione


99

Quindi provo a importare il file sql in rds (1G MEM, 1 CPU). Il file sql è come 1.4G

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

È rimasto bloccato su:

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

Il contenuto effettivo di sql è:

/*!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 non esiste in rds, quindi faccio:

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

Ancora senza fortuna.

Risposte:


180

Rimuovere l' DEFINER=..istruzione dal file sqldump o sostituire i valori utente con CURRENT_USER.

Il server MySQL fornito da RDS non consente una DEFINERsintassi per un altro utente (nella mia esperienza).

Puoi utilizzare uno sedscript per rimuoverli dal file:

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

3
Hai ragione. Il motivo per cui non funziona è che la specifica di un altro utente come DEFINERquando l'utente connesso non dispone del SUPERprivilegio (che di per sé non è consentito in RDS) consentirebbe un'escalation di privilegi arbitraria: i programmi memorizzati vengono eseguiti con le credenziali e i privilegi DEFINER(al contrario di quelli dell'utente chiamante - loro INVOKER), per impostazione predefinita. Anche in caso di errore del server .
Michael - sqlbot

Amico, sei un salvavita. La mia società di hosting mi aveva detto che il database era danneggiato durante l'esportazione e che non si poteva fare nulla per ripristinarlo. Soluzione perfetta.
Woody

5
Per qualche motivo ho dovuto usare * invece di +:sed 's/\sDEFINER=`[^`]*`@`[^`]*`//' -i oldfile.sql
Berend de Boer

Grazie @BerenddeBoer
Awolad Hossain

1
@WonderLand Puoi provare awkquale potrebbe essere un po 'più veloce dised
hjpotter92

50

Se il tuo file di dump non ha DEFINER, assicurati che anche queste righe di seguito vengano rimosse se sono presenti o commentate con --:

All'inizio:

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

Alla fine:

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

13
Puoi prevenirli aggiungendo --set-gtid-purged=OFFal tuo mysqldumpcomando. Trovato qui: stackoverflow.com/a/56251925
Illya Moskvin

17

Un altro trucco utile è invocare mysqldump con l'opzione --set-gtid-purged = OFF che non scrive le seguenti righe nel file di output:

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

non sono sicuro di quello DEFINER.


1
Grazie! Mi ha aiutato in caso di RDS
Victor

Grazie. Nel mio caso ho eseguito SET @@GLOBAL.GTID_MODE = OFF;in MySql Workbench nel lato di esportazione dal database di origine
Byron Wong

8

Solo un aggiornamento extra per MacOS per la risposta di hjpotter92.

Per sedriconoscere il motivo in MacOS, dovrai aggiungere una barra rovesciata prima del =segno, in questo modo:

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

funziona a partire dal 2020, utilizzando MariaDB 10.4 su macOS Catalina
Wayne

4

Problema : stai tentando di importare dati (utilizzando il file mysqldump) nel tuo database mysql, ma sembra che tu non abbia l'autorizzazione per eseguire tale operazione.

Soluzione : supponendo che i dati vengano migrati, seminati e aggiornati nel database mysql, scatta un'istantanea utilizzando mysqldump ed esportala su file

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

Dalla documentazione di mysql:

GTID : un identificatore di transazione globale (GTID) è un identificatore univoco creato e associato a ciascuna transazione commessa sul server di origine (master). Questo identificatore è univoco non solo per il server su cui ha avuto origine, ma è univoco su tutti i server in una determinata configurazione di replica. Esiste una mappatura 1 a 1 tra tutte le transazioni e tutti i GTID.

--set-gtid-purged = OFF SET @@ GLOBAL.gtid_purged non viene aggiunto all'output e SET @@ SESSION.sql_log_bin = 0 non viene aggiunto all'output. Per un server in cui i GTID non sono in uso, utilizzare questa opzione o AUTO. Utilizza questa opzione solo per un server in cui sono in uso GTID se sei sicuro che il set GTID richiesto sia già presente in gtid_purged sul server di destinazione e non debba essere modificato, o se prevedi di identificare e aggiungere manualmente eventuali GTID mancanti.

Successivamente connettiti al tuo mysql con l'utente root, concedi i permessi, svuotali e verifica che i tuoi privilegi utente siano stati aggiornati correttamente.

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`                     |
+------------------------------------------------------------------+

ora ricaricare i dati e l'operazione dovrebbe essere consentita .

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

3

Per importare il file di database in .sql.gzformato, rimuovere il definitore e importare utilizzando il comando seguente

zcat path_to_db_to_import.sql.gz | sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' | mysql -u user -p new_db_name
  1. In precedenza, esporta il database in formato .sql.gz utilizzando il comando seguente.

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

  2. Importa il database esportato e rimuovi il definitore utilizzando il comando seguente,

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


2

Quando ripristini il backup, assicurati di provare con lo stesso nome utente per quello vecchio e quello nuovo.


2

Soluzione completa

Tutte le soluzioni di cui sopra vanno bene. E qui combinerò tutte le soluzioni in modo che funzioni per tutte le situazioni.

  1. DEFINER fisso

Per Linux e Mac

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

Per Windows
scarica atom o notepad ++, apri il tuo file sql di dump con atom o notepad ++, premi Ctrl + F
cerca la parola DEFINER e rimuovi la riga DEFINER = admin@% (o potrebbe essere leggermente diversa per te) da qualsiasi luogo e salva il file.
Come per esempio
prima di rimuovere quella riga: CREATE DEFINER = admin@ %PROCEDUREMyProcedure
Dopo aver rimosso quella riga: CREATE PROCEDUREMyProcedure

  1. Rimuovere le 3 righe Rimuovere tutte queste 3 righe dal file dump. È possibile utilizzare il comando sed o aprire il file nell'editor Atom e cercare ogni riga, quindi rimuovere la riga.
    Esempio: Apri Dump2020.sql in Atom, premi ctrl + F, cerca SET @@ SESSION.SQL_LOG_BIN = 0 , rimuovi quella riga.
SET @@SESSION.SQL_LOG_BIN= 0;
SET @@GLOBAL.GTID_PURGED=/*!80000 '+'*/ '';
SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN;
  1. C'è un problema con il tuo file generato Potresti incontrare qualche problema se il tuo file dump.sql generato non è corretto. Ma qui, non spiegherò come generare un file di dump. Ma puoi chiedermi ( _ )

1

Ho commentato tutte le righe che iniziano con SETnel *.sqlfile e ha funzionato.


0

* La risposta potrebbe essere applicabile solo a MacOS *

Durante il tentativo di importare un file .sql in un contenitore Docker, ho riscontrato il messaggio di errore:

Accesso negato; è necessario (almeno uno dei) privilegi SUPER per questa operazione

Quindi, mentre provavo alcuni degli altri suggerimenti, ho ricevuto l'errore seguente sul mio MacOS (osx)

sed: errore RE: sequenza di byte illegale

Infine, il seguente comando da questa risorsa ha risolto il mio problema di "Accesso negato".

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

Quindi potrei importare nel database docker con:

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

Spero che sia di aiuto! :)


0

È necessario impostare "on" il parametro del server "log_bin_trust_function_creators" sul lato server. Questo lo puoi trovare facilmente sulla lama del lato sinistro se è azzurro maria db.


-1

Dichiarazione

DEFINER = username@ `%

è un problema nel dump del backup.

La soluzione che puoi aggirare è rimuovere tutta la voce dal file di dump sql e importare i dati dalla console GCP.

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

Prova a importare un nuovo file (NEW-CLEANED-DUMP.sql).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.