Commit d846b55d authored by Nikita Malyavin's avatar Nikita Malyavin

MDEV-17891 Assertion failure upon attempt to replace into a full table

Problem: Assertion `transactional_table || !changed ||
thd->transaction.stmt.modified_non_trans_table' failed due REPLACE into a
versioned table.

It is not specific to system versioning/pertitioning/heap, but this
combination makes it much easier to reproduce.

The thing is to make first ha_update_row call succeed to make
info->deleted != 0. And then make REPLACE fail by any reason.

In this scenario we overflow versioned partition, so next ha_update_row
succeeds, but corresponding ha_write_row fails to insert history record.

Fix: modified_non_trans_table is set in one missed place
parent 9a645dae
...@@ -530,6 +530,7 @@ set timestamp=1523466002.799571; ...@@ -530,6 +530,7 @@ set timestamp=1523466002.799571;
insert into t1 values (11),(12); insert into t1 values (11),(12);
set timestamp=1523466004.169435; set timestamp=1523466004.169435;
delete from t1 where pk in (11, 12); delete from t1 where pk in (11, 12);
set timestamp= default;
# #
# MDEV-18136 Server crashes in Item_func_dyncol_create::prepare_arguments # MDEV-18136 Server crashes in Item_func_dyncol_create::prepare_arguments
# #
...@@ -682,6 +683,41 @@ create table t1 (a int) with system versioning partition by system_time ...@@ -682,6 +683,41 @@ create table t1 (a int) with system versioning partition by system_time
(partition p1 history, partition pn current); (partition p1 history, partition pn current);
alter table t1 add partition (partition p2); alter table t1 add partition (partition p2);
ERROR HY000: Wrong partitioning type, expected type: `SYSTEM_TIME` ERROR HY000: Wrong partitioning type, expected type: `SYSTEM_TIME`
# MDEV-17891 Assertion failures in select_insert::abort_result_set and
# mysql_load upon attempt to replace into a full table
set @@max_heap_table_size= 1024*1024;
create or replace table t1 (
pk integer auto_increment,
primary key (pk),
f varchar(45000)
) with system versioning engine=memory
partition by system_time interval 1 year (partition p1 history,
partition pn current);
# fill the table until full
insert into t1 () values (),(),(),(),(),(),(),(),(),(),(),(),(),(),(),();
insert into t1 (f) select f from t1;
ERROR HY000: The table 't1' is full
# leave space for exactly one record in current partition
delete from t1 where pk = 1;
# copy all data into history partition
replace into t1 select * from t1;
replace into t1 select * from t1;
ERROR HY000: The table 't1' is full
create or replace table t1 (
pk integer auto_increment,
primary key (pk),
f varchar(45000)
) with system versioning engine=memory
partition by system_time interval 1 year (partition p1 history,
partition pn current);
insert into t1 () values (),(),(),(),(),(),(),(),(),(),(),(),(),(),(),();
select * from t1 into outfile 'load.data';
load data infile 'load.data' replace into table t1;
load data infile 'load.data' replace into table t1;
ERROR HY000: The table 't1' is full
load data infile 'load.data' replace into table t1;
ERROR HY000: The table 't1' is full
set @@max_heap_table_size= 1048576;
drop table t1; drop table t1;
# #
# MDEV-22178 Assertion `info->alias.str' failed in partition_info::check_partition_info instead of ER_VERS_WRONG_PARTS # MDEV-22178 Assertion `info->alias.str' failed in partition_info::check_partition_info instead of ER_VERS_WRONG_PARTS
......
...@@ -48,3 +48,16 @@ INSERT INTO t1 () VALUES (),(),(),(),(),(); ...@@ -48,3 +48,16 @@ INSERT INTO t1 () VALUES (),(),(),(),(),();
UPDATE IGNORE t1 SET f = 1; UPDATE IGNORE t1 SET f = 1;
REPLACE t1 SELECT * FROM t1; REPLACE t1 SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
# MDEV-22540 ER_DUP_ENTRY upon REPLACE or Assertion failed
set timestamp=1589245268.41934;
create table t1 (a int primary key) with system versioning;
insert into t1 values (1),(2);
connect con1,localhost,root,,test;
set timestamp=1589245268.52093;
replace into t1 values (1),(2);
connection default;
replace into t1 values (1),(2);
connection con1;
replace into t1 values (1),(2);
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
drop table t1;
...@@ -482,6 +482,7 @@ set timestamp=1523466002.799571; ...@@ -482,6 +482,7 @@ set timestamp=1523466002.799571;
insert into t1 values (11),(12); insert into t1 values (11),(12);
set timestamp=1523466004.169435; set timestamp=1523466004.169435;
delete from t1 where pk in (11, 12); delete from t1 where pk in (11, 12);
set timestamp= default;
--echo # --echo #
--echo # MDEV-18136 Server crashes in Item_func_dyncol_create::prepare_arguments --echo # MDEV-18136 Server crashes in Item_func_dyncol_create::prepare_arguments
...@@ -649,7 +650,51 @@ create table t1 (a int) with system versioning partition by system_time ...@@ -649,7 +650,51 @@ create table t1 (a int) with system versioning partition by system_time
--error ER_PARTITION_WRONG_TYPE --error ER_PARTITION_WRONG_TYPE
alter table t1 add partition (partition p2); alter table t1 add partition (partition p2);
--echo # MDEV-17891 Assertion failures in select_insert::abort_result_set and
--echo # mysql_load upon attempt to replace into a full table
--let $max_heap_table_size_orig= `select @@max_heap_table_size;`
set @@max_heap_table_size= 1024*1024;
create or replace table t1 (
pk integer auto_increment,
primary key (pk),
f varchar(45000)
) with system versioning engine=memory
partition by system_time interval 1 year (partition p1 history,
partition pn current);
--echo # fill the table until full
insert into t1 () values (),(),(),(),(),(),(),(),(),(),(),(),(),(),(),();
--error ER_RECORD_FILE_FULL
insert into t1 (f) select f from t1;
--echo # leave space for exactly one record in current partition
delete from t1 where pk = 1;
--echo # copy all data into history partition
replace into t1 select * from t1;
--error ER_RECORD_FILE_FULL
replace into t1 select * from t1;
create or replace table t1 (
pk integer auto_increment,
primary key (pk),
f varchar(45000)
) with system versioning engine=memory
partition by system_time interval 1 year (partition p1 history,
partition pn current);
insert into t1 () values (),(),(),(),(),(),(),(),(),(),(),(),(),(),(),();
select * from t1 into outfile 'load.data';
load data infile 'load.data' replace into table t1;
--error ER_RECORD_FILE_FULL
load data infile 'load.data' replace into table t1;
--error ER_RECORD_FILE_FULL
load data infile 'load.data' replace into table t1;
# Cleanup # Cleanup
--let $datadir= `select @@datadir`
--remove_file $datadir/test/load.data
eval set @@max_heap_table_size= $max_heap_table_size_orig;
drop table t1; drop table t1;
--echo # --echo #
......
...@@ -59,4 +59,22 @@ UPDATE IGNORE t1 SET f = 1; ...@@ -59,4 +59,22 @@ UPDATE IGNORE t1 SET f = 1;
REPLACE t1 SELECT * FROM t1; REPLACE t1 SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--echo # MDEV-22540 ER_DUP_ENTRY upon REPLACE or Assertion failed
set timestamp=1589245268.41934;
create table t1 (a int primary key) with system versioning;
insert into t1 values (1),(2);
--connect (con1,localhost,root,,test)
set timestamp=1589245268.52093;
replace into t1 values (1),(2);
--connection default
replace into t1 values (1),(2);
--connection con1
--error ER_DUP_ENTRY
replace into t1 values (1),(2);
drop table t1;
--source suite/versioning/common_finish.inc --source suite/versioning/common_finish.inc
...@@ -1959,6 +1959,8 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) ...@@ -1959,6 +1959,8 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
if (likely(!error)) if (likely(!error))
{ {
info->deleted++; info->deleted++;
if (!table->file->has_transactions())
thd->transaction.stmt.modified_non_trans_table= TRUE;
if (table->versioned(VERS_TIMESTAMP)) if (table->versioned(VERS_TIMESTAMP))
{ {
store_record(table, record[2]); store_record(table, record[2]);
......
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