Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-5704

replicate_ignore_db='mysql' does not work on mariaDB 5.5.35

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Minor
    • Resolution: Not a Bug
    • Affects Version/s: 5.5.35
    • Fix Version/s: None
    • Component/s: None
    • Labels:
      None

      Description

      My purpose is to ignore replication for the mysql database.

      I was trying to filter the replication for the mysql database in a master - slave configuration with mariaDB 5.5.35 , but I was not successful in the following configuration:

                Replicate_Do_DB: 
                Replicate_Ignore_DB: mysql
                Replicate_Do_Table: 
                Replicate_Ignore_Table: 
      

      I tested this by creating a new user.

      However with the following configuration it works:

               Slave_IO_Running: Yes
               Slave_SQL_Running: Yes
               Replicate_Do_DB: 
               Replicate_Ignore_DB: mysql,multitestrep
               Replicate_Do_Table: 
               Replicate_Ignore_Table: 
               Replicate_Wild_Do_Table: 
      

      multitestrep is a test database created only for this purpose.
      Unless I am not mistaking , it looks that the slave is ignoring the variable replicate_ignore_db if set global replicate_ignore_db='mysql'; but if the string contains another valid/existing database , then both databases are not replicated (this is what I need).

      My purpose is to ignore replication for the mysql database and the only solution I found is to set replicate_ignore_db='mysql,multitestrep';

      I tested this many times and it can be reproduced each time.

      Regards.

        Gliffy Diagrams

          Attachments

            Activity

            Hide
            elenst Elena Stepanova added a comment -

            Hi,

            Could you please describe your test in more detail?

            What is the exact statement that you use to create a user?
            What binlog_format does your server use?
            How exactly do you pass replicate-ignore-db values?
            How do you check whether your statement was replicated?

            Thanks

            Show
            elenst Elena Stepanova added a comment - Hi, Could you please describe your test in more detail? What is the exact statement that you use to create a user? What binlog_format does your server use? How exactly do you pass replicate-ignore-db values? How do you check whether your statement was replicated? Thanks
            Hide
            cristian.nicoara82 Cristian Nicoara added a comment -

            Hello,

            – grant all privileges on database.* to user@'192.168.1.1' identified by 'password' require ssl;
            – binlog_format = MIXED
            – I noticed that replicate-ignore-db can be set while running and it works , but I tried both ways: by configuration and by set global ...
            – show grants for user on slave

            replicate_ignore_db = multitestrep
            replicate_ignore_db = mysql

            Show
            cristian.nicoara82 Cristian Nicoara added a comment - Hello, – grant all privileges on database.* to user@'192.168.1.1' identified by 'password' require ssl; – binlog_format = MIXED – I noticed that replicate-ignore-db can be set while running and it works , but I tried both ways: by configuration and by set global ... – show grants for user on slave replicate_ignore_db = multitestrep replicate_ignore_db = mysql
            Hide
            elenst Elena Stepanova added a comment -

            Hi Cristian,

            Account management statements (GRANT, CREATE USER and such) are written into the binary log as they are, not as updates to mysql.user table; so, they are replicated, regardless replicate_ignore_db. Thus, when the value does not work as you expect it to, it is actually the correct behavior.
            Now, it would be a miracle if any value of replicate_ignore_db stopped replication of GRANT statements. Could you please provide the exact steps and the checks that you performed to ensure that the statements were not replicated?

            Thanks.

            Show
            elenst Elena Stepanova added a comment - Hi Cristian, Account management statements ( GRANT , CREATE USER and such) are written into the binary log as they are, not as updates to mysql.user table; so, they are replicated, regardless replicate_ignore_db. Thus, when the value does not work as you expect it to, it is actually the correct behavior. Now, it would be a miracle if any value of replicate_ignore_db stopped replication of GRANT statements. Could you please provide the exact steps and the checks that you performed to ensure that the statements were not replicated? Thanks.
            Hide
            cristian.nicoara82 Cristian Nicoara added a comment - - edited

            Hello,

            we have this slave setting: Replicate_Ignore_DB: multitestrep,mysql

            but the following behavior is interesting :

            on master:
            MariaDB [(none)]> grant all privileges on dbname.* to test88888@'192.168.1.25' identified by 'mypass' require ssl;
            Query OK, 0 rows affected (0.01 sec)

            – replication works and on slave we can see the new user created.

            but the following env on master:
            MariaDB [multitestrep]> grant all privileges on dbname.* to test88888@'192.168.1.26' identified by 'mypass' require ssl;
            Query OK, 0 rows affected (0.00 sec)

            – in this case the replication does not work , I cannot find the new user replicated on slave .

            I believe that this behavior made me believe that this is a functional workaround ... but it is not .

            But, is there a way to prevent mysql database replication if binlog_format=MIXED ? To my knowledge if we go on binlog_format=ROW and Replicate_Ignore_DB=mysql , then it should work . Am I correct ? I am sorry if this is the wrong place to ask .

            Thank you .

            Show
            cristian.nicoara82 Cristian Nicoara added a comment - - edited Hello, we have this slave setting: Replicate_Ignore_DB: multitestrep,mysql but the following behavior is interesting : on master: MariaDB [(none)] > grant all privileges on dbname.* to test88888@'192.168.1.25' identified by 'mypass' require ssl; Query OK, 0 rows affected (0.01 sec) – replication works and on slave we can see the new user created. but the following env on master: MariaDB [multitestrep] > grant all privileges on dbname.* to test88888@'192.168.1.26' identified by 'mypass' require ssl; Query OK, 0 rows affected (0.00 sec) – in this case the replication does not work , I cannot find the new user replicated on slave . I believe that this behavior made me believe that this is a functional workaround ... but it is not . But, is there a way to prevent mysql database replication if binlog_format=MIXED ? To my knowledge if we go on binlog_format=ROW and Replicate_Ignore_DB=mysql , then it should work . Am I correct ? I am sorry if this is the wrong place to ask . Thank you .
            Hide
            elenst Elena Stepanova added a comment -

            I believe that this behavior made me believe that this is a functional workaround ... but it is not .

            But, is there a way to prevent mysql database replication if binlog_format=MIXED ? To my knowledge if we go on binlog_format=ROW and Replicate_Ignore_DB=mysql , then it should work . Am I correct ? I am sorry if this is the wrong place to ask .

            Sorry, I wasn't accurate enough in my previous comment. Besides, the fact that you run your GRANT statements with different default databases changes things.

            The way replicate-ignore-db works is very much non-intuitive. Indeed, it differs dramatically for STATEMENT and ROW replication (MIXED is mostly STATEMENT unless it's forced into ROW mode); but in your case, you run GRANT statements, which are always replicated in STATEMENT mode, regardless the binlog format.

            So, to understand why you get what you get, you should look at how replicate-ignore-db works for STATEMENT-based replication.
            See this explanation for replicate-do-db: http://dev.mysql.com/doc/refman/5.5/en/replication-options-slave.html#option_mysqld_replicate-do-db (for ignore-db, it's pretty much the same).

            In your case, slave decides whether to replicate GRANT statement based on the default schema which was set on master when the statement was run. It does not take into account at all which tables get modified.
            The default schema is set by USE <schema name>, or by providing it on the client command line.
            With MariaDB command-line client, the schema is shown in the prompt.
            In your example above, the first GRANT (192.168.1.25) was run without any default schema at all (none). Thus, nothing prevents replicating the statement.
            The second GRANT (192.168.1.26) was run with multitestrep default schema, which is on the ignore list – this is why it was not replicated.

            For GRANT statements, it will work the same way with any binlog_format, so switching to ROW is not a solution.
            If you can make sure that GRANT statements are only executed lets say with 'mysql' default schema (or any other schema which is on the ignore list), it will be the simplest solution for your problem.

            Another way is to explicitly issue SET SQL_LOG_BIN=0 before running GRANT (and SET SQL_LOG_BIN=1 afterwards); but it is not quite the same as skipping replication, it will cause the GRANT not being written into the master binary log at all.

            Unfortunately I'm afraid there is no better way to prevent the replication.

            Show
            elenst Elena Stepanova added a comment - I believe that this behavior made me believe that this is a functional workaround ... but it is not . But, is there a way to prevent mysql database replication if binlog_format=MIXED ? To my knowledge if we go on binlog_format=ROW and Replicate_Ignore_DB=mysql , then it should work . Am I correct ? I am sorry if this is the wrong place to ask . Sorry, I wasn't accurate enough in my previous comment. Besides, the fact that you run your GRANT statements with different default databases changes things. The way replicate-ignore-db works is very much non-intuitive. Indeed, it differs dramatically for STATEMENT and ROW replication (MIXED is mostly STATEMENT unless it's forced into ROW mode); but in your case, you run GRANT statements, which are always replicated in STATEMENT mode, regardless the binlog format. So, to understand why you get what you get, you should look at how replicate-ignore-db works for STATEMENT-based replication. See this explanation for replicate-do-db: http://dev.mysql.com/doc/refman/5.5/en/replication-options-slave.html#option_mysqld_replicate-do-db (for ignore-db, it's pretty much the same). In your case, slave decides whether to replicate GRANT statement based on the default schema which was set on master when the statement was run. It does not take into account at all which tables get modified. The default schema is set by USE <schema name> , or by providing it on the client command line. With MariaDB command-line client, the schema is shown in the prompt. In your example above, the first GRANT (192.168.1.25) was run without any default schema at all (none). Thus, nothing prevents replicating the statement. The second GRANT (192.168.1.26) was run with multitestrep default schema, which is on the ignore list – this is why it was not replicated. For GRANT statements, it will work the same way with any binlog_format, so switching to ROW is not a solution. If you can make sure that GRANT statements are only executed lets say with 'mysql' default schema (or any other schema which is on the ignore list), it will be the simplest solution for your problem. Another way is to explicitly issue SET SQL_LOG_BIN=0 before running GRANT (and SET SQL_LOG_BIN=1 afterwards); but it is not quite the same as skipping replication, it will cause the GRANT not being written into the master binary log at all. Unfortunately I'm afraid there is no better way to prevent the replication.
            Hide
            elenst Elena Stepanova added a comment -

            As a variant of the second solution, instead of setting SQL_LOG_BIN, you can use the pair{{skip_replication}} (on master) and replicate_events_marked_for_skip (on slave). In this case, you'll need to set the variable on the slave once and forever, while on master you'll have to set skip_replication every time before issuing the state of statements that you don't want to replicate, and revert it afterwards. It should prevent replication much like SQL_LOG_BIN would, the difference is that the statements will still be written to the binary logs, which in some cases can be desirable. See https://mariadb.com/kb/en/selectively-skipping-replication-of-binlog-events/ for more details.

            Show
            elenst Elena Stepanova added a comment - As a variant of the second solution, instead of setting SQL_LOG_BIN, you can use the pair{{skip_replication}} (on master) and replicate_events_marked_for_skip (on slave). In this case, you'll need to set the variable on the slave once and forever, while on master you'll have to set skip_replication every time before issuing the state of statements that you don't want to replicate, and revert it afterwards. It should prevent replication much like SQL_LOG_BIN would, the difference is that the statements will still be written to the binary logs, which in some cases can be desirable. See https://mariadb.com/kb/en/selectively-skipping-replication-of-binlog-events/ for more details.
            Hide
            cristian.nicoara82 Cristian Nicoara added a comment -

            Thank you for you help , I used the second solution with skip_replication ...

            Regards.

            Show
            cristian.nicoara82 Cristian Nicoara added a comment - Thank you for you help , I used the second solution with skip_replication ... Regards.
            Hide
            pomyk Patryk Pomykalski added a comment -

            We use "replicate-wild-ignore-table = mysql.%" and seems to work without problems.

            Show
            pomyk Patryk Pomykalski added a comment - We use "replicate-wild-ignore-table = mysql.%" and seems to work without problems.
            Hide
            elenst Elena Stepanova added a comment -

            How interesting, you are right.. And I'm not even sure it's supposed to, the documentation is not so clear about it, but it is surely convenient.

            Show
            elenst Elena Stepanova added a comment - How interesting, you are right.. And I'm not even sure it's supposed to, the documentation is not so clear about it, but it is surely convenient.

              People

              • Assignee:
                elenst Elena Stepanova
                Reporter:
                cristian.nicoara82 Cristian Nicoara
              • Votes:
                0 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                • Due:
                  Created:
                  Updated:
                  Resolved: