Skip to content

Commit edeeaac

Browse files
kevgsvuvova
authored andcommitted
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()
1 parent 75afaa7 commit edeeaac

File tree

7 files changed

+66
-14
lines changed

7 files changed

+66
-14
lines changed

mysql-test/include/have_innodb.combinations

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ innodb-cmpmem
66
innodb-cmp-per-index
77
innodb-trx
88
innodb-locks
9+
innodb-lock-waits
910
innodb-buffer-pool-stats
1011
innodb-buffer-page
1112
innodb-buffer-page-lru
@@ -24,6 +25,7 @@ innodb-cmpmem
2425
innodb-cmp-per-index
2526
innodb-trx
2627
innodb-locks
28+
innodb-lock-waits
2729
innodb-metrics
2830
innodb-buffer-pool-stats
2931
innodb-buffer-page

mysql-test/suite/versioning/r/insert.result

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,3 +371,9 @@ create or replace table t1 (pk int primary key) with system versioning;
371371
create trigger tr before insert on t1 for each row select 1 into @a;
372372
insert into t1 values (1),(2);
373373
drop table t1;
374+
create table t1 (pk int primary key, i int) with system versioning;
375+
replace into t1 values (1,10),(1,100),(1,1000);
376+
select pk,i,row_end > '2038-01-01' from t1 for system_time all;
377+
pk i row_end > '2038-01-01'
378+
1 1000 1
379+
drop table t1;

mysql-test/suite/versioning/r/update.result

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,20 @@ create or replace table t1 (a int primary key, b int)
620620
with system versioning engine myisam;
621621
insert into t1 (a) values (1);
622622
replace t1 values (1,2),(1,3),(2,4);
623-
ERROR 23000: Duplicate entry '1-YYYY-MM-DD hh:mm:ss.uuuuuu' for key 'PRIMARY'
623+
create or replace table t1 (pk int, a char(3), b char(3), primary key(pk))
624+
engine=innodb with system versioning;
625+
insert into t1 (pk) values (1);
626+
connect con1,localhost,root,,test;
627+
start transaction;
628+
select * from t1 for update;
629+
pk a b
630+
1 NULL NULL
631+
connection default;
632+
update t1 set b = 'foo';
633+
connection con1;
634+
update t1 set a = 'bar';
635+
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
636+
disconnect con1;
637+
connection default;
624638
drop database test;
625639
create database test;

mysql-test/suite/versioning/t/insert.test

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,5 +267,12 @@ select *, row_start > @a, row_end > @a from t1 for system_time all;
267267
create or replace table t1 (pk int primary key) with system versioning;
268268
create trigger tr before insert on t1 for each row select 1 into @a;
269269
insert into t1 values (1),(2);
270+
drop table t1;
270271

272+
#
273+
# MDEV-14794 Limitations which the row end as a part of PK imposes due to CURRENT_TIMESTAMP behavior and otherwise
274+
#
275+
create table t1 (pk int primary key, i int) with system versioning;
276+
replace into t1 values (1,10),(1,100),(1,1000);
277+
select pk,i,row_end > '2038-01-01' from t1 for system_time all;
271278
drop table t1;

mysql-test/suite/versioning/t/update.test

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
-- source suite/versioning/common.inc
1+
--source suite/versioning/common.inc
22

33
delimiter ~~;
44
create procedure test_01(
@@ -280,9 +280,30 @@ call verify_vtq;
280280
create or replace table t1 (a int primary key, b int)
281281
with system versioning engine myisam;
282282
insert into t1 (a) values (1);
283-
--replace_regex /'1-[- .\d:]+'/'1-YYYY-MM-DD hh:mm:ss.uuuuuu'/
284-
--error ER_DUP_ENTRY
283+
285284
replace t1 values (1,2),(1,3),(2,4);
286285

286+
#
287+
# MDEV-14829 Assertion `0' failed in Protocol::end_statement upon concurrent UPDATE
288+
#
289+
290+
create or replace table t1 (pk int, a char(3), b char(3), primary key(pk))
291+
engine=innodb with system versioning;
292+
293+
insert into t1 (pk) values (1);
294+
connect (con1,localhost,root,,test);
295+
start transaction;
296+
select * from t1 for update;
297+
connection default;
298+
send update t1 set b = 'foo';
299+
connection con1;
300+
let $wait_condition= select count(*) from information_schema.innodb_lock_waits;
301+
source include/wait_condition.inc;
302+
error ER_LOCK_DEADLOCK;
303+
update t1 set a = 'bar';
304+
disconnect con1;
305+
connection default;
306+
reap;
307+
287308
drop database test;
288309
create database test;

sql/sql_insert.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1640,6 +1640,11 @@ int vers_insert_history_row(TABLE *table)
16401640
// Set Sys_end to now()
16411641
table->vers_update_end();
16421642

1643+
Field *row_start= table->vers_start_field();
1644+
Field *row_end= table->vers_end_field();
1645+
if (row_start->cmp(row_start->ptr, row_end->ptr) >= 0)
1646+
return 0;
1647+
16431648
return table->file->ha_write_row(table->record[0]);
16441649
}
16451650

sql/sql_update.cc

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -948,25 +948,22 @@ int mysql_update(THD *thd,
948948
}
949949
else if (!error)
950950
{
951-
updated++;
952-
953951
if (has_vers_fields && table->versioned())
954952
{
955953
if (table->versioned(VERS_TIMESTAMP))
956954
{
957955
store_record(table, record[2]);
958-
if ((error = vers_insert_history_row(table)))
959-
{
960-
restore_record(table, record[2]);
961-
break;
962-
}
956+
error= vers_insert_history_row(table);
963957
restore_record(table, record[2]);
964958
}
965-
updated_sys_ver++;
959+
if (!error)
960+
updated_sys_ver++;
966961
}
962+
if (!error)
963+
updated++;
967964
}
968-
else if (!ignore ||
969-
table->file->is_fatal_error(error, HA_CHECK_ALL))
965+
966+
if (error && (!ignore || table->file->is_fatal_error(error, HA_CHECK_ALL)))
970967
{
971968
/*
972969
If (ignore && error is ignorable) we don't have to

0 commit comments

Comments
 (0)