mysql
システムデータベースには、ユーザーアカウントおよびそのアカウントが保持する権限に関する情報を含む複数の付与テーブルが含まれています。 このセクションでは、これらのテーブルについて説明します。 システムデータベース内の他のテーブルの詳細は、セクション5.3「mysql システムスキーマ」 を参照してください。
ここでは付与テーブルの基本構造と、サーバーがクライアントと対話するときに付与テーブルの内容をどのように使用するかについて説明します。 ただし、通常は付与テーブルを直接変更しません。 CREATE USER
、GRANT
、REVOKE
などのアカウント管理ステートメントを使用してアカウントを設定し、各アカウントで使用可能な権限を制御すると、変更が間接的に行われます。 セクション13.7.1「アカウント管理ステートメント」を参照してください。 このようなステートメントを使用してアカウント操作を実行すると、サーバーはユーザーの代わりに付与テーブルを変更します。
INSERT
、UPDATE
、DELETE
などのステートメントを使用して付与テーブルを直接変更することはお薦めできません。独自のリスクで実行してください。 これらの変更の結果として誤った形式となった行を、サーバーは随意で無視します。
付与テーブルを変更する操作の場合、サーバーはテーブルが予期された構造を持っているかどうかをチェックし、持っていない場合はエラーを生成します。 テーブルを必要な構造に更新するには、MySQL のアップグレード手順を実行します。 セクション2.11「MySQL のアップグレード」を参照してください。
次の mysql
データベーステーブルには付与情報が格納されています。
-
user
: ユーザーアカウント、静的グローバル権限およびその他の非権限カラム。 -
global_grants
: 動的グローバル権限。 -
db
: Database-level privileges. -
tables_priv
: Table-level privileges. -
columns_priv
: Column-level privileges. -
procs_priv
: ストアドプロシージャおよびファンクション権限。 -
proxies_priv
: Proxy-user privileges. -
default_roles
: デフォルトのユーザーロール。 -
role_edges
: ロールサブグラフのエッジ。 -
password_history
: パスワード変更履歴。
静的グローバル権限と動的グローバル権限の違いの詳細は、静的権限と動的権限 を参照してください。)
MySQL 8.0 では、付与テーブルは InnoDB
ストレージエンジンを使用し、トランザクションです。 MySQL 8.0 より前は、付与テーブルは MyISAM
ストレージエンジンを使用しており、非トランザクションでした。 付与テーブルストレージエンジンのこの変更により、CREATE USER
や GRANT
などのアカウント管理ステートメントの動作に付随する変更が可能になります。 以前は、複数のユーザーを指定したアカウント管理ステートメントは、一部のユーザーでは成功し、他のユーザーでは失敗していました。 現在は、各ステートメントはトランザクションに対応し、指定されたすべてのユーザーに対して成功するか、エラーが発生した場合はロールバックされて何の影響も与えなくなりました。
各付与テーブルにはスコープカラムと権限カラムがあります。
有効範囲カラムは、テーブルの各行の有効範囲、つまり行が適用されるコンテキストを決定します。 たとえば、
Host
とUser
の値が'h1.example.net'
および'bob'
のuser
テーブルの行は、ユーザー名bob
を指定するクライアントによってホストh1.example.net
からサーバーに対して行われる認証接続に適用されます。 同様に、Host
、User
およびDb
カラムの'h1.example.net'
、'bob'
および'reports'
の値を含むdb
テーブルの行は、bob
がホストh1.example.net
から接続してreports
データベースにアクセスする場合に適用されます。tables_priv
テーブルおよびcolumns_priv
テーブルには、それぞれの行に適用されるテーブルまたはテーブルとカラムの組み合わせを示すスコープカラムがあります。procs_priv
スコープカラムは、それぞれの行に適用されるストアドルーチンを示します。権限カラムは、テーブルの行で付与される権限、つまり実行が許可される操作を示します。 サーバーは、さまざまな付与テーブル内の情報を結合して、ユーザー権限の完全な説明を形成します。セクション6.2.7「アクセス制御、ステージ 2: リクエストの確認」 では、このルールについて説明します。
また、権限付与テーブルには、スコープまたは権限評価以外の目的で使用されるカラムが含まれる場合があります。
サーバーは次の方法で付与テーブルを使用します。
-
user
テーブルのスコープカラムは、入接続を拒否または許可するかを決定します。 許可された接続の場合、user
テーブルで付与された権限は、ユーザーの静的グローバル権限を示します。 このテーブルで付与される権限は、サーバー上の all データベースに適用されます。注意静的グローバル権限はすべてのデータベースに対する権限とみなされるため、静的グローバル権限を使用すると、ユーザーは、部分的な取消しによってデータベースレベルで制限されているデータベースを除き、
SHOW DATABASES
を使用するか、INFORMATION_SCHEMA
のSCHEMATA
テーブルを調べることで、すべてのデータベース名を表示できます。 global_grants
テーブルには、ユーザーアカウントへの動的グローバル権限の現在の割当てがリストされます。 行ごとに、有効範囲カラムによって、権限カラムで指定された権限を持つユーザーが決定されます。db
テーブルのスコープカラムは、どのユーザーがどのホストからどのデータベースにアクセスできるかを決定します。 権限カラムによって、許可される操作が決まります。 データベースレベルで付与される権限は、データベースのほかテーブルやストアドプログラムなどのデータベース内のすべてのオブジェクトに適用されます。tables_priv
およびcolumns_priv
テーブルはdb
テーブルと似ていますが、これらはさらに粒度が細かく、データベースレベルでなくテーブルレベルおよびカラムレベルに適用されます。 テーブルレベルで付与される権限は、テーブルおよびそのすべてのカラムに適用されます。 カラムレベルで付与される権限は、特定のカラムにのみ適用されます。procs_priv
テーブルはストアドルーチン (ストアドプロシージャーとストアドファンクション) に適用されます。 ルーチンレベルで付与される権限は、単一のプロシージャまたは関数にのみ適用されます。proxies_priv
テーブルには、他のユーザーのプロキシとして機能できるユーザーと、ユーザーが他のユーザーにPROXY
権限を付与できるかどうかが示されます。default_roles
テーブルとrole_edges
テーブルには、ロール関係に関する情報が含まれています。password_history
テーブルでは、パスワードの再利用に関する制限を有効にするために、以前に選択したパスワードが保持されます。 セクション6.2.15「パスワード管理」を参照してください。
サーバーは、起動時に付与テーブルの内容をメモリーに読み取ります。 FLUSH PRIVILEGES
ステートメントを発行するか、mysqladmin flush-privileges または mysqladmin reload コマンドを実行することによって、テーブルをリロードするようサーバーに指示することができます。 付与テーブルへの変更は、セクション6.2.13「権限変更が有効化される時期」で示すように反映されます。
アカウントを変更する場合は、変更が意図したとおりの効果を持つことを確認することをお薦めします。 特定のアカウントの権限を確認するには、SHOW GRANTS
ステートメントを使用します。 たとえば、ユーザー名およびホスト名の値がそれぞれ bob
および pc84.example.com
のアカウントに付与された権限を調べるには、次のステートメントを使用します。
SHOW GRANTS FOR 'bob'@'pc84.example.com';
アカウントの非特権プロパティーを表示するには、SHOW CREATE USER
を使用します:
SHOW CREATE USER 'bob'@'pc84.example.com';
サーバーは mysql
データベース内の user
および db
テーブルを、アクセス制御のステージ 1 とステージ 2 の両方で使用します (セクション6.2「アクセス制御とアカウント管理」を参照してください)。 user
と db
のテーブルのカラムをここで示します。
表 6.4 user テーブルおよび db テーブルのカラム
テーブル名 | user |
db |
---|---|---|
スコープカラム | Host |
Host |
User |
Db |
|
User |
||
権限カラム | Select_priv |
Select_priv |
Insert_priv |
Insert_priv |
|
Update_priv |
Update_priv |
|
Delete_priv |
Delete_priv |
|
Index_priv |
Index_priv |
|
Alter_priv |
Alter_priv |
|
Create_priv |
Create_priv |
|
Drop_priv |
Drop_priv |
|
Grant_priv |
Grant_priv |
|
Create_view_priv |
Create_view_priv |
|
Show_view_priv |
Show_view_priv |
|
Create_routine_priv |
Create_routine_priv |
|
Alter_routine_priv |
Alter_routine_priv |
|
Execute_priv |
Execute_priv |
|
Trigger_priv |
Trigger_priv |
|
Event_priv |
Event_priv |
|
Create_tmp_table_priv |
Create_tmp_table_priv |
|
Lock_tables_priv |
Lock_tables_priv |
|
References_priv |
References_priv |
|
Reload_priv |
||
Shutdown_priv |
||
Process_priv |
||
File_priv |
||
Show_db_priv |
||
Super_priv |
||
Repl_slave_priv |
||
Repl_client_priv |
||
Create_user_priv |
||
Create_tablespace_priv |
||
Create_role_priv |
||
Drop_role_priv |
||
セキュリティーカラム | ssl_type |
|
ssl_cipher |
||
x509_issuer |
||
x509_subject |
||
plugin |
||
authentication_string |
||
password_expired |
||
password_last_changed |
||
password_lifetime |
||
account_locked |
||
Password_reuse_history |
||
Password_reuse_time |
||
Password_require_current |
||
User_attributes |
||
リソース制御カラム | max_questions |
|
max_updates |
||
max_connections |
||
max_user_connections |
user
テーブルの plugin
カラムおよび authentication_string
カラムには、認証プラグインおよび資格証明情報が格納されます。
サーバーは、アカウント行の plugin
カラムで指定されたプラグインを使用して、アカウントの接続試行を認証します。
plugin
カラムは空にできません。 起動時および実行時に、FLUSH PRIVILEGES
が実行されると、サーバーは user
テーブルの行をチェックします。 plugin
カラムが空の行の場合、サーバーは次の形式のエラーログに警告を書き込みます:
[Warning] User entry 'user_name'@'host_name' has an empty plugin
value. The user will be ignored and no one can login with this user
anymore.
プラグインがないアカウントにプラグインを割り当てるには、ALTER USER
ステートメントを使用します。
password_expired
カラムを使用すると、DBA はアカウントパスワードを期限切れにでき、ユーザーはパスワードをリセットする必要があります。 デフォルトの password_expired
値は 'N'
ですが、ALTER USER
ステートメントを使用して 'Y'
に設定できます。 アカウントパスワードが期限切れになると、ユーザーが新しいアカウントパスワードを確立するために ALTER USER
ステートメントを発行するまで、サーバーへの後続の接続でアカウントによって実行されるすべての操作でエラーが発生します。
期限切れのパスワードは、現在の値に設定することで 「reset」 で使用できますが、適切なポリシーとして、別のパスワードを選択することをお薦めします。 DBA は、適切なパスワード再利用ポリシーを確立することで、非キューを強制できます。 パスワード再利用ポリシーを参照してください。
password_last_changed
は、パスワードが最後に変更された日時を示す TIMESTAMP
カラムです。 この値は、MySQL 組込み認証プラグイン (mysql_native_password
、sha256_password
または caching_sha2_password
) を使用するアカウントに対してのみ NULL
以外です。 他のアカウント (外部認証システムを使用して認証されたアカウントなど) の場合、値は NULL
です。
password_last_changed
は、CREATE USER
、ALTER USER
および SET PASSWORD
ステートメント、およびアカウントの作成やアカウントパスワードの変更を行う GRANT
ステートメントによって更新されます。
password_lifetime
は、アカウントパスワードの存続期間を日数で示します。 パスワードが存続期間を過ぎた場合 (password_last_changed
カラムを使用して評価)、クライアントがアカウントを使用して接続すると、サーバーはパスワードの有効期限が切れたとみなします。 ゼロより大きい N
の値は、パスワードを N
日ごとに変更する必要があることを意味します。 値 0 を指定すると、自動パスワード有効期限が無効になります。 値が NULL
(デフォルト) の場合は、default_password_lifetime
システム変数で定義されているグローバル有効期限ポリシーが適用されます。
account_locked
は、アカウントがロックされているかどうかを示します (セクション6.2.19「アカウントロック」 を参照)。
Password_reuse_history
は、アカウントの PASSWORD HISTORY
オプションの値、またはデフォルト履歴の NULL
の値です。
Password_reuse_time
は、アカウントの PASSWORD REUSE INTERVAL
オプション、またはデフォルト間隔の NULL
の値です。
Password_require_current
(MySQL 8.0.13 で追加) は、次のテーブルに示すように、アカウントの PASSWORD REQUIRE
オプションの値に対応します。
表 6.5 許可される Password_require_current 値
Password_require_current 値 | 対応する PASSWORD REQUIRE オプション |
---|---|
'Y' |
PASSWORD REQUIRE CURRENT |
'N' |
PASSWORD REQUIRE CURRENT OPTIONAL |
NULL |
PASSWORD REQUIRE CURRENT DEFAULT |
User_attributes
(MySQL 8.0.14 で追加) は、他のカラムに格納されていないアカウント属性を格納する JSON 形式のカラムです:
additional_password
: セカンダリパスワード (存在する場合)。 デュアルパスワードのサポートを参照してください。Restrictions
: 制限リスト (ある場合)。 制限は、部分失効操作によって追加されます。 属性値は、それぞれ制限されたデータベースの名前とそれに適用可能な制限を示すDatabase
およびRestrictions
キーを持つ要素の配列です (セクション6.2.12「部分取消しを使用した権限の制限」 を参照)。Password_locking
: 失敗したログイントラッキングおよび一時アカウントロックの条件 (存在する場合)(失敗したログイントラッキングと一時アカウントロック を参照)。Password_locking
属性は、CREATE USER
およびALTER USER
ステートメントのFAILED_LOGIN_ATTEMPTS
およびPASSWORD_LOCK_TIME
オプションに従って更新されます。 属性値は、アカウントに指定されているようなオプションの値を示すfailed_login_attempts
およびpassword_lock_time_days
キーを含むハッシュです。 キーがない場合、その値は暗黙的に 0 になります。 キー値が暗黙的または明示的に 0 の場合、対応する機能は無効になります。 この属性は、MySQL 8.0.19 で追加されました。
適用される属性がない場合、User_attributes
は NULL
です。
例: セカンダリパスワードを持ち、部分的に取り消されたデータベース権限を持つアカウントのカラム値には、additional_password
および Restrictions
属性が含まれます:
mysql> SELECT User_attributes FROM mysql.User WHERE User = 'u'\G
*************************** 1. row ***************************
User_attributes: {"Restrictions":
[{"Database": "mysql", "Privileges": ["SELECT"]}],
"additional_password": "hashed_credentials"}
存在する属性を確認するには、JSON_KEYS()
関数を使用します:
SELECT User, Host, JSON_KEYS(User_attributes)
FROM mysql.user WHERE User_attributes IS NOT NULL;
Restrictions
などの特定の属性を抽出するには、次のようにします:
SELECT User, Host, User_attributes->>'$.Restrictions'
FROM mysql.user WHERE User_attributes->>'$.Restrictions' <> '';
アクセス制御の第 2 段階で、サーバーはリクエスト検証を実行して、各クライアントが発行するリクエストごとに十分な権限を持っていることを確認します。 user
および db
付与テーブルに加えて、テーブルに関するリクエストの場合、サーバーは tables_priv
および columns_priv
テーブルを参照することもあります。 後者のテーブルは、テーブルレベルおよびカラムレベルでの細かい権限制御を提供します。 これらには、次の表に示すカラムがあります。
表 6.6 tables_priv テーブルおよび columns_priv テーブルのカラム
テーブル名 | tables_priv |
columns_priv |
---|---|---|
スコープカラム | Host |
Host |
Db |
Db |
|
User |
User |
|
Table_name |
Table_name |
|
Column_name |
||
権限カラム | Table_priv |
Column_priv |
Column_priv |
||
その他のカラム | Timestamp |
Timestamp |
Grantor |
Timestamp
カラムと Grantor
カラムは、それぞれ現在のタイムスタンプと CURRENT_USER
値に設定されますが、それ以外の場合は使用されません。
ストアドルーチンに関するリクエストを検証するために、サーバーは procs_priv
テーブルを参照することがあり、このテーブルには次の表に示すカラムがあります。
表 6.7 procs_priv テーブルのカラム
テーブル名 | procs_priv |
---|---|
スコープカラム | Host |
Db |
|
User |
|
Routine_name |
|
Routine_type |
|
権限カラム | Proc_priv |
その他のカラム | Timestamp |
Grantor |
Routine_type
カラムは、'FUNCTION'
または 'PROCEDURE'
の値を持つ ENUM
カラムであり、その行が示すルーチンのタイプを指します。 このカラムにより、同じ名前を持つ関数とプロシージャーに別々に権限を付与することができます。
Timestamp
カラムおよび Grantor
カラムは未使用です。
proxies_priv
テーブルには、プロキシアカウントに関する情報が記録されます。 これには次のカラムがあります。
Host
,User
: プロキシアカウント (プロキシアカウントに対するPROXY
権限を持つアカウント)。Proxied_host
,Proxied_user
: プロキシされたアカウント。Grantor
,Timestamp
: Unused.With_grant
: プロキシアカウントがPROXY
権限を他のアカウントに付与できるかどうか。
アカウントが PROXY
権限を他のアカウントに付与できるようにするには、With_grant
が 1 に設定され、Proxied_host
および Proxied_user
が権限を付与できるアカウントを示す行が proxies_priv
テーブルに含まれている必要があります。 たとえば、MySQL のインストール時に作成された'root'@'localhost'
アカウントの proxies_priv
テーブルには、''@''
の PROXY
権限 (すべてのユーザーおよびすべてのホスト) の付与を可能にする行があります。 これにより、root
はプロキシユーザーを設定したり、プロキシユーザーを設定するための権限をほかのアカウントに委任したりできます。 セクション6.2.18「プロキシユーザー」を参照してください。
global_grants
テーブルには、ユーザーアカウントへの動的グローバル権限の現在の割当てがリストされます。 テーブルには次のカラムがあります。
USER
,HOST
: 権限が付与されるアカウントのユーザー名およびホスト名。PRIV
: 権限名。WITH_GRANT_OPTION
: アカウントが他のアカウントに権限を付与できるかどうか。
default_roles
テーブルには、デフォルトのユーザーロールがリストされます。 これには次のカラムがあります。
HOST
,USER
: デフォルトロールが適用されるアカウントまたはロール。DEFAULT_ROLE_HOST
,DEFAULT_ROLE_USER
: デフォルトロール。
role_edges
テーブルには、ロールサブグラフのエッジがリストされます。 これには次のカラムがあります。
FROM_HOST
,FROM_USER
: ロールが付与されているアカウント。TO_HOST
,TO_USER
: アカウントに付与されるロール。WITH_ADMIN_OPTION
: アカウントがWITH ADMIN OPTION
を使用して他のアカウントにロールを付与したり、他のアカウントからロールを取り消すことができるかどうか。
password_history
テーブルには、パスワード変更に関する情報が含まれています。 これには次のカラムがあります。
Host
,User
: パスワード変更が発生したアカウント。Password_timestamp
: パスワード変更が発生した時刻。Password
: 新しいパスワードハッシュ値。
password_history
テーブルには、MySQL がアカウントパスワード履歴の長さと再利用間隔の両方に対してチェックを実行できるように、アカウントごとに空でない十分な数のパスワードが蓄積されます。 両方の制限外のエントリの自動プルーニングは、パスワード変更の試行が発生したときに行われます。
空のパスワードはパスワード履歴にカウントされず、いつでも再利用される可能性があります。
アカウントの名前が変更されると、一致するようにそのエントリの名前が変更されます。 アカウントが削除されるか、その認証プラグインが変更されると、そのエントリは削除されます。
付与テーブルのスコープカラムには文字列が格納されています。 それぞれのデフォルト値は空の文字列です。 次のテーブルに、各カラムで許可される文字数を示します。
表 6.8 付与テーブルの有効範囲カラム長
カラム名 | 最大許容文字数 |
---|---|
Host 、Proxied_host
|
255 (MySQL 8.0.17 より前の 60) |
User 、Proxied_user
|
32 |
Db |
64 |
Table_name |
64 |
Column_name |
64 |
Routine_name |
64 |
Host
および Proxied_host
の値は、権限付与テーブルに格納される前に小文字に変換されます。
アクセスチェックの目的で、User
, Proxied_user
, authentication_string
, Db
と Table_name
の値の比較では大/小文字が区別されます。 Host
, Proxied_host
, Column_name
と Routine_name
の値の比較では、大/小文字は区別されません。
user
テーブルおよび db
テーブルでは、ENUM('N','Y') DEFAULT 'N'
として宣言された個別のカラムに各権限がリストされます。 つまり、各権限は無効または有効にすることができ、デフォルトは無効です。
tables_priv
、columns_priv
および procs_priv
の各テーブルでは、権限カラムを SET
カラムとして宣言します。 これらのカラムの値は、テーブルによって制御されるあらゆる組み合わせの権限を含むことができます。 カラム値にリストされている権限のみが入力されます。
表 6.9 Set タイプ権限のカラム値
テーブル名 | カラム名 | 可能な Set 要素 |
---|---|---|
tables_priv |
Table_priv |
'Select', 'Insert', 'Update', 'Delete', 'Create', 'Drop', 'Grant', 'References', 'Index', 'Alter', 'Create View', 'Show view', 'Trigger' |
tables_priv |
Column_priv |
'Select', 'Insert', 'Update', 'References' |
columns_priv |
Column_priv |
'Select', 'Insert', 'Update', 'References' |
procs_priv |
Proc_priv |
'Execute', 'Alter Routine', 'Grant' |
RELOAD
、SHUTDOWN
、SYSTEM_VARIABLES_ADMIN
などの管理権限を指定するのは、user
テーブルおよび global_grants
テーブルのみです。 管理操作はサーバー自体での操作であって、データベース固有でないため、これらの権限をほかの付与テーブルにリストする理由はありません。 したがって、サーバーは、ユーザーが管理操作を実行できるかどうかを判断するために、user
および global_grants
テーブルのみを参照する必要があります。
FILE
権限も、user
テーブルでのみ指定されます。 このような管理権限ではありませんが、サーバーホスト上のファイルの読取りまたは書込みを行うユーザー権限は、アクセスされるデータベースから独立しています。
MySQL 8.0.22 では、MySQL 付与テーブルに対する同時 DML 操作および DDL 操作を許可するために、MySQL 付与テーブルに対して以前に行ロックを取得した読取り操作は、非ロック読取りとして実行されます。 MySQL 付与テーブルで非ロック読み取りとして実行される操作には、次のものがあります:
任意のトランザクション分離レベルを使用して、結合リストおよびサブクエリー (
SELECT ... FOR SHARE
ステートメントを含む) を介して付与テーブルからデータを読み取るSELECT
ステートメントおよびその他の読取り専用ステートメント。任意のトランザクション分離レベルを使用して (結合リストまたはサブクエリーを介して) 付与テーブルからデータを読み取り、変更を伴わない DML 操作。
付与テーブルからデータを読み取るときに行ロックを取得しなくなったステートメントは、ステートメントベースレプリケーションの使用中に実行された場合に警告を報告します。
使用時 -binlog_format=mixed
、付与テーブルからデータを読み取る DML 操作は、混合モードのレプリケーションで操作を安全にするために、行イベントとしてバイナリログに書き込まれます。
付与テーブルからデータを読み取る SELECT ... FOR SHARE
ステートメントは警告を報告します。 FOR SHARE
句を使用する場合、読取りロックは付与テーブルではサポートされません。
付与テーブルからデータを読み取り、SERIALIZABLE
分離レベルを使用して実行される DML 操作では、警告がレポートされます。 SERIALIZABLE
分離レベルの使用時に通常取得される読取りロックは、付与テーブルではサポートされていません。