$ sudo apt-get install mysql-server mysql-client
$ mysql -u root -p
mysql> grant all on testdb.* to 'testuser'@'%' identified by 'testpass';
mysql> quit;
$ mysql -u testuser -ptestpass
ERROR 1045 (28000): Access denied for user 'testuser'@'localhost' (using password: YES)
WTF? Why is the testuser being denied access? We just created it!Let's have a look at the users in the system:
$ mysql -u root -p
mysql > select User,Host from mysql.user order by User;
+------------------+----------------+
| User | Host |
+------------------+----------------+
| | localhost |
| | ubuntu-desktop |
| debian-sys-maint | localhost |
| root | localhost |
| root | ubuntu-desktop |
| root | 127.0.0.1 |
| testuser | % |
+------------------+----------------+
7 rows in set (0.00 sec)
mysql > quit;
Notice the empty user names (these show up as "Any" in phpmyadmin). It turns out that ''@'localhost' will trump 'testuser'@'%'. Why is this? Intuitively you'd think that a wildcard ('%') would win out, but in fact 'localhost' beats '%'-- because it is more specific. From the MySQL Docs:One account ('monty'@'localhost') can be used only when connecting from the local host. The other ('monty'@'%') can be used to connect from any other host. Note that it is necessary to have both accounts for monty to be able to connect from anywhere as monty. Without the localhost account, the anonymous-user account for localhost that is created by mysql_install_db would take precedence when monty connects from the local host. As a result, monty would be treated as an anonymous user. The reason for this is that the anonymous-user account has a more specific Host column value than the 'monty'@'%' account and thus comes earlier in the user table sort order.
So what we need to do is have two testusers-- one at 'localhost' and one at '%'. (Although if you know testuser is only ever going to connect locally, you don't need the '%'.)$ mysql -u root -p
mysql> grant all on testdb.* to 'testuser'@'localhost' identified by 'testpass';
mysql> quit;
$ mysql -u testuser -ptestpass
mysql> quit;
Woot!