summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2019-12-05 11:30:19 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2019-12-05 12:49:23 +0200
commited1b8838b7abd84c765643d337b47a105f91739a (patch)
tree3441f08de00316a9cf7f71d5ab2010e0afa8ce31
parentaeec6ecde0a8fd72e89aec98bccb47fc1ac1e415 (diff)
downloadmariadb-git-ed1b8838b7abd84c765643d337b47a105f91739a.tar.gz
Do not add MDL changes to sql_class.h
thd_innodb_lock_wait_timeout(): Renamed from thd_lock_wait_timeout() to avoid confusion. thd_lock_wait_timeout(), thd_mdl_context(): New interfaces, to be used for acquiring or releasing MDL.
-rw-r--r--include/mysql/service_thd_mdl.h55
-rw-r--r--include/service_versions.h3
-rw-r--r--sql/mdl.cc40
-rw-r--r--sql/mdl.h24
-rw-r--r--sql/sql_class.cc25
-rw-r--r--sql/sql_plugin_services.ic12
-rw-r--r--storage/innobase/dict/dict0dict.cc57
-rw-r--r--storage/innobase/handler/ha_innodb.cc12
-rw-r--r--storage/innobase/include/ha_prototypes.h13
-rw-r--r--storage/innobase/include/trx0trx.h2
-rw-r--r--storage/innobase/lock/lock0lock.cc2
11 files changed, 149 insertions, 96 deletions
diff --git a/include/mysql/service_thd_mdl.h b/include/mysql/service_thd_mdl.h
new file mode 100644
index 00000000000..86d5d1ef3dc
--- /dev/null
+++ b/include/mysql/service_thd_mdl.h
@@ -0,0 +1,55 @@
+/* Copyright (c) 2019, MariaDB Corporation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+#pragma once
+
+/**
+ @file include/mysql/service_thd_mdl.h
+ This service provides functions for plugins and storage engines to access
+ metadata locks.
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct thd_mdl_service_st {
+ ulong (*thd_lock_wait_timeout_func)(MYSQL_THD);
+ void *(*thd_mdl_context)(MYSQL_THD);
+} *thd_mdl_service;
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+# define thd_lock_wait_timeout(_THD) \
+ thd_mdl_service->thd_lock_wait_timeout_func(_THD)
+# define thd_mdl_context(_THD) thd_mdl_service->thd_mdl_context(_THD)
+#else
+/**
+ Read the value of lock_wait_timeout.
+ @param thd the session, or NULL to read the global value
+ @return the value of lock_wait_timeout
+*/
+ulong thd_lock_wait_timeout(MYSQL_THD thd);
+/**
+ MDL_context accessor
+ @param thd the current session
+ @return pointer to thd->mdl_context
+*/
+void *thd_mdl_context(MYSQL_THD thd);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/include/service_versions.h b/include/service_versions.h
index 16d21ac40d3..66451ee3ea5 100644
--- a/include/service_versions.h
+++ b/include/service_versions.h
@@ -1,5 +1,5 @@
/* Copyright (c) 2009, 2010, Oracle and/or its affiliates.
- Copyright (c) 2012, 2017, MariaDB
+ Copyright (c) 2012, 2019, MariaDB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -43,3 +43,4 @@
#define VERSION_thd_wait 0x0100
#define VERSION_wsrep 0x0202
#define VERSION_json 0x0100
+#define VERSION_thd_mdl 0x0100
diff --git a/sql/mdl.cc b/sql/mdl.cc
index 78520393fb7..e7c0d699d76 100644
--- a/sql/mdl.cc
+++ b/sql/mdl.cc
@@ -3210,46 +3210,6 @@ bool MDL_context::has_explicit_locks()
return false;
}
-template
-bool acquire_shared_table_mdl<true>(THD *thd, const char *db_name,
- const char *tbl_name,
- MDL_ticket **out_mdl_ticket);
-template
-bool acquire_shared_table_mdl<false>(THD *thd, const char *db_name,
- const char *tbl_name,
- MDL_ticket **out_mdl_ticket);
-template<bool no_wait>
-bool acquire_shared_table_mdl(THD *thd, const char *db_name,
- const char *tbl_name,
- MDL_ticket **out_mdl_ticket)
-{
- MDL_request mdl_request;
- mdl_request.init(MDL_key::TABLE, db_name, tbl_name,
- MDL_SHARED, MDL_EXPLICIT);
- if (no_wait)
- {
- if (thd->mdl_context.try_acquire_lock(&mdl_request)
- || !mdl_request.ticket)
- return true;
- }
- else
- {
- if (thd->mdl_context.acquire_lock(&mdl_request,
- thd->variables.lock_wait_timeout))
- return true;
- }
-
- if (out_mdl_ticket)
- *out_mdl_ticket= mdl_request.ticket;
-
- return false;
-}
-
-void release_mdl(THD *thd, MDL_ticket *mdl_ticket)
-{
- thd->mdl_context.release_lock(mdl_ticket);
-}
-
#ifdef WITH_WSREP
static
const char *wsrep_get_mdl_namespace_name(MDL_key::enum_mdl_namespace ns)
diff --git a/sql/mdl.h b/sql/mdl.h
index c4243f9f5d5..b084670e5c6 100644
--- a/sql/mdl.h
+++ b/sql/mdl.h
@@ -1106,28 +1106,4 @@ void mdl_dbug_print_locks();
#else
static inline void mdl_dbug_print_locks() {}
#endif /* DBUG_OFF */
-
-/**
- Acquire shared metadata lock on the given table name with
- explicit duration.
-
- @param thd thread to which mdl lock belongs to
- @param db_name database name
- @param tbl_name table name
- @param out_mdl_ticket pointer to MDL_ticket upon successful lock
- attempt
-*/
-template<bool no_wait=false>
-bool acquire_shared_table_mdl(THD *thd, const char *db_name,
- const char *tbl_name,
- MDL_ticket **out_mdl_ticket);
-
-/**
- Release MDL_EXPLICIT lock held by a ticket
-
- @param thd thread to which lock belongs to
- @param mdl_ticket lock ticket
-*/
-void release_mdl(THD *thd, MDL_ticket *mdl_ticket);
-
#endif /* MDL_H */
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 022403a95a0..a4582b6b678 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -5310,6 +5310,31 @@ extern "C" void thd_wait_end(MYSQL_THD thd)
#endif // INNODB_COMPATIBILITY_HOOKS */
+
+/**
+ Read the value of lock_wait_timeout.
+ @param thd the session, or NULL to read the global value
+ @return the value of lock_wait_timeout
+*/
+extern "C" ulong thd_lock_wait_timeout(MYSQL_THD thd)
+{
+ return thd
+ ? thd->variables.lock_wait_timeout
+ : global_system_variables.lock_wait_timeout;
+}
+
+
+/**
+ MDL_context accessor
+ @param thd the current session
+ @return pointer to thd->mdl_context
+*/
+extern "C" void *thd_mdl_context(MYSQL_THD thd)
+{
+ return &thd->mdl_context;
+}
+
+
/****************************************************************************
Handling of statement states in functions and triggers.
diff --git a/sql/sql_plugin_services.ic b/sql/sql_plugin_services.ic
index c3b0088c9bd..2677a38bf59 100644
--- a/sql/sql_plugin_services.ic
+++ b/sql/sql_plugin_services.ic
@@ -1,5 +1,5 @@
/* Copyright (c) 2009, 2010, Oracle and/or its affiliates.
- Copyright (c) 2012, 2014, Monty Program Ab
+ Copyright (c) 2012, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -17,6 +17,7 @@
/* support for Services */
#include <service_versions.h>
#include <mysql/service_wsrep.h>
+#include <mysql/service_thd_mdl.h>
struct st_service_ref {
const char *name;
@@ -220,6 +221,12 @@ struct json_service_st json_handler=
json_unescape_json
};
+static struct thd_mdl_service_st thd_mdl_handler=
+{
+ thd_lock_wait_timeout,
+ thd_mdl_context
+};
+
static struct st_service_ref list_of_services[]=
{
{ "base64_service", VERSION_base64, &base64_handler },
@@ -243,6 +250,7 @@ static struct st_service_ref list_of_services[]=
{ "thd_timezone_service", VERSION_thd_timezone, &thd_timezone_handler },
{ "thd_wait_service", VERSION_thd_wait, &thd_wait_handler },
{ "wsrep_service", VERSION_wsrep, &wsrep_handler },
- { "json_service", VERSION_json, &json_handler }
+ { "json_service", VERSION_json, &json_handler },
+ { "thd_mdl_service", VERSION_thd_mdl, &thd_mdl_handler }
};
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index 72112ffc42b..7a9c5ef6a3a 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -37,6 +37,7 @@ Created 1/8/1996 Heikki Tuuri
#include "fil0fil.h"
#include <algorithm>
#include "sql_table.h"
+#include <mysql/service_thd_mdl.h>
/** dummy index for ROW_FORMAT=REDUNDANT supremum and infimum records */
dict_index_t* dict_ind_redundant;
@@ -165,6 +166,47 @@ dict_lru_validate(void);
/*===================*/
#endif /* UNIV_DEBUG */
+
+/**
+ Acquire shared metadata lock with explicit duration on a table name.
+ @param thd current thread
+ @param db database name
+ @param t table name
+ @param trylock whether to fail if the request would block
+ @return granted MDL_ticket
+ @retval nullptr on failure
+*/
+static MY_ATTRIBUTE((nonnull))
+MDL_ticket *acquire_mdl(THD *thd, const char *db, const char *t, bool trylock)
+{
+ MDL_context *mdlc= static_cast<MDL_context*>(thd_mdl_context(thd));
+ ut_ad(mdlc);
+ if (!mdlc)
+ return nullptr;
+
+ MDL_request request;
+ request.init(MDL_key::TABLE, db, t, MDL_SHARED, MDL_EXPLICIT);
+ if (trylock
+ ? mdlc->try_acquire_lock(&request)
+ : mdlc->acquire_lock(&request, thd_lock_wait_timeout(thd)))
+ return nullptr;
+
+ return request.ticket;
+}
+
+
+/**
+ Release a metadata lock.
+ @param thd session
+ @param mdl metadata lock
+*/
+static MY_ATTRIBUTE((nonnull)) void release_mdl(THD *thd, MDL_ticket *mdl)
+{
+ if (MDL_context *mdlc= static_cast<MDL_context*>(thd_mdl_context(thd)))
+ mdlc->release_lock(mdl);
+}
+
+
/* Stream for storing detailed information about the latest foreign key
and unique key errors. Only created if !srv_read_only_mode */
FILE* dict_foreign_err_file = NULL;
@@ -767,7 +809,6 @@ bool dict_parse_tbl_name(const char* tbl_name,
return true;
}
-
/** Acquire MDL shared for the table name.
@tparam trylock whether to use non-blocking operation
@param[in,out] table table object
@@ -818,17 +859,11 @@ retry_mdl:
if (unaccessible)
return nullptr;
- if (trylock)
- {
- if (acquire_shared_table_mdl<true>(thd, db_buf, tbl_buf, mdl))
- return nullptr;
+ *mdl= acquire_mdl(thd, db_buf, tbl_buf, trylock);
+ if (*mdl)
mdl_acquire= true;
- }
- else
- {
- if (!acquire_shared_table_mdl(thd, db_buf, tbl_buf, mdl))
- mdl_acquire= true;
- }
+ else if (trylock)
+ return nullptr;
table= dict_table_open_on_id(table_id, dict_locked, table_op);
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 7268868e742..df9523b95d8 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -1704,14 +1704,10 @@ thd_is_select(
return(thd_sql_command(thd) == SQLCOM_SELECT);
}
-/******************************************************************//**
-Returns the lock wait timeout for the current connection.
-@return the lock wait timeout, in seconds */
-ulong
-thd_lock_wait_timeout(
-/*==================*/
- THD* thd) /*!< in: thread handle, or NULL to query
- the global innodb_lock_wait_timeout */
+/**
+@param thd session, or NULL to query the global value
+@return innodb_lock wait timeout */
+ulong thd_innodb_lock_wait_timeout(THD* thd)
{
/* According to <mysql/plugin.h>, passing thd == NULL
returns the global value of the session variable. */
diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h
index 443dce51ff5..22dc84ae241 100644
--- a/storage/innobase/include/ha_prototypes.h
+++ b/storage/innobase/include/ha_prototypes.h
@@ -297,14 +297,11 @@ const char*
thd_innodb_tmpdir(
THD* thd);
-/******************************************************************//**
-Returns the lock wait timeout for the current connection.
-@return the lock wait timeout, in seconds */
-ulong
-thd_lock_wait_timeout(
-/*==================*/
- THD* thd); /*!< in: thread handle, or NULL to query
- the global innodb_lock_wait_timeout */
+/**
+@param thd session, or NULL to query the global value
+@return innodb_lock wait timeout */
+ulong thd_innodb_lock_wait_timeout(THD* thd);
+
/** Get status of innodb_tmpdir.
@param[in] thd thread handle, or NULL to query
the global innodb_tmpdir.
diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h
index 2245168b169..e5c2c62a502 100644
--- a/storage/innobase/include/trx0trx.h
+++ b/storage/innobase/include/trx0trx.h
@@ -419,7 +419,7 @@ from innodb_lock_wait_timeout via trx_t::mysql_thd.
@return lock wait timeout in seconds */
#define trx_lock_wait_timeout_get(t) \
((t)->mysql_thd != NULL \
- ? thd_lock_wait_timeout((t)->mysql_thd) \
+ ? thd_innodb_lock_wait_timeout((t)->mysql_thd) \
: 0)
/**
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index 77fee83aef2..056f31f7959 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -1704,7 +1704,7 @@ lock_rec_enqueue_waiting(
ut_ad(0);
}
- if (trx->mysql_thd && thd_lock_wait_timeout(trx->mysql_thd) == 0) {
+ if (trx->mysql_thd && !thd_innodb_lock_wait_timeout(trx->mysql_thd)) {
trx->error_state = DB_LOCK_WAIT_TIMEOUT;
return DB_LOCK_WAIT_TIMEOUT;
}