Closed d-rupp closed 2 years ago
@d-rupp hi and welcome to the project! Needs opinion of specialists, @bmalynovytch @Jorge-Rodriguez @rsicart what do you think of the issue and the suggested options?
Hi @d-rupp !
Thank you for your submission and your time. What I don't get is, at what point in time did MariaDB or MySQL introduce "per database" user management ?
Module mysql_user
doesn't allow a database name to be specified because user management is global (but still allows to specify per database privileges)
No, that´s not what i mean.
User management is global - and it is written into the "mysql" database.
We are using replication filters (for example binlog-ignore-db) to exclude the "mysql" database from replication on ONE backend node (of several) so we can manage separate permissions on that server (for customer BI queries for example). Replication filters are a complicated issue, i suggest you take a look at the documentation link.
But global statements are ALWAY replicated and can not be filtered. Since the mysql_user module issues the user management queries as global statements they will always be applied, no matter if you want them filtered out or not.
But if i set the database to "mysql" or connect to the mysql shell, issue a "use mysql" and then issue "create user xyz, grant foo to user, etc" those statements will not be replicated to a node that is using a replication filter on the mysql database.
My suggestion would be to make this a configureable setting for those who need it.
Got it !
Maybe dumb question, but why not enforcing usage of mysql
DB when managing users ?
That would solve your issue, and shouldn't harm other users ? (it would still require some tests to be confirmed)
That is a 5 letter solution, i´m all for it :)
If you're ready to be part of History, feel free to fill up a PR 😉
SUMMARY
In replication setups that use filters on the mysql database (to have different privileges for single nodes or certain branches of the replication tree) using this module will break replication. Since the module is not using any database the statements will not be filtered out and you may try to change users that do not exists on the filtered replica.
I could open a PR to fix this, but i wanted to discuss how you want this solved as i see two possible solutions.
Root cause is that the mysql_user plugin does not set a database. This makes the user change statements bypass the mysql binlog/replication filters.
We could either A) hardcode the default database for the mysql_user plugin to "mysql" as this is the place the permissions are stored anyway and usually the database that is filtered. B) make the database setting configureable for the mysql_user plugin so the user can decide if this feature is needed.
I did test A on my setup and it works flawlessly but i could understand why one would want to make this configureable. Let me know which solution you prefer and i will open a PR.
ISSUE TYPE
COMPONENT NAME
mysql_user
ANSIBLE VERSION
COLLECTION VERSION
CONFIGURATION
no changed configuration
OS / ENVIRONMENT
Ubuntu 20.04.2 LTS @ ansible controller RHEL7.9 with Percona Server 5.7.35 @ database hosts
STEPS TO REPRODUCE
You need a replication setup with at least three chained nodes.
writer -> intermediate -> backend
On the intermediate node you configure a replication filter ("binlog-ignore-db = mysql") to apply changes to the mysql database locally but not write them to the binlog for further replication (you could also do replicate-ignore-db to apply on this node).
The writer and intermediate pair share their mysql permissions. The backend has completely different permissions.
When you use the mysql_user plugin to change or remove a user the replication will break on the backend with it being unable to find the entries that need to be changed. When you use the mysql_user plugin to add a user it will add the user on the backend even though that is not supposed to happen.
EXPECTED RESULTS
Statements properly filtered by the intermediate node and not replicated to the backend.
ACTUAL RESULTS
Replication breaks or user is wrongfully added to the backend