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.