diff options
author | Jon Olav Hauglid <jon.hauglid@sun.com> | 2009-12-09 10:44:01 +0100 |
---|---|---|
committer | Jon Olav Hauglid <jon.hauglid@sun.com> | 2009-12-09 10:44:01 +0100 |
commit | fcae99271a82b8ab16883a135fa679711ce97b62 (patch) | |
tree | f4d748210ba947d843a9dd5f10b45f4cc19ca921 /sql/mdl.cc | |
parent | 59f82702a18799621a19f1a880e9f80cb374b1ce (diff) | |
download | mariadb-git-fcae99271a82b8ab16883a135fa679711ce97b62.tar.gz |
Backport of revno: 2617.68.39
Bug #47249 assert in MDL_global_lock::is_lock_type_compatible
This assert could be triggered if LOCK TABLES were used to lock
both a table and a view that used the same table. The table would have
to be first WRITE locked and then READ locked. So "LOCK TABLES v1
WRITE, t1 READ" would eventually trigger the assert, "LOCK TABLES
v1 READ, t1 WRITE" would not. The reason is that the ordering of locks
in the interal representation made a difference when executing
FLUSH TABLE on the table.
During FLUSH TABLE, a lock was upgraded to exclusive. If this lock
was of type MDL_SHARED and not MDL_SHARED_UPGRADABLE, an internal
counter in the MDL subsystem would get out of sync. This would happen
if the *last* mention of the table in LOCK TABLES was a READ lock.
The counter in question is the number exclusive locks (active or intention).
This is used to make sure a global metadata lock is only taken when the
counter is zero (= no conflicts). The counter is increased when a
MDL_EXCLUSIVE or MDL_SHARED_UPGRADABLE lock is taken, but not when
upgrade_shared_lock_to_exclusive() is used to upgrade directly
from MDL_SHARED to MDL_EXCLUSIVE.
This patch fixes the problem by searching for a TABLE instance locked
with MDL_SHARED_UPGRADABLE or MDL_EXCLUSIVE before calling
upgrade_shared_lock_to_exclusive(). The patch also adds an assert checking
that only MDL_SHARED_UPGRADABLE locks are upgraded to exclusive.
Test case added to lock_multi.test.
Diffstat (limited to 'sql/mdl.cc')
-rw-r--r-- | sql/mdl.cc | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/sql/mdl.cc b/sql/mdl.cc index f9b52b17f5f..879b12a4cac 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -1005,6 +1005,9 @@ MDL_ticket::upgrade_shared_lock_to_exclusive() if (m_type == MDL_EXCLUSIVE) DBUG_RETURN(FALSE); + /* Only allow upgrades from MDL_SHARED_UPGRADABLE */ + DBUG_ASSERT(m_type == MDL_SHARED_UPGRADABLE); + pthread_mutex_lock(&LOCK_mdl); old_msg= MDL_ENTER_COND(thd, mysys_var); |