MySQL 11 min read

MySQLでユーザー一覧を表示する ― mysql.userとSHOW GRANTS、hostごとに別ユーザー

MySQL には SHOW USERS のようなコマンドがありません。ユーザーは mysql.user 表に入っているので、SELECT で一覧を出します。この記事の出力は MySQL 8.4.6 で採りました。

まず見る(結論)

  • 一覧は SELECT user, host FROM mysql.user;
  • MySQL のアカウントは「ユーザー名@host」の組。同じ名前でも host が違えば別のアカウント
  • 権限は SHOW GRANTS FOR 'ユーザー'@'host';
  • mysql.user を読むには権限が要る。一般ユーザーでは ERROR 1142

ユーザー一覧を出す

mysql> SELECT user, host FROM mysql.user ORDER BY user, host;
+------------------+-------------+
| user             | host        |
+------------------+-------------+
| app              | %           |
| app              | localhost   |
| mysql.infoschema | localhost   |
| mysql.session    | localhost   |
| mysql.sys        | localhost   |
| ro               | 192.168.0.% |
| root             | %           |
| root             | localhost   |
+------------------+-------------+

(並ぶアカウントは環境によって違います。この例の app と ro は検証用に作ったものです。一部の行を省いています)

app が2行あります。'app'@'%'(どこからでも)と 'app'@'localhost'(同じマシンから)は、パスワードも権限も別々に持つ、別のアカウントです。接続したときは、host がより具体的に一致する方が選ばれます。同じマシンから app で入ると 'app'@'localhost' の権限で動くので、'app'@'%' に GRANT した権限が効かないことがあります。

mysql.infoschema、mysql.session、mysql.sys は MySQL 自身が使うアカウントで、ロックされています。削除しないでください。

認証方式やロック状態も見る

mysql> SELECT user, host, plugin, account_locked, password_expired, password_last_changed
    ->   FROM mysql.user;
+------------------+-------------+-----------------------+----------------+------------------+-----------------------+
| user             | host        | plugin                | account_locked | password_expired | password_last_changed |
+------------------+-------------+-----------------------+----------------+------------------+-----------------------+
| app              | %           | caching_sha2_password | N              | N                | 2026-10-17 10:16:23   |
| root             | %           | caching_sha2_password | N              | N                | 2026-10-17 04:24:11   |
| ro               | 192.168.0.% | caching_sha2_password | N              | N                | 2026-10-17 10:16:23   |
| app              | localhost   | caching_sha2_password | N              | N                | 2026-10-17 10:16:23   |
| mysql.infoschema | localhost   | caching_sha2_password | Y              | N                | 2026-10-17 04:24:06   |
| mysql.session    | localhost   | caching_sha2_password | Y              | N                | 2026-10-17 04:24:06   |
| mysql.sys        | localhost   | caching_sha2_password | Y              | N                | 2026-10-17 04:24:06   |
| root             | localhost   | caching_sha2_password | N              | N                | 2026-10-17 04:24:11   |
+------------------+-------------+-----------------------+----------------+------------------+-----------------------+

plugin は認証方式です。古いクライアントで接続できないときは、ここが原因のことがあります。8.4 では旧来の mysql_native_password が既定で無効なので、クライアントやドライバーを caching_sha2_password に対応した版に上げます。account_locked が Y のアカウントはログインできません。

権限を見る

mysql> SHOW GRANTS FOR 'ro'@'192.168.0.%';
+-------------------------------------------------+
| Grants for ro@192.168.0.%                       |
+-------------------------------------------------+
| GRANT USAGE ON *.* TO `ro`@`192.168.0.%`        |
| GRANT SELECT ON `sugdb`.* TO `ro`@`192.168.0.%` |
+-------------------------------------------------+

USAGE は「権限なし」の意味で、どのユーザーにも必ず付いています。実際の権限は2行目の sugdb への SELECT です。

host を省くと '%' とみなされます。SHOW GRANTS FOR 'app'; は 'app'@'%' の権限を返し、'app'@'localhost' の権限は出ません。

mysql> SHOW GRANTS FOR 'app';
+---------------------------------+
| Grants for app@%                |
+---------------------------------+
| GRANT USAGE ON *.* TO `app`@`%` |
+---------------------------------+

自分の権限は、引数なしの SHOW GRANTS; で見られます。

今どのアカウントで入っているか

mysql> SELECT USER(), CURRENT_USER();
+----------------+----------------+
| USER()         | CURRENT_USER() |
+----------------+----------------+
| root@localhost | root@localhost |
+----------------+----------------+

USER() は接続時に名乗ったユーザー名と接続元、CURRENT_USER() は実際に権限の判定に使われているアカウントです。'app'@'%' と 'app'@'localhost' のどちらで動いているか分からないときは、CURRENT_USER() を見ます。

一般ユーザーでは一覧を出せない

ERROR 1142 (42000): SELECT command denied to user 'app'@'localhost' for table 'user'

ユーザーの一覧や他人の権限を見るのは管理者の作業なので、root など権限のあるアカウントで実行します。