commit 92a573d41a239d60d3dd6fa6600e9cb9aa825226 Author: Sachin <sachin.setiya@mariadb.com> Date: Fri Sep 20 14:43:50 2019 +0530 MDEV-20574 Position of events reported by mysqlbinlog is wrong with encrypted binlogs, SHOW BINLOG EVENTS reports the correct one. Send Start_encryption_log_event as Ignorable_log_event to slave, So that mysqlbinlog can update its log_pos. diff --git a/mysql-test/suite/binlog_encryption/mysqlbinlog.result b/mysql-test/suite/binlog_encryption/mysqlbinlog.result index 71758f7d6e7..e97e0569571 100644 --- a/mysql-test/suite/binlog_encryption/mysqlbinlog.result +++ b/mysql-test/suite/binlog_encryption/mysqlbinlog.result @@ -4,3 +4,4 @@ INSERT INTO t1 VALUES (1),(2),(3); REPLACE INTO t1 VALUES (4); DROP TABLE t1; FLUSH LOGS; +FOUND 1 /Ignorable event type 164.*/ in binlog_enc.sql diff --git a/mysql-test/suite/binlog_encryption/mysqlbinlog.test b/mysql-test/suite/binlog_encryption/mysqlbinlog.test index b80388aaa45..108dbd8782f 100644 --- a/mysql-test/suite/binlog_encryption/mysqlbinlog.test +++ b/mysql-test/suite/binlog_encryption/mysqlbinlog.test @@ -17,5 +17,8 @@ let outfile=$MYSQLTEST_VARDIR/tmp/binlog_enc.sql; exec $MYSQL_BINLOG $local > $outfile; exec $MYSQL_BINLOG $local --force-read >> $outfile; exec $MYSQL_BINLOG $remote >> $outfile; +--let SEARCH_FILE= $outfile +--let SEARCH_PATTERN= Ignorable event type 164.* +--source include/search_pattern_in_file.inc remove_file $outfile; diff --git a/sql/log_event.cc b/sql/log_event.cc index 0e0d69b515c..66f1d6bc790 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2077,6 +2077,19 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len, alg != BINLOG_CHECKSUM_ALG_OFF)) event_len= event_len - BINLOG_CHECKSUM_LEN; + /* + Create an object of Ignorable_log_event for unrecognized sub-class. + So that SLAVE SQL THREAD will only update the position and continue. + We should look for this flag first instead of judging by event_type + Any event can be Ignorable_log_event if it has this flag on. + look into @note of Ignorable_log_event + */ + if (uint2korr(buf + FLAGS_OFFSET) & LOG_EVENT_IGNORABLE_F) + { + ev= new Ignorable_log_event(buf, fdle, + get_type_str((Log_event_type) event_type)); + goto exit; + } switch(event_type) { case QUERY_EVENT: ev = new Query_log_event(buf, event_len, fdle, QUERY_EVENT); @@ -2203,24 +2216,13 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len, ev = new Start_encryption_log_event(buf, event_len, fdle); break; default: - /* - Create an object of Ignorable_log_event for unrecognized sub-class. - So that SLAVE SQL THREAD will only update the position and continue. - */ - if (uint2korr(buf + FLAGS_OFFSET) & LOG_EVENT_IGNORABLE_F) - { - ev= new Ignorable_log_event(buf, fdle, - get_type_str((Log_event_type) event_type)); - } - else - { - DBUG_PRINT("error",("Unknown event code: %d", - (uchar) buf[EVENT_TYPE_OFFSET])); - ev= NULL; - break; - } + DBUG_PRINT("error",("Unknown event code: %d", + (uchar) buf[EVENT_TYPE_OFFSET])); + ev= NULL; + break; } } +exit: if (ev) { diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index edff750a9a3..137b7947598 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -2289,12 +2289,16 @@ static int send_format_descriptor_event(binlog_send_info *info, IO_CACHE *log, } /* - Read the following Start_encryption_log_event but don't send it to slave. - Slave doesn't need to know whether master's binlog is encrypted, - and if it'll want to encrypt its logs, it should generate its own - random nonce, not use the one from the master. + Read the following Start_encryption_log_event and send it to slave as + Ignorable_log_event. Although Slave doesn't need to know whether master's + binlog is encrypted but he needs to update slave log pos (for mysqlbinlog). + + If slave want to encrypt its logs, it should generate its own + random nonce, it should not use the one from the master. */ - packet->length(0); + /* reset transmit packet for the event read from binary log file */ + if (reset_transmit_packet(info, info->flags, &ev_offset, &info->errmsg)) + DBUG_RETURN(1); info->last_pos= linfo->pos; error= Log_event::read_log_event(log, packet, info->fdev, opt_master_verify_checksum @@ -2308,12 +2312,13 @@ static int send_format_descriptor_event(binlog_send_info *info, IO_CACHE *log, DBUG_RETURN(1); } - event_type= (Log_event_type)((uchar)(*packet)[LOG_EVENT_OFFSET]); + event_type= (Log_event_type)((uchar)(*packet)[LOG_EVENT_OFFSET + ev_offset]); if (event_type == START_ENCRYPTION_EVENT) { Start_encryption_log_event *sele= (Start_encryption_log_event *) - Log_event::read_log_event(packet->ptr(), packet->length(), &info->errmsg, - info->fdev, BINLOG_CHECKSUM_ALG_OFF); + Log_event::read_log_event(packet->ptr() + ev_offset, packet->length() + - ev_offset, &info->errmsg, info->fdev, + BINLOG_CHECKSUM_ALG_OFF); if (!sele) { info->error= ER_MASTER_FATAL_ERROR_READING_BINLOG; @@ -2327,6 +2332,14 @@ static int send_format_descriptor_event(binlog_send_info *info, IO_CACHE *log, delete sele; DBUG_RETURN(1); } + /* Make it Ignorable_log_event and send it */ + (*packet)[FLAGS_OFFSET+ev_offset] |= LOG_EVENT_IGNORABLE_F; + if (my_net_write(info->net, (uchar*) packet->ptr(), packet->length())) + { + info->errmsg= "Failed on my_net_write()"; + info->error= ER_UNKNOWN_ERROR; + DBUG_RETURN(1); + } delete sele; } else if (start_pos == BIN_LOG_HEADER_SIZE) -- Regards Sachin Setiya Software Engineer at MariaDB