1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00

MDEV-14605 Changes to "ON UPDATE CURRENT_TIMESTAMP" fields are not

always logged properly with binlog_row_image=MINIMAL

There are two issues fixed in this commit.
The first is an observation of a multi-table UPDATE binlogged
in row-format in binlog_row_image=MINIMAL mode. While the UPDATE aims
at a table with an ON-UPDATE attribute its binlog after-image misses
to record also installed default value.
The reason for that turns out missed marking of default-capable fields
in TABLE::write_set.

This is fixed to mark such fields similarly to 10.2's MDEV-10134 patch (db7edfed17)
that introduced it. The marking follows up 93d1e5ce0b841bed's idea
to exploit TABLE:rpl_write_set introduced there though,
and thus does not mess (in 10.1) with the actual MDEV-10134 agenda.
The patch makes formerly arg-less TABLE::mark_default_fields_for_write()
to accept an argument which would be TABLE:rpl_write_set.

The 2nd issue is extra columns in in binlog_row_image=MINIMAL before-image
while merely a packed primary key is enough. The test main.mysqlbinlog_row_minimal
always had a wrong result recorded.
This is fixed to invoke a function that intended for read_set
possible filtering and which is called (supposed to) in all type of MDL, UPDATE
including; the test results have gotten corrected.

At *merging* from 10.1->10.2 the 1st "main" part of the patch is unnecessary
since the bug is not observed in 10.2, so only hunks from

  sql/sql_class.cc

are required.
This commit is contained in:
Andrei Elkin
2019-01-20 19:00:16 +02:00
parent 17c75bd272
commit f9ac7032cb
5 changed files with 155 additions and 29 deletions

View File

@ -6390,6 +6390,22 @@ int THD::binlog_update_row(TABLE* table, bool is_trans,
DBUG_ASSERT(is_current_stmt_binlog_format_row() &&
((WSREP(this) && wsrep_emulate_bin_log) || mysql_bin_log.is_open()));
/**
Save a reference to the original read bitmaps
We will need this to restore the bitmaps at the end as
binlog_prepare_row_images() may change table->read_set.
table->read_set is used by pack_row and deep in
binlog_prepare_pending_events().
*/
MY_BITMAP *old_read_set= table->read_set;
/**
This will remove spurious fields required during execution but
not needed for binlogging. This is done according to the:
binlog-row-image option.
*/
binlog_prepare_row_images(table);
size_t const before_maxlen = max_row_length(table, before_record);
size_t const after_maxlen = max_row_length(table, after_record);
@ -6401,9 +6417,9 @@ int THD::binlog_update_row(TABLE* table, bool is_trans,
uchar *after_row= row_data.slot(1);
size_t const before_size= pack_row(table, table->read_set, before_row,
before_record);
before_record);
size_t const after_size= pack_row(table, table->rpl_write_set, after_row,
after_record);
after_record);
/* Ensure that all events in a GTID group are in the same cache */
if (variables.option_bits & OPTION_GTID_BEGIN)
@ -6431,6 +6447,9 @@ int THD::binlog_update_row(TABLE* table, bool is_trans,
int error= ev->add_row_data(before_row, before_size) ||
ev->add_row_data(after_row, after_size);
/* restore read set for the rest of execution */
table->column_bitmaps_set_no_signal(old_read_set,
table->write_set);
return error;
}