アクセスが拒否されました; この操作にはSUPER特権(少なくとも1つ)が必要です


99

だから私はSQLファイルをrds(1G MEM、1CPU)にインポートしようとします。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 */;;

another_user rdsには存在しないので、私はそうします:

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

まだ運がない。

回答:


180

DEFINER=..sqldumpファイルからステートメントを削除するか、ユーザー値をCURRENT_USER。に置き換えます。

RDSによって提供されるMySQLサーバーは、DEFINER(私の経験では)別のユーザーの構文を許可しません。

sedスクリプトを使用して、ファイルからそれらを削除できます。

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

3
あなたは正しいです。それが機能しない理由はDEFINER、ログインしたユーザーがSUPER特権を持っていない場合(それ自体はRDSでは許可されていません)として別のユーザーを指定すると、任意の特権の昇格が許可されるためです-ストアドプログラムは、その資格情報と特権で実行されますDEFINER(呼び出し元のユーザーのものとは対照的に-彼らのINVOKER)、デフォルトで。また、サーバー障害時
Michael-sqlbot 2017年

あなたは命の恩人です。私のホスティング会社は、エクスポート時にデータベースが破損していて、復元するために何もできないと言っていました。完璧なソリューション。
ウッディ

5
何らかの理由で私は+を*使う代わりにする必要がありました:sed 's/\sDEFINER=`[^`]*`@`[^`]*`//' -i oldfile.sql
Berend・デ・ボーア

ありがとう@ BerenddeBoer–
Awolad Hossain

1
@WonderLandあなたはawkそれより少し速いかもしれないことを試すことができますsed
hjpotter92 2018年

50

ダンプファイルにがない場合はDEFINER、以下の行もある場合は削除するか、コメントアウトして--ください。

開始時:

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

最後に:

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

13
コマンドに追加することで、これらを防ぐことができ--set-gtid-purged=OFFますmysqldump。ここで見つかりました:stackoverflow.com/a/56251925
IllyaMoskvin19年

17

もう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についてはよくわかりません。


1
ありがとう!RDSの場合に役立ちました
ビクター

ありがとうございました。私の場合、私は走ったSET @@GLOBAL.GTID_MODE = OFF;ソース・データベースからエクスポート側でのMySQL Workbenchで
バイロン・ウォン

8

hjpotter92の答えのためのMacOSの追加アップデート。

sedMacOSでパターンを認識させるには=、次のように、記号の前に円記号を追加する必要があります。

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

MacOSのカタリナにMariaDB 10.4を使用して、2020年のように動作
ウェイン・

4

問題:(mysqldumpファイルを使用して)データをmysqlデータベースにインポートしようとしていますが、その操作を実行する権限がないようです。

解決策:データがmysqlデータベースで移行、シード、更新されたと仮定して、mysqldumpを使用してスナップショットを作成し、ファイルにエクスポートします

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

mysqlドキュメントから:

GTID-グローバルトランザクション識別子(GTID)は、オリジンサーバー(マスター)でコミットされた各トランザクションに作成および関連付けられた一意の識別子です。この識別子は、それが発生したサーバーだけでなく、特定のレプリケーション設定のすべてのサーバーで一意です。すべてのトランザクションとすべてのGTIDの間には1対1のマッピングがあります。

--set-gtid-purged = OFF SET @@ GLOBAL.gtid_purgedは出力に追加されず、SET @@ SESSION.sql_log_bin = 0は出力に追加されません。GTIDが使用されていないサーバーの場合は、このオプションまたはAUTOを使用します。このオプションは、必要な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

データベースファイルを.sql.gzフォーマットでインポートするには、definerを削除し、以下のコマンドを使用してインポートします

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 = @(または少し異なる場合があります)という行を削除してファイルを保存します。 たとえば 、その行を削除する前に:CREATE DEFINER = @ PROCEDURE その行を削除した後:CREATE PROCEDUREadmin%

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ファイルが適切でない場合、問題が発生する可能性があります。ただし、ここでは、ダンプファイルを生成する方法については説明しません。しかし、あなたは私に尋ねることができます(_


0

*回答はMacOSにのみ適用される場合があります*

.sqlファイルをDockerコンテナーにインポートしようとすると、次のエラーメッセージが表示されました。

アクセスが拒否されました; この操作にはSUPER特権(少なくとも1つ)が必要です

次に、他の提案のいくつかを試しているときに、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」を設定する必要があります。これは紺碧のマリアdbなら左側の刃で簡単に見つけることができます。


-1

ステートメント

DEFINER = username@ `%

バックアップダンプの問題です。

回避できる解決策は、SQLダンプファイルからすべてのエントリを削除し、GCPコンソールからデータをインポートすることです。

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

新しいファイル(NEW-CLEANED-DUMP.sql)をインポートしてみてください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.