Not seeing database from localhost but seeing it when connecting to server - mysql

I'm connecting to the mysql server as user 'someuser'. When I connect to the server from my localbox I get to see all the databases.
However, when I SSH into the server and login with 'someuser' and execute show databases; I only see two: information_schema and test
How can I view all the databases when I SSH into the DB as well?
show grants; shows the below
mysql> show grants;
| Grants for dev#localhost |
| GRANT USAGE ON *.* TO 'someuser'#'localhost' IDENTIFIED BY PASSWORD '*' |
Edit
When I SSH into the server and login to mysql using root then I can see all the databases fine.

GRANT USAGE is not what you want. According to the mysql documentation:
USAGE Synonym for “no privileges”
It is used at the global level with GRANT to modify account attributes such as resource limits or SSL characteristics without affecting existing account privileges.
http://dev.mysql.com/doc/refman/5.1/en/grant.html
You need to grant actual privileges to your "someuser" user for the database the user needs to see. For example, if you grant select privileges on the mysql.*:
GRANT SELECT ON mysql.*
TO someuser#localhost IDENTIFIED BY "somepassword";
FLUSH PRIVILEGES;
Now, someuser connected from localhost will be able to see the mysql database when executing
SHOW DATABASES;
However, you might want to reserve the access to the mysql database for root only.

Related

MySQL: Flush Privileges Not Effective For Existing Connection

So on my database granting/revoking privileges kind of only takes effect after establishing a new connection. I need it effective instantly though, and as I understand this is what flush privileges should be for, but for some reason it doesn't work.
My setup:
(there is an established database connection from server1 to database server)
Database server:
GRANT ALL PRIVILEGES ON *.* TO 'user'#'1.2.3.4';
FLUSH PRIVILEGES;
SHOW GRANTS FOR user#1.2.3.4;
> GRANT ALL PRIVILEGES ON *.* TO 'user'#'1.2.3.4' IDENTIFIED BY PASSWORD <secret>
Server1 (IP 1.2.3.4):
SHOW GRANTS;
> GRANT ALL PRIVILEGES ON *.* TO 'user'#'1.2.3.4' IDENTIFIED BY PASSWORD <secret>
SHOW DATABASES;
> only information_schema, doesn't show any other databases
And only after re-establishing the database connection does SHOW DATABASES update to show all databases. Same behaviour for when I query information_schema.tables to gather available databases.
The SHOW GRANTS on the server1 always shows the correct info immediately.
This is reproducible and is the same for revoke commands. MySQL server version is 5.6 if that's important.
So on my database granting/revoking privileges kind of only takes effect after establishing a new connection.
That is true.
I need it effective instantly though.
You Can't Do That™. Changed privileges take effect with new connections.

How to grant all privileges to root user in MySQL 8.0

Tried
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'#'%' IDENTIFIED BY 'root' WITH GRANT OPTION;
Getting
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near 'IDENTIFIED BY 'root' WITH GRANT OPTION' at line 1.
Note: The same is working when tried in previous versions.
Also tried
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'#'%' WITH GRANT OPTION;
Getting
ERROR 1410 (42000): You are not allowed to create a user with GRANT
MySQL (8.0.11.0) username/password is root/root.
Starting with MySQL 8 you no longer can (implicitly) create a user using the GRANT command. Use CREATE USER instead, followed by the GRANT statement:
mysql> CREATE USER 'root'#'%' IDENTIFIED BY 'PASSWORD';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'#'%' WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES;
Caution about the security risks about WITH GRANT OPTION, see:
Grant all privileges on database
I see a lot of (wrong) answers, it is just as simple as this:
USE mysql;
CREATE USER 'user'#'localhost' IDENTIFIED BY 'P#ssW0rd';
GRANT ALL ON *.* TO 'user'#'localhost';
FLUSH PRIVILEGES;
Note: instead of a self-created user you can use root to connect to the database. However, using the default root account to let an application connect to the database is not the preferred way. Alternative privileges can be applied as follows (be careful and remember the least-privilege principle):
-- Grant user permissions to all tables in my_database from localhost --
GRANT ALL ON my_database.* TO 'user'#'localhost';
-- Grant user permissions to my_table in my_database from localhost --
GRANT ALL ON my_database.my_table TO 'user'#'localhost';
-- Grant user permissions to all tables and databases from all hosts --
GRANT ALL ON *.* TO 'user'#'*';
If you would somehow run into the following error:
ERROR 1130 (HY000): Host ‘1.2.3.4’ is not allowed to connect to this
MySQL server
You need add/change the following two lines in /etc/mysql/my.cnf and restart mysql:
bind-address = 0.0.0.0
skip-networking
You could run into the following error, which is a bit confusing:
ERROR 1410 (42000): You are not allowed to create a user with GRANT
This means that either the user does not exist at all OR that the user#host combination does not exist. You can easily check for this with the following command:
SELECT host, user FROM user
1) This worked for me. First, create a new user. Example: User foo with password bar
> mysql> CREATE USER 'foo'#'localhost' IDENTIFIED WITH mysql_native_password BY 'bar';
2) Replace the below code with a username with 'foo'.
> mysql> GRANT ALL PRIVILEGES ON database_name.* TO'foo'#'localhost';
Note: database_name is the database that you want to have privileges, . means all on all
3) Login as user foo
mysql> mysql -u foo -p
Password: bar
4) Make sure your initial connection from Sequelize is set to foo with pw bar.
Just my 2 cents on the subject. I was having the exact same issue with trying to connect from MySQL Workbench. I'm running a bitnami-mysql virtual machine to set up a local sandbox for development.
Bitnami's tutorial said to run the 'Grant All Privileges' command:
/opt/bitnami/mysql/bin/mysql -u root -p -e "grant all privileges on *.* to 'root'#'%' identified by 'PASSWORD' with grant option";
This was clearly not working, I finally got it to work using Mike Lischke's answer.
What I think happened was that the root#% user had the wrong credentials associated to it. So if you've tried to modify the user's privileges and with no luck try:
Dropping the user.
Create the user again.
Make sure you have the correct binding on your MySQL config file.
In my case I've commented the line out since it's just for a sandbox environment.
1. Dropping the user.
From Mysql Console:
List Users (helpful to see all your users):
select user, host from mysql.user;
Drop Desired User:
drop user '{{ username }}'#'%';
2. Create the user again.
Create User and Grant Permissions:
CREATE USER '{{ username }}'#'%' IDENTIFIED BY '{{ password }}';
GRANT ALL PRIVILEGES ON *.* TO '{{ username }}'#'%' WITH GRANT OPTION;
Run this command:
FLUSH PRIVILEGES;
3. Make sure you have the correct binding on your MySQL config file.
Locate your MySQL config file (additional notes at the end). If you want to have MySQL listen for connections on more than one network find the following line on the config file:
bind-address=127.0.0.1
and comment it using a '#':
#bind-address=127.0.0.1
For production environments you might want to use limit the network access (additional notes at the end).
Then restart your MySQL service.
Hope this helps someone having the same issue!
Binding: If you want to know more about this I suggest looking at the following
solution How to bind MySQL server to more than one IP address. It
basically says you can leave MySQL open and limit connections by using
a firewall, or natively if you have MySQL version 8.0.13 and above.
MySQL Config File The file could have different locations depending on your
Linux distribution and installation. On my system it was located at
'/etc/my.cnf'. Here are other suggested locations:
/etc/mysql/mysql.conf.d
/etc/mysql/my.cnf
You can also search for the config locations as shown in this website:
How to find locations of MySQL config files.
For those who've been confused by CREATE USER 'root'#'localhost' when you already have a root account on the server machine, keep in mind that your 'root'#'localhost' and 'root'#'your_remote_ip' are two different users (same user name, yet different scope) in mysql server. Hence, creating a new user with your_remote_ip postfix will actually create a new valid root user that you can use to access the mysql server from a remote machine.
For example, if you're using root to connect to your mysql server from a remote machine whose IP is 10.154.10.241 and you want to set a password for the remote root account which is 'Abcdef123!##', here are steps you would want to follow:
On your mysql server machine, do mysql -u root -p, then enter your password for root to login.
Once in mysql> session, do this to create root user for the remote scope:
mysql> CREATE USER 'root'#'10.154.10.241' IDENTIFIED BY 'Abcdef123!##';
After the Query OK message, do this to grant the newly created root user all privileges:
mysql> GRANT ALL ON *.* TO 'root'#'10.154.10.241';
And then:
FLUSH PRIVILEGES;
Restart the mysqld service:
sudo service mysqld restart
Confirm that the server has successfully restarted:
sudo service mysqld status
If the steps above were executed without any error, you can now access to the mysql server from a remote machine using root.
My Specs:
mysql --version
mysql Ver 8.0.16 for Linux on x86_64 (MySQL Community Server - GPL)
What worked for me:
mysql> CREATE USER 'username'#'localhost' IDENTIFIED BY 'desired_password';
mysql> GRANT ALL PRIVILEGES ON db_name.* TO 'username'#'localhost' WITH GRANT OPTION;
Response in both queries:
Query OK, O rows affected (0.10 sec*)
N.B: I created a database (db_name) earlier and was creating a user credential with all privileges granted to all tables in the DB in place of using the default root user which I read somewhere is a best practice.
The specified user just doesn't exist on your MySQL (so, MySQL is trying to create it with GRANT as it did before version 8, but fails with the limitations, introduced in this version).
MySQL's pretty dumb at this point, so if you have 'root'#'localhost' and trying to grant privileges to 'root'#'%' it treats them as different users, rather than generalized notion for root user on any host, including localhost.
The error message is also misleading.
So, if you're getting the error message, check your existing users with something like this
SELECT CONCAT("'", user, "'#'", host, "'") FROM mysql.user;
and then create missing user (as Mike advised) or adjust your GRANT command to the actual exisiting user specificaion.
You will get this error
ERROR 1410 (42000): You are not allowed to create a user with GRANT
If you are trying to run a GRANT on a user that doesn't exist!
Therefore, first run this to make sure the user you use in your GRANT matches exactly to what you have:
select User, Host from user;
In particular pay attention whether the user you created is at localhost but the one you are trying to grant to is %
Copy this and use it at once:
CREATE USER 'username'#'localhost' IDENTIFIED BY 'password';
GRANT ALL ON *.* TO 'username'#'localhost';
FLUSH PRIVILEGES;
Instead of using single lines of code such as:
CREATE USER 'username'#'localhost' IDENTIFIED BY 'password';
Then:
GRANT ALL ON *.* TO 'username'#'localhost';
Then:
FLUSH PRIVILEGES;
Many thanks #Nebulastic
If you want to only allow remote IP using following command
CREATE USER 'user_test'#'113.yy.xx.94' IDENTIFIED BY 'YOUR_PWD';
GRANT ALL ON *.* TO 'user_test'#'113.yy.xx.94';
FLUSH PRIVILEGES;
This worked for me:
mysql> FLUSH PRIVILEGES
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'#'%'WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES
Check out your username and domain is the same as created before. Mysql select account by the two colums in user table.If it is different, mysql may think you want to create a new account by grant,which is not supported after 8.0 version.
My Specs:
mysql --version
mysql Ver 8.0.19 for Linux on x86_64 (MySQL Community Server - GPL)
What worked for me:
mysql> USE mysql;
mysql> UPDATE User SET Host='%' WHERE User='root' AND Host='localhost';
this commands work for me:
1-login to mysql and see all users
sudo mysql -u root
select user, host from mysql.user;
2-delete old user
drop user root#localhost;
3-create new user
CREATE USER 'root'#'localhost' IDENTIFIED BY 'mypassword'
4-add all privileges to it:
GRANT ALL ON *.* TO 'root'#'localhost'
ALTER USER 'root'#'localhost' IDENTIFIED WITH mysql_native_password
BY 'mypassword';
5-finally flush privileges
FLUSH PRIVILEGES;
in select statement, changing 'user'#'%' to 'user'#'localhost' solved my problem
In my case I wanted to do something similar, I followed some steps from here but the best way was as #nebulasic mentioned:
USE mysql;
CREATE USER 'user'#'localhost' IDENTIFIED BY 'P#ssW0rd';
GRANT ALL ON *.* TO 'user'#'localhost';
FLUSH PRIVILEGES;
After this I encountered an error while trying to query the database or connect with SQLTools from VSCode.
Client does not support authentication protocol requested by server; consider upgrading MySQL client
Running this query will fix the problem:
ALTER USER 'user'#'localhost' IDENTIFIED WITH mysql_native_password BY 'Your_newP#s$w0Rd';
I also want to mention that these steps are ok to work in a local environment, when doing something in production is recommended to allocate each user to each database with generated password accordingly and different other security measures if necessary.
Well, I just had the same problem. Even if route had '%' could not connect remotely. Now, having a look at my.ini file (config file in windows) the bind-address statement was missed.
So... I putted this bind-address = * after [mysqld] and restarted the service. Now it works!
1. grant privileges
mysql> GRANT ALL PRIVILEGES ON . TO 'root'#'%'WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES
2. check user table:
mysql> use mysql
mysql> select host,user from user
3.Modify the configuration file
mysql default bind ip:127.0.0.1, if we want to remote visit services,just delete config
#Modify the configuration file
vi /usr/local/etc/my.cnf
#Comment out the ip-address option
[mysqld]
# Only allow connections from localhost
#bind-address = 127.0.0.1
4.finally restart the services
brew services restart mysql
Try this, i had the same issue and i tried few options, but the below worked.
GRANT ALL ON . TO 'root'#'%';
Reference used - https://www.digitalocean.com/community/tutorials/how-to-install-linux-apache-mysql-php-lamp-stack-on-ubuntu-20-04#step-6-%E2%80%94-testing-database-connection-from-php-optional
ubuntu 22.04.1
Mysql Ver 8.0.31-0
My root had no GRANT privileges so I could not grant new users any previligies.
Solution was to Drop current root user and create new one using 'mysql_native_password'.
Commands as follows
Login to mysql with as root
mysql> DROP USER 'root'#'localhost' IDENTIFIED BY 'PASSWORD' FROM mysql.user;
mysql> CREATE USER 'root'#'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'#'locahost' WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES;
This may work:
grant all on dbtest.* to 'dbuser'#'%' identified by 'mysql_password';
I had this same issue, which led me here. In particular, for local development, I wanted to be able to do mysql -u root -p without sudo. I don't want to create a new user. I want to use root from a local PHP web app.
The error message is misleading, as there was nothing wrong with the default 'root'#'%' user privileges.
Instead, as several people mentioned in the other answers, the solution was simply to set bind-address=0.0.0.0 instead of bind-address=127.0.0.1 in my /etc/mysql/mysql.conf.d/mysqld.cnf config. No changes were otherwise required.
I had the same problem on CentOS and this worked for me (version: 8.0.11):
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'#'%'
Stary mysql with sudo
sudo mysql

User not granted for mysql database but still can query?

Here is what I do to check grants for a specific user:
mysql> SHOW GRANTS FOR mmuser1;
+-----------------------------------------------------------------------------------------------------------------+
| Grants for mmuser1#% |
+-----------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'mmuser1'#'%' IDENTIFIED BY PASSWORD '*fesfesfesfes' |
| GRANT ALL PRIVILEGES ON `shopping_mm`.* TO 'mmuser1'#'%'
However, if I do the following:
mysql -ummuser1 -p
I can acccess and query another database (sports). Also, when doing:
SELECT Db,User FROM db;
I can see this Db associated with this user.
How is it possible that is not showing in the Grants table?
As documented under SHOW GRANTS Syntax:
If you specify only the user name part of the account name, a host name part of '%' is used.
It is likely that you have granted permission to your user with an explicit hostname, e.g. 'mmuser1'#'localhost'. As documented later on the same page, this can be verified once connected:
To list the privileges granted to the account that you are using to connect to the server, you can use any of the following statements:
SHOW GRANTS;
SHOW GRANTS FOR CURRENT_USER;
SHOW GRANTS FOR CURRENT_USER();
Or, alternatively, simply inspect CURRENT_USER:
SELECT CURRENT_USER;
Maybe you have a wildcard user that is usually default in Mysql is setup?
Any or % for the user name or host will allow any username/host permission to the DB, like in the picture below
You should remove these users that are usually default in MySQL
This picture is the default accounts that are installed with MYSQL , and all of them should be deleted as soon as you create a new user as none of them are secure, they allow - any username USAGE access to the db's

User can't access a database

In my PHP script, I'm accessing two databases db1 and db2. I have a user myuser#localhost that can access db1 but can't access db2.
When selecting from mysql.user table, there is one record and the host for that user is a wildcard %, there isn't a localhost host.
SELECT user, host FROM mysql.user WHERE user = 'myuser'; give me:
+------------+------+
| user | host |
+------------+------+
| myuser | % |
+------------+------+
1 row in set (0.00 sec)
Looking at GRANTS for that user, I see same permissions for db1 as for db2
SHOW GRANTS FOR 'myuser'#'%';
+-----------------------------------------------------------------------------------------------------------+
| Grants for myuser#% |
+-----------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'myuser'#'%' IDENTIFIED BY PASSWORD '*7733323232...' |
| GRANT ALL PRIVILEGES ON `db1`.* TO 'myuser'#'%' |
| GRANT ALL PRIVILEGES ON `db2`.* TO 'myuser'#'%' |
+-----------------------------------------------------------------------------------------------------------+
In my PHP script I can access db1 however I get an error: INSERT command denied to user 'myuser'#'localhost' for table 'HISTORY'.
It says user is myuser#localhost and people suggested adding permission for myuser#localhost however, why does this user have access to db1 and not to db2?
localhost does not match % in MySQL. It seems like it should, but in fact it doesn't. You'd have to separately grant privileges to user#localhost, both for the USAGE privilege, and for the privileges on each database.
Or you can connect as user#127.0.0.1 which does match %. Using the IP address for localhost seems like it should work identically to localhost, but it doesn't. You need to have two lines in the mysql.user table (and also in the mysql.db table in your case) to enable both.
To demonstrate the difference between localhost and 127.0.0.1:
Connecting as mysql -h localhost uses the UNIX socket interface, and bypasses TCP/IP. This can be slightly better for performance, but it has the effect on grant matching described above.
You can force a local TCP/IP connection by connecting as mysql -h 127.0.0.1. Then it will pick up the grants you have made to myuser#%.
So to get the same user, password, and privileges for both the socket interface and the TCP/IP interface, you'd need to run all of the following statements:
GRANT USAGE ON *.* TO 'myuser'#'%' IDENTIFIED BY PASSWORD '*7733323232...'
GRANT USAGE ON *.* TO 'myuser'#'localhost' IDENTIFIED BY PASSWORD '*7733323232...'
GRANT ALL PRIVILEGES ON `db1`.* TO 'myuser'#'%'
GRANT ALL PRIVILEGES ON `db1`.* TO 'myuser'#'localhost'
GRANT ALL PRIVILEGES ON `db2`.* TO 'myuser'#'%'
GRANT ALL PRIVILEGES ON `db2`.* TO 'myuser'#'localhost'
If you haven't done that already, you need to run flush privileges so that mysql knows there was a change and reloads the privileges table for users:
FLUSH PRIVILEGES;
This very likely has nothing to do with GRANTs.
A very common reason for having incorrect access rights is because of default users that exist in MySQL. Specially ones with '' for User (anonymous users) and/or Host in mysql.user table. Because of the way MySQL handles authentication and proxy users, and the sorting rules used on mysql.user table entries, one could end up using an unexpected user than the one they used for authentication.
Use SELECT USER(); to find out the connecting user that was used during authentication and SELECT CURRENT_USER(); to find out the effective user whose privileges apply during the current session.
And from http://dev.mysql.com/doc/refman/5.6/en/connection-access.html
It is a common misconception to think that, for a given user name, all
rows that explicitly name that user are used first when the server
attempts to find a match for the connection. This is not true.
If you are able to connect to the server, but your privileges are not
what you expect, you probably are being authenticated as some other
account.
A mysql.user table similar to following
+-----------+----------+-
| Host | User | ...
+-----------+----------+-
| % | root | ... (root from any host)
| % | jeffrey | ... (jeffrey from any host)
| localhost | root | ... (root from localhost)
| localhost | | ... (any user from localhost)
+-----------+----------+-
becomes,
+-----------+----------+-
| Host | User | ...
+-----------+----------+-
| localhost | root | ...
| localhost | | ...
| % | jeffrey | ...
| % | root | ...
+-----------+----------+-
whenever the server reads the user table into memory, in order to handle multiple matches.
When a client attempts to connect, the server looks through the rows in sorted order and uses the first row that matches the client host name and user name.
Precedence is given as: values (IP address, host name, user name, etc.) > '%' > ''
Most of the time application server/client is running in the same host as the database, causing the host name to be picked up as localhost during authentication.
mysql -u jeffrey uses jeffrey#localhost which gets matched against ''#localhost instead of jeffrey#%.
Executing $MYSQL_HOME/bin/mysql_secure_installation will remove anonymous users, while securing the installation, alleviating this unexpected behaviour.
Also check:
[1] http://bugs.mysql.com/bug.php?id=36576 (check comment before last)
[2] http://bugs.mysql.com/bug.php?id=69570
Just thought I'd add an answer. I was trying this on ubuntu. Tried the grants, flushes, nothing worked (this is immediately after by apt-get install mysql-server). Just for grins I bounced the server, that worked and my new user can now login. I did:
sudo service mysql restart
I don't know what that worked, but it did.
You must GRANT privileges also to 'myuser'#'localhost':
GRANT ALL PRIVILEGES ON `db1`.* TO 'myuser'#'localhost';
GRANT ALL PRIVILEGES ON `db2_beta`.* TO 'myuser'#'localhost';
Otherwise the anonymous user #localhost created during db install takes precedence among your user with the wildcard hostname (%), as described here:
http://dev.mysql.com/doc/refman/5.5/en/adding-users.html
According to the mysql manual here:
If you modify the grant tables indirectly using account-management
statements such as GRANT, REVOKE, or SET PASSWORD, the server notices
these changes and loads the grant tables into memory again
immediately.
If you modify the grant tables directly using statements such as
INSERT, UPDATE, or DELETE, your changes have no effect on privilege
checking until you either restart the server or tell it to reload the
tables. If you change the grant tables directly but forget to reload
them, your changes have no effect until you restart the server. This
may leave you wondering why your changes do not seem to make any
difference!
This does seem to be true in most cases. However, in my situation I was working with an Amazon Web Services (AWS) RDS mysql instance. After many unsuccessful attempts to grant the user permissions I tried a FLUSH PRIVILEGES and the database was immediately visible to the user. If you come across this while looking for a solution on the Amazon Web Services RDS platform you might want to give this a try and see if it helps.
This SO question contains the most complete solutions to this problem and is the first in most search results so I wanted to add this response for anyone using RDS. Hopefully it will save RDS admins some time.
I have run into the same problem in the past. Have you tried the following?
GRANT ALL ON `db1`.* TO 'myuser'#'%' IDENTIFIED BY PASSWORD '*7733323232...';
GRANT ALL ON `db2`.* TO 'myuser'#'%' IDENTIFIED BY PASSWORD '*7733323232...';
FLUSH PRIVILEGES;

MySQL Show Grants for... is different than mysql.db and information_schema.schema_privileges

I have discovered a difference between show grants for user#host and the mysql.db table. Why is this?
How can I resolve this? We are worried about security.
I ran a show grants against users in mysql.users. In mysql.users the user is user#xxx.xxx.xxx.xx and when I run show grants it says GRANT USAGE TO user#xxx.xxx.xxx.xx
This worried me as this user also seems to be able to access a database.
When I looked in mysql.db and information_schema.schema_privileges I can see the same user as user with a host of xxx.xxx.% with full access to that database.
What gives?
Edit - Deeper Explanation:
Here is what I have:
show grants for 'myuser'#'xxx.xxx.xxx.xxx';
It returns:
GRANT USAGE ON *.* TO 'myuser'#'xxx.xxx.xxx.xxx' IDENTIFIED BY PASSWORD 'xxxxxxxxxxxxxxxxx'
If I run:
select host,db,user from mysql.db where user='myuser';
I get:
+----------+------------+------------+
| host | db | user |
+----------+------------+------------+
|xxx.xxx.% | somedb | myuser |
+----------+------------+------------+
Don't worry.
The mysql.user table mitigates specific global privileges on all databases.
If a user is restricted to a specific database, you will only see database specific grants in the mysql.db table. A user restricted to a database does not need SUPER, PROCESS, SHUTDOWN, and privileges like these.
If you create a user withglobal privileges (thus landing the user in mysql.user), you cannot revoke global privileges only to demote the user to a specfic database. If you try to do so with REVOKE commands, you will see the user in mysql.user with the original Y values on all columns and the same user in mysql.db with Y values on database specific privileges.
You must completely drop the user and create the user fresh with the lower privileges.
Here is an example based on the comments
mysql> show grants for advdb#'%';
+-----------------------------------------------------------------------------+
| Grants for advdb#% |
+-----------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'advdb'#'%' IDENTIFIED BY PASSWORD '................' |
| GRANT ALL PRIVILEGES ON `advertpro`.* TO 'advdb'#'%' |
+-----------------------------------------------------------------------------+
The GRANT USAGE simply allows you to know what MD5 password is involved with authentication (if the password is not blank). Note that advdb can login from any IP address and only access the advertpro database.
The user does not need PROCESS privilege unless you want the user to see all processes in the processlist, even the one that belong to others.
The user does not need SUPER privilege unless you want the user to write in a read-only mysql instance, start and stop replication, zap binary logs, and things like these.
The user does not need SHUTDOWN privilege unless you want the user to shutdown mysql from the OS command line user the mysqladmin client program.
To copy the priv you are looking for,
SHOW GRANTS FOR 'user'#'xxx.xxx.xxx.%';
Copy the output to text file
Edit the host to xxx.xxx.xxx.xx
Add a semicolon
Paste that to the other server
OK let's hack that:
UPDATE mysql.db
SET host='xxx.xxx.xxx.xxx'
WHERE user='myuser'
AND host='xxx.xxx.%'
AND db='somedb';
FLUSH PRIVILEGES;
This should it !!!
To dump the MySQL Grants in SQL, you can do pt-show-grants
It is much better to port the mysql grants using pt-show-grants.
Here is my personal emulation of what pt-show-grants does
mysql -hhostaddr -umyuserid -pmypassword --skip-column-names -A -e"SELECT CONCAT('SHOW GRANTS FOR ''',user,'''#''',host,''';') FROM mysql.user WHERE user<>''" | mysql -hhostaddr -umyuserid -pmypassword --skip-column-names -A | sed 's/$/;/g' > MySQLUserGrants.sql