VillageSQL is a drop-in replacement for MySQL with extensions.
All examples in this guide work on VillageSQL. Install Now →
Creating Users
@'localhost' part is the host restriction — this account can only connect from the local machine. Common host patterns:
| Host | Meaning |
|---|---|
'localhost' | Local socket connections only |
'127.0.0.1' | TCP loopback only |
'%' | Any host (network access) |
'192.168.1.%' | Any host in that subnet |
'app.example.com' | Specific hostname |
'alice'@'localhost' and 'alice'@'%' are two distinct accounts, even though the username is the same.
Granting Privileges
database.table notation:
*.*— all databases, all tables (global)myapp.*— all tables in themyappdatabasemyapp.orders— only theorderstable
Privilege Levels
| Level | Scope | Example |
|---|---|---|
| Global | All databases | GRANT RELOAD ON *.* |
| Database | One database | GRANT CREATE ON myapp.* |
| Table | One table | GRANT SELECT ON myapp.users |
| Column | Specific columns | GRANT SELECT (id, name) ON myapp.users |
| Stored routine | Procedure or function | GRANT EXECUTE ON PROCEDURE myapp.get_user |
| Privilege | What it allows |
|---|---|
SELECT | Read rows |
INSERT | Insert rows |
UPDATE | Modify rows |
DELETE | Delete rows |
CREATE | Create tables and databases |
DROP | Drop tables and databases |
INDEX | Create and drop indexes |
ALTER | Alter table structure |
EXECUTE | Run stored procedures and functions |
PROCESS | See all running queries (SHOW PROCESSLIST) |
SUPER | Override restrictions; administrative operations |
ALL PRIVILEGES | All privileges for the specified scope |
Viewing Grants
Revoking Privileges
ERROR 1141: There is no such grant defined for user. The user retains any privileges granted at other levels — revoking SELECT ON myapp.* does not remove SELECT ON myapp.orders if that was granted separately.
Changing Passwords
Roles (MySQL 8.0+)
Roles are named collections of privileges. Instead of granting individual privileges to each user, grant a role.Dropping Users
Least-Privilege Best Practices
Give each account only the privileges it needs:- Application read replicas:
SELECTonly - Application write account:
SELECT,INSERT,UPDATE,DELETE - Application schema account (migrations): add
CREATE,ALTER,DROP,INDEX - DBA account:
ALL PRIVILEGESon*.* - Never grant
SUPERorALLto application accounts
app.example.com should use 'appuser'@'app.example.com', not 'appuser'@'%'.
Frequently Asked Questions
Does MySQL flush grants automatically?
In MySQL 8.0, all changes viaCREATE USER, GRANT, REVOKE, and ALTER USER take effect immediately — no FLUSH PRIVILEGES needed. FLUSH PRIVILEGES is only necessary if you modify the grant tables directly with INSERT/UPDATE (which you shouldn’t do).
What’s the difference between localhost and 127.0.0.1?
localhost in MySQL refers to the Unix socket connection (local file socket), not the network loopback. 127.0.0.1 is the TCP loopback. If your client connects via TCP even on the same machine, use 127.0.0.1 as the host restriction.
Troubleshooting
| Problem | Solution |
|---|---|
ERROR 1045: Access denied for user | Wrong password, wrong host, or account doesn’t exist — verify with SELECT user, host FROM mysql.user |
| User can connect but can’t query | Check grants with SHOW GRANTS FOR 'user'@'host' — the privilege level must match the scope (database vs global) |
GRANT fails with ERROR 1044 | Current user lacks the GRANT OPTION privilege — connect as root or a user with GRANT OPTION |
| User created but can’t log in from app server | The @'host' pattern doesn’t match the app server’s hostname or IP — add or update the account host pattern |
DROP USER fails | Verify the exact user/host combination: SELECT user, host FROM mysql.user WHERE user = 'alice' |

