Bug #105365 | replicate-wild-ignore-table=mysql.% and grant break replication | ||
---|---|---|---|
Submitted: | 28 Oct 2021 14:31 | Modified: | 12 Jan 2022 15:56 |
Reporter: | lalit Choudhary | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Replication | Severity: | S3 (Non-critical) |
Version: | 5.7,8.0, 8.0.27 | OS: | Any |
Assigned to: | CPU Architecture: | Any |
[28 Oct 2021 14:31]
lalit Choudhary
[31 Oct 2021 9:27]
MySQL Verification Team
Hello Lalit, Thank you for the report and feedback. -- Simple master-> slave setup, followed steps from your report - rm -rf master/ bin/mysqld --initialize-insecure --basedir=$PWD --datadir=$PWD/master --log-error-verbosity=3 bin/mysqld --no-defaults --basedir=$PWD --datadir=$PWD/master --core-file --socket=/tmp/mysql_master.sock --port=3306 --log-error=$PWD/master/log.err --log-bin=master-bin --server_id=1 2>&1 & rm -rf slave/ bin/mysqld --initialize-insecure --basedir=$PWD --datadir=$PWD/slave --log-error-verbosity=3 bin/mysqld --no-defaults --basedir=$PWD --datadir=$PWD/slave --core-file --socket=/tmp/mysql_slave.sock --port=3307 --log-error=$PWD/slave/log.err --log-bin=slave-bin --server_id=2 --replicate-wild-ignore-table=mysql.% 2>&1 & - master bin/mysql -uroot -S /tmp/mysql_master.sock --prompt='Master>' Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 5.7.36-log MySQL Community Server (GPL) Copyright (c) 2000, 2021, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. Master> Master>CREATE USER 'repl'@'localhost' IDENTIFIED BY 'slavepass'; Query OK, 0 rows affected (0.00 sec) Master>GRANT REPLICATION SLAVE ON *.* TO 'repl'@'localhost'; Query OK, 0 rows affected (0.00 sec) Master> Master>CREATE USER 'repl'@'127.0.0.1' IDENTIFIED BY 'slavepass'; Query OK, 0 rows affected (0.00 sec) Master>GRANT REPLICATION SLAVE ON *.* TO 'repl'@'127.0.0.1'; Query OK, 0 rows affected (0.00 sec) Master>FLUSH PRIVILEGES; Query OK, 0 rows affected (0.01 sec) Master>show master status; +-------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +-------------------+----------+--------------+------------------+-------------------+ | master-bin.000001 | 1220 | | | | +-------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec) - slave bin/mysql -uroot -S /tmp/mysql_slave.sock --prompt='Slave>' Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 5.7.36-log MySQL Community Server (GPL) Copyright (c) 2000, 2021, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. Slave>CHANGE MASTER TO -> MASTER_HOST='localhost', -> MASTER_PORT=3306, -> MASTER_USER='repl', -> MASTER_PASSWORD='slavepass', -> MASTER_LOG_FILE='master-bin.000001', -> MASTER_LOG_POS=1220; Query OK, 0 rows affected, 2 warnings (0.02 sec) Slave>start slave; Query OK, 0 rows affected (0.00 sec) Slave>show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: localhost Master_User: repl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: master-bin.000001 Read_Master_Log_Pos: 1220 Relay_Log_File: support-cluster03-relay-bin.000002 Relay_Log_Pos: 321 Relay_Master_Log_File: master-bin.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: mysql.% Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 1220 Relay_Log_Space: 540 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 1 Master_UUID: 66c06f4d-3a2b-11ec-af67-000017016152 Master_Info_File: /export/home/tmp/ushastry/mysql-5.7.36/slave/master.info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 0 Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version: 1 row in set (0.00 sec) - master Master>create database test; Query OK, 1 row affected (0.01 sec) Master>use test Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed Master>create table test.t1(c1 int); Query OK, 0 rows affected (0.02 sec) Master>show tables; +----------------+ | Tables_in_test | +----------------+ | t1 | +----------------+ 1 row in set (0.00 sec) Master>drop table test.t1; Query OK, 0 rows affected (0.01 sec) Master>grant select on test.t1 to msandbox@'127.%'; ERROR 1146 (42S02): Table 'test.t1' doesn't exist - slave No issues observed. Am I missing anything here? Could you please try in latest builds and confirm if you are seeing this? Thank you! regards, Umesh regards, Umesh
[6 Nov 2021 13:45]
lalit Choudhary
Hi Umesh, I see in your test you are creating and dropping a table on MASTER only and that is the reason you don't see an issue. Following are the reproducible steps: 1. Setup simple replication( default file position based replication) 2. On SLAVE add replication filter in my.cnf replicate-wild-ignore-table=mysql.% 3. Restart slave mysqld service #####On MASTER: master [localhost] {msandbox} ((none)) > create table test.t1(c1 int); Query OK, 0 rows affected (0.05 sec) #####ON SLAVE: verify table replicated and DROP table on SLAVE only. slave1 [localhost] {msandbox} (test) > show tables; +----------------+ | Tables_in_test | +----------------+ | t1 | +----------------+ 1 row in set (0.01 sec) slave1 [localhost] {msandbox} (test) > drop table test.t1; Query OK, 0 rows affected (0.02 sec) ####On MASTER master [localhost] {root} ((none)) > grant select on test.t1 to msandbox@'127.%'; ###On SLAVE check the replication status, 5.7: Slave_IO_Running: Yes Slave_SQL_Running: No Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: mysql.% Last_Errno: 1146 Last_Error: Error 'Table 'test.t1' doesn't exist' on query. Default database: ''. Query: 'GRANT SELECT ON `test`.`t1` TO 'msandbox'@'127.%''
[7 Nov 2021 7:20]
MySQL Verification Team
Thank you for the feedback. Verified as described. regards, Umesh
[10 Nov 2021 9:15]
Sven Sandberg
Posted by developer: Thank you for the bug report. AFAIU, the expectation is that SQL admin statements that implicitly update tables in the mysql database, such as GRANT, will be excluded by using a filter like replicate-wild-ignore-table=mysql.% However, replication filters don't work that way. Table-level filters are evaluated only for tables that are mentioned explicitly in the query. (And only for tables which the query actually operates on - not on test.t1 in the GRANT statement since the query does not actually operate on test.t1 - although this is not the reason for the error.) Since GRANT statements don't mention the grant tables in the query, the mysql.% filter does not help. The tool we have for achieving what I think was intended here, is to use a database filter. For DDLs and admin statements, database filters operate on the *used* database (as in `USE db`), so the following procedure would filter out the GRANT statement: - Configure: replicate-ignore-db=nonreplicated - Execute: USE `nonreplicated`; GRANT ...; This only works when the replication admin has sufficient control over the SQL, so that they can enforce the discipline to always execute USE `nonreplicated` before any GRANT or other admin statement. We do not have other tools to achieve this. The manual is does not describe these aspects, so changing this to a documentation bug.
[12 Jan 2022 15:56]
Margaret Fisher
Posted by developer: Thanks for the report! I've added the following which will show when the new release documentation is published: MySQL 8.0 Reference Manual / Replication / Configuring Replication / Replication and Binary Logging Options and Variables / Replica Server Options and Variables https://dev.mysql.com/doc/refman/8.0/en/replication-options-replica.html#option_mysqld_rep... Important: Table-level replication filters are only applied to tables that are explicitly mentioned and operated on in the query. They do not apply to tables that are implicitly updated by the query. For example, a GRANT statement, which updates the mysql.user system table but does not mention that table, is not affected by a filter that specifies mysql.% as the wildcard pattern. https://dev.mysql.com/doc/refman/8.0/en/replication-options-replica.html#option_mysqld_rep... Important: Table-level replication filters are only applied to tables that are explicitly mentioned and operated on in the query. They do not apply to tables that are implicitly updated by the query. For example, a GRANT statement, which updates the mysql.user system table but does not mention that table, is not affected by a filter that specifies mysql.% as the wildcard pattern. If you need to filter out GRANT statements or other administrative statements, a possible workaround is to use the replicate-ignore-db filter. This filter operates on the default database that is currently in effect, as determined by the USE statement. You can therefore create a filter to ignore statements for a database that is not replicated, then issue the USE statement to switch the default database to that one immediately before issuing any administrative statements that you want to ignore. In the administrative statement, name the actual database where the statement is applied. For example, if replicate-ignore-db=nonreplicated is configured on the replica server, the following sequence of statements causes the GRANT statement to be ignored, because the default database nonreplicated is in effect: USE nonreplicated; GRANT SELECT, INSERT ON replicated.t1 TO 'someuser'@'somehost'; MySQL 8.0 Reference Manual / Replication / Replication Implementation / How Servers Evaluate Replication Filtering Rules / Evaluation of Table-Level Replication Options https://dev.mysql.com/doc/refman/8.0/en/replication-rules-table-options.html Important: Table-level replication filters are only applied to tables that are explicitly mentioned and operated on in the query. They do not apply to tables that are implicitly updated by the query. For example, a GRANT statement, which updates the mysql.user system table but does not mention that table, is not affected by a filter that specifies mysql.% as the wildcard pattern.