Commit edeeaac4 authored by Eugene Kosov's avatar Eugene Kosov Committed by Sergei Golubchik

MDEV-14829 Assertion `0' failed in Protocol::end_statement upon concurrent UPDATE

vers_insert_history_row(): do not insert rows with zero or negative lifetime.

mysql_update(): properly handle error from vers_insert_history_row()
parent 75afaa7e
...@@ -6,6 +6,7 @@ innodb-cmpmem ...@@ -6,6 +6,7 @@ innodb-cmpmem
innodb-cmp-per-index innodb-cmp-per-index
innodb-trx innodb-trx
innodb-locks innodb-locks
innodb-lock-waits
innodb-buffer-pool-stats innodb-buffer-pool-stats
innodb-buffer-page innodb-buffer-page
innodb-buffer-page-lru innodb-buffer-page-lru
...@@ -24,6 +25,7 @@ innodb-cmpmem ...@@ -24,6 +25,7 @@ innodb-cmpmem
innodb-cmp-per-index innodb-cmp-per-index
innodb-trx innodb-trx
innodb-locks innodb-locks
innodb-lock-waits
innodb-metrics innodb-metrics
innodb-buffer-pool-stats innodb-buffer-pool-stats
innodb-buffer-page innodb-buffer-page
......
...@@ -371,3 +371,9 @@ create or replace table t1 (pk int primary key) with system versioning; ...@@ -371,3 +371,9 @@ create or replace table t1 (pk int primary key) with system versioning;
create trigger tr before insert on t1 for each row select 1 into @a; create trigger tr before insert on t1 for each row select 1 into @a;
insert into t1 values (1),(2); insert into t1 values (1),(2);
drop table t1; drop table t1;
create table t1 (pk int primary key, i int) with system versioning;
replace into t1 values (1,10),(1,100),(1,1000);
select pk,i,row_end > '2038-01-01' from t1 for system_time all;
pk i row_end > '2038-01-01'
1 1000 1
drop table t1;
...@@ -620,6 +620,20 @@ create or replace table t1 (a int primary key, b int) ...@@ -620,6 +620,20 @@ create or replace table t1 (a int primary key, b int)
with system versioning engine myisam; with system versioning engine myisam;
insert into t1 (a) values (1); insert into t1 (a) values (1);
replace t1 values (1,2),(1,3),(2,4); replace t1 values (1,2),(1,3),(2,4);
ERROR 23000: Duplicate entry '1-YYYY-MM-DD hh:mm:ss.uuuuuu' for key 'PRIMARY' create or replace table t1 (pk int, a char(3), b char(3), primary key(pk))
engine=innodb with system versioning;
insert into t1 (pk) values (1);
connect con1,localhost,root,,test;
start transaction;
select * from t1 for update;
pk a b
1 NULL NULL
connection default;
update t1 set b = 'foo';
connection con1;
update t1 set a = 'bar';
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
disconnect con1;
connection default;
drop database test; drop database test;
create database test; create database test;
...@@ -267,5 +267,12 @@ select *, row_start > @a, row_end > @a from t1 for system_time all; ...@@ -267,5 +267,12 @@ select *, row_start > @a, row_end > @a from t1 for system_time all;
create or replace table t1 (pk int primary key) with system versioning; create or replace table t1 (pk int primary key) with system versioning;
create trigger tr before insert on t1 for each row select 1 into @a; create trigger tr before insert on t1 for each row select 1 into @a;
insert into t1 values (1),(2); insert into t1 values (1),(2);
drop table t1;
#
# MDEV-14794 Limitations which the row end as a part of PK imposes due to CURRENT_TIMESTAMP behavior and otherwise
#
create table t1 (pk int primary key, i int) with system versioning;
replace into t1 values (1,10),(1,100),(1,1000);
select pk,i,row_end > '2038-01-01' from t1 for system_time all;
drop table t1; drop table t1;
-- source suite/versioning/common.inc --source suite/versioning/common.inc
delimiter ~~; delimiter ~~;
create procedure test_01( create procedure test_01(
...@@ -280,9 +280,30 @@ call verify_vtq; ...@@ -280,9 +280,30 @@ call verify_vtq;
create or replace table t1 (a int primary key, b int) create or replace table t1 (a int primary key, b int)
with system versioning engine myisam; with system versioning engine myisam;
insert into t1 (a) values (1); insert into t1 (a) values (1);
--replace_regex /'1-[- .\d:]+'/'1-YYYY-MM-DD hh:mm:ss.uuuuuu'/
--error ER_DUP_ENTRY
replace t1 values (1,2),(1,3),(2,4); replace t1 values (1,2),(1,3),(2,4);
#
# MDEV-14829 Assertion `0' failed in Protocol::end_statement upon concurrent UPDATE
#
create or replace table t1 (pk int, a char(3), b char(3), primary key(pk))
engine=innodb with system versioning;
insert into t1 (pk) values (1);
connect (con1,localhost,root,,test);
start transaction;
select * from t1 for update;
connection default;
send update t1 set b = 'foo';
connection con1;
let $wait_condition= select count(*) from information_schema.innodb_lock_waits;
source include/wait_condition.inc;
error ER_LOCK_DEADLOCK;
update t1 set a = 'bar';
disconnect con1;
connection default;
reap;
drop database test; drop database test;
create database test; create database test;
...@@ -1640,6 +1640,11 @@ int vers_insert_history_row(TABLE *table) ...@@ -1640,6 +1640,11 @@ int vers_insert_history_row(TABLE *table)
// Set Sys_end to now() // Set Sys_end to now()
table->vers_update_end(); table->vers_update_end();
Field *row_start= table->vers_start_field();
Field *row_end= table->vers_end_field();
if (row_start->cmp(row_start->ptr, row_end->ptr) >= 0)
return 0;
return table->file->ha_write_row(table->record[0]); return table->file->ha_write_row(table->record[0]);
} }
......
...@@ -948,25 +948,22 @@ int mysql_update(THD *thd, ...@@ -948,25 +948,22 @@ int mysql_update(THD *thd,
} }
else if (!error) else if (!error)
{ {
updated++;
if (has_vers_fields && table->versioned()) if (has_vers_fields && table->versioned())
{ {
if (table->versioned(VERS_TIMESTAMP)) if (table->versioned(VERS_TIMESTAMP))
{ {
store_record(table, record[2]); store_record(table, record[2]);
if ((error = vers_insert_history_row(table))) error= vers_insert_history_row(table);
{
restore_record(table, record[2]);
break;
}
restore_record(table, record[2]); restore_record(table, record[2]);
} }
updated_sys_ver++; if (!error)
updated_sys_ver++;
} }
if (!error)
updated++;
} }
else if (!ignore ||
table->file->is_fatal_error(error, HA_CHECK_ALL)) if (error && (!ignore || table->file->is_fatal_error(error, HA_CHECK_ALL)))
{ {
/* /*
If (ignore && error is ignorable) we don't have to If (ignore && error is ignorable) we don't have to
......
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