Commit 498a96a4 authored by Aleksey Midenkov's avatar Aleksey Midenkov

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.
parent 57cab7cd
......@@ -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;
......@@ -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;
......@@ -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()
......
......@@ -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++)
......
......@@ -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 */
......
......@@ -1536,8 +1536,15 @@ struct TABLE
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 @@ struct TABLE
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();
......
......@@ -6183,7 +6183,7 @@ int maria_recreate_table(HA_CHECK *param, MARIA_HA **org_info, char *filename)
}
/* 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)
{
......
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