MySQL Show Users
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
SHOW USERS;
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
SELECT user, host FROM mysql.user ORDER BY user, host;
Result: 8 rows
| user | host |
|---|---|
| dash | localhost |
| etl | 10.0.0.% |
| mysql.infoschema | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| old_bi | localhost |
| root | localhost |
| viewer | % |
mysql.sys, mysql.session and mysql.infoschema are internal, locked system accounts. Leave them alone.Hide system accounts and show useful details:
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
| user | host | plugin | account_locked | password_expired | password_lifetime | pwd_changed |
|---|---|---|---|---|---|---|
| dash | localhost | caching_sha2_password | N | N | 30 | 2026-10-19 |
| etl | 10.0.0.% | caching_sha2_password | N | N | NULL | 2026-10-19 |
| old_bi | localhost | caching_sha2_password | Y | N | NULL | 2026-10-19 |
| root | localhost | caching_sha2_password | N | N | NULL | 2026-10-19 |
| viewer | % | caching_sha2_password | Y | Y | NULL | 2026-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:
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
| user | host_entries | hosts |
|---|---|---|
| dash | 1 | localhost |
| etl | 1 | 10.0.0.% |
| old_bi | 1 | localhost |
| root | 1 | localhost |
| viewer | 1 | % |
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:
SELECT USER() AS login_as, CURRENT_USER() AS authenticated_as;
Result: 1 row
| login_as | authenticated_as |
|---|---|
| root@localhost | root@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?
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.%` |
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:
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:
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
| grantee | table_schema | privileges |
|---|---|---|
| 'etl'@'10.0.0.%' | analytics | INSERT,SELECT,UPDATE |
| 'mysql.session'@'localhost' | performance_schema | SELECT |
| 'mysql.sys'@'localhost' | sys | TRIGGER |
| 'viewer'@'%' | analytics | SELECT |
6. Finding Risky or Stale Accounts
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
| user | host | status |
|---|---|---|
| old_bi | localhost | locked |
| dash | localhost | ok |
| etl | 10.0.0.% | ok |
| root | localhost | ok |
7. Who Is Connected Right Now?
Accounts are not the same as sessions. List live connections with the process list:
SELECT user, COUNT(*) AS sessions FROM information_schema.processlist GROUP BY user;
Result: 2 rows
| user | sessions |
|---|---|
| root | 1 |
| event_scheduler | 1 |
SHOW PROCESSLIST; -- one row per connection: id, user, host, db, command, time, state
SHOW FULL PROCESSLIST; -- including the full SQL text
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 PROCESSLISTshows who is connected now.