MySQL道普請便り

第221回MySQL 8.4から追加された権限とその機能

2024/5に、MySQL 8.4 LTS(Long-Term Support)がリリースされました。今回は、MySQL 8.4で追加された権限と、その機能について紹介したいと思います。

はじめに、MySQL 8.0~8.4の間に追加された権限は以下の通りです。

  • FLUSH_PRIVILEGES権限
  • OPTIMIZE_LOCAL_TABLE権限
  • SET_ANY_DEFINER権限
  • ALLOW_NONEXISTENT_DEFINER権限
  • TRANSACTION_GTID_TAG権限

これらはすべて動的権限になります。それぞれの権限の内容と、それに基づく機能を説明します。

FLUSH_PRIVILEGES権限

FLUSH_PRIVILEGES権限は、その名の通りFLUSH PRIVILEGESステートメントを実行するための権限です。MySQL 8.0でこのコマンドを実行するにはRELOAD権限が必要でした。MySQL 8.4においてもRELOAD権限は後方互換のためサポートされており、この権限を保持するユーザーはFLUSH PRIVILEGESステートメントの実行は可能です。RELOAD権限はいくつかのオペレーションを可能するための権限であり、FLUSH PRIVILEGESステートメントの実行もその中の1つです。権限分離のために新たにFLUSH_PRIVILEGES権限が追加されたと思われます。

FLUSH PRIVILEGESステートメントは、mysqlシステムスキーマの権限テーブル(user,dbテーブル等)をGRANT文を介さずにINSERTやDELETEにて直接変更した場合、その変更をMySQLサーバーに反映するために利用します。ちなみに、この方法はMySQL公式では非推奨となっています。推奨しているのはGRANT文を利用した権限変更です。この方法はFLUSH PRIVILEGESステートメントの実行の必要はなく、ステートメント完了すると変更が反映されます。

OPTIMIZE_LOCAL_TABLE権限

OPTIMIZE_LOCAL_TABLE権限は、OPTIMIZE LOCAL TABLEおよびOPTIMIZE NO_WRITE_TO_BINLOG TABLEステートメントを実行するための権限です。

OPTIMIZE TABLEステートメントはテーブルデータやインデックスの断片化を解消するためにテーブルを再編成します。このステートメントはレプリケーションされるようにバイナリログに書き込まれます。OPTIMIZE LOCAL TABLEおよびOPTIMIZE NO_WRITE_TO_BINLOG TABLEステートメントは、OPTIMIZE TABLEステートメントにNO_WRITE_TO_BINLOGキーワード、またはそのエイリアスLOCALを指定することでバイナリログに書き込まれないようになり、レプリケーションされなくなります。

SET_ANY_DEFINER権限とALLOW_NONEXISTENT_DEFINER権限

この2つの権限は、以下のデータベースオブジェクトを作成するステートメントに関連します。

  • CREATE PROCEDUREステートメント
  • CREATE FUNCTIONステートメント
  • CREATE TRIGGERステートメント
  • CREATE EVENTステートメント
  • CREATE VIEWステートメント

これらのデータベースオブジェクトにはDEFINERを設定する必要があり、それに影響します。

SET_ANY_DEFINER権限

この権限を持つユーザーアカウントは前述のデータベースオブジェクトに対して、任意のユーザーアカウントをDEFINERとして指定することが可能です。ただし、この権限を持たないユーザーアカウントでも、自身のユーザーアカウントをDEFINERとして指定することは可能です。

また、SYSTEM_USER権限をもつユーザーアカウントをDEFINERとして指定する場合は、自身もSYSTEM_USER権限を持っていなくてはいけません。

SET_ANY_DEFINER権限を持たないユーザーで実行
mysql> CREATE DEFINER='existent_user'@'%' VIEW b_view AS SELECT * FROM b;
ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER or SET_ANY_DEFINER privilege(s) for this operation
SET_ANY_DEFINER権限を持つユーザーで実行
mysql> CREATE DEFINER='existent_user'@'%' VIEW b_view AS SELECT * FROM b;
Query OK, 0 rows affected, 0 warning (0.00 sec)

ALLOW_NONEXISTENT_DEFINER権限

デフォルトではセキュリティや操作ミスを防ぐために、孤立したデータベースオブジェクト(存在しないユーザーアカウントをDEFINERに指定するなど)はエラーになるようになっています。このエラーを無視するには、このALLOW_NONEXISTENT_DEFINER権限を付与する必要があります。CREATE時はSET_ANY_DEFINER権限と共に必要になります。

ALLOW_NONEXISTENT_DEFINER権限を持たないユーザーで実行
mysql> CREATE DEFINER='non_existent_user'@'%' VIEW b_view AS SELECT * FROM b;
ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER or ALLOW_NONEXISTENT_DEFINER privilege(s) for this operation
ALLOW_NONEXISTENT_DEFINER権限を持つユーザーで実行
mysql> CREATE DEFINER='non_existent_user'@'%' VIEW b_view AS SELECT * FROM b;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> show warnings;
+-------+------+----------------------------------------------------------+
| Level | Code | Message                                                  |
+-------+------+----------------------------------------------------------+
| Note  | 1449 | The user specified as a definer ('non_existent_user'@'%') does not exist |
+-------+------+----------------------------------------------------------+
1 row in set (0.00 sec)

TRANSACTION_GTID_TAG権限

MySQL8.4からはGTIDのフォーマットが拡張され、タグを付与できるようになりました。タグを付与することで、トランザクションのグループを識別できるようになります。タグのGTIDについては今回は説明しませんので、詳しくは19.1.4 Changing GTID Mode on Online Serversをご確認ください。

GTIDにタグを付与するには、対象のユーザーアカウントにTRANSACTION_GTID_TAG権限が必要になります。

まとめ

MySQL 8.4で追加された権限とその機能について簡単に紹介しました。

今回は以下の公式ドキュメントを参考に作成したので、より詳細を確認したい方はご参照ください。

おすすめ記事

記事・ニュース一覧