拒绝访问; 您需要(至少其中一种)SUPER权限才能执行此操作


87

因此,我尝试将sql文件导入rds(1G MEM,1 CPU)。sql文件就像1.4G

mysql -h xxxx.rds.amazonaws.com -u用户-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 */;;

another_user 在rds中不存在,所以我这样做:

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

仍然没有运气。

Answers:


166

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

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

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

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

3
没错 它不起作用的原因是,如果将另一个用户指定为DEFINER登录用户不具有SUPER特权(RDS本身不允许该特权),则将允许任意特权升级-存储程序以其凭据和特权运行DEFINER(而不是主叫用户的- INVOKER)。同样在服务器故障时
Michael-sqlbot

伙计,您是救生员。如果我的托管公司告诉我导出时损坏的数据库,并且无法执行任何还原操作。完美的解决方案。
伍迪

4
由于某些原因,我不得不使用*而不是+:sed 's/\sDEFINER=`[^`]*`@`[^`]*`//' -i oldfile.sql
Berend de Boer

感谢@BerenddeBoer
Awolad Hossain '18

1
@WonderLand你可以尝试awk可能会快一点比sed
hjpotter92

34

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

在开始时:

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

在最后:

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

12
您可以通过添加--set-gtid-purged=OFFmysqldump命令中来防止这些情况。在这里找到:stackoverflow.com/a/56251925
Illya Moskvin

13

另一个有用的技巧是使用选项--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之一。


谢谢!它帮助我在RDS的情况下
维克托

谢谢。就我而言,我SET @@GLOBAL.GTID_MODE = OFF;在源数据库的导出端的MySql Workbench中运行
Byron Wong,

8

只是macOS额外更新了hjpotter92答案。

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

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

自2020年开始运作,在macOS Catalina上使用MariaDB 10.4
Wayne

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_purged中已经存在所需的GTID集并且不应对其进行更改,或者如果您计划手动识别并添加任何丢失的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

要以.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


2

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


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@ %PROCEDUREMyProcedure
删除该行之后:CREATE PROCEDUREMyProcedure

  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文件不正确,则可能会遇到问题。但是在这里,我不会解释如何生成转储文件。但是你可以问我(_

0

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


0

*答案可能仅适用于MacOS *

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

拒绝访问; 您需要(至少其中一种)SUPER权限才能执行此操作

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

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

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

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

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

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

希望这可以帮助!:)


0

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


-1

声明

DEFINER = username@`%

是备份转储中的问题。

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

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.