Intermediary slave does not log master changes with binlog_rows_query_log_events
Affects | Status | Importance | Assigned to | Milestone | ||
---|---|---|---|---|---|---|
MySQL Server |
Unknown
|
Unknown
|
||||
Percona Server moved to https://jira.percona.com/projects/PS | Status tracked in 5.7 | |||||
5.5 |
Invalid
|
Undecided
|
Unassigned | |||
5.6 |
Fix Released
|
High
|
Vlad Lesin | |||
5.7 |
Fix Released
|
High
|
Vlad Lesin |
Bug Description
Description:
Common scenario to reduce IO load on master is to create intermediary slave which uses BLACKHOLE storage engine, specify option log-slave-updates for it and replicate from this intermediary slave to multiple slaves with data.
However, if configuration file on master has option binlog_
According to the user manual at https:/
How to repeat:
Setup replication chain: A -> B -> C
Create InnoDB table on A.
Convert InnoDB table to Blackhole on B.
Same table on C continue using InnoDB storage engine.
Now modify content on A. INSERT will be recorded correctly, UPDATE and DELETE will be recorded on master, but not on B even if it has option log-slave-updates
I will also attach test case for MTR.
tags: | added: upstream |
Let's consider the following backtrace in 5.7:
#0 ha_blackhole: :update_ row (this=0x7fff9c0 0eec0, old_data= 0x7fff9c010040 "\371\002", new_data= 0x7fff9c010030 "\371\002") blackhole/ ha_blackhole. cc:121 :ha_update_ row (this=0x7fff9c0 0eec0, old_data= 0x7fff9c010040 "\371\002", new_data= 0x7fff9c010030 "\371\002") cc:8479 rows_log_ event:: do_exec_ row (this=0x7fff9c0 1deb0, rli=0x3915b80) event.cc: 12974 event:: do_apply_ row (this=0x7fff9c0 1deb0, rli=0x3915b80) at ./sql/log_ event.cc: 10048 event:: do_index_ scan_and_ update (this=0x7fff9c0 1deb0, rli=0x3915b80) event.cc: 10442 event:: do_apply_ event (this=0x7fff9c0 1deb0, rli=0x3915b80) at ./sql/log_ event.cc: 11232 :apply_ event (this=0x7fff9c0 1deb0, rli=0x3915b80) at ./sql/log_ event.cc: 3447 and_update_ pos (ptr_ev= 0x7ffff10ff8a0, thd=0x7fff9c000950, rli=0x3915b80) slave.cc: 4762 log_event (thd=0x7fff9c00 0950, rli=0x3915b80) at ./sql/rpl_ slave.cc: 5277 slave.cc: 7488 68a0) at ./storage/ perfschema/ pfs.cc: 2188 0700) at pthread_ create. c:333 unix/sysv/ linux/x86_ 64/clone. S:109
at ./storage/
#1 0x0000000000fd8372 in handler:
at ./sql/handler.
#2 0x00000000018ee9f3 in Update_
at ./sql/log_
#3 0x00000000018e5f43 in Rows_log_
#4 0x00000000018e6fe0 in Rows_log_
at ./sql/log_
#5 0x00000000018e91a1 in Rows_log_
#6 0x00000000018cfe7c in Log_event:
#7 0x000000000194be2b in apply_event_
at ./sql/rpl_
#8 0x000000000194d5f3 in exec_relay_
#9 0x00000000019549df in handle_slave_sql (arg=0x38bf6f0) at ./sql/rpl_
#10 0x0000000001e7e80d in pfs_spawn_thread (arg=0x7fffa007
#11 0x00007ffff6f5e6ba in start_thread (arg=0x7ffff110
#12 0x00007ffff63f33dd in clone () at ../sysdeps/
and ha_blackhole: :update_ row():
int ha_blackhole: :update_ row(const uchar *old_data, uchar *new_data) ENTER(" ha_blackhole: :update_ row"); applier( thd) && thd->query().str == NULL) RETURN( HA_ERR_ WRONG_COMMAND) ;
{
DBUG_
THD *thd= ha_thd();
if (is_slave_
DBUG_RETURN(0);
DBUG_
}
So in the case if this function is invoked from slave thread and it's query string is empty, then it's supposed the function finishes successfully, otherwise some error is returned. The same logic exists in some other blackhole engine functions.
If "binlog_ rows_query_ log_events = 1" binary log contains events with queries. The queries are ignored, but during "Rows_query_ log_event" event execution (see Rows_query_ log_event: :do_apply_ event() ) thread query string is filled with the query from the event. And when then Update_ rows_log_ event:: do_exec_ row() is executed, sql thread has query in thd->m_ query_string, and this condition:
is_slave_ applier( thd) && thd->query().str == NULL
becomes false, what leads to errors during execution of blackhole engine functions such as ha_blackhole: :update_ row(). Such errors are output to error log and sql thread stops, as a result is't binary log is not filling.
The question is what does this "is_slave_ applier( thd) && thd->query().str == NULL" condition mean? I suppose the condition means that binlog format is "row".
So would propose the following fix: to replace "thd->query().str == NULL" with "thd->variables .binlog_ format == BINLOG_FORMAT_ROW".