I'm having trouble granting permissions to a user on a single database. The user can't log in once I've done what's below. I'm running as root on MySQL 5.6
SELECT USER(),CURRENT_USER();
+----------------+----------------+
| USER() | CURRENT_USER() |
+----------------+----------------+
| root@localhost | root@localhost |
+----------------+----------------+
Here's my database list (abridged)
list databases;
+-------------------------+
| Database |
+-------------------------+
| hr_test |
First I create the new user
CREATE USER 'hr_test_user'@'localhost' IDENTIFIED BY 'password';
This seems to work (i'm not showing all the other users).
select * from information_schema.user_privileges;
| 'hr_test_user'@'localhost' | def | USAGE | NO |
I then try to grant privileges to one database
GRANT ALL PRIVILEGES ON hr_test.* TO 'hr_test_user'@'localhost' IDENTIFIED BY 'password';
FLUSH PRIVILEGES;
When I run "select * from information_schema.user_privileges;" nothing has changed, the user just has "usage". When the user tries to log in they get rejected.
However when I grant wide privileges as such the line below I get all privileges.
GRANT ALL PRIVILEGES ON *.* TO 'hr_test_user'@'localhost' IDENTIFIED BY 'password';
The table shows these privileges (abridged)
| 'hr_test_user'@'localhost' | def | SELECT | NO |
| 'hr_test_user'@'localhost' | def | INSERT | NO |
| 'hr_test_user'@'localhost' | def | UPDATE | NO |
| 'hr_test_user'@'localhost' | def | DELETE | NO |
| 'hr_test_user'@'localhost' | def | CREATE | NO |
| 'hr_test_user'@'localhost' | def | DROP | NO |
I can drop the user and do it again, but I get the same result. I've done this before to create other users with no problems, I even recorded exactly what I did last time when it worked, so I'm puzzled.
It looks like I'm identifying the database I want to grant privileges on incorrectly, but I can't spot what I'm doing wrong. Can anyone else?
Update
Based on the answer from @SQL.RK I recreated the user with the privileges required, then ran this additional command
select * from information_schema.SCHEMA_PRIVILEGES;
This is the relevant part of the output
| 'hr_test_user'@'localhost' | def | hr_test | SELECT | NO |
| 'hr_test_user'@'localhost' | def | hr_test | INSERT | NO |
| 'hr_test_user'@'localhost' | def | hr_test | UPDATE | NO |
| 'hr_test_user'@'localhost' | def | hr_test | DELETE | NO |
| 'hr_test_user'@'localhost' | def | hr_test | CREATE | NO |
That looks fine to me. I tried to log in and it worked, when I did what seems exactly the same as before!
Theory
I copied this text out of my password manager where I keep database authentication information and the commands I use to create databases. I noticed when I copied out of there I didn't have to hit enter in MySQL. I wonder if the grant command wasn't actually executing.
I don't think this is it because "grant all privileges" was also in there and that worked. I'm a bit stumped. I won't mark this as answered just yet, I'd like to hear any theories or hear if I've done anything clearly incorrect first.
Update 2
show grants;
+-------------------------------------------------------------------------------------------+
| Grants for hr_test_user@localhost |
+-------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'hr_test_user'@'localhost' IDENTIFIED BY PASSWORD <secret> |
| GRANT SELECT, INSERT, UPDATE, DELETE, CREATE ON `hr_test`.* TO 'hr_test_user'@'localhost' |
+-------------------------------------------------------------------------------------------+
Best Answer
Based on your comment, I say don't worry.
The output for
SHOW GRANTS;
is correct. The userhr_test_user
can only access thehr_test
database, and no other database.Why would the output be split like that ?
mysql.user
stores the user,host,password ofhr_test_user
@localhost
mysql.db
stores the privileges ofhr_test_user
@localhost
You will have to run the grants for each individual database to access them.
For example, to add grants for
db1
anddb2
, you would runNow, I have some bad news. If you have a test database, you should drop it. Do not create any test databases because mysql installations will secretly give away full access to a test database that is named
test
or any database name starting withtest_
. I wrote all about that in MySQL : Why are there "test" entries in mysql.db?If you need any test databases, don't name it
test
and don't name it withtest_
as prefix.