diff --git a/mysql-test/main/alter_table_online_debug.result b/mysql-test/main/alter_table_online_debug.result index c576714892f..89e34a90490 100644 --- a/mysql-test/main/alter_table_online_debug.result +++ b/mysql-test/main/alter_table_online_debug.result @@ -1346,6 +1346,21 @@ c x 2 123456 3 123456 drop table t; +# Test that all the fields are unpacked. +create table t (a int, b int) engine=innodb; +insert into t values (NULL, 123), (NULL, 456); +set debug_sync= "alter_table_copy_end signal copy wait_for goon"; +alter table t drop a, add primary key(b), algorithm=copy; +connection con1; +set debug_sync= "now wait_for copy"; +update t set b = b + 100; +set debug_sync= "now signal goon"; +connection default; +select * from t; +b +223 +556 +drop table t; set debug_sync= reset; disconnect con1; disconnect con2; diff --git a/mysql-test/main/alter_table_online_debug.test b/mysql-test/main/alter_table_online_debug.test index 513770666f2..a3b97ce698d 100644 --- a/mysql-test/main/alter_table_online_debug.test +++ b/mysql-test/main/alter_table_online_debug.test @@ -1527,6 +1527,24 @@ set debug_sync= "now signal goon"; select * from t; drop table t; +--echo # Test that all the fields are unpacked. +create table t (a int, b int) engine=innodb; +insert into t values (NULL, 123), (NULL, 456); + +set debug_sync= "alter_table_copy_end signal copy wait_for goon"; +send alter table t drop a, add primary key(b), algorithm=copy; +--connection con1 +set debug_sync= "now wait_for copy"; +update t set b = b + 100; + +set debug_sync= "now signal goon"; + +--connection default +--reap +select * from t; + +drop table t; + set debug_sync= reset; --disconnect con1 diff --git a/sql/rpl_record.cc b/sql/rpl_record.cc index 908d2c39d97..602b7755dcb 100644 --- a/sql/rpl_record.cc +++ b/sql/rpl_record.cc @@ -228,24 +228,28 @@ int unpack_row(const rpl_group_info *rgi, TABLE *table, uint const colcnt, const TABLE *conv_table= rpl_data.conv_table; DBUG_PRINT("debug", ("Table data: tabldef: %p, conv_table: %p", tabledef, conv_table)); - + bool is_online_alter= rpl_data.is_online_alter(); DBUG_ASSERT(rgi); - for (field_ptr= begin_ptr; field_ptr < end_ptr && *field_ptr; ++field_ptr) + for (field_ptr= begin_ptr; field_ptr < end_ptr + /* In Online Alter conv_table can be wider than + original table, but we need to unpack it all. */ + && (*field_ptr || is_online_alter); + ++field_ptr) { /* If there is a conversion table, we pick up the field pointer to the conversion table. If the conversion table or the field pointer is NULL, no conversions are necessary. */ - Field *conv_field= - conv_table ? conv_table->field[field_ptr - begin_ptr] : NULL; - Field *const f= - conv_field ? conv_field : *field_ptr; - DBUG_PRINT("debug", ("Conversion %srequired for field '%s' (#%ld)", + Field *conv_field= conv_table ? conv_table->field[i] : NULL; + Field *const f= conv_field ? conv_field : *field_ptr; +#ifdef DBUG_TRACE + Field *dbg= is_online_alter ? f : *field_ptr; +#endif + DBUG_PRINT("debug", ("Conversion %srequired for field '%s' (#%u)", conv_field ? "" : "not ", - (*field_ptr)->field_name.str, - (long) (field_ptr - begin_ptr))); + dbg->field_name.str, i)); DBUG_ASSERT(f != NULL); /* @@ -254,7 +258,7 @@ int unpack_row(const rpl_group_info *rgi, TABLE *table, uint const colcnt, */ if (bitmap_is_set(cols, (uint)(field_ptr - begin_ptr))) { - if (!rpl_data.is_online_alter()) + if (!is_online_alter) (*field_ptr)->set_has_explicit_value(); if ((null_mask & 0xFF) == 0) { @@ -351,7 +355,7 @@ int unpack_row(const rpl_group_info *rgi, TABLE *table, uint const colcnt, conv_field->sql_type(source_type); conv_field->val_str(&value_string); DBUG_PRINT("debug", ("Copying field '%s' of type '%s' with value '%s'", - (*field_ptr)->field_name.str, + dbg->field_name.str, source_type.c_ptr_safe(), value_string.c_ptr_safe())); #endif copy.set(*field_ptr, f, TRUE); @@ -362,7 +366,7 @@ int unpack_row(const rpl_group_info *rgi, TABLE *table, uint const colcnt, (*field_ptr)->sql_type(target_type); (*field_ptr)->val_str(&value_string); DBUG_PRINT("debug", ("Value of field '%s' of type '%s' is now '%s'", - (*field_ptr)->field_name.str, + dbg->field_name.str, target_type.c_ptr_safe(), value_string.c_ptr_safe())); #endif } @@ -442,7 +446,7 @@ int unpack_row(const rpl_group_info *rgi, TABLE *table, uint const colcnt, *current_row_end = pack_ptr; if (master_reclength) { - if (*field_ptr) + if (!is_online_alter && *field_ptr) *master_reclength = (ulong)((*field_ptr)->ptr - table->record[0]); else *master_reclength = table->s->reclength; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 3a9a8dbb6d4..80a4f7fd871 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -12052,6 +12052,8 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, #ifdef HAVE_REPLICATION if (online && error < 0) { + MEM_UNDEFINED(from->record[0], from->s->rec_buff_length * 2); + MEM_UNDEFINED(to->record[0], to->s->rec_buff_length * 2); thd_progress_next_stage(thd); Table_map_log_event table_event(thd, from, from->s->table_map_id, from->file->has_transactions());