summaryrefslogtreecommitdiff
path: root/sql/mdl.h
diff options
context:
space:
mode:
authorAlexey Botchkov <holyfoot@askmonty.org>2013-04-12 18:06:51 +0500
committerAlexey Botchkov <holyfoot@askmonty.org>2013-04-12 18:06:51 +0500
commit1a600125ff77b57f6bcb57ba2fff45293ab7257d (patch)
tree765189555c7cc611e4f635822f705a95876cca9f /sql/mdl.h
parentff3407a111ec268e7bd5e726a75527089871c914 (diff)
downloadmariadb-git-1a600125ff77b57f6bcb57ba2fff45293ab7257d.tar.gz
MDEV-3917 multiple use locks (GET_LOCK) in one connection.
The patch contributed by Konstantin Osipov applied. Native comments: Implement multiple user-level locks per connection. GET_LOCK() function in MySQL allows a connection to hold at most one user level lock. Taking a new lock automatically releases the old lock, if any. The limit of one lock per session existed since early versions of MySQL didn't have a deadlock detector for SQL locks. MDL patches in MySQL 5.5 added a deadlock detector, so starting from 5.5 it became possible to take multiple locks in any order -- a deadlock, should it occur, would be detected and an error returned to the client which closed the wait chain. This is exactly what is done in this patch: ULLs are moved to use MDL subsystem.
Diffstat (limited to 'sql/mdl.h')
-rw-r--r--sql/mdl.h43
1 files changed, 29 insertions, 14 deletions
diff --git a/sql/mdl.h b/sql/mdl.h
index 68f24a7a0e8..a86b45e180f 100644
--- a/sql/mdl.h
+++ b/sql/mdl.h
@@ -212,6 +212,7 @@ public:
TRIGGER,
EVENT,
COMMIT,
+ USER_LOCK, /* user level locks. */
/* This should be the last ! */
NAMESPACE_END };
@@ -492,6 +493,7 @@ public:
}
enum_mdl_type get_type() const { return m_type; }
MDL_lock *get_lock() const { return m_lock; }
+ MDL_key *get_key() const;
void downgrade_exclusive_lock(enum_mdl_type type);
bool has_stronger_or_equal_type(enum_mdl_type type) const;
@@ -653,6 +655,7 @@ public:
bool is_lock_owner(MDL_key::enum_mdl_namespace mdl_namespace,
const char *db, const char *name,
enum_mdl_type mdl_type);
+ unsigned long get_lock_owner(MDL_key *mdl_key);
bool has_lock(const MDL_savepoint &mdl_savepoint, MDL_ticket *mdl_ticket);
@@ -721,9 +724,9 @@ private:
Lists of MDL tickets:
---------------------
The entire set of locks acquired by a connection can be separated
- in three subsets according to their: locks released at the end of
- statement, at the end of transaction and locks are released
- explicitly.
+ in three subsets according to their duration: locks released at
+ the end of statement, at the end of transaction and locks are
+ released explicitly.
Statement and transactional locks are locks with automatic scope.
They are accumulated in the course of a transaction, and released
@@ -732,11 +735,12 @@ private:
locks). They must not be (and never are) released manually,
i.e. with release_lock() call.
- Locks with explicit duration are taken for locks that span
+ Tickets with explicit duration are taken for locks that span
multiple transactions or savepoints.
These are: HANDLER SQL locks (HANDLER SQL is
transaction-agnostic), LOCK TABLES locks (you can COMMIT/etc
- under LOCK TABLES, and the locked tables stay locked), and
+ under LOCK TABLES, and the locked tables stay locked), user level
+ locks (GET_LOCK()/RELEASE_LOCK() functions) and
locks implementing "global read lock".
Statement/transactional locks are always prepended to the
@@ -745,20 +749,19 @@ private:
a savepoint, we start popping and releasing tickets from the
front until we reach the last ticket acquired after the savepoint.
- Locks with explicit duration stored are not stored in any
+ Locks with explicit duration are not stored in any
particular order, and among each other can be split into
- three sets:
+ four sets:
- [LOCK TABLES locks] [HANDLER locks] [GLOBAL READ LOCK locks]
+ [LOCK TABLES locks] [USER locks] [HANDLER locks] [GLOBAL READ LOCK locks]
The following is known about these sets:
- * GLOBAL READ LOCK locks are always stored after LOCK TABLES
- locks and after HANDLER locks. This is because one can't say
- SET GLOBAL read_only=1 or FLUSH TABLES WITH READ LOCK
- if one has locked tables. One can, however, LOCK TABLES
- after having entered the read only mode. Note, that
- subsequent LOCK TABLES statement will unlock the previous
+ * GLOBAL READ LOCK locks are always stored last.
+ This is because one can't say SET GLOBAL read_only=1 or
+ FLUSH TABLES WITH READ LOCK if one has locked tables. One can,
+ however, LOCK TABLES after having entered the read only mode.
+ Note, that subsequent LOCK TABLES statement will unlock the previous
set of tables, but not the GRL!
There are no HANDLER locks after GRL locks because
SET GLOBAL read_only performs a FLUSH TABLES WITH
@@ -853,6 +856,18 @@ extern bool mysql_notify_thread_having_shared_lock(THD *thd, THD *in_use,
extern "C" const char* thd_enter_cond(MYSQL_THD thd, mysql_cond_t *cond,
mysql_mutex_t *mutex, const char *msg);
extern "C" void thd_exit_cond(MYSQL_THD thd, const char *old_msg);
+extern "C" unsigned long thd_get_thread_id(const MYSQL_THD thd);
+
+/**
+ Check if a connection in question is no longer connected.
+
+ @details
+ Replication apply thread is always connected. Otherwise,
+ does a poll on the associated socket to check if the client
+ is gone.
+*/
+extern "C" int thd_is_connected(MYSQL_THD thd);
+
#ifndef DBUG_OFF
extern mysql_mutex_t LOCK_open;