I will document the workaround for getting a good backup of users, grants and roles for the purpose of migrating a complete system from one server to another in this post.
The order these commands are executed are important so the creation of the commands will take account of this. Role Creation -> Role Grants -> User Creation -> User Grants -> Role Defaults
Role Creation
Code:
mysql --skip-column-names --no-auto-rehash --silent --execute="SELECT User FROM mysql.user WHERE is_role = 'Y';" | sed 's/^/CREATE ROLE /;s/$/;/g;1s/^/## Create Roles ##\n/' > /tmp/role-create.sql
Example output:
Code:
## Create Roles ##
CREATE ROLE r_dba;
CREATE ROLE r_db1;
CREATE ROLE r_db2;
Role Grants
Code:
mysql --skip-column-names --no-auto-rehash --silent --execute="SELECT CONCAT('SHOW GRANTS FOR ''',User,''';') FROM mysql.user WHERE is_role = 'Y'" | mysql --skip-column-names --no-auto-rehash | sed 's/$/;/g;1s/^/## Grants for Roles ##\n/' > /tmp/role-grants.sql
Example output:
Code:
## Grants for Roles ##
GRANT USAGE ON *.* TO `r_dba`;
GRANT ALL PRIVILEGES ON *.* TO `r_dba`;
GRANT USAGE ON *.* TO `r_db1`;
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE ON `db1`.* TO `r_db1`;
GRANT USAGE ON *.* TO `r_db2`;
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE ON `db2`.* TO `r_db2`;
User Creation
Code:
mysql --skip-column-names --no-auto-rehash --silent --execute="SELECT User,Host,Password FROM mysql.user WHERE is_role = 'N' AND User NOT IN ('mariadb.sys','root','mysql');" | sed 's/\t/`@`/;s/\t/` IDENTIFIED BY `/;s/^/CREATE USER `/;s/$/`;/;1s/^/## Create Users ##\n/' > /tmp/user-create.sql
Example output:
Code:
## Create Users ##
CREATE USER `u_dba`@`localhost` IDENTIFIED BY `*0123456789012345678901234567891234567891`;
CREATE USER `u_db1`@`localhost` IDENTIFIED BY `*0123456789012345678901234567891234567891`;
CREATE USER `u_db2`@`localhost` IDENTIFIED BY `*0123456789012345678901234567891234567891`;
User Grants
Code:
mysql --skip-column-names --no-auto-rehash --silent --execute="SELECT CONCAT('SHOW GRANTS FOR ''',User,'''@''',Host,''';') FROM mysql.user WHERE User <> '' AND is_role = 'N' AND user NOT IN ('mysql','mariadb.sys','root');" | mysql --skip-column-names --no-auto-rehash | sed 's/$/;/g;1s/^/## Grants for Users ##\n/' > /tmp/user-grants.sql
Example output:
Code:
## Grants for Users ##
GRANT `r_dba` TO `u_dba`@`localhost`;
GRANT USAGE ON *.* TO `u_dba`@`localhost` IDENTIFIED BY PASSWORD `*0123456789012345678901234567891234567891`;
GRANT `r_db1` TO `u_db1`@`localhost`;
GRANT USAGE ON *.* TO `u_db1`@`localhost` IDENTIFIED BY PASSWORD `*0123456789012345678901234567891234567891`;
GRANT `r_db2` TO `u_db2`@`localhost`;
GRANT USAGE ON *.* TO `u_db2`@`localhost` IDENTIFIED BY PASSWORD `*0123456789012345678901234567891234567891`;
Role Defaults
Code:
mysql --skip-column-names --no-auto-rehash --silent --execute="SELECT default_role,User,Host FROM mysql.user WHERE is_role = 'N' AND User NOT IN ('mariadb.sys','root','mysql') AND default_role <> '';" | sed 's/\t/ FOR `/;s/\t/`@`/;s/^/SET DEFAULT ROLE /;1s/^/## Set Default Roles ##\n/;s/$/`;/' > /tmp/role-default.sql
Example output:
Code:
## Set Default Roles ##`;
SET DEFAULT ROLE r_dba FOR `u_dba`@`localhost`;
SET DEFAULT ROLE r_db1 FOR `u_db1`@`localhost`;
SET DEFAULT ROLE r_db2 FOR `u_db2`@`localhost`;
Thanks,
LHammonds