1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

MDEV-22413 Server hangs upon UPDATE on a view reading from versioned partitioned table

UPDATE gets access to history records because versioning conditions
are not set for VIEW. This leads to endless loop of inserting history
records when clustered index is rebuilt and ha_rnd_next() returns
newly inserted history record.

Return back original behavior of failing on write-locked table in
historical query.

35b679b9 assumed that SELECT_LEX::lock_type influences anything, but
actually at this point table is already locked. Original bug report
was tempesta-tech/mariadb#102
This commit is contained in:
Aleksey Midenkov
2020-05-28 22:22:19 +03:00
parent 3e9b96b6ff
commit dd9773b723
7 changed files with 67 additions and 13 deletions

View File

@ -650,6 +650,26 @@ pk f
update t1 set f=pk; update t1 set f=pk;
delete from t1; delete from t1;
drop table t1; drop table t1;
# Test cleanup #
drop database test; # MDEV-22413 Server hangs upon UPDATE/DELETE on a view reading from versioned partitioned table
create database test; #
create or replace table t1 (f char(6)) engine innodb with system versioning;
insert into t1 values (null);
update t1 set f= 'foo';
update t1 set f= 'bar';
create or replace view v1 as select * from t1 for system_time all;
update v1 set f = '';
ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
create or replace table t1 (f char(6)) engine innodb with system versioning
partition by system_time limit 1
(partition p1 history, partition p2 history, partition pn current);
insert into t1 values (null);
update t1 set f= 'foo';
update t1 set f= 'bar';
create or replace view v1 as select * from t1 for system_time all;
update v1 set f= '';
ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
delete from v1;
ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
drop view v1;
drop table t1;

View File

@ -206,8 +206,7 @@ ERROR HY000: Table `t1` is not system-versioned
create or replace table t1 (x int) with system versioning; create or replace table t1 (x int) with system versioning;
insert into t1 values (1); insert into t1 values (1);
select * from t1 for system_time all for update; select * from t1 for system_time all for update;
x ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
1
create or replace table t1 (a int not null auto_increment primary key) with system versioning; create or replace table t1 (a int not null auto_increment primary key) with system versioning;
select * from (t1 as t2 left join t1 as t3 using (a)) natural left join t1; select * from (t1 as t2 left join t1 as t3 using (a)) natural left join t1;
a a

View File

@ -229,8 +229,7 @@ ERROR HY000: Table `t1` is not system-versioned
create or replace table t1 (x int) with system versioning; create or replace table t1 (x int) with system versioning;
insert into t1 values (1); insert into t1 values (1);
select * from t1 for system_time as of now() for update; select * from t1 for system_time as of now() for update;
x ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
1
create or replace table t1 (a int not null auto_increment primary key) with system versioning; create or replace table t1 (a int not null auto_increment primary key) with system versioning;
select * from (t1 as t2 left join t1 as t3 using (a)) natural left join t1; select * from (t1 as t2 left join t1 as t3 using (a)) natural left join t1;
a a

View File

@ -583,7 +583,6 @@ update t1 left join t2 on a > b set b= 2 order by b;
# cleanup # cleanup
drop table t1, t2; drop table t1, t2;
--source suite/versioning/common_finish.inc
--echo # --echo #
--echo # MDEV-17091 Assertion `old_part_id == m_last_part' failed in --echo # MDEV-17091 Assertion `old_part_id == m_last_part' failed in
--echo # ha_partition::update_row or `part_id == m_last_part' in --echo # ha_partition::update_row or `part_id == m_last_part' in
@ -605,6 +604,35 @@ update t1 set f=pk;
delete from t1; delete from t1;
drop table t1; drop table t1;
--echo # Test cleanup --echo #
drop database test; --echo # MDEV-22413 Server hangs upon UPDATE/DELETE on a view reading from versioned partitioned table
create database test; --echo #
create or replace table t1 (f char(6)) engine innodb with system versioning;
insert into t1 values (null);
update t1 set f= 'foo';
update t1 set f= 'bar';
create or replace view v1 as select * from t1 for system_time all;
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
update v1 set f = '';
create or replace table t1 (f char(6)) engine innodb with system versioning
partition by system_time limit 1
(partition p1 history, partition p2 history, partition pn current);
insert into t1 values (null);
update t1 set f= 'foo';
update t1 set f= 'bar';
create or replace view v1 as select * from t1 for system_time all;
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
update v1 set f= '';
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
delete from v1;
# cleanup
drop view v1;
drop table t1;
--source suite/versioning/common_finish.inc

View File

@ -123,6 +123,7 @@ select * from t1 for system_time all;
create or replace table t1 (x int) with system versioning; create or replace table t1 (x int) with system versioning;
insert into t1 values (1); insert into t1 values (1);
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
select * from t1 for system_time all for update; select * from t1 for system_time all for update;
create or replace table t1 (a int not null auto_increment primary key) with system versioning; create or replace table t1 (a int not null auto_increment primary key) with system versioning;

View File

@ -128,6 +128,7 @@ select * from t1 for system_time all;
create or replace table t1 (x int) with system versioning; create or replace table t1 (x int) with system versioning;
insert into t1 values (1); insert into t1 values (1);
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
select * from t1 for system_time as of now() for update; select * from t1 for system_time as of now() for update;
create or replace table t1 (a int not null auto_increment primary key) with system versioning; create or replace table t1 (a int not null auto_increment primary key) with system versioning;

View File

@ -832,10 +832,16 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables)
if (vers_conditions.is_set()) if (vers_conditions.is_set())
{ {
if (vers_conditions.was_set() &&
table->lock_type > TL_READ_NO_INSERT &&
!vers_conditions.delete_history)
{
my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), table->alias.str);
DBUG_RETURN(-1);
}
if (vers_conditions.type == SYSTEM_TIME_ALL) if (vers_conditions.type == SYSTEM_TIME_ALL)
continue; continue;
lock_type= TL_READ; // ignore TL_WRITE, history is immutable anyway
} }
const LEX_CSTRING *fstart= const LEX_CSTRING *fstart=