A remote client cannot create a database on a MySQL server because the account it logs in with lacks the global CREATE privilege, and the account that has it (root) exists only as 'root'@'localhost'. Fix it in two places: create a root-equivalent account whose host part is '%' (or the admin PC's address) with GRANT ALL PRIVILEGES ON *.*, and remove or widen bind-address in the server configuration so the listener accepts connections from that address. Per-schema grants on individual databases will never let a client create a new one, because CREATE DATABASE is evaluated against global privileges.
What do the symptoms tell you before you change anything?
Look at the trend first. The signal chain for a MySQL login is: the client sends a user name plus the address it connects from; the server matches that pair against the Host and User columns of mysql.user; the matched row decides which global privileges apply, and mysql.db rows add per-schema privileges on top. Every symptom in this class maps to one stage of that chain. Read them in order and you avoid changing grants when the fault is a closed port, or opening ports when the fault is a grant.
| Signal | Where it originates | Symptom when the value is wrong |
|---|---|---|
| TCP connection to server port (default 3306) |
bind-address in my.cnf/my.ini, host firewall |
Client times out or reports it cannot connect to the server on that host; no MySQL error number at all |
| Client source address | Remote PC's IP as seen by the server | Access denied for 'root'@'<remote-ip>' even though the password is correct; no row in mysql.user matches that host |
| Global privileges on matched account |
mysql.user row (or SHOW GRANTS) |
Login succeeds, tables can be edited, CREATE DATABASE is denied |
| Administrative metadata queries issued by the tool | Client tool behaviour at connect time | SQLyog connects and works; MySQL Administrator refuses the same credentials or errors on its status views |
The SQLyog-versus-MySQL Administrator difference is diagnostic on its own. SQLyog only runs the statements you ask for, so a per-schema account is enough for table work. MySQL Administrator reads server status, the process list and the grant tables as soon as it connects, and an account with schema-only privileges cannot serve those queries. That is a privilege-level symptom, not a network one, so widening bind-address will not change it.
Why does MySQL treat root@localhost and root@% as different accounts?
An account in MySQL is the pair 'user'@'host', not the user name alone. A default installation creates 'root'@'localhost' and nothing else, which is deliberate: it keeps the superuser unreachable from the network until an administrator explicitly decides otherwise. When a client on another machine presents the user name root, the server searches for a row whose Host pattern matches the client's address. localhost does not match an IP address, so the login is rejected before the password is even considered. The % wildcard in the host column matches any address; a specific address such as the admin PC's IP restricts the match to that one machine.
The second stage is independent of the first. bind-address tells the daemon which interface to listen on. If it is set to 127.0.0.1, the server never sees the remote SYN, and no grant can help. The two controls are in series: the listener must accept the connection, then the grant table must match the account.
How do you open remote root access?
Do the grant work through the SQL command line on the server, not through a GUI privilege editor. The GUI hides the host part of the account and makes it easy to edit 'root'@'localhost' while believing you have created a remote account.
- On the server, log in locally as root and confirm which accounts exist:
You will typically see onlymysql -u root -p SELECT User, Host FROM mysql.user;root | localhost. - Create the remote superuser. Use the admin PC's IP address instead of
%if the client's address is fixed; use%if it will later connect from anywhere:
Older servers acceptCREATE USER 'root'@'%' IDENTIFIED BY 'strong-password'; GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION; FLUSH PRIVILEGES;IDENTIFIED BYdirectly inside theGRANTstatement; newer ones require theCREATE USERstep first. If one form errors, use the other. - Open the listener. Edit
my.cnf(Linux) ormy.ini(Windows) under the[mysqld]section. Either comment outbind-addressor set it to the interface address the remote PC reaches. Also removeskip-networkingif present. - Restart the MySQL service so the daemon rebinds.
- Open the server port (3306 unless changed with
port=) in the host firewall for the admin PC's address or subnet. - From the remote PC, connect with the new account and immediately run
CREATE DATABASE test_remote;to prove the global privilege is live.
If the goal is only to create databases rather than full superuser control, grant less: GRANT CREATE, DROP, ALTER ON *.* TO 'dbadmin'@'%' covers schema creation without SUPER or FILE. Tuning does not fix wiring, and a wide grant does not fix a firewall; keep each control doing its own job.
How do you verify the fix instead of assuming it?
Measure each stage of the chain separately, in the same order the server evaluates it.
- On the server, confirm the listener is bound to a reachable interface:
netstat -an(Windows) orss -ltn(Linux) should show port 3306 on0.0.0.0or the LAN address, not127.0.0.1. - From the remote PC, test raw TCP reachability to port 3306 before involving any SQL client. A connection that opens and immediately receives the server greeting proves bind-address and firewall are correct.
- Log in and ask the server who it thinks you are: must return
root@%(or the specific host you granted). If it returns an unexpected host pattern, another row matched first; MySQL prefers the most specific host match. - Run
SHOW GRANTS;and confirmALL PRIVILEGES ON *.*(or at leastCREATE) is present for that identity. - Create and drop a throwaway database. Then reconnect with MySQL Administrator; its status and user-administration views should now populate, since the account can read the grant tables.
Which pitfalls recur on remote MySQL administration?
Forgetting FLUSH PRIVILEGES after editing the grant tables directly with INSERT or UPDATE leaves the in-memory privilege cache unchanged; GRANT and CREATE USER statements reload automatically, direct table edits do not. Editing bind-address in a configuration file the service does not read is common on Windows where several my.ini candidates exist; check the service's command line for the --defaults-file path. An anonymous account ''@'%' or ''@'localhost' left over from installation can out-match your new row for some connections and produce an access-denied error with an empty user name; drop it. The % wildcard does not match localhost connections through the Unix socket, so local tools keep using 'root'@'localhost' and the two accounts can drift to different passwords.
Exposing a 'root'@'%' account on a port reachable from the internet is a brute-force target. When the admin PC moves off the LAN, prefer an SSH tunnel or VPN terminating on the server and keep bind-address local, rather than granting root from every address. Both SQLyog and MySQL Administrator support connecting through a tunnel, so nothing in the workflow changes.
FAQ
Can I create a new database from a remote PC with only per-schema privileges in MySQL?
No. CREATE DATABASE requires the CREATE privilege at global scope (ON *.*), which per-database grants in mysql.db cannot supply; grant it on *.* to the remote account.
Does granting privileges to 'root'@'%' also change 'root'@'localhost'?
No. They are separate rows in mysql.user with independent passwords and privileges, so local logins continue to use the original account and are unaffected by the remote grant.
Can I skip changing bind-address if I have already granted root@%?
Only if the server is not bound to 127.0.0.1. Check with netstat -an or ss -ltn on the server; if 3306 shows on the loopback address only, the grant is unreachable until bind-address is widened and the service restarted.
Does SQLyog connecting while MySQL Administrator fails mean the network is wrong?
No, it means the account lacks administrative privileges. SQLyog runs only what you ask, whereas MySQL Administrator reads server status and the grant tables at connect time, so a schema-only account satisfies the first and not the second.
Can I restrict remote root to one machine instead of using the % wildcard?
Yes. Grant to 'root'@'192.168.x.y' (the admin PC's address) instead of 'root'@'%'; MySQL matches the client's source address against the host column and only that machine will authenticate.
Stop and escalate when the server greeting is received on port 3306, returns the expected root@% identity, SHOW GRANTS lists ALL PRIVILEGES ON *.*, and the client tool still refuses to create a database or populate its administrative views. At that point the fault is in the client software or a server-side setting outside the grant tables, and the MySQL documentation and support channels, or the client tool vendor's support, are the correct next step.