Backing up permissions for individual databases
Sometimes, you want to backup individual databases in MySQL to move to a different server. This part is easy using mysqldump:
shell> mysqldump -u root -p --databases db1 db2 ... > backup.sql
The problem is, what happens when you want to backup the permissions associated with these databases? Well, here are a few queries to help you out.
-- Grab the users with global permissions, -- with permissions to the databases you want, -- and tables/stored procedures in it. mysql> SELECT u.* INTO OUTFILE '/tmp/user.txt' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '\\' LINES TERMINATED BY '\n' FROM mysql.user u WHERE u.Select_priv='Y' UNION SELECT u.* FROM mysql.user u, mysql.db d WHERE d.Db IN('db1', 'db2', ...) AND d.User = u.user UNION SELECT u.* FROM mysql.user u, mysql.tables_priv t WHERE t.Db IN('db1', 'db2', ...) AND t.User = u.User UNION SELECT u.* FROM mysql.user u, mysql.procs_priv p WHERE p.Db IN('db1', 'db2', ...) AND p.User = u.User; -- Now, grab the database permissions, and those of objects in the database. mysql> SELECT * INTO OUTFILE '/tmp/db.txt' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '\\' LINES TERMINATED BY '\n' FROM mysql.db WHERE Db IN('db1', 'db2', ...); mysql> SELECT * INTO OUTFILE '/tmp/tables_priv.txt' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '\\' LINES TERMINATED BY '\n' FROM mysql.tables_priv WHERE Db IN('db1', 'db2', ...); mysql> SELECT * INTO OUTFILE '/tmp/procs_priv.txt' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '\\' LINES TERMINATED BY '\n' FROM mysql.procs_priv WHERE Db IN('db1', 'db2', ...);
Then, re-loading the permissions onto the new server is simple:
mysql> LOAD DATA INFILE '/tmp/user.txt' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '\\' LINES TERMINATED BY '\n' INTO TABLE mysql.user; mysql> LOAD DATA INFILE '/tmp/db.txt' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '\\' LINES TERMINATED BY '\n' INTO TABLE mysql.db; mysql> LOAD DATA INFILE '/tmp/tables_priv.txt' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '\\' LINES TERMINATED BY '\n' INTO TABLE mysql.tables_priv; mysql> LOAD DATA INFILE '/tmp/procs_priv.txt' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '\\' LINES TERMINATED BY '\n' INTO TABLE mysql.procs_priv;
All up, a few queries to account for everything, but pretty easy to include in your backup/restore process. For further development, you could put the database list in a variable, so that you only need to change it on one line, rather than 6.
Permissions by interface on the local server
I had an issue come up recently that involved some confusion over permissions for the same user, connecting through different interfaces. For example, say you have a server with the public IP address of 192.168.0.1. You could connect to it from the local machine using the following commands:
shell> mysql -h localhost # Connects through the socket file shell> mysql -h 127.0.0.1 # Connects through the loopback interface shell> mysql -h 192.168.0.1 # Connects through the network interface
They all connect to the local server, but they can all have different permissions. Here are a couple of rules to make your life easier:
- Don’t use @127.0.0.1, unless you absolutely can’t use the socket file for some reason. Connecting through @localhost is usually faster than the loopback device, and it’s easier to type.
- Only connect through the network interface if you’re planning on moving the application to a different server later on.
That’s all.


