Accès refusé; vous avez besoin d'au moins un des privilèges SUPER pour cette opération

89

J'essaye donc d'importer le fichier sql dans rds (1G MEM, 1 CPU). Le fichier sql est comme 1.4G

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

Il est resté bloqué à:

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

Le contenu SQL réel est:

/*!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 n'existe pas dans rds, alors je fais:

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

Toujours pas de chance.

Kenpeter
la source

Réponses:

167

Supprimez l' DEFINER=..instruction de votre fichier sqldump ou remplacez les valeurs utilisateur par CURRENT_USER.

Le serveur MySQL fourni par RDS ne permet pas de DEFINERsyntaxe pour un autre utilisateur (d'après mon expérience).

Vous pouvez utiliser un sedscript pour les supprimer du fichier:

sed 's/\sDEFINER=`[^`]*`@`[^`]*`//g' -i oldfile.sql
hjpotter92
la source
3
Tu as raison. La raison pour laquelle cela ne fonctionne pas est que la spécification d'un autre utilisateur comme DEFINERlorsque l'utilisateur connecté n'a pas le SUPERprivilège (qui lui-même n'est pas autorisé dans RDS) permettrait une élévation arbitraire des privilèges - les programmes stockés s'exécutent avec les informations d'identification et les privilèges de leur DEFINER(par opposition à ceux de l'utilisateur appelant - leur INVOKER), par défaut. Également à Server Fault .
Michael - sqlbot
Homme tu es un sauveur de vie. Si ma société d'hébergement m'avait dit que la base de données était corrompue lors de l'exportation et que rien ne pouvait être fait pour la restaurer. Solution parfaite.
Woody
4
Pour une raison quelconque, j'ai dû utiliser * au lieu de +:sed 's/\sDEFINER=`[^`]*`@`[^`]*`//' -i oldfile.sql
Berend de Boer
Merci @BerenddeBoer
Awolad Hossain
1
@WonderLand Vous pouvez essayer awkce qui pourrait être un peu plus rapide quesed
hjpotter92
35

Si votre fichier de vidage n'a pas DEFINER, assurez-vous que ces lignes ci-dessous sont également supprimées si elles sont là, ou commentées avec --:

Au début:

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

À la fin:

-- SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN;
Jeremy Jones
la source
12
Vous pouvez les empêcher en ajoutant --set-gtid-purged=OFFà votre mysqldumpcommande. Trouvé ici: stackoverflow.com/a/56251925
Illya Moskvin
13

Une autre astuce utile consiste à appeler mysqldump avec l'option --set-gtid-purged = OFF qui n'écrit pas les lignes suivantes dans le fichier de sortie:

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

pas sûr de celui de DEFINER.

quimm2003
la source
Merci! Cela m'a aidé en cas de RDS
Victor
Merci. Dans mon cas, j'ai couru SET @@GLOBAL.GTID_MODE = OFF;dans MySql Workbench du côté exportation à partir de la base de données source
Byron Wong
8

Juste une mise à jour supplémentaire MacOS pour la réponse hjpotter92.

Pour faire sedreconnaître le modèle sous MacOS, vous devrez ajouter une barre oblique inverse avant le =signe, comme ceci:

sed -i old 's/\DEFINER\=`[^`]*`@`[^`]*`//g' file.sql
Marcel
la source
fonctionne à partir de 2020, en utilisant MariaDB 10.4 sur macOS Catalina
Wayne
4

Problème : vous essayez d'importer des données (en utilisant le fichier mysqldump) dans votre base de données mysql, mais il semble que vous n'avez pas l'autorisation d'effectuer cette opération.

Solution : en supposant que vos données sont migrées, semées et mises à jour dans votre base de données mysql, prenez un instantané à l'aide de mysqldump et exportez-le dans un fichier

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

Depuis la documentation mysql:

GTID - Un identifiant global de transaction (GTID) est un identifiant unique créé et associé à chaque transaction validée sur le serveur d'origine (maître). Cet identifiant est unique non seulement pour le serveur dont il provient, mais est unique sur tous les serveurs dans une configuration de réplication donnée. Il existe un mappage 1 à 1 entre toutes les transactions et tous les GTID.

--set-gtid-purged = OFF SET @@ GLOBAL.gtid_purged n'est pas ajouté à la sortie et SET @@ SESSION.sql_log_bin = 0 n'est pas ajouté à la sortie. Pour un serveur sur lequel les GTID ne sont pas utilisés, utilisez cette option ou AUTO. N'utilisez cette option que pour un serveur sur lequel des GTID sont utilisés si vous êtes sûr que l'ensemble GTID requis est déjà présent dans gtid_purged sur le serveur cible et ne doit pas être modifié, ou si vous prévoyez d'identifier et d'ajouter manuellement les GTID manquants.

Ensuite, connectez-vous à votre mysql avec l'utilisateur root, donnez des autorisations, videz-les et vérifiez que vos privilèges d'utilisateur ont été correctement mis à jour.

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

rechargez maintenant les données et l'opération devrait être autorisée .

mysql -h [host] -u [user] -p[pass] [db_name] < [mysql_dump_name].sql
avivamg
la source
3

Pour importer un fichier de base de données au .sql.gzformat, supprimez le définisseur et importez à l'aide de la commande ci-dessous

zcat path_to_db_to_import.sql.gz | sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' | mysql -u user -p new_db_name
  1. Auparavant, exportez la base de données au format .sql.gz en utilisant la commande ci-dessous.

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

  2. Importez cette base de données exportée et supprimez le définisseur en utilisant la commande ci-dessous,

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

Kazim Noorani
la source
2

Lorsque vous restaurez la sauvegarde, assurez-vous d'essayer avec le même nom d'utilisateur pour l'ancien et le nouveau.

mafei
la source
2

Solution complète

Toutes les solutions ci-dessus conviennent. Et ici je vais combiner toutes les solutions pour que ça marche dans toutes les situations.

  1. DEFINER fixe

Pour Linux et Mac

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

Pour Windows
téléchargez atom ou notepad ++, ouvrez votre fichier sql de vidage avec atom ou notepad ++, appuyez sur Ctrl + F
recherchez le mot DEFINER et supprimez la ligne DEFINER = admin@% (ou peut être un peu différente pour vous) de partout et enregistrez le fichier.
Comme par exemple
avant de supprimer cette ligne: CREATE DEFINER = admin@ %PROCEDUREMyProcedure
Après avoir supprimé cette ligne: CREATE PROCEDUREMyProcedure

  1. Supprimez les 3 lignes Supprimez toutes ces 3 lignes du fichier de vidage. Vous pouvez utiliser la commande sed ou ouvrir le fichier dans l'éditeur Atom et rechercher chaque ligne, puis supprimer la ligne.
    Exemple: Ouvrez Dump2020.sql dans Atom, appuyez sur ctrl + F, recherchez SET @@ SESSION.SQL_LOG_BIN = 0 , supprimez cette ligne.
SET @@SESSION.SQL_LOG_BIN= 0;
SET @@GLOBAL.GTID_PURGED=/*!80000 '+'*/ '';
SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN;
  1. Il y a un problème avec votre fichier généré Vous pourriez rencontrer un problème si votre fichier dump.sql généré n'est pas correct. Mais ici, je ne vais pas expliquer comment générer un fichier de vidage. Mais tu peux me demander ( _ )
novice2ninja
la source
0

J'ai commenté toutes les lignes commençant par SETdans le *.sqlfichier et cela a fonctionné.

Tengerye
la source
0

* La réponse ne peut s'appliquer qu'à MacOS *

En essayant d'importer un fichier .sql dans un conteneur docker, j'ai rencontré le message d'erreur:

Accès refusé; vous avez besoin d'au moins un des privilèges SUPER pour cette opération

Ensuite, en essayant certaines des autres suggestions, j'ai reçu l'erreur ci-dessous sur mon MacOS (osx)

sed: erreur RE: séquence d'octets illégale

Enfin, la commande suivante de cette ressource a résolu mon problème «Accès refusé».

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

Je pourrais donc importer dans la base de données docker avec:

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

J'espère que cela t'aides! :)

Mike Dubs
la source
0

Besoin de définir "on" le paramètre serveur "log_bin_trust_function_creators" côté serveur. Celui-ci que vous pouvez facilement trouver sur la lame latérale gauche s'il s'agit de maria db azur.

karthik varada
la source
-1

Déclaration

DEFINER = username@ `%

est un problème dans votre sauvegarde de sauvegarde.

La solution que vous pouvez contourner consiste à supprimer toutes les entrées du fichier de vidage SQL et à importer les données de la console GCP.

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

Essayez d'importer un nouveau fichier (NEW-CLEANED-DUMP.sql).

Harsh Manvar
la source