diff options
author | Aleksey Midenkov <midenok@gmail.com> | 2019-05-11 17:27:23 +0300 |
---|---|---|
committer | Aleksey Midenkov <midenok@gmail.com> | 2019-10-10 00:20:34 +0300 |
commit | a92f3146d22cb3b290228c0e66eb1ea6c7b7c373 (patch) | |
tree | 012598feb31ab78c15501db3a17f7919945131d4 | |
parent | 647a38818a44012c22128e0e1cad96739aa8a5c2 (diff) | |
download | mariadb-git-a92f3146d22cb3b290228c0e66eb1ea6c7b7c373.tar.gz |
MDEV-19406 Assertion on updating view of join with versioned table
TABLE::mark_columns_needed_for_update(): use_all_columns() assigns
pointer of all_set into read_set and write_set, but this is not good
since all_set is changed later by
TABLE::mark_columns_used_by_index_no_reset().
Do column_bitmaps_signal() whenever we change read_set/write_set.
-rw-r--r-- | mysql-test/suite/versioning/r/update.result | 11 | ||||
-rw-r--r-- | mysql-test/suite/versioning/t/update.test | 15 | ||||
-rw-r--r-- | sql/log_event.cc | 2 | ||||
-rw-r--r-- | sql/sql_insert.cc | 1 | ||||
-rw-r--r-- | sql/table.cc | 32 |
5 files changed, 51 insertions, 10 deletions
diff --git a/mysql-test/suite/versioning/r/update.result b/mysql-test/suite/versioning/r/update.result index af263a63fae..eaa8549b38a 100644 --- a/mysql-test/suite/versioning/r/update.result +++ b/mysql-test/suite/versioning/r/update.result @@ -265,3 +265,14 @@ ERROR 40001: Deadlock found when trying to get lock; try restarting transaction disconnect con1; connection default; drop table t1; +# +# MDEV-19406 Assertion on updating view of join with versioned table +# +create or replace table t1 (pk int primary key, a date, b int, index(b)) engine=innodb with system versioning; +create or replace table t2 (c int); +create or replace view v as select * from t1 join t2; +insert into t1 (pk) values (1); +update t1 set a= '2012-12-12'; +update v set a= '2000-01-01' order by b limit 1; +drop view v; +drop table t1, t2; diff --git a/mysql-test/suite/versioning/t/update.test b/mysql-test/suite/versioning/t/update.test index a9550564a15..e41c7d15995 100644 --- a/mysql-test/suite/versioning/t/update.test +++ b/mysql-test/suite/versioning/t/update.test @@ -177,4 +177,19 @@ connection default; reap; drop table t1; +--echo # +--echo # MDEV-19406 Assertion on updating view of join with versioned table +--echo # +--disable_warnings +create or replace table t1 (pk int primary key, a date, b int, index(b)) engine=innodb with system versioning; +create or replace table t2 (c int); +create or replace view v as select * from t1 join t2; + +insert into t1 (pk) values (1); +update t1 set a= '2012-12-12'; +update v set a= '2000-01-01' order by b limit 1; # point of failure +drop view v; +drop table t1, t2; +--enable_warnings + source suite/versioning/common_finish.inc; diff --git a/sql/log_event.cc b/sql/log_event.cc index dc7203fc94f..78111e86f20 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -13450,6 +13450,7 @@ Rows_log_event::write_row(rpl_group_info *rgi, { ulong sec_part; bitmap_set_bit(table->read_set, table->vers_start_field()->field_index); + table->file->column_bitmaps_signal(); // Check whether a row came from unversioned table and fix vers fields. if (table->vers_start_field()->get_timestamp(&sec_part) == 0 && sec_part == 0) table->vers_update_fields(); @@ -14010,6 +14011,7 @@ int Rows_log_event::find_row(rpl_group_info *rgi) table->vers_end_field()->set_max(); m_vers_from_plain= true; } + table->file->column_bitmaps_signal(); } DBUG_PRINT("info",("looking for the following record")); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 7913ea2b2ec..dc8ee19b1e1 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1945,6 +1945,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) if (table->versioned(VERS_TRX_ID)) { bitmap_set_bit(table->write_set, table->vers_start_field()->field_index); + table->file->column_bitmaps_signal(); table->vers_start_field()->store(0, false); } if (unlikely(error= table->file->ha_update_row(table->record[1], diff --git a/sql/table.cc b/sql/table.cc index e2b2a5ec273..34523767eb4 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -6510,15 +6510,16 @@ void TABLE::mark_columns_needed_for_delete() } } - if (need_signal) - file->column_bitmaps_signal(); - if (s->versioned) { bitmap_set_bit(read_set, s->vers_start_field()->field_index); bitmap_set_bit(read_set, s->vers_end_field()->field_index); bitmap_set_bit(write_set, s->vers_end_field()->field_index); + need_signal= true; } + + if (need_signal) + file->column_bitmaps_signal(); } @@ -6531,7 +6532,7 @@ void TABLE::mark_columns_needed_for_delete() updated columns to be read. If this is no the case, we do like in the delete case and mark - if neeed, either the primary key column or all columns to be read. + if needed, either the primary key column or all columns to be read. (see mark_columns_needed_for_delete() for details) If the engine has HA_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will @@ -6595,14 +6596,18 @@ void TABLE::mark_columns_needed_for_update() need_signal= true; } } - /* - For System Versioning we have to read all columns since we will store - a copy of previous row with modified Sys_end column back to a table. - */ if (s->versioned) { - // We will copy old columns to a new row. - use_all_columns(); + /* + For System Versioning we have to read all columns since we store + a copy of previous row with modified row_end back to a table. + + Without write_set versioning.rpl,row is unstable until MDEV-16370 is + applied. + */ + bitmap_union(read_set, &s->all_set); + bitmap_union(write_set, &s->all_set); + need_signal= true; } if (check_constraints) { @@ -7991,7 +7996,10 @@ void TABLE::vers_update_fields() if (versioned(VERS_TIMESTAMP)) { if (!vers_write) + { + file->column_bitmaps_signal(); return; + } if (vers_start_field()->store_timestamp(in_use->query_start(), in_use->query_start_sec_part())) DBUG_ASSERT(0); @@ -7999,11 +8007,15 @@ void TABLE::vers_update_fields() else { if (!vers_write) + { + file->column_bitmaps_signal(); return; + } } vers_end_field()->set_max(); bitmap_set_bit(read_set, vers_end_field()->field_index); + file->column_bitmaps_signal(); } |