拒绝访问;您需要(至少一个)此操作的SUPER权限

时间:2017-05-17 04:35:45

标签: mysql amazon-web-services amazon-rds

所以我尝试将sql文件导入rds(1G MEM,1个CPU)。 sql文件类似于1.4G

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

它陷入了困境:

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

实际的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 */;;
rds中不存在

another_user,所以我这样做:

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

仍然没有运气。

16 个答案:

答案 0 :(得分:81)

从sqldump文件中删除DEFINER=..语句,或用CURRENT_USER替换用户值。

RDS提供的MySQL服务器不允许其他用户使用DEFINER语法(根据我的经验)。

您可以使用sed脚本将其从文件中删除:

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

答案 1 :(得分:16)

另一个有用的技巧是使用--set-gtid-purged = OFF选项调用mysqldump,该选项不会将以下行写入输出文件:

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

不确定DEFINER之一。

答案 2 :(得分:4)

问题:您正在尝试将数据(使用mysqldump文件)导入到mysql数据库中,但是似乎您没有执行该操作的权限。

解决方案:假设您的数据已在mysql数据库中迁移,播种和更新,请使用mysqldump拍摄快照并将其导出到文件中

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

来自mysql文档:

GTID -全局交易标识符(GTID)是创建的唯一标识符 并与在源服务器上提交的每个事务关联 (主)。该标识符不仅对于它所在的服务器是唯一的 起源,但是在给定复制中的所有服务器上都是唯一的 设定。所有交易和所有交易之间都存在一对一的映射 GTID。

-set-gtid-purged = OFF SET @@ GLOBAL.gtid_purged未添加到输出中,并且SET @@ SESSION.sql_log_bin = 0未添加到输出中。对于服务器 不使用GTID,请使用此选项或AUTO。仅使用此选项 如果您确定需要使用GTID,则对于使用GTID的服务器 目标服务器上的gtid_purged中已经存在GTID集,并且 不应更改,或者如果您计划识别并添加任何缺失的内容 手动设置GTID。

然后使用root用户,授予权限连接到mysql,刷新它们,并验证您的用户权限是否正确更新。

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

现在重新加载数据并应该允许该操作

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

答案 3 :(得分:4)

我们新建RDS实例时,默认主用户不是root用户。但只能获得该数据库实例的某些权限。此权限不包括 SET 权限。现在,如果您的默认主用户尝试执行 mysql SET 命令,那么您将面临以下错误:Access denied;您需要(至少)SUPER 或 SYSTEM_VARIABLES_ADMIN 权限来执行此操作

解决方案 1

注释掉或删除这些行

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

解决方案 2

您还可以通过使用 -f 选项加载转储文件的其余部分来忽略错误。

mysql -f <REPLACE_DB_NAME> -u <REPLACE_DB_USER> -h <DB_HOST_HERE> -p < dumpfile.sql

答案 4 :(得分:3)

要以.sql.gz格式导入数据库文件,请删除定义程序并使用以下命令导入

zcat path_to_db_to_import.sql.gz | sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' | mysql -u user -p new_db_name
  1. 以前,请使用以下命令以.sql.gz格式导出数据库。

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

  2. 使用以下命令导入导出的数据库并删除定义程序,

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

答案 5 :(得分:3)

还原备份时,请确保为旧的和新的用户使用相同的用户名。

答案 6 :(得分:2)

只是MacOS的hjpotter92答案的额外更新。

要使sed识别MacOS中的模式,您必须在=符号前添加反斜杠,如下所示:

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

答案 7 :(得分:2)

完整解决方案

以上所有解决方案都可以。在这里,我将结合所有解决方案,使其适用于所有情况。

  1. 已修复DEFINER

对于Linux和Mac

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

对于Windows
下载atom或notepad ++,使用atom或notepad ++打开转储sql文件,按Ctrl + F
搜索单词 DEFINER ,然后从各处删除行 DEFINER = admin @ % (或对您而言可能有所不同),然后保存文件。
例如
删除该行之前: CREATE DEFINER = admin @ %程序MyProcedure
删除该行之后:创建过程MyProcedure

  1. 删除3行 从转储文件中删除所有这3行。您可以使用 sed 命令或在Atom编辑器中打开文件并搜索每一行,然后删除该行。
    示例:在Atom中打开Dump2020.sql,按ctrl + F,搜索 SET @@ SESSION.SQL_LOG_BIN = 0 ,删除该行。
SET @@SESSION.SQL_LOG_BIN= 0;
SET @@GLOBAL.GTID_PURGED=/*!80000 '+'*/ '';
SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN;
  1. 您生成的文件有问题 如果生成的dump.sql文件不正确,则可能会遇到一些问题。但是在这里,我不会解释如何生成转储文件。但是你可以问我( _

答案 8 :(得分:1)

如果您的转储文件中没有DEFINER,请确保下面的这些行(如果有的话)也被删除,或者用--注释掉了:

开始时:

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

最后:

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

答案 9 :(得分:1)

以上解决方案都不适合我。我必须执行以下操作:

  • mysqldump 中使用以下标志:

    mysqldump --databases <db1> <db2> --master-data=1 --single-transaction --order- 
    by-primary --foce -r all.sql -h<host> -u<user> -p<password>
    
  • 删除如下所示的行:

    CHANGE MASTER TO MASTER_LOG_FILE='binlog.....
    
    • 在我的文件中,那是第 22 行,所以我运行:sed -i '22d' all.sql
  • 将数据导入您的 RDS:

    mysql -h<host> -u<user> -p<password>
    $ source all.sql
    

答案 10 :(得分:0)

声明

  

DEFINER = db.getCollection.aggregate([ {"$group" : {"_id": "$usage", "count": {"$sum" : 1}}}, {"$sort": {"count": -1}}, {"$match": {"count":{ $gte: 2 } }}, ]) @`%

是备份转储中的问题。

您可以解决的解决方案是从sql dump文件中删除所有条目,并从GCP控制台导入数据。

  

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

尝试导入新文件(NEW-CLEANED-DUMP.sql)。

答案 11 :(得分:0)

我评论了SET文件中所有以*.sql开头的行,并且行得通。

答案 12 :(得分:0)

*答案可能仅适用于MacOS *

尝试将.sql文件导入Docker容器时,遇到错误消息:

访问被拒绝;您需要(至少一种)SUPER特权才能 该操作

然后尝试其他一些建议时,我在MacOS(osx)上收到以下错误

sed:RE错误:非法字节序列

最后,来自此resource的以下命令解决了我的“访问被拒绝”问题。

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

因此我可以使用以下命令导入docker数据库:

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

希望这会有所帮助! :)

答案 13 :(得分:0)

需要在服务器端设置“ on”服务器参数“ log_bin_trust_function_creators”。如果它是天蓝色的玛丽亚分贝,您可以在左侧刀片上轻松找到它。

答案 14 :(得分:0)

如果有帮助,当我尝试在我的 AWS MySQL RDS 上恢复数据库转储时,我收到此错误:

ERROR 1227 (42000) at line 18: Access denied; you need (at least one of) the SUPER, 
SYSTEM_VARIABLES_ADMIN or SESSION_VARIABLES_ADMIN privilege(s) for this operation

我不必更改 DEFINER 或删除/注释掉行。我刚做了:

GRANT SESSION_VARIABLES_ADMIN ON *.* TO myuser@'myhost';
GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO myuser@'myhost';

而且我能够进行恢复。

答案 15 :(得分:0)

转储中的问题。

请尝试通过以下方式获取转储:

mysqldump -h databasehost --user=databaseusername --password --single-transaction 数据库名 | sed -e 's/DEFINER[ ]=[ ][^]*/*/' | gzip > /tmp/database.sql.gz

然后,尝试通过以下方式导入:

zcat /tmp/database.sql.gz | mysql -h 数据库主机 -u 用户名 -p 数据库名称