MDEV-12882 - Assertion failed in MDL_context::upgrade_shared_lock

Relaxed assertion (in MySQL it was removed).
For "LOCK TABLES t1 WRITE CONCURRENT, t1 READ" upgrade lock to weakest
existing suitable lock, which is MDL_SHARED_NO_READ_WRITE.
This commit is contained in:
Sergey Vojtovich 2017-06-22 17:35:36 +04:00
parent 0d69d313a1
commit dd710e7552
4 changed files with 49 additions and 3 deletions

22
mysql-test/r/mdl.result Normal file
View File

@ -0,0 +1,22 @@
#
# MDEV-12882 - Assertion `mdl_ticket->m_type == MDL_SHARED_UPGRADABLE ||
# mdl_ticket->m_type == MDL_SHARED_NO_WRITE ||
# mdl_ticket->m_type == MDL_SHARED_NO_READ_WRITE ||
# mdl_ticket->m_type == MDL_SHARED_READ'
# failed in MDL_context::upgrade_shared_lock
#
CREATE TABLE t1(a INT) ENGINE=InnoDB;
LOCK TABLES t1 WRITE CONCURRENT, t1 AS t2 READ;
SELECT * FROM information_schema.metadata_lock_info;
THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
9 MDL_INTENTION_EXCLUSIVE NULL Global read lock
9 MDL_SHARED_NO_READ_WRITE NULL Table metadata lock test t1
UNLOCK TABLES;
LOCK TABLES t1 AS t2 READ, t1 WRITE CONCURRENT;
SELECT * FROM information_schema.metadata_lock_info;
THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
9 MDL_INTENTION_EXCLUSIVE NULL Global read lock
9 MDL_SHARED_WRITE NULL Table metadata lock test t1
9 MDL_SHARED_READ_ONLY NULL Table metadata lock test t1
UNLOCK TABLES;
DROP TABLE t1;

19
mysql-test/t/mdl.test Normal file
View File

@ -0,0 +1,19 @@
--source include/have_metadata_lock_info.inc
--source include/have_innodb.inc
--echo #
--echo # MDEV-12882 - Assertion `mdl_ticket->m_type == MDL_SHARED_UPGRADABLE ||
--echo # mdl_ticket->m_type == MDL_SHARED_NO_WRITE ||
--echo # mdl_ticket->m_type == MDL_SHARED_NO_READ_WRITE ||
--echo # mdl_ticket->m_type == MDL_SHARED_READ'
--echo # failed in MDL_context::upgrade_shared_lock
--echo #
CREATE TABLE t1(a INT) ENGINE=InnoDB;
LOCK TABLES t1 WRITE CONCURRENT, t1 AS t2 READ;
SELECT * FROM information_schema.metadata_lock_info;
UNLOCK TABLES;
LOCK TABLES t1 AS t2 READ, t1 WRITE CONCURRENT;
SELECT * FROM information_schema.metadata_lock_info;
UNLOCK TABLES;
DROP TABLE t1;

View File

@ -2320,11 +2320,12 @@ MDL_context::upgrade_shared_lock(MDL_ticket *mdl_ticket,
if (mdl_ticket->has_stronger_or_equal_type(new_type)) if (mdl_ticket->has_stronger_or_equal_type(new_type))
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
/* Only allow upgrades from SHARED_UPGRADABLE/NO_WRITE/NO_READ_WRITE/READ */ /* Only allow upgrades from UPGRADABLE/NO_WRITE/NO_READ_WRITE/READ/WRITE */
DBUG_ASSERT(mdl_ticket->m_type == MDL_SHARED_UPGRADABLE || DBUG_ASSERT(mdl_ticket->m_type == MDL_SHARED_UPGRADABLE ||
mdl_ticket->m_type == MDL_SHARED_NO_WRITE || mdl_ticket->m_type == MDL_SHARED_NO_WRITE ||
mdl_ticket->m_type == MDL_SHARED_NO_READ_WRITE || mdl_ticket->m_type == MDL_SHARED_NO_READ_WRITE ||
mdl_ticket->m_type == MDL_SHARED_READ); mdl_ticket->m_type == MDL_SHARED_READ ||
mdl_ticket->m_type == MDL_SHARED_WRITE);
mdl_xlock_request.init(&mdl_ticket->m_lock->key, new_type, mdl_xlock_request.init(&mdl_ticket->m_lock->key, new_type,
MDL_TRANSACTION); MDL_TRANSACTION);

View File

@ -2787,6 +2787,7 @@ retry:
! table->prelocking_placeholder && ! table->prelocking_placeholder &&
table->table->file->lock_count() == 0) table->table->file->lock_count() == 0)
{ {
enum enum_mdl_type lock_type;
/* /*
In case when LOCK TABLE ... READ LOCAL was issued for table with In case when LOCK TABLE ... READ LOCAL was issued for table with
storage engine which doesn't support READ LOCAL option and doesn't storage engine which doesn't support READ LOCAL option and doesn't
@ -2799,9 +2800,12 @@ retry:
deadlock_handler.init(); deadlock_handler.init();
thd->push_internal_handler(&deadlock_handler); thd->push_internal_handler(&deadlock_handler);
lock_type= table->table->mdl_ticket->get_type() == MDL_SHARED_WRITE ?
MDL_SHARED_NO_READ_WRITE : MDL_SHARED_READ_ONLY;
bool result= thd->mdl_context.upgrade_shared_lock( bool result= thd->mdl_context.upgrade_shared_lock(
table->table->mdl_ticket, table->table->mdl_ticket,
MDL_SHARED_READ_ONLY, lock_type,
thd->variables.lock_wait_timeout); thd->variables.lock_wait_timeout);
thd->pop_internal_handler(); thd->pop_internal_handler();