Listing database accounts provides a quick audit of who can authenticate, where connections are allowed from, and which entries might be obsolete or risky. Keeping an accurate account inventory also speeds up troubleshooting when logins fail or permissions drift.
MySQL and MariaDB store account definitions in the system schema (the mysql database), where each account is identified by a User name combined with a Host pattern. During authentication, the server matches the incoming connection to the best-fitting User@Host entry, so the same username can exist multiple times with different host rules.
Reading mysql.user usually requires an administrative account (for example root) or equivalent privileges, and selecting sensitive columns can expose credential hashes. Use queries that return only User and Host for routine auditing, and remember that localhost and remote client hosts are distinct account scopes.
$ mysql --user=root --password Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 34 Server version: 8.0.44 MySQL Community Server - GPL Copyright (c) 2000, 2025, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql>
Add --host and --port when connecting to a remote server.
mysql> SELECT USER() AS client_user, CURRENT_USER() AS authenticated_user; +----------------+--------------------+ | client_user | authenticated_user | +----------------+--------------------+ | root@localhost | root@localhost | +----------------+--------------------+ 1 row in set (0.00 sec)
CURRENT_USER() reflects the matched User@Host entry used for privilege evaluation.
mysql> SELECT User, Host FROM mysql.user ORDER BY User, Host; +------------------+-----------+ | User | Host | +------------------+-----------+ | app | % | | app | localhost | | app_user | 10.0.0.% | | app_user | localhost | | appuser | % | | mysql.infoschema | localhost | | mysql.session | localhost | | mysql.sys | localhost | | new_user | localhost | | root | % | | root | localhost | | user | % | +------------------+-----------+ 12 rows in set (0.00 sec)
An account is the combination of User and Host, so repeated usernames represent different accounts.
mysql> SELECT CONCAT(QUOTE(User), '@', QUOTE(Host)) AS account
-> FROM mysql.user
-> ORDER BY User, Host;
+--------------------------------+
| account |
+--------------------------------+
| 'app'@'%' |
| 'app'@'localhost' |
| 'app_user'@'10.0.0.%' |
| 'app_user'@'localhost' |
| 'appuser'@'%' |
| 'mysql.infoschema'@'localhost' |
| 'mysql.session'@'localhost' |
| 'mysql.sys'@'localhost' |
| 'new_user'@'localhost' |
| 'root'@'%' |
| 'root'@'localhost' |
| 'user'@'%' |
+--------------------------------+
12 rows in set (0.00 sec)
Avoid selecting authentication_string, password, or similar credential fields on shared terminals or in shared logs.
mysql> SHOW GRANTS FOR 'app_user'@'10.0.0.%'; +--------------------------------------------------------------------+ | Grants for app_user@10.0.0.% | +--------------------------------------------------------------------+ | GRANT USAGE ON *.* TO `app_user`@`10.0.0.%` | | GRANT SELECT, INSERT, UPDATE ON `appdb`.* TO `app_user`@`10.0.0.%` | +--------------------------------------------------------------------+ 2 rows in set (0.00 sec)
A mismatched Host value returns an error even when the username exists.
mysql> exit Bye