[MDEV-10712] Stored procedures are replicated unexpectedly Created: 2016-08-31  Updated: 2016-09-07  Resolved: 2016-09-07

Status: Closed
Project: MariaDB Server
Component/s: Documentation, Replication
Affects Version/s: N/A
Fix Version/s: N/A

Type: Bug Priority: Minor
Reporter: Igor Pashev Assignee: Ian Gilfillan
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to MDEV-10652 Invalid definer for a procedure Closed

 Description   

We are using multi-source replication and observed in MDEV-10652 that stored procedures are replicated unconditionally.

The setup includes:

1. ROW-based binary logs at masters. Masters are MySQL 5.6 at AWS RDS and standalone MariaDB 10.1.x.
2. Slave channel configuration:

foo.replicate_wild_do_table = foo.%
foo.replicate_ignore_table = foo.beep
foo.replicate_ignore_table = foo.tmp

What seems correct: changes to the foo database are replicated, changes to the mysql database or any other databases are ignored, GRANT, REVOKE are ignored, procedures bound to the foo database are replicated (DROP PROCEDURE foo.xxx, CREATE PROCEDURE foo.xxx, etc.).

What seems wrong: procedures bound to other databases are replicated as well regardless of replication options. E. i. DROP PROCEDURE mysql.yyy and CREATE PROCEDURE mysql.yyy is executed on the slave.

I tried various replication options like do-db, ignore-db and setting default database before working with procedures on the master, and this made no difference. E. g.:

USE mysql;
CREATE PROCEDURE yyy ...;

I think since the user managment commands (GRANT, REVOKE) are ignored in this setup, procedures bound to other databases should be ignored as well.

Usage of sql_log_bin=0; is not an option, because it may require the SUPER privilege and would break other slaves that are supposed to replicate the entire master. Same for @@skip_replication which is in addition a MariaDB-specific feature.



 Comments   
Comment by Elena Stepanova [ 2016-08-31 ]

Regarding replicate_wild_do_table, please check documentation, it explicitly says that the option does not apply to procedures:

This option applies to tables, views, and triggers. It does not apply to stored procedures and functions, or events. To filter statements operating on the latter objects, use one or more of the -replicate*-db options.

Regarding replicate_do_db, it is supposed to work, and from what I see, it does work, but you need to take into account specifics of using it. You said "I tried various replication options like do-db, ignore-db and setting default database", I assume it means you tried setting replicate-do-db and you tried setting default database, but not both at once. By the definition of the option, you need to do both at once.

Statement-based replication. Tell the slave SQL thread to restrict replication to statements where the default database (that is, the one selected by USE) is db_name. To specify more than one database, use this option multiple times, once for each database

Despite the fact that your binlog format is set to ROW, only statement-based rules apply in this case, because DDL operations such as SP creation are always logged in statement format.

So, to have it work successfully (that is, to ignore the procedures), you need to configure your server with replicate-do-db=foo, start the server, switch to a default database other than foo, and run CREATE PROCEDURE statement.

If you try that and it does not work, please paste or attach

  • the output from the MySQL client where you perform the action on master;
  • the relevant portion of the binary log;
  • output of SHOW ALL SLAVES STATUS from the slave;
  • output from MySQL client on slave where we can see that the procedure has been indeed replicated

To avoid any unexpected coincidences, I suggest to use a clearly unique name for the procedure which you'll create for the test.

Comment by Igor Pashev [ 2016-08-31 ]

> I assume it means you tried setting replicate-do-db and you tried setting default database, but not both at once. By the definition of the option, you need to do both at once.

I was sure I tested all the combinations, otherwise I would write up this case. Apparently, it's not true.

Now I checked again, and found this working:

1. On the slave

          Replicate_Ignore_DB: mysql
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table: foo.%
  Replicate_Wild_Ignore_Table:

2. On the master:

USE mysql;
CREATE PROCEDURE whatever() BEGIN END;

Thank you, and NOT-A-BUG

Comment by Elena Stepanova [ 2016-08-31 ]

greenman,
I think specifics of replicate_wild_do_table needs to be documented in the KB, it's an important and non-obvious piece of information.

This option applies to tables, views, and triggers. It does not apply to stored procedures and functions, or events.

Maybe there are other things that should be added to.

By the way, it probably also applies to databases.

Comment by Ian Gilfillan [ 2016-09-07 ]

I have expanded on the replicate_wild_do_table documentation.

Comment by Igor Pashev [ 2016-09-07 ]

I just remembered, every time I read that part of docs ("This option applies to tables, views, and triggers. It does not apply to stored procedures and functions, or events") and look at "positive options" (replicate_do), I think "ok, I don't need them anyway"

Comment by Ian Gilfillan [ 2016-09-07 ]

Agree, that's why I rather worded it as "restriction does not apply" in our docs, another reminder of what it's actually doing!

Generated at Thu Feb 08 07:44:21 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.