From 6266493fc33cfcfd3f878c6955b53576277f52ba Mon Sep 17 00:00:00 2001 From: Jimmy Yang <jimmy.yang@oracle.com> Date: Wed, 20 Sep 2017 01:38:26 +0200 Subject: [PATCH] Bug #25729649 LOCK0LOCK.CC:NNN:ADD_POSITION != __NULL Reviewed-by: Sunny Bains <sunny.bains@oracle.com> --- .../innodb/r/high_prio_trx_predicate.result | 30 +++++++++ .../innodb/t/high_prio_trx_predicate.test | 61 +++++++++++++++++++ storage/innobase/lock/lock0lock.cc | 7 ++- 3 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 mysql-test/suite/innodb/r/high_prio_trx_predicate.result create mode 100644 mysql-test/suite/innodb/t/high_prio_trx_predicate.test diff --git a/mysql-test/suite/innodb/r/high_prio_trx_predicate.result b/mysql-test/suite/innodb/r/high_prio_trx_predicate.result new file mode 100644 index 00000000000..965e1e0f6ad --- /dev/null +++ b/mysql-test/suite/innodb/r/high_prio_trx_predicate.result @@ -0,0 +1,30 @@ +CREATE TABLE tab(c1 int NOT NULL PRIMARY KEY,c2 POINT NOT NULL); +CREATE SPATIAL INDEX idx1 on tab(c2); +INSERT INTO tab(c1,c2) VALUES(1,ST_GeomFromText('POINT(10 10)')); + +# On connection 1 +set transaction isolation level serializable ; +START TRANSACTION; +SELECT ST_AsText(c2) FROM tab WHERE MBRWithin(c2, ST_GeomFromText('POLYGON((5 5, 15 5, 15 15, 5 15, 5 5))')); +ST_AsText(c2) +POINT(10 10) + +# On connection 2 +start transaction; +INSERT INTO tab(c1,c2) VALUES(7, ST_GeomFromText('POINT(11 11)'));; + +# On connection 3 +include/start_transaction_high_prio.inc +START TRANSACTION /* HIGH PRIORITY */; +INSERT INTO tab(c1,c2) VALUES(8, ST_GeomFromText('POINT(10 10)')); +COMMIT; + +# On connection 1 +COMMIT; +ERROR HY000: Got error 149 during COMMIT +include/assert.inc ['There is a 8 in tab'] +SELECT c1 FROM tab; +c1 +1 +8 +DROP TABLE tab; diff --git a/mysql-test/suite/innodb/t/high_prio_trx_predicate.test b/mysql-test/suite/innodb/t/high_prio_trx_predicate.test new file mode 100644 index 00000000000..6503e90653b --- /dev/null +++ b/mysql-test/suite/innodb/t/high_prio_trx_predicate.test @@ -0,0 +1,61 @@ +# Scenario: +# T1=({R(B)}) +# T2=({W(B)}) +# T3=({W(B), C}, HIGH_PRIORITY). +# +# Outcome: T1 must abort, T2 must commit. + +--source include/count_sessions.inc + +CREATE TABLE tab(c1 int NOT NULL PRIMARY KEY,c2 POINT NOT NULL); +CREATE SPATIAL INDEX idx1 on tab(c2); +INSERT INTO tab(c1,c2) VALUES(1,ST_GeomFromText('POINT(10 10)')); + +--connect(con1,localhost,root,,test) +--connect(con2,localhost,root,,test) +--connect(con3,localhost,root,,test) + +--echo +--echo # On connection 1 +--connection con1 +set transaction isolation level serializable ; +START TRANSACTION; +SELECT ST_AsText(c2) FROM tab WHERE MBRWithin(c2, ST_GeomFromText('POLYGON((5 5, 15 5, 15 15, 5 15, 5 5))')); + + +--echo +--echo # On connection 2 +--connection con2 +start transaction; +--send INSERT INTO tab(c1,c2) VALUES(7, ST_GeomFromText('POINT(11 11)')); + +--echo +--echo # On connection 3 +--connection con3 +--source include/start_transaction_high_prio.inc +INSERT INTO tab(c1,c2) VALUES(8, ST_GeomFromText('POINT(10 10)')); +COMMIT; +--disconnect con3 + +--echo +--echo # On connection 1 +--connection con1 +--error ER_ERROR_DURING_COMMIT +COMMIT; +--disconnect con1 + +--connection default +--let $assert_text= 'There is a 8 in tab' +--let $assert_cond= [SELECT COUNT(*) AS count FROM tab WHERE tab.c1 = 8, count, 1] = 1 +--source include/assert.inc + +--connection con2 +--reap; +--disconnect con2 + +--connection default +SELECT c1 FROM tab; + +DROP TABLE tab; + +--source include/wait_until_count_sessions.inc diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index f25ac596d5f..cde267aa638 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2014, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -2728,7 +2728,10 @@ RecLock::lock_add_priority( lock_t* grant_position = NULL; lock_t* add_position = NULL; - HASH_SEARCH(hash, lock_sys->rec_hash, m_rec_id.fold(), lock_t*, + /* Different lock (such as predicate lock) are on different hash */ + hash_table_t* lock_hash = lock_hash_get(m_mode); + + HASH_SEARCH(hash, lock_hash, m_rec_id.fold(), lock_t*, lock_head, ut_ad(lock_head->is_record_lock()), true); ut_ad(lock_head);