エラーの内容
.sql ダンプファイルをインポートしようとすると、MySQLが突然停止します:
ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER privilege(s) for this operation
インポートが途中で失敗します。データベースは部分的にしか復元されないか、まったく空のままになります。このエラーが厄介なのは、ダンプファイル内のどのステートメントが原因かすぐにわからない点です。
発生原因
ダンプファイルには SUPER 権限がなければ実行できないステートメントが含まれており、現在のユーザーにはその権限がありません。主な原因は次の3つです:
- DEFINER句 — ストアドプロシージャ、トリガー、ビューが
DEFINER=original_user@%`` として書き込まれた状態でエクスポートされている - SETステートメント —
SET @@SESSION.SQL_LOG_BIN = 0やSET GLOBAL変数など - GTID関連ステートメント — ソースサーバーでGTIDレプリケーションが有効になっている場合に
SET @@GLOBAL.GTID_PURGEDが含まれる
AWS RDS、Google Cloud SQL、そして多くの共有ホスティングプロバイダーは、管理者レベルのユーザーであっても意図的にSUPERをブロックしています。ただし、これはクラウドに限った問題ではありません。制限されたユーザーとしてインポートする際はローカル環境でも同様の問題が起きます。
まず問題のある行を特定する
推測で進めないでください。インポートエラーをファイルに書き出して、MySQLが何に詰まっているかを正確に確認しましょう:
mysql -u youruser -p yourdatabase < dump.sql 2> import_errors.log
cat import_errors.log
または、既知の問題箇所をダンプファイルから直接検索します:
grep -n 'DEFINER' dump.sql | head -20
grep -n 'SQL_LOG_BIN' dump.sql
grep -n 'GTID_PURGED' dump.sql
grep -n の行番号を使えば、5万行のダンプファイルを手探りでスクロールする代わりに、問題箇所を正確に特定できます。
修正1:ダンプからDEFINERを削除する(最も一般的な修正)
約90%のケースはこれで解決します。sed を使ってインポート前にすべてのDEFINER句を取り除きます:
sed -i 's/DEFINER=[^*]*\*/\*/g' dump.sql
元のファイルを変更せずに残したい場合は、クリーンなコピーに書き出します:
sed 's/DEFINER=[^*]*\*/\*/g' dump.sql > dump_clean.sql
mysql -u youruser -p yourdatabase < dump_clean.sql
macOSにはBSD版のsedが搭載されており、インプレース編集には拡張引数が必要です:
sed -i '' 's/DEFINER=[^*]*\*/\*/g' dump.sql
DEFINERを削除すると、MySQLはそれらのオブジェクトにインポートユーザーのIDを使用するため、SUPERは不要になります。
修正2:GTID_PURGEDステートメントを削除する
エラーが SET @@GLOBAL.GTID_PURGED を含む行を指しているか確認します:
grep -n 'GTID_PURGED' dump.sql
次のような行が見つかるはずです:
SET @@GLOBAL.GTID_PURGED=/*!80000 '+'*/ '4b8e2c1a-1234-5678-abcd-ef0123456789:1-100';
その行を削除してから、インポートを再試行します。ダンプの作成を自分でコントロールできる場合は、エクスポート時にGTIDステートメントを除外するのがよりクリーンな方法です:
mysqldump --set-gtid-purged=OFF -u root -p yourdatabase > dump.sql
修正3:SQL_LOG_BINの行を無効にする
一部のダンプには先頭付近に SET @@SESSION.SQL_LOG_BIN= 0; が含まれており、これもSUPERチェックに引っかかります。sedでコメントアウトします:
sed -i 's/SET @@SESSION.SQL_LOG_BIN= 0/-- SET @@SESSION.SQL_LOG_BIN= 0/g' dump.sql
またはテキストエディタでダンプを開き、その行を手動で削除するだけでも構いません。ファイルが小さければその方が早いことが多いです。
修正4:より慎重にエクスポートする(ソースをコントロールできる場合)
自分でダンプを作成している場合は、最初から権限が必要なステートメントをスキップするフラグを使用します:
mysqldump \
--set-gtid-purged=OFF \
--no-tablespaces \
--skip-definer \
-u root -p yourdatabase > dump_clean.sql
--skip-definer はMySQL 8.0.32以降とMariaDB 10.x以降で利用可能です。それより古いバージョンでは、修正1の sed アプローチにフォールバックしてください。
修正5:一時的にSUPERを付与する(ローカルMySQLのみ)
root権限で自分のマシン上のMySQLを実行していますか?インポートユーザーにSUPERを付与し、インポートを実行してから権限を削除します:
mysql -u root -p
GRANT SUPER ON *.* TO 'youruser'@'localhost';
FLUSH PRIVILEGES;
インポートを実行します:
mysql -u youruser -p yourdatabase < dump.sql
その後すぐに権限を取り消します:
REVOKE SUPER ON *.* FROM 'youruser'@'localhost';
FLUSH PRIVILEGES;
AWS RDSやマネージドデータベースではこの方法は使えません。それらのプラットフォームはプラットフォームレベルでSUPERをブロックしており、MySQL内からは回避できません。
インポートの完了を確認する
エラーなくインポートが完了したら、簡単なサニティチェックを実行します:
-- テーブルを確認
SHOW TABLES;
-- トリガーを確認
SHOW TRIGGERS;
-- ストアドプロシージャを確認
SHOW PROCEDURE STATUS WHERE Db = 'yourdatabase';
-- ビューを確認
SHOW FULL TABLES WHERE Table_type = 'VIEW';
さらに確実にするために、ソースと行数を比較します:
SELECT table_name, table_rows
FROM information_schema.tables
WHERE table_schema = 'yourdatabase'
ORDER BY table_name;
table_rows はInnoDBでは推定値であるため、5%未満の差異は正常です。正確なカウントが必要な場合は、精度が重要なテーブルで SELECT COUNT(*) を実行してください。
クイックリファレンス:どの修正を使うか
- トリガー/ビューのDEFINERエラー → 修正1(sedでDEFINERを削除)
- GTID_PURGEDエラー → 修正2(行を削除するか --set-gtid-purged=OFF でダンプ)
- SQL_LOG_BINエラー → 修正3(行をコメントアウト)
- ソースサーバーをコントロールできる場合 → 修正4(クリーンなダンプフラグを使用)
- ローカルMySQLでrootがある場合 → 修正5(一時的にSUPERを付与)
予防策
最初からクリーンなダンプを作成しておけば、修正は常に容易になります。ストレスのかかるリストア中にこの問題を二度と経験しないよう、バックアップスクリプトに次のフラグを追加しておきましょう:
mysqldump \
--set-gtid-purged=OFF \
--no-tablespaces \
--single-transaction \
-u root -p yourdatabase > backup_$(date +%Y%m%d).sql
もう一つ記録しておく価値があるのは、各環境でインポートを担当するMySQLユーザーです。権限が多すぎるユーザーはセキュリティリスクになり、少なすぎると最悪のタイミング(本番環境のリストア中)にこのエラーに直面します。チームメンバーが深夜2時でも見つけられる場所に書き残しておきましょう。
チームでデータベースの認証情報を共有している場合は、定期的にパスワードをローテーションしてください。ToolCraftのパスワードジェネレーターはブラウザ上で完結して動作するため、サーバーには何も送信されません。

