【问题标题】:Access denied; you need (at least one of) the SUPER privilege(s) for this operation拒绝访问;您需要(至少一个)超级权限才能执行此操作
【发布时间】:2017-10-16 09:00:37
【问题描述】:

所以我尝试将 sql 文件导入 rds (1G MEM, 1 CPU)。 sql文件好像1.4G

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

它卡在:

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';

还是没有运气。

【问题讨论】:

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


    【解决方案1】:

    另一个有用的技巧是使用选项--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 的情况下它对我有帮助
    • 谢谢。就我而言,我在 MySql Workbench 中从源数据库的导出端运行 SET @@GLOBAL.GTID_MODE = OFF;
    • 我已经从转储文件中删除了这两行,然后它对我有用 --SET @@SESSION.SQL_LOG_BIN= 0; SET @@GLOBAL.GTID_PURGED=/*!80000 '+'*/ '';
    • 谢谢。我通过在 MySQL Workbench 中指定 --set-gtid-purged=OFF 解决了这个问题。
    【解决方案2】:

    问题

    下面的语句或行你的转储文件创建问题

    DEFINER=username@`%

    简单的解决方案

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

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

    上述命令将有助于从转储文件中删除所有这些行,并在没有 Definer 的情况下创建新的新转储文件。

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

    【讨论】:

      【解决方案3】:

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

      • 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
        

      【讨论】:

        【解决方案4】:

        转储中的问题。

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

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

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

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

        【讨论】:

          【解决方案5】:

          如果有帮助,当我尝试在我的 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';
          

          我能够进行恢复。

          【讨论】:

            【解决方案6】:

            当我们创建一个新的 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
            

            【讨论】:

              【解决方案7】:

              需要在服务器端设置“on”服务器参数“log_bin_trust_function_creators”。如果它是 azure maria db,您可以在左侧刀片上轻松找到这个。

              【讨论】:

                【解决方案8】:

                完整解决方案

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

                1. 固定定义器

                适用于 Linux 和 Mac

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

                Windows
                下载 atom 或 notepad++,使用 atom 或 notepad++ 打开您的转储 sql 文件,按 Ctrl+F
                搜索单词 DEFINER,然后从任何地方删除 DEFINER=admin@% 行(或者可能对您来说可能略有不同)并保存文件。
                比如
                在删除该行之前:CREATE DEFINER=admin@% PROCEDURE MyProcedure
                删除该行后:CREATE PROCEDURE 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 文件不正确,您可能会遇到一些问题。但在这里,我不会解释如何生成转储文件。但你可以问我 (_)

                【讨论】:

                  【解决方案9】:

                  当您恢复备份时,请务必尝试为旧用户名和新用户名使用相同的用户名。

                  【讨论】:

                    【解决方案10】:

                    要以.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 &gt; path_to_db_exported.sql.gz;

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

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

                    【讨论】:

                      【解决方案11】:

                      * 答案可能仅适用于 MacOS *

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

                      访问被拒绝;您需要(至少其中一项)超级权限 这个操作

                      然后在尝试其他一些建议时,我在我的 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
                      

                      希望这会有所帮助! :)

                      【讨论】:

                        【解决方案12】:

                        问题:您正在尝试将数据(使用 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。

                        然后使用 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
                        

                        【讨论】:

                          【解决方案13】:

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

                          一开始:

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

                          最后:

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

                          【讨论】:

                          • 您可以通过将--set-gtid-purged=OFF 添加到您的mysqldump 命令来阻止这些。在这里找到:stackoverflow.com/a/56251925
                          • @IllyaMoskvin 这对我有用。在我的 sql 工作台中导出日期时 --> 高级选项 --> set-gtid-purged - 将 'SET @@GLOBAL.GTID_PURGED' 添加到输出中 --> 设置为“OFF”
                          • 也为我工作。我有 mariadb 版本的 mysql。
                          【解决方案14】:

                          我在*.sql 文件中注释了所有以SET 开头的行并且它有效。

                          【讨论】:

                          • 好人,真的很形象。你做得很好
                          【解决方案15】:

                          只是一个针对 hjpotter92 答案的 MacOS 额外更新。

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

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

                          【讨论】:

                          • 工作于 2020 年,在 macOS Catalina 上使用 MariaDB 10.4
                          • 这对我也适用于 MacOS。非常感谢!
                          【解决方案16】:

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

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

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

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

                          【讨论】:

                          • 你是对的。它不起作用的原因是,当登录用户没有SUPER 权限(RDS 本身不允许)时,将另一个用户指定为DEFINER 将允许任意权限升级——存储的程序运行默认情况下,他们的DEFINER 的凭据和权限(而不是调用用户的凭据和权限——他们的INVOKER)。还有at Server Fault.
                          • 伙计,你是救生员。让我的托管公司在导出时告诉我数据库损坏并且无法恢复。完美的解决方案。
                          • 出于某种原因,我不得不使用 * 而不是 +:sed 's/\sDEFINER=`[^`]*`@`[^`]*`//' -i oldfile.sql
                          • 有更快的选择吗?如果 sql 文件很大,sed 会有点慢
                          • @WonderLand 你可以试试awk,它可能比sed快一点
                          猜你喜欢
                          • 2015-09-27
                          • 2016-11-08
                          • 2020-06-12
                          • 2015-01-28
                          • 2023-01-28
                          • 2016-08-06
                          • 2020-09-04
                          • 2013-09-04
                          • 2016-08-07
                          相关资源
                          最近更新 更多