summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2022-07-01 12:29:16 +0200
committerNikita Malyavin <nikitamalyavin@gmail.com>2022-10-17 15:24:45 +0300
commit71e1a13b3708e147056a785bf87f5b8cb9c98af4 (patch)
tree0513bf71e7319748bc060210a72f00a390563cb8
parent0fcaf0018a2c74db622c957638255a0ab1031194 (diff)
downloadmariadb-git-71e1a13b3708e147056a785bf87f5b8cb9c98af4.tar.gz
MDEV-28967 Assertion `marked_for_write_or_computed()' failed in Field_new_decimal::store_value / online_alter_read_from_binlog`
in the catch-up phase of the online alter we apply row events, they're unpacked into `from->record[0]` and then converted to `to->record[0]`. This needs all fields of `from` to be in the `write_set`. Although practically `Field::unpack()` does not assert the `write_set`, and `Field::reset()` - used when a field value is not present in the after-image - also doesn't assert the `write_set` for many types, `Field_new_decimal::reset()` does.
-rw-r--r--mysql-test/main/alter_table_online_debug.result19
-rw-r--r--mysql-test/main/alter_table_online_debug.test28
-rw-r--r--sql/sql_table.cc2
3 files changed, 49 insertions, 0 deletions
diff --git a/mysql-test/main/alter_table_online_debug.result b/mysql-test/main/alter_table_online_debug.result
index e9b6199ba5f..019e70eec10 100644
--- a/mysql-test/main/alter_table_online_debug.result
+++ b/mysql-test/main/alter_table_online_debug.result
@@ -608,3 +608,22 @@ NULL
connection default;
drop table t1;
set debug_sync= reset;
+#
+# MDEV-28967 Assertion `marked_for_write_or_computed()' failed in Field_new_decimal::store_value / online_alter_read_from_binlog`
+#
+create table t1 (a decimal(8,2), b varchar(8));
+insert into t1 (b) values ('x');
+set debug_sync= 'now wait_for downgraded';
+connection con2;
+set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for goforit';
+alter table t1 force, algorithm=copy, lock=none;
+connection default;
+insert t1 (b) values ('k');
+insert t1 (b) values ('m');
+set debug_sync= 'now signal goforit';
+connection con2;
+drop table t1;
+set debug_sync= reset;
+#
+# End of 10.10 tests
+#
diff --git a/mysql-test/main/alter_table_online_debug.test b/mysql-test/main/alter_table_online_debug.test
index 7ab4031f77c..d3a9a581ab3 100644
--- a/mysql-test/main/alter_table_online_debug.test
+++ b/mysql-test/main/alter_table_online_debug.test
@@ -742,3 +742,31 @@ select * from t1;
--connection default
drop table t1;
set debug_sync= reset;
+
+--echo #
+--echo # MDEV-28967 Assertion `marked_for_write_or_computed()' failed in Field_new_decimal::store_value / online_alter_read_from_binlog`
+--echo #
+create table t1 (a decimal(8,2), b varchar(8));
+insert into t1 (b) values ('x');
+
+--send set debug_sync= 'now wait_for downgraded'
+
+--connection con2
+set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for goforit';
+--send alter table t1 force, algorithm=copy, lock=none
+
+--connection default
+--reap
+insert t1 (b) values ('k');
+insert t1 (b) values ('m');
+set debug_sync= 'now signal goforit';
+
+--connection con2
+--reap
+
+drop table t1;
+set debug_sync= reset;
+
+--echo #
+--echo # End of 10.10 tests
+--echo #
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 4709206bca4..f852af4a7cc 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -12386,6 +12386,8 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
rli.relay_log.description_event_for_exec=
new Format_description_log_event(4);
+ // We'll be filling from->record[0] from row events
+ bitmap_set_all(from->write_set);
// We restore bitmaps, because update event is going to mess up with them.
to->default_column_bitmaps();