3.

MySQLでユーザー一覧を表示|mysql.user・SHOW GRANTSの使い方

編集
この記事の要点
  • MySQL: SELECT user, host FROM mysql.user; が基本。root 系の admin 権限ユーザーで実行
  • 権限の中身は SHOW GRANTS FOR "user"@"host"; で 1 ユーザーずつ確認
  • information_schema.USER_PRIVILEGES で行的に取得して集計可能
  • PostgreSQL: \du または SELECT * FROM pg_roles;
  • Oracle: SELECT username, account_status FROM dba_users; — ロック状態と認証プラグインも同じビューで確認

MySQL の場合

基本: mysql.user テーブル

-- 全ユーザー (アカウント = user + host のセット)
SELECT user, host FROM mysql.user;

-- +------------------+-----------+
-- | user             | host      |
-- +------------------+-----------+
-- | root             | localhost |
-- | mysql.sys        | localhost |
-- | mysql.session    | localhost |
-- | app_user         | %         |   ← 全 IP から接続可
-- | readonly         | 10.0.%    |   ← 社内 LAN のみ
-- +------------------+-----------+

MySQL は ユーザー名と接続元ホスト名の組み合わせでアカウントを管理します。同じ app_user でも 'app_user'@'localhost''app_user'@'%' は別アカウント扱い。

認証プラグインや有効期限も見る

-- MySQL 5.7 以降
SELECT user, host, plugin, password_expired, account_locked
FROM mysql.user
ORDER BY user, host;

-- +-----------+-----------+-----------------------+------------------+----------------+
-- | user      | host      | plugin                | password_expired | account_locked |
-- +-----------+-----------+-----------------------+------------------+----------------+
-- | root      | localhost | caching_sha2_password | N                | N              |
-- | mysql.sys | localhost | caching_sha2_password | N                | Y              |  ← ロック中
-- +-----------+-----------+-----------------------+------------------+----------------+

個別の権限を確認

SHOW GRANTS FOR 'app_user'@'%';

-- +------------------------------------------------------------------+
-- | Grants for app_user@%                                            |
-- +------------------------------------------------------------------+
-- | GRANT USAGE ON *.* TO 'app_user'@'%'                             |
-- | GRANT SELECT, INSERT, UPDATE, DELETE ON `appdb`.* TO 'app_user'@'%' |
-- +------------------------------------------------------------------+

-- 現在ログイン中の自分の権限
SHOW GRANTS;
SHOW GRANTS FOR CURRENT_USER();

information_schema 経由

-- 全権限を行で取得
SELECT * FROM information_schema.USER_PRIVILEGES;

-- グローバル権限の集計
SELECT GRANTEE, GROUP_CONCAT(PRIVILEGE_TYPE) AS privs
FROM   information_schema.USER_PRIVILEGES
GROUP  BY GRANTEE;

-- スキーマレベル権限
SELECT * FROM information_schema.SCHEMA_PRIVILEGES;

-- テーブルレベル権限
SELECT * FROM information_schema.TABLE_PRIVILEGES;

PostgreSQL の場合

psql のメタコマンド

postgres=# \du
                                     List of roles
 Role name |                         Attributes                         | Member of
-----------+------------------------------------------------------------+-----------
 app_user  |                                                            | {}
 readonly  | Cannot login                                               | {ro_group}
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}

postgres=# \du+      -- 詳細表示 (コメント含む)
postgres=# \dg       -- グループロールのみ

SQL から取得

SELECT rolname, rolsuper, rolcreaterole, rolcreatedb, rolcanlogin,
       rolconnlimit, rolvaliduntil
FROM   pg_roles
WHERE  rolname NOT LIKE 'pg_%'      -- 内部ロール除外
ORDER BY rolname;

-- 旧 pg_user (LOGIN ロールのみ表示する互換ビュー)
SELECT usename, usesuper, valuntil FROM pg_user;

-- 全権限を一覧
SELECT grantee, table_schema, table_name, privilege_type
FROM   information_schema.table_privileges
WHERE  grantee NOT IN ('postgres', 'PUBLIC')
ORDER BY grantee, table_schema, table_name;

PostgreSQL 9.0 以降は ユーザーとグループの区別が無くなり、すべて「ロール (Role)」として扱われます。ログイン可能なロール = 旧ユーザー、ログイン不可で他のロールにメンバーシップを持つロール = 旧グループ、という関係です。

Oracle の場合

-- DBA 権限ユーザーで
SELECT username, account_status, created, default_tablespace,
       authentication_type, profile
FROM   dba_users
ORDER  BY username;

-- ACCOUNT_STATUS で見られる主な状態
-- OPEN                          ... 利用可
-- LOCKED                        ... 管理者がロック
-- EXPIRED                       ... パスワード期限切れ
-- EXPIRED & LOCKED              ... ロック + 期限切れ
-- LOCKED(TIMED)                 ... 連続失敗で自動ロック

-- 一般ユーザーから見える範囲
SELECT username FROM all_users;
SELECT username FROM user_users;       -- 自分自身

-- ユーザーの持つロール
SELECT * FROM dba_role_privs WHERE grantee = 'APP_USER';

-- ユーザーのシステム権限
SELECT * FROM dba_sys_privs WHERE grantee = 'APP_USER';

-- ユーザーのオブジェクト権限
SELECT * FROM dba_tab_privs WHERE grantee = 'APP_USER';

DB 間の対応表

目的MySQLPostgreSQLOracle
ユーザー一覧SELECT user,host FROM mysql.user\du / pg_rolesdba_users
権限SHOW GRANTS\dp / information_schema.table_privilegesdba_sys_privs / dba_tab_privs
ロール(MySQL 8.0+) mysql.role_edgespg_auth_membersdba_role_privs
現在のユーザーSELECT CURRENT_USER()SELECT current_userSELECT USER FROM dual

削除済みユーザーが残るケース

テーブルの所有者やオブジェクトの所有者として残っている場合、DROP USER は失敗します。次のパターンに注意。

  • MySQL: 接続中セッションが残っていると DROP USER しても接続が切れるまで権限が有効に見えることがある
  • PostgreSQL: REASSIGN OWNED BY old_user TO new_user; + DROP OWNED BY old_user; の順で先にオブジェクトの所有を移す
  • Oracle: DROP USER xxx CASCADE で所有スキーマごと削除されるため誤削除に厳重注意

認証プラグインの確認 (MySQL)

-- MySQL 8.0 既定: caching_sha2_password
-- 古いクライアントが繋がらない場合 mysql_native_password に戻す
ALTER USER 'app'@'%' IDENTIFIED WITH mysql_native_password BY 'newpass';

-- LDAP 認証 (Enterprise Edition)
ALTER USER 'app'@'%' IDENTIFIED WITH authentication_ldap_simple;

-- 認証プラグインの一覧
SELECT user, host, plugin FROM mysql.user;

FAQ

Q: mysql.user を参照できない
A: 一般ユーザーには参照権限がありません。root または SELECT ON mysql.* 権限を持つアカウントで接続してください。

Q: 同じ user 名で host が違うレコードがいくつもある
A: それが MySQL の正常挙動。接続元 IP / ホスト名ごとに別アカウントです。一括で消すなら DROP USER 'app'@'host1', 'app'@'host2' のように指定。

Q: Oracle で「ロックされたユーザー」を解除したい
A: ALTER USER scott ACCOUNT UNLOCK; でロック解除、IDENTIFIED BY new_password でパスワード再設定。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. ユーザー作成
  2. ユーザー名変更(RENAME USER)
  3. ユーザー一覧の表示

最近更新/作成されたページ