How to Migrate MySQL Users to Another Server

I wanted to Migrate MySQL from one server to another. Usually, I could just copy over the MySQL data directory (/var/lib/mysql) to the new server, this will copy over MySQL users and data. On this server, the MySQL data file (ibdata1) was too large, 200 GB approx. If I do a mysqldump, the SQL file was only 10 GB, so I decided not to copy over the data directory to the new server.

I did a MySQL dump of all databases with the command

mysqldump --events --routines --triggers --all-databases > all-dbs.sql

Copy the file all-dbs.sql to the new server and tried to restore with the command

mysql < all-dbs.sql

It failed because MySQL on old and new servers are different, recent MySQL versions have users table changed to view.

So I backed up individual MySQL databases using MySQL backup all databases, copied over to the new server, and restore the databases. When restoring databases, I get an error saying the database does not exist, I created the databases and restored the SQL files.

Now we have all databases and data on new server. We need to create all users with correct permissions. To do this, on source server, run

pt-show-grants

pt-show-grants is part of Percona Toolkit. You can install Percona Toolkit on Ubuntu/Debian with the command

apt install percona-toolkit

If you have password for root user, you can use

pt-show-grants --host localhost --user root --ask-pass

The command will show the SQL commands used to create the users with the correct permission. Copy it and run it on new server MySQL command prompt. This will create all users on new server with proper permissions.

Copy a specific user to new server

To view commands to create a specific user, you can run the command

show grants for 'USER_HERE'@'HOST_HERE';

Example

show grants for 'root'@'localhost';

Copy all MySQL users to the new server

If you don't have Percona Toolkit installed, you can use the following command

mysql -u root --silent --skip-column-names -A -e"SELECT CONCAT('SHOW GRANTS FOR ''',user,'''@''',host,''';') FROM mysql.user WHERE user<>''" | mysql -u root --skip-column-names -A

It will generate SQL commands to create users, copy and run it on new server to create MySQL users.

Here is a bash script to do the same

mysql --silent --skip-column-names --execute "select concat('\'',User,'\'@\'',Host,'\'') as User from mysql.user" | sort | \
while read u
 do echo "-- $u"; mysql --silent --skip-column-names --execute "show grants for $u" | sed 's/$/;/'
done

Back to MySQL

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *