00:00

MySQL Show Users

Last updated: 3 min read

There is no SHOW USERS statement in MySQL. Accounts are stored in the system table mysql.user, and you list them with an ordinary SELECT. This tutorial shows how to list accounts, find out who you are logged in as, check what each account can do, and see who is connected.

1. There Is No SHOW USERS

query.sql
SHOW USERS;
Output
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 'USERS' at line 1

2. Listing Accounts from mysql.user

query.sql
SELECT user, host FROM mysql.user ORDER BY user, host;

Result: 8 rows

userhost
dashlocalhost
etl10.0.0.%
mysql.infoschemalocalhost
mysql.sessionlocalhost
mysql.syslocalhost
old_bilocalhost
rootlocalhost
viewer%
Accounts named mysql.sys, mysql.session and mysql.infoschema are internal, locked system accounts. Leave them alone.

Hide system accounts and show useful details:

details.sql
SELECT user, host, plugin, account_locked, password_expired, password_lifetime,
       DATE(password_last_changed) AS pwd_changed
FROM mysql.user
WHERE user NOT LIKE 'mysql.%'
ORDER BY user;

Result: 5 rows

userhostpluginaccount_lockedpassword_expiredpassword_lifetimepwd_changed
dashlocalhostcaching_sha2_passwordNN302026-10-19
etl10.0.0.%caching_sha2_passwordNNNULL2026-10-19
old_bilocalhostcaching_sha2_passwordYNNULL2026-10-19
rootlocalhostcaching_sha2_passwordNNNULL2026-10-19
viewer%caching_sha2_passwordYYNULL2026-10-19

viewer appears too: roles are stored as locked accounts.

3. Unique User Names

Because an account is user + host, a name can appear more than once. List each name once:

query.sql
SELECT user, COUNT(*) AS host_entries, GROUP_CONCAT(host) AS hosts
FROM mysql.user WHERE user NOT LIKE 'mysql.%'
GROUP BY user;

Result: 5 rows

userhost_entrieshosts
dash1localhost
etl110.0.0.%
old_bi1localhost
root1localhost
viewer1%

4. Who Am I?

USER() is the name and host you tried to log in as; CURRENT_USER() is the account MySQL actually matched, whose privileges apply:

query.sql
SELECT USER() AS login_as, CURRENT_USER() AS authenticated_as;

Result: 1 row

login_asauthenticated_as
root@localhostroot@localhost

They can differ, for example when you connect from 10.0.0.15 and match the 'etl'@'10.0.0.%' account.

5. What Can an Account Do?

query.sql
SHOW GRANTS FOR 'etl'@'10.0.0.%';

Result: 2 rows

Grants for etl@10.0.0.%
GRANT USAGE ON *.* TO `etl`@`10.0.0.%`
GRANT SELECT, INSERT, UPDATE ON `analytics`.* TO `etl`@`10.0.0.%`
query.sql
SHOW GRANTS FOR 'dash'@'localhost';

Result: 2 rows

Grants for dash@localhost
GRANT USAGE ON *.* TO `dash`@`localhost`
GRANT `viewer`@`%` TO `dash`@`localhost`

Include the privileges that come from roles with USING:

query.sql
SHOW GRANTS FOR 'dash'@'localhost' USING 'viewer';

Result: 3 rows

Grants for dash@localhost
GRANT USAGE ON *.* TO `dash`@`localhost`
GRANT SELECT ON `analytics`.* TO `dash`@`localhost`
GRANT `viewer`@`%` TO `dash`@`localhost`

Privileges per database across all accounts:

query.sql
SELECT grantee, table_schema, GROUP_CONCAT(privilege_type ORDER BY privilege_type) AS privileges
FROM information_schema.schema_privileges
GROUP BY grantee, table_schema;

Result: 4 rows

granteetable_schemaprivileges
'etl'@'10.0.0.%'analyticsINSERT,SELECT,UPDATE
'mysql.session'@'localhost'performance_schemaSELECT
'mysql.sys'@'localhost'sysTRIGGER
'viewer'@'%'analyticsSELECT

6. Finding Risky or Stale Accounts

audit.sql
SELECT user, host,
       CASE WHEN account_locked = 'Y' THEN 'locked'
            WHEN password_expired = 'Y' THEN 'password expired'
            WHEN host = '%' THEN 'any host!'
            ELSE 'ok' END AS status
FROM mysql.user
WHERE user NOT LIKE 'mysql.%' AND user <> 'viewer'
ORDER BY status, user;

Result: 4 rows

userhoststatus
old_bilocalhostlocked
dashlocalhostok
etl10.0.0.%ok
rootlocalhostok

7. Who Is Connected Right Now?

Accounts are not the same as sessions. List live connections with the process list:

query.sql
SELECT user, COUNT(*) AS sessions FROM information_schema.processlist GROUP BY user;

Result: 2 rows

usersessions
root1
event_scheduler1
processlist.sql
SHOW PROCESSLIST;          -- one row per connection: id, user, host, db, command, time, state
SHOW FULL PROCESSLIST;     -- including the full SQL text
Without the PROCESS privilege, an account only sees its own sessions.

8. Summary

  • There's no SHOW USERS; query SELECT user, host FROM mysql.user.
  • Add columns like plugin, account_locked and password_expired for an audit view.
  • CURRENT_USER() shows the account whose privileges you have.
  • SHOW GRANTS FOR … [USING role] shows what an account can do.
  • SHOW PROCESSLIST shows who is connected now.