diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2019-12-05 11:30:19 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2019-12-05 12:49:23 +0200 |
commit | ed1b8838b7abd84c765643d337b47a105f91739a (patch) | |
tree | 3441f08de00316a9cf7f71d5ab2010e0afa8ce31 | |
parent | aeec6ecde0a8fd72e89aec98bccb47fc1ac1e415 (diff) | |
download | mariadb-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.h | 55 | ||||
-rw-r--r-- | include/service_versions.h | 3 | ||||
-rw-r--r-- | sql/mdl.cc | 40 | ||||
-rw-r--r-- | sql/mdl.h | 24 | ||||
-rw-r--r-- | sql/sql_class.cc | 25 | ||||
-rw-r--r-- | sql/sql_plugin_services.ic | 12 | ||||
-rw-r--r-- | storage/innobase/dict/dict0dict.cc | 57 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 12 | ||||
-rw-r--r-- | storage/innobase/include/ha_prototypes.h | 13 | ||||
-rw-r--r-- | storage/innobase/include/trx0trx.h | 2 | ||||
-rw-r--r-- | storage/innobase/lock/lock0lock.cc | 2 |
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; } |