summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Midenkov <midenok@gmail.com>2019-12-02 11:48:37 +0300
committerAleksey Midenkov <midenok@gmail.com>2019-12-02 11:48:37 +0300
commit498a96a4789e58549ce87b5843e804e055ab327f (patch)
tree36da2d9f9c8180fbad55e0413c70f8c0702b68f0
parent57cab7cd5114d3ef47203118cddd3ad0a22f2861 (diff)
downloadmariadb-git-498a96a4789e58549ce87b5843e804e055ab327f.tar.gz
MDEV-20441 ER_CRASHED_ON_USAGE upon update on versioned Aria table
Turn read cache off for update and multi-update for versioned table. no_cache is reinited on each TABLE open because it is applicable for specific algorithms. As a side fix vers_insert_history_row() honors vers_write setting. Aria with row_format=fixed uses IO_CACHE of type READ_CACHE for sequential read in update loop. When history row is inserted inside this loop the cache misses it and fails with error. TODO: Currently maria_extra() does not support SEQ_READ_APPEND. Probably it might be possible to use this type of cache.
-rw-r--r--mysql-test/suite/versioning/r/update.result9
-rw-r--r--mysql-test/suite/versioning/t/update.test12
-rw-r--r--sql/sql_insert.cc2
-rw-r--r--sql/sql_update.cc15
-rw-r--r--sql/table.cc1
-rw-r--r--sql/table.h11
-rw-r--r--storage/maria/ma_check.c2
7 files changed, 43 insertions, 9 deletions
diff --git a/mysql-test/suite/versioning/r/update.result b/mysql-test/suite/versioning/r/update.result
index eaa8549b38a..08b105e952b 100644
--- a/mysql-test/suite/versioning/r/update.result
+++ b/mysql-test/suite/versioning/r/update.result
@@ -276,3 +276,12 @@ 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;
+#
+# MDEV-20441 ER_CRASHED_ON_USAGE upon update on versioned Aria table
+#
+create or replace table t1 (a varchar(8))
+engine=aria row_format=fixed
+with system versioning;
+insert into t1 (a) values ('foo');
+update t1 set a = 'bar';
+drop table t1;
diff --git a/mysql-test/suite/versioning/t/update.test b/mysql-test/suite/versioning/t/update.test
index e41c7d15995..148cbbdc707 100644
--- a/mysql-test/suite/versioning/t/update.test
+++ b/mysql-test/suite/versioning/t/update.test
@@ -157,7 +157,6 @@ replace t1 values (1,2),(1,3),(2,4);
--echo #
--echo # MDEV-14829 Assertion `0' failed in Protocol::end_statement upon concurrent UPDATE
--echo #
-
create or replace table t1 (pk int, a char(3), b char(3), primary key(pk))
engine=innodb with system versioning;
@@ -192,4 +191,15 @@ drop view v;
drop table t1, t2;
--enable_warnings
+--echo #
+--echo # MDEV-20441 ER_CRASHED_ON_USAGE upon update on versioned Aria table
+--echo #
+create or replace table t1 (a varchar(8))
+engine=aria row_format=fixed
+with system versioning;
+
+insert into t1 (a) values ('foo');
+update t1 set a = 'bar';
+drop table t1;
+
source suite/versioning/common_finish.inc;
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 334b6b2d667..e747b645e9d 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1646,6 +1646,8 @@ static int last_uniq_key(TABLE *table,uint keynr)
int vers_insert_history_row(TABLE *table)
{
DBUG_ASSERT(table->versioned(VERS_TIMESTAMP));
+ if (!table->vers_write)
+ return 0;
restore_record(table,record[1]);
// Set Sys_end to now()
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 1e5440ee4fe..d3b771acdad 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -184,10 +184,10 @@ static bool check_fields(THD *thd, List<Item> &items, bool update_view)
return FALSE;
}
-static bool check_has_vers_fields(TABLE *table, List<Item> &items)
+bool TABLE::vers_check_update(List<Item> &items)
{
List_iterator<Item> it(items);
- if (!table->versioned())
+ if (!versioned_write())
return false;
while (Item *item= it++)
@@ -195,8 +195,11 @@ static bool check_has_vers_fields(TABLE *table, List<Item> &items)
if (Item_field *item_field= item->field_for_view_update())
{
Field *field= item_field->field;
- if (field->table == table && !field->vers_update_unversioned())
+ if (field->table == this && !field->vers_update_unversioned())
+ {
+ no_cache= true;
return true;
+ }
}
}
return false;
@@ -415,7 +418,7 @@ int mysql_update(THD *thd,
{
DBUG_RETURN(1);
}
- bool has_vers_fields= check_has_vers_fields(table, fields);
+ bool has_vers_fields= table->vers_check_update(fields);
if (check_key_in_view(thd, table_list))
{
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias.str, "UPDATE");
@@ -2133,7 +2136,7 @@ multi_update::initialize_tables(JOIN *join)
if (safe_update_on_fly(thd, join->join_tab, table_ref, all_tables))
{
table_to_update= table; // Update table on the fly
- has_vers_fields= check_has_vers_fields(table, *fields);
+ has_vers_fields= table->vers_check_update(*fields);
continue;
}
}
@@ -2609,7 +2612,7 @@ int multi_update::do_updates()
if (table->vfield)
empty_record(table);
- has_vers_fields= check_has_vers_fields(table, *fields);
+ has_vers_fields= table->vers_check_update(*fields);
check_opt_it.rewind();
while(TABLE *tbl= check_opt_it++)
diff --git a/sql/table.cc b/sql/table.cc
index e008e6a3ded..291418f55fe 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -4688,6 +4688,7 @@ void TABLE::init(THD *thd, TABLE_LIST *tl)
cond_selectivity_sampling_explain= NULL;
vers_write= s->versioned;
quick_condition_rows=0;
+ no_cache= false;
initialize_quick_structures();
#ifdef HAVE_REPLICATION
/* used in RBR Triggers */
diff --git a/sql/table.h b/sql/table.h
index 1dda70ae0da..ca5565250de 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -1536,9 +1536,16 @@ public:
return s->versioned == type;
}
- bool versioned_write(vers_sys_type_t type= VERS_UNDEFINED) const
+ bool versioned_write() const
{
DBUG_ASSERT(versioned() || !vers_write);
+ return versioned() ? vers_write : false;
+ }
+
+ bool versioned_write(vers_sys_type_t type) const
+ {
+ DBUG_ASSERT(type);
+ DBUG_ASSERT(versioned() || !vers_write);
return versioned(type) ? vers_write : false;
}
@@ -1557,6 +1564,8 @@ public:
ulonglong vers_start_id() const;
ulonglong vers_end_id() const;
+ bool vers_check_update(List<Item> &items);
+
int delete_row();
void vers_update_fields();
void vers_update_end();
diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c
index eadac5b04eb..101c33b7802 100644
--- a/storage/maria/ma_check.c
+++ b/storage/maria/ma_check.c
@@ -6183,7 +6183,7 @@ end:
}
- /* write suffix to data file if neaded */
+/* Write suffix to data file if needed */
int maria_write_data_suffix(MARIA_SORT_INFO *sort_info, my_bool fix_datafile)
{