LHammonds
October 6th, 2020, 05:16 PM
In the past, I've used the following command to export users and their privileges:
mysql --skip-column-names --no-auto-rehash --silent --execute="SELECT CONCAT('SHOW GRANTS FOR ''',user,'''@''',host,''';') FROM mysql.user WHERE user<>''" | mysql --skip-column-names --no-auto-rehash | sed 's/$/;/g' > /tmp/db-grants.sql
MariaDB implemented roles (https://mariadb.com/kb/en/roles/) in 2013 with version 10. I have only just now started to utilize roles and found that it broke my backups.
That same command above will fail will it comes across a role name which is stored as a pseudo-user in the user table. Example:
ERROR 1141 (42000) at line 4: There is no such grant defined for user 'r_myrole' on host '%'
To keep that syntax error from occurring, I modified the statement with a check for "is_role" as follows:
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'" | mysql --skip-column-names --no-auto-rehash | sed 's/$/;/g' > /tmp/db-grants.sql
Now the backup continues but the exported .sql file is worthless. In the database design, all the grants were removed from the users and added to the roles which are not exported in that .sql file. Even though the syntax is correct, the import will not work because it now looks like this:
GRANT `r_myrole` TO `u_myuser`@`localhost`;
GRANT USAGE ON *.* TO `u_myuser`@`localhost` IDENTIFIED BY PASSWORD 'mypassword';
#1 - The 1st command will not work when migrating to a new server because r_myrole does not exist AND the u_myuser does not yet exist.
#2 - The 2nd command will create the user but without any additional privileges (because the privileges are stored in the role).
So, to fix this, roles need to be exported 1st, then their associated grants, then the users and finally their granted role (with default setting)
I have yet to see where anyone on the Internet has addressed this since its inception 7 years ago.
I am thinking about writing a script that will create a usable .sql file to import on a clean system but don't want to re-create the wheel if not necessary.
Anyone know of a solution using the built-in features (preferred) or 3rd-party utility?
EDIT #1: Example of commands to create and assign a role:
CREATE ROLE r_db1;
GRANT SELECT,INSERT,UPDATE,DELETE ON db1.* TO r_db1;
CREATE USER 'u_db1'@'localhost' IDENTIFIED BY 'InsertPasswordHere';
GRANT r_db1 TO 'u_db1'@'localhost';
SET DEFAULT ROLE r_db1 FOR 'u_db1'@'localhost';
EDIT #2: The 1st roadblock is that this command does not exist:
SHOW CREATE ROLE r_dba1;
Which means I will have to export a list of roles and manually make each "create role" entry.
EDIT #3: I also asked this question at MariaDB (https://mariadb.com/kb/en/show-create-role/)
EDIT #4: Please up-vote these issues if you would like to see them resolved:
MDEV-22311 (https://jira.mariadb.org/browse/MDEV-22311) - implement SHOW CREATE ROLE
MDEV-22313 (https://jira.mariadb.org/browse/MDEV-22313) - SHOW GRANTS does not prints a user's default role
LHammonds
mysql --skip-column-names --no-auto-rehash --silent --execute="SELECT CONCAT('SHOW GRANTS FOR ''',user,'''@''',host,''';') FROM mysql.user WHERE user<>''" | mysql --skip-column-names --no-auto-rehash | sed 's/$/;/g' > /tmp/db-grants.sql
MariaDB implemented roles (https://mariadb.com/kb/en/roles/) in 2013 with version 10. I have only just now started to utilize roles and found that it broke my backups.
That same command above will fail will it comes across a role name which is stored as a pseudo-user in the user table. Example:
ERROR 1141 (42000) at line 4: There is no such grant defined for user 'r_myrole' on host '%'
To keep that syntax error from occurring, I modified the statement with a check for "is_role" as follows:
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'" | mysql --skip-column-names --no-auto-rehash | sed 's/$/;/g' > /tmp/db-grants.sql
Now the backup continues but the exported .sql file is worthless. In the database design, all the grants were removed from the users and added to the roles which are not exported in that .sql file. Even though the syntax is correct, the import will not work because it now looks like this:
GRANT `r_myrole` TO `u_myuser`@`localhost`;
GRANT USAGE ON *.* TO `u_myuser`@`localhost` IDENTIFIED BY PASSWORD 'mypassword';
#1 - The 1st command will not work when migrating to a new server because r_myrole does not exist AND the u_myuser does not yet exist.
#2 - The 2nd command will create the user but without any additional privileges (because the privileges are stored in the role).
So, to fix this, roles need to be exported 1st, then their associated grants, then the users and finally their granted role (with default setting)
I have yet to see where anyone on the Internet has addressed this since its inception 7 years ago.
I am thinking about writing a script that will create a usable .sql file to import on a clean system but don't want to re-create the wheel if not necessary.
Anyone know of a solution using the built-in features (preferred) or 3rd-party utility?
EDIT #1: Example of commands to create and assign a role:
CREATE ROLE r_db1;
GRANT SELECT,INSERT,UPDATE,DELETE ON db1.* TO r_db1;
CREATE USER 'u_db1'@'localhost' IDENTIFIED BY 'InsertPasswordHere';
GRANT r_db1 TO 'u_db1'@'localhost';
SET DEFAULT ROLE r_db1 FOR 'u_db1'@'localhost';
EDIT #2: The 1st roadblock is that this command does not exist:
SHOW CREATE ROLE r_dba1;
Which means I will have to export a list of roles and manually make each "create role" entry.
EDIT #3: I also asked this question at MariaDB (https://mariadb.com/kb/en/show-create-role/)
EDIT #4: Please up-vote these issues if you would like to see them resolved:
MDEV-22311 (https://jira.mariadb.org/browse/MDEV-22311) - implement SHOW CREATE ROLE
MDEV-22313 (https://jira.mariadb.org/browse/MDEV-22313) - SHOW GRANTS does not prints a user's default role
LHammonds