権限管理
TiDBは、構文や権限タイプを含め、 MySQL 5.7の権限管理システムをサポートしています。また、MySQL 8.0の以下の機能もサポートしています。
- TiDB 3.0以降で利用可能になったSQLロール。
- TiDB 5.1以降では、動的な権限が可能になりました。
このドキュメントでは、権限に関連するTiDB操作、TiDB操作に必要な権限、および権限システムの実装について説明します。
特権関連の操作
権限を付与する
GRANT文は、ユーザーアカウントに権限を付与します。
例えば、次のステートメントを使用して、 xxxユーザーにtestデータベースを読み取る権限を付与します。
GRANT SELECT ON test.* TO 'xxx'@'%';
xxxユーザーにすべてのデータベースに対するすべての権限を付与するには、次のステートメントを使用します。
GRANT ALL PRIVILEGES ON *.* TO 'xxx'@'%';
バージョン8.5.6以降、TiDBはMySQL互換の列レベルの権限管理メカニズムをサポートしています。指定したテーブルの特定の列に対して、 SELECT 、 INSERT 、 UPDATE 、およびREFERENCES権限を付与または取り消すことができます。詳細については、列レベルの権限管理を参照してください。
デフォルトでは、 GRANTステートメントは、指定されたユーザーが存在しない場合にエラーを返します。この動作は、 SQLモードNO_AUTO_CREATE_USERが指定されているかどうかによって異なります。
SET sql_mode=DEFAULT;
Query OK, 0 rows affected (0.00 sec)
SELECT @@sql_mode;
+-------------------------------------------------------------------------------------------------------------------------------------------+
| @@sql_mode |
+-------------------------------------------------------------------------------------------------------------------------------------------+
| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+-------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
SELECT * FROM mysql.user WHERE user='idontexist';
Empty set (0.00 sec)
GRANT ALL PRIVILEGES ON test.* TO 'idontexist';
ERROR 1105 (HY000): You are not allowed to create a user with GRANT
SELECT user,host,authentication_string FROM mysql.user WHERE user='idontexist';
Empty set (0.00 sec)
次の例では、SQL モードidontexist NO_AUTO_CREATE_USERが空のパスワードで自動的に作成されます。これはセキュリティ上のリスクとなるため推奨されません。ユーザー名のスペルミスがあると、空のパスワードで新しいユーザーが作成されてしまいます。
SET @@sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
Query OK, 0 rows affected (0.00 sec)
SELECT @@sql_mode;
+-----------------------------------------------------------------------------------------------------------------------+
| @@sql_mode |
+-----------------------------------------------------------------------------------------------------------------------+
| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION |
+-----------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
SELECT * FROM mysql.user WHERE user='idontexist';
Empty set (0.00 sec)
GRANT ALL PRIVILEGES ON test.* TO 'idontexist';
Query OK, 1 row affected (0.05 sec)
SELECT user,host,authentication_string FROM mysql.user WHERE user='idontexist';
+------------+------+-----------------------+
| user | host | authentication_string |
+------------+------+-----------------------+
| idontexist | % | |
+------------+------+-----------------------+
1 row in set (0.01 sec)
GRANTコマンドでは、あいまい一致を使用してデータベースに権限を付与できます。
GRANT ALL PRIVILEGES ON `te%`.* TO genius;
Query OK, 0 rows affected (0.00 sec)
SELECT user,host,db FROM mysql.db WHERE user='genius';
+--------|------|-----+
| user | host | db |
+--------|------|-----+
| genius | % | te% |
+--------|------|-----+
1 row in set (0.00 sec)
この例では、 %内のte%により、 teで始まるすべてのデータベースに権限が付与されます。
権限を取り消す
REVOKEステートメントを使用すると、システム管理者はユーザーアカウントから権限を取り消すことができます。
REVOKEステートメントはGRANTステートメントに対応します。
REVOKE ALL PRIVILEGES ON `test`.* FROM 'genius'@'localhost';
注記:
権限を取り消すには、完全一致が必要です。一致する結果が見つからない場合は、エラーが表示されます。
REVOKE ALL PRIVILEGES ON `te%`.* FROM 'genius'@'%';
ERROR 1141 (42000): There is no such grant defined for user 'genius' on host '%'
あいまい一致、エスケープシーケンス、文字列、識別子について:
GRANT ALL PRIVILEGES ON `te\%`.* TO 'genius'@'localhost';
Query OK, 0 rows affected (0.00 sec)
この例では、完全一致を使用してte%という名前のデータベースを検索します。 %は\エスケープ文字を使用しているため、 %はワイルドカードとして扱われません。
文字列はシングルクォーテーションマーク('')で囲み、識別子はバッククォート(``)で囲みます。違いは以下のとおりです。
GRANT ALL PRIVILEGES ON 'test'.* TO 'genius'@'localhost';
ERROR 1064 (42000): You have an error in your SQL syntax; check the
manual that corresponds to your MySQL server version for the right
syntax to use near ''test'.* to 'genius'@'localhost'' at line 1
GRANT ALL PRIVILEGES ON `test`.* TO 'genius'@'localhost';
Query OK, 0 rows affected (0.00 sec)
テーブル名として特別なキーワードを使用する場合は、バッククォート(``)で囲みます。例:
CREATE TABLE `select` (id int);
Query OK, 0 rows affected (0.27 sec)
ユーザーに付与された権限を確認する
SHOW GRANTSステートメントを使用すると、ユーザーに付与されている権限を確認できます。例:
SHOW GRANTS; -- show grants for the current user
+-------------------------------------------------------------+
| Grants for User |
+-------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION |
+-------------------------------------------------------------+
SHOW GRANTS FOR 'root'@'%'; -- show grants for a specific user
例えば、ユーザーrw_user@192.168.%を作成し、そのユーザーにtest.write_tableテーブルへの書き込み権限とグローバルな読み取り権限を付与します。
CREATE USER `rw_user`@`192.168.%`;
GRANT SELECT ON *.* TO `rw_user`@`192.168.%`;
GRANT INSERT, UPDATE ON `test`.`write_table` TO `rw_user`@`192.168.%`;
rw_user@192.168.%ユーザーに付与された権限を表示します。
SHOW GRANTS FOR `rw_user`@`192.168.%`;
+------------------------------------------------------------------+
| Grants for rw_user@192.168.% |
+------------------------------------------------------------------+
| GRANT Select ON *.* TO 'rw_user'@'192.168.%' |
| GRANT Insert,Update ON test.write_table TO 'rw_user'@'192.168.%' |
+------------------------------------------------------------------+
動的な権限
バージョン5.1以降、TiDBはMySQL 8.0から取り入れた動的権限をサポートしています。動的権限は、特定の操作に対するよりきめ細かなアクセスを実装することで、 SUPER権限を置き換えることを目的としています。たとえば、動的権限を使用すると、システム管理者はBACKUPとRESTORE操作のみを実行できるユーザーアカウントを作成できます。
動的権限には以下が含まれます。
BACKUP_ADMINRESTORE_ADMINSYSTEM_USERSYSTEM_VARIABLES_ADMINROLE_ADMINCONNECTION_ADMINPLACEMENT_ADMINは、権限所有者が配置ポリシーを作成、変更、削除できるようにします。DASHBOARD_CLIENTは、権限所有者が TiDB ダッシュボードにログインできるようにします。RESTRICTED_TABLES_ADMINは、SEM が有効になっている場合に、権限所有者がシステム テーブルを表示できるようにします。RESTRICTED_STATUS_ADMINを使用すると、SEM が有効になっているときに、権限所有者はSHOW [GLOBAL|SESSION] STATUSですべてのステータス変数を表示できます。RESTRICTED_VARIABLES_ADMINは、SEM が有効になっている場合に、権限所有者がすべてのシステム変数を表示できるようにします。RESTRICTED_USER_ADMINSEM が有効になっている場合、特権所有者が SUPER ユーザーによってアクセス権を取り消されることを禁止します。RESTRICTED_CONNECTION_ADMIN権限所有者がRESTRICTED_USER_ADMINユーザーの接続を強制終了することを許可します。この権限はKILLおよびKILL TIDBステートメントに影響します。RESTRICTED_REPLICA_WRITER_ADMIN使用すると、TiDB クラスタで読み取り専用モードが有効になっている場合でも、権限所有者は影響を受けることなく書き込みまたは更新操作を実行できます。詳細については、tidb_restricted_read_only参照してください。
動的権限の全セットを確認するには、 SHOW PRIVILEGESステートメントを実行してください。プラグインは新しい権限を追加できるため、割り当て可能な権限のリストは、TiDB のインストール環境によって異なる場合があります。
SUPER特権
SUPER権限は、ユーザーがほぼすべての操作を実行できるようにします。デフォルトでは、rootユーザーのみにこの権限が付与されています。他のユーザーにこの権限を付与する際は注意してください。SUPER権限はMySQL 8.0で非推奨になりました推奨になりました。よりきめ細かいアクセス制御を提供するために動的権限に置き換えることができます。
TiDB操作に必要な権限
TiDBユーザーの権限はINFORMATION_SCHEMA.USER_PRIVILEGESテーブルで確認できます。例:
SELECT * FROM INFORMATION_SCHEMA.USER_PRIVILEGES WHERE grantee = "'root'@'%'";
+------------+---------------+-------------------------+--------------+
| GRANTEE | TABLE_CATALOG | PRIVILEGE_TYPE | IS_GRANTABLE |
+------------+---------------+-------------------------+--------------+
| 'root'@'%' | def | Select | YES |
| 'root'@'%' | def | Insert | YES |
| 'root'@'%' | def | Update | YES |
| 'root'@'%' | def | Delete | YES |
| 'root'@'%' | def | Create | YES |
| 'root'@'%' | def | Drop | YES |
| 'root'@'%' | def | Process | YES |
| 'root'@'%' | def | References | YES |
| 'root'@'%' | def | Alter | YES |
| 'root'@'%' | def | Show Databases | YES |
| 'root'@'%' | def | Super | YES |
| 'root'@'%' | def | Execute | YES |
| 'root'@'%' | def | Index | YES |
| 'root'@'%' | def | Create User | YES |
| 'root'@'%' | def | Create Tablespace | YES |
| 'root'@'%' | def | Trigger | YES |
| 'root'@'%' | def | Create View | YES |
| 'root'@'%' | def | Show View | YES |
| 'root'@'%' | def | Create Role | YES |
| 'root'@'%' | def | Drop Role | YES |
| 'root'@'%' | def | CREATE TEMPORARY TABLES | YES |
| 'root'@'%' | def | LOCK TABLES | YES |
| 'root'@'%' | def | CREATE ROUTINE | YES |
| 'root'@'%' | def | ALTER ROUTINE | YES |
| 'root'@'%' | def | EVENT | YES |
| 'root'@'%' | def | SHUTDOWN | YES |
| 'root'@'%' | def | RELOAD | YES |
| 'root'@'%' | def | FILE | YES |
| 'root'@'%' | def | CONFIG | YES |
| 'root'@'%' | def | REPLICATION CLIENT | YES |
| 'root'@'%' | def | REPLICATION SLAVE | YES |
+------------+---------------+-------------------------+--------------+
31 rows in set (0.00 sec)
変更する
ALTERステートメントすべてにおいて、ユーザーは対応するテーブルに対するALTER権限を持っている必要があります。ALTER...DROPおよびALTER...RENAME TO以外のステートメントについては、ユーザーは対応するテーブルに対してINSERTおよびCREATEの権限を持っている必要があります。ALTER...DROPステートメントを使用するには、ユーザーは対応するテーブルに対してDROP権限を持っている必要があります。ALTER...RENAME TOステートメントを実行するには、ユーザーは名前変更前にテーブルに対するDROP権限を持ち、名前変更後にテーブルに対するCREATEおよびINSERT権限ている必要があります。
注記:
MySQL 5.7のドキュメントでは、テーブルに対して
INSERT操作を実行するには、CREATEおよびALTERの権限であるとされています。しかし、実際にはMySQL 5.7では、この場合ALTER権限のみが必要です。現在、TiDB のALTER権限は、MySQL の実際の動作と一致しています。
バックアップ
SUPERまたはBACKUP_ADMINの権限が必要です。
インポートジョブをキャンセルする
他のユーザーが作成したジョブをキャンセルするにはSUPER権限が必要です。それ以外の場合は、現在のユーザーが作成したジョブのみキャンセルできます。
データベースの作成
データベースに対するCREATE権限が必要です。
インデックスを作成する
テーブルに対するINDEX権限が必要です。
テーブルを作成する
テーブルに対するCREATE権限が必要です。
CREATE TABLE...LIKE...ステートメントを実行するには、テーブルに対するSELECT権限が必要です。
ビューの作成
CREATE VIEW権限が必要です。
注記:
現在のユーザーがビューを作成したユーザーでない場合、
CREATE VIEWとSUPERの両方の権限が必要です。
データベースの削除
データベースに対するDROP権限が必要です。
インデックスを削除
テーブルに対するINDEX権限が必要です。
テーブルを削除する
テーブルに対するDROP権限が必要です。
インポート先
対象テーブルに対してSELECT 、 UPDATE 、 INSERT 、 DELETE 、およびALTERの権限が必要です。TiDBにローカルに保存されているファイルをインポートするには、 FILE権限も必要です。
データの読み込み
テーブルに対してINSERT権限が必要です。 REPLACE INTOを使用する場合は、 DELETE権限も必要です。
テーブルを切り捨てる
テーブルに対するDROP権限が必要です。
テーブル名の変更
テーブル名を変更する前に、 ALTERおよびDROPの権限が必要であり、テーブル名を変更する後にはCREATEおよびINSERTの権限。
表の分析
テーブルに対するINSERTおよびSELECTの権限が必要です。
ロック統計
テーブルに対するINSERTおよびSELECTの権限が必要です。
統計情報をアンロックする
テーブルに対するINSERTおよびSELECTの権限が必要です。
見せる
SHOW CREATE TABLEテーブルに対する単一の権限を必要とします。
SHOW CREATE VIEWにはSHOW VIEWの権限が必要です。
SHOW GRANTSはSELECTデータベースへのmysql権限を必要とします。対象ユーザーが現在のユーザーである場合、 SHOW GRANTS権限を必要としません。
SHOW PROCESSLISTは、他のユーザーに属する接続を表示するためにPROCESSの権限を必要とします。
SHOW IMPORT JOBは、他のユーザーに属する接続を表示するためにSUPER権限を必要とします。権限がない場合は、現在のユーザーが作成したジョブのみが表示されます。
SHOW STATS_LOCKEDはSELECT mysql.stats_table_locked }} テーブルに対する権限を必要とします。
ロール/ユーザーの作成
CREATE ROLEにはCREATE ROLEの権限が必要です。
CREATE USERにはCREATE USERの権限が必要です。
ロール/ユーザーを削除する
DROP ROLEにはDROP ROLEの権限が必要です。
DROP USERにはCREATE USERの権限が必要です。
ユーザーの変更
CREATE USER権限が必要です。
付与
GRANTによって付与された権限を持つGRANT権限が必要です。
ユーザーを暗黙的に作成するには、追加のCREATE USER権限が必要です。
GRANT ROLEにはSUPERまたはROLE_ADMIN権限が必要です。
取り消す
GRANT権限と、 REVOKEステートメントで指定されている権限が必要です。
REVOKE ROLEにはSUPERまたはROLE_ADMIN権限が必要です。
グローバル設定
グローバル変数を設定するには、 SUPERまたはSYSTEM_VARIABLES_ADMINの権限が必要です。
管理者
SUPERの権限が必要です。
デフォルトロールを設定する
SUPERの権限が必要です。
殺す
他のユーザーセッションを終了するには、 SUPERまたはCONNECTION_ADMINの権限が必要です。
リソースグループを作成する
SUPERまたはRESOURCE_GROUP_ADMINの権限が必要です。
アルター・リソース・グループ
SUPERまたはRESOURCE_GROUP_ADMINの権限が必要です。
リソースグループを削除する
SUPERまたはRESOURCE_GROUP_ADMINの権限が必要です。
リソースの校正
SUPERまたはRESOURCE_GROUP_ADMINの権限が必要です。
リソースグループを設定する
システム変数tidb_resource_control_strict_mode ONに設定されている場合、このステートメントを実行するにはSUPERまたはRESOURCE_GROUP_ADMINまたはRESOURCE_GROUP_USERの権限が必要です。
特権システムの導入
権限テーブル
次のmysqlシステムテーブルすべての権限関連データが保存されているため、特別です。
mysql.user(ユーザーアカウント、グローバル権限)mysql.db(データベースレベルの権限)mysql.tables_priv(テーブルレベルの権限)mysql.columns_priv(列レベルの権限。v8.5.6以降でサポート)
これらのテーブルには、データの有効範囲と権限情報が含まれています。たとえば、 mysql.userテーブルでは次のようになります。
SELECT User,Host,Select_priv,Insert_priv FROM mysql.user LIMIT 1;
+------|------|-------------|-------------+
| User | Host | Select_priv | Insert_priv |
+------|------|-------------|-------------+
| root | % | Y | Y |
+------|------|-------------|-------------+
1 row in set (0.00 sec)
このレコードでは、 HostとUserはrootユーザーから任意のホスト ( % ) から送信された接続要求を受け入れることができると判断します。 Select_privとInsert_privは、ユーザーがグローバルなSelectおよびInsert権限を持っていることを意味します。 mysql.userテーブルの有効範囲はグローバルです。
Host内のUserとmysql.dbは、ユーザーがアクセスできるデータベースを決定します。有効な範囲はデータベースです。
注記:
GRANT、CREATE USER}}、DROP USERFLUSH PRIVILEGESが実行されるまで予期しない動作が発生する可能性があります。
接続確認
クライアントが接続要求を送信すると、TiDBサーバーはログイン操作を検証します。TiDBサーバーは最初にmysql.userテーブルをチェックします。 UserとHostのレコードが接続要求と一致する場合、TiDBサーバーはauthentication_stringを検証します。
ユーザーの識別は、接続を開始するホストHostとユーザー名Userの2つの情報に基づいています。ユーザー名が空でない場合、指定されたユーザー名と完全に一致する必要があります。
User + Host userテーブルの複数の行に一致する可能性があります。このシナリオに対処するため、 userテーブルの行はソートされます。クライアントが接続すると、テーブルの行が 1 つずつチェックされ、最初に一致した行が検証に使用されます。ソート時には、ホストがユーザーよりも優先されます。
リクエストの確認
接続が成功すると、要求検証プロセスによって、その操作に権限があるかどうかがチェックされます。
データベース関連のリクエスト( INSERT 、 UPDATE )の場合、リクエスト検証プロセスではまずmysql.userテーブルでユーザーのグローバル権限を確認します。権限が付与されている場合は、直接アクセスできます。付与されていない場合は、 mysql.dbテーブルを確認します。
userテーブルは、デフォルトのデータベースに関係なく、グローバルな権限を持ちます。たとえば、 DELETEのuser権限は、任意の行、テーブル、またはデータベースに適用できます。
dbテーブルでは、空のユーザーは匿名ユーザー名に一致します。 User列ではワイルドカードは使用できません。 Host列とDb列の値には、パターンマッチングを使用できる%と_を使用できます。
userおよびdbテーブルのデータも、メモリにロードされるときにソートされます。
%とtables_privにおけるcolumns_privの使用方法は似ていますが、 Db 、 Table_name 、 Column_nameの列値には%を含めることはできません。読み込み時のソートも同様です。
有効期間
TiDB が起動すると、いくつかの権限チェックテーブルがメモリにロードされ、キャッシュされたデータを使用して権限が検証されます。 GRANT 、 REVOKE 、 CREATE USER 、 DROP USER権限管理ステートメントを実行すると、すぐに反映されます。
mysql.userなどのテーブルをINSERT 、 DELETE 、 UPDATE手動で編集しても、すぐに反映されません。この動作は MySQL と互換性があり、権限キャッシュはFLUSH PRIVILEGESステートメントで更新できます。