Commit d6e0d29f authored by Sergei Golubchik's avatar Sergei Golubchik

Fix write_set too

* in online ALTER it must include the complete new row,
  note that an UPDATE should set all extra columns to their
  default values, as if UPDATE was completely done before the ALTER.
* in rpl WRITE_ROWS_EVENT it must include all extra slave columns,
  but not existing columns unmarked in the m_cols (sequences do that)
* in rpl UPDATE/DELETE events it should follow m_cols_ai

also: default values must be updated for WRITE_ROWS_EVENT and
for UPDATE/DELETE in the online ALTER mode, see above.
Update the result file accordingly.

Extend bitmap_copy() to support arguments of different lengths
parent 4a00bc87
......@@ -62,12 +62,12 @@ a
connection slave;
select * from t1 order by a;
a z1 z2 z3
11 12 13 13
12 13 14 14
13 14 15 15
14 15 16 16
15 16 17 17
16 17 18 18
11 12 13 3
12 13 14 4
13 14 15 5
14 15 16 6
15 16 17 7
16 17 18 8
connection master;
update t1 set a = a-10;
select * from t1 order by a;
......@@ -147,7 +147,7 @@ a z1 z2 z3
4 5 6 6
5 6 7 7
6 7 8 8
13 14 15 15
13 14 15 5
connection master;
update t1 set a = a - 10 where a = 13;
select * from t1 order by a;
......
......@@ -576,14 +576,17 @@ uint bitmap_bits_set(const MY_BITMAP *map)
void bitmap_copy(MY_BITMAP *map, const MY_BITMAP *map2)
{
my_bitmap_map *to= map->bitmap, *from= map2->bitmap, *end;
uint len= no_words_in_map(map), len2 = no_words_in_map(map2);
DBUG_ASSERT(map->bitmap);
DBUG_ASSERT(map2->bitmap);
DBUG_ASSERT(map->n_bits == map2->n_bits);
end= map->last_word_ptr;
while (to <= end)
end= to + MY_MIN(len, len2 - 1);
while (to < end)
*to++ = *from++;
if (len2 <= len)
*to= (*from & ~map2->last_word_mask) | (*to & map2->last_word_mask);
}
......
......@@ -5061,6 +5061,9 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi)
if (m_width == table->s->fields && bitmap_is_set_all(&m_cols))
set_flags(COMPLETE_ROWS_F);
Rpl_table_data rpl_data{};
if (rgi) rgi->get_table_data(table, &rpl_data);
/*
Set tables write and read sets.
......@@ -5074,37 +5077,29 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi)
DBUG_PRINT_BITSET("debug", "Setting table's read_set from: %s", &m_cols);
bitmap_set_all(table->read_set);
if (get_general_type_code() == DELETE_ROWS_EVENT ||
get_general_type_code() == UPDATE_ROWS_EVENT)
bitmap_set_all(table->write_set);
table->rpl_write_set= table->write_set;
if (rpl_data.copy_fields)
/* always full rows, all bits set */;
else
if (get_general_type_code() == WRITE_ROWS_EVENT)
bitmap_copy(table->write_set, &m_cols); // for sequences
else
{
bitmap_intersect(table->read_set,&m_cols);
bitmap_intersect(table->write_set, &m_cols_ai);
table->mark_columns_per_binlog_row_image();
if (table->vfield)
table->mark_virtual_columns_for_write(0);
}
bitmap_set_all(table->write_set);
table->rpl_write_set= table->write_set;
/* WRITE ROWS EVENTS store the bitmap in m_cols instead of m_cols_ai */
MY_BITMAP *after_image= ((get_general_type_code() == UPDATE_ROWS_EVENT) ?
&m_cols_ai : &m_cols);
bitmap_intersect(table->write_set, after_image);
if (table->versioned())
{
bitmap_set_bit(table->write_set, table->s->vers.start_fieldno);
bitmap_set_bit(table->write_set, table->s->vers.end_fieldno);
}
/* Mark extra replica columns for write */
for (Field **field_ptr= table->field; *field_ptr; ++field_ptr)
{
Field *field= *field_ptr;
if (field->field_index >= m_cols.n_bits && field->stored_in_db())
bitmap_set_bit(table->write_set, field->field_index);
}
this->slave_exec_mode= slave_exec_mode_options; // fix the mode
// Do event specific preparations
......@@ -5118,8 +5113,6 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi)
extra columns on the slave. In that case, do not force
MODE_NO_AUTO_VALUE_ON_ZERO.
*/
Rpl_table_data rpl_data{};
if (rgi) rgi->get_table_data(table, &rpl_data);
sql_mode_t saved_sql_mode= thd->variables.sql_mode;
if (!is_auto_inc_in_extra_columns())
thd->variables.sql_mode= (rpl_data.copy_fields ? saved_sql_mode : 0)
......
......@@ -389,7 +389,8 @@ int unpack_row(rpl_group_info *rgi, TABLE *table, uint const colcnt,
}
}
if (table->default_field)
if (table->default_field && (rpl_data.is_online_alter() ||
LOG_EVENT_IS_WRITE_ROW(rgi->current_event->get_type_code())))
{
error= table->update_default_fields(table->in_use->lex->ignore);
if (unlikely(error))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment