diff --git a/mysql-test/r/mdl.result b/mysql-test/r/mdl.result new file mode 100644 index 00000000000..1a7291d922b --- /dev/null +++ b/mysql-test/r/mdl.result @@ -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; diff --git a/mysql-test/t/mdl.test b/mysql-test/t/mdl.test new file mode 100644 index 00000000000..1770e53b61a --- /dev/null +++ b/mysql-test/t/mdl.test @@ -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; diff --git a/sql/mdl.cc b/sql/mdl.cc index f1a505f3d84..25809c3d9cc 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -2320,11 +2320,12 @@ MDL_context::upgrade_shared_lock(MDL_ticket *mdl_ticket, if (mdl_ticket->has_stronger_or_equal_type(new_type)) 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 || mdl_ticket->m_type == MDL_SHARED_NO_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_TRANSACTION); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 412cd1dac70..7c910e87c75 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2787,6 +2787,7 @@ retry: ! table->prelocking_placeholder && table->table->file->lock_count() == 0) { + enum enum_mdl_type lock_type; /* In case when LOCK TABLE ... READ LOCAL was issued for table with storage engine which doesn't support READ LOCAL option and doesn't @@ -2799,9 +2800,12 @@ retry: deadlock_handler.init(); 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( table->table->mdl_ticket, - MDL_SHARED_READ_ONLY, + lock_type, thd->variables.lock_wait_timeout); thd->pop_internal_handler();