Ahosting Logo
Knowledge Base

How to Manage Database Users and Privileges

Creating a database is three steps and the third is the one people skipCreate the databaseyou get a name with your accountprefixCreate the usera username and password, stillunconnectedAdd the user to the databasewith privileges; this is thestep that is skippedSkip the third and both objects exist but nothing links them. The error names access, not the missing link.

A database and the user that connects to it are separate things, and the relationship between them is where most database access problems come from. A database with no user attached is present, empty of permissions, and produces a connection error that says nothing about permissions.

Three steps, and the third is the one people skip

In cPanel's MySQL Databases screen:

Create the database. It gets your account prefix automatically, account_wordpress rather than wordpress. The full name including the prefix is what goes in your configuration.

Create the user. Also prefixed, and with its own password.

Add the user to the database and grant privileges. This is a separate action, and skipping it leaves both objects existing and unconnected.

The resulting error is a connection failure that reads as a wrong password, and people spend an hour re-typing one that was correct.

Which privileges to grant

The interface offers ALL PRIVILEGES and a list of individual ones.

For a normal application (WordPress and most others) ALL PRIVILEGES on its own database is the practical answer. The application needs to create tables during installation and alter them during updates, and a restricted set breaks upgrades in ways that are hard to diagnose.

Note what that does not mean: the user has full rights on one database and no access to any other. The isolation is between databases, not within one.

Where a restricted user genuinely fits is a read-only reporting connection: SELECT alone, for something that queries and never writes.

One user per application

The rule worth following on any account holding more than one site.

A single user granted access to five databases means a compromise of the weakest application reaches the other four. Separate users limit it to one.

It also makes credentials rotatable. Changing a shared user's password breaks five sites at once; changing a per-application user's password breaks the one you are working on.

Passwords: long, generated, and not typed anywhere

You never type a database password by hand. It lives in a configuration file. So there is no reason for it to be short or memorable.

Use the generator, take the long option, and paste it into the application's configuration.

Then check where that configuration file sits. A file holding database credentials inside public_html can be downloaded if the server ever stops executing PHP, which happens during misconfigurations more often than people expect. Understanding file permissions goes into placement.

Changing a password takes two steps too

Change it on the user in cPanel, then update the application's configuration to match.

Doing the first without the second takes the site down immediately, with a connection error. That is the most common self-inflicted database outage there is, and it is entirely avoidable by doing them in one sitting.

For WordPress the value lives in wp-config.phpUnderstanding wp-config.php goes into the file.

localhost, not the domain

On shared hosting the database host is almost always localhost, because the application and the database run on the same machine.

Putting your domain there attempts a network connection to a database that is not listening for one, and the error is a timeout instead of a refusal, which reads as the server being slow.

Remote database access is a separate feature, off by default, and it should stay off unless something genuinely needs it. A database reachable from the internet is scanned constantly.

Deleting a user is not deleting the database

Removing a user leaves the database and its data intact but unreachable. Removing a database leaves any user that was attached to it, now attached to nothing.

Both are common after uninstalling an application, and both accumulate: orphaned databases counting against your account, and users nobody can account for.

When you remove an application, remove its database and its user deliberately. The application's own uninstaller usually does both, which is a reason to use it rather than deleting files. There is more in installing applications with Softaculous.

After a restore, check the user

A restored database frequently comes back without its user attached, because the two are stored separately.

The symptom is an application reporting a connection error against a database that is plainly present and populated, which is confusing enough that people restore again rather than checking the privileges.

Re-add the user to the database and grant privileges. That is usually the whole fix. For what else does not travel, see restoring from backup.

Read the error rather than guessing

Access denied for user: wrong password, or the user is not attached to that database.

Unknown database. The name is wrong, usually the missing account prefix.

Can't connect to MySQL server. The host is wrong, or the database service is down.

Those three cover nearly every case, and they point at three different fixes, which is why reading the message is faster than changing the password again.

The settings that apply to the whole server; the database version, and whether it is reachable from outside at all: sit in WHM instead: Managing MySQL and Remote Database Access in WHM walks through them.

A copied site left pointing at the live database writes to real data while you believe you are testing. How to Make a Development Copy of a Site in cPanel explains avoiding it.

Check what the user can actually reach

Privileges are granted per database, and an application failing with a permission error is usually holding a user granted on something else.

mysql -e "SHOW GRANTS FOR 'user_app'@'localhost'"
mysql -e "SELECT db, user, host FROM mysql.db WHERE user='user_app'"

Read the grants rather than the panel. What appears there is what the server will enforce, and the panel occasionally shows an intent that did not apply.

The common finding is a user with rights on a database that has since been renamed or restored under a different name, so the grant references something that no longer exists and the application connects to something it cannot read.

Rotate the password in both places

Changing a database password breaks the site immediately, because the application is still presenting the old one.

grep -n "DB_PASSWORD" ~/public_html/wp-config.php | cut -c1-40
mysql -u user_app -p -e "SELECT 1" 2>&1 | tail -1

Change it on the database, update the application configuration, then test the connection with the new value before doing anything else.

Do this at a quiet time and keep the old value until the new one is confirmed working. A rotation performed on a Friday with no verification is how a site spends a weekend showing a connection error, and the fix takes thirty seconds once somebody looks. Fixing the database connection error deals with the symptom.

Watch these steps on screen 2 clips · 1:36

Recorded on a real panel, no narration, captions on screen. Opens here without leaving the page and without an account. Every name, address and figure shown is made up for the recording.