Followup to Bug#45225 Locking: hang if drop table with no timeout

This patch prevents system threads and system table accesses from
using user-specified values for "lock_wait_timeout". Instead all
such accesses are done using the default value (1 year).

This prevents background tasks (such as replication, events, 
accessing stored function definitions, logging, reading time-zone
information, etc.) from failing in cases where the global value
of "lock_wait_timeout" is set very low.

The patch also simplifies the open tables API. Rather than adding
another convenience function for opening and locking system tables,
this patch removes most of the existing convenience functions for
open_and_lock_tables_derived(). Before, open_and_lock_tables() was
a convenience function that enforced derived tables handling, while
open_and_lock_tables_derived() was the main function where derived
tables handling was optional. Now, this convencience function is
gone and the main function is renamed to open_and_lock_tables(). 

No test case added as it would have required the use of --sleep to
check that system threads and system tables have a different timeout
value from the user-specified "lock_wait_timeout" system variable.
This commit is contained in:
Jon Olav Hauglid 2010-02-24 18:04:00 +01:00
parent b6e0f92f05
commit dd42aab840
24 changed files with 128 additions and 114 deletions

View File

@ -574,7 +574,7 @@ Event_db_repository::open_event_table(THD *thd, enum thr_lock_type lock_type,
tables.init_one_table("mysql", 5, "event", 5, "event", lock_type); tables.init_one_table("mysql", 5, "event", 5, "event", lock_type);
if (simple_open_n_lock_tables(thd, &tables)) if (open_and_lock_tables(thd, &tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
{ {
close_thread_tables(thd); close_thread_tables(thd);
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
@ -1129,11 +1129,10 @@ Event_db_repository::check_system_tables(THD *thd)
DBUG_ENTER("Event_db_repository::check_system_tables"); DBUG_ENTER("Event_db_repository::check_system_tables");
DBUG_PRINT("enter", ("thd: 0x%lx", (long) thd)); DBUG_PRINT("enter", ("thd: 0x%lx", (long) thd));
/* Check mysql.db */ /* Check mysql.db */
tables.init_one_table("mysql", 5, "db", 2, "db", TL_READ); tables.init_one_table("mysql", 5, "db", 2, "db", TL_READ);
if (simple_open_n_lock_tables(thd, &tables)) if (open_and_lock_tables(thd, &tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
{ {
ret= 1; ret= 1;
sql_print_error("Cannot open mysql.db"); sql_print_error("Cannot open mysql.db");
@ -1148,7 +1147,7 @@ Event_db_repository::check_system_tables(THD *thd)
/* Check mysql.user */ /* Check mysql.user */
tables.init_one_table("mysql", 5, "user", 4, "user", TL_READ); tables.init_one_table("mysql", 5, "user", 4, "user", TL_READ);
if (simple_open_n_lock_tables(thd, &tables)) if (open_and_lock_tables(thd, &tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
{ {
ret= 1; ret= 1;
sql_print_error("Cannot open mysql.user"); sql_print_error("Cannot open mysql.user");
@ -1168,7 +1167,7 @@ Event_db_repository::check_system_tables(THD *thd)
/* Check mysql.event */ /* Check mysql.event */
tables.init_one_table("mysql", 5, "event", 5, "event", TL_READ); tables.init_one_table("mysql", 5, "event", 5, "event", TL_READ);
if (simple_open_n_lock_tables(thd, &tables)) if (open_and_lock_tables(thd, &tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
{ {
ret= 1; ret= 1;
sql_print_error("Cannot open mysql.event"); sql_print_error("Cannot open mysql.event");

View File

@ -203,6 +203,9 @@ pre_init_event_thread(THD* thd)
thd->version= refresh_version; thd->version= refresh_version;
thd->set_time(); thd->set_time();
/* Do not use user-supplied timeout value for system threads. */
thd->variables.lock_wait_timeout= LONG_TIMEOUT;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }

View File

@ -9504,6 +9504,8 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused)))
my_net_init(&thd->net, 0); my_net_init(&thd->net, 0);
thd->main_security_ctx.master_access= ~0; thd->main_security_ctx.master_access= ~0;
thd->main_security_ctx.priv_user = 0; thd->main_security_ctx.priv_user = 0;
/* Do not use user-supplied timeout value for system threads. */
thd->variables.lock_wait_timeout= LONG_TIMEOUT;
CHARSET_INFO *charset_connection; CHARSET_INFO *charset_connection;
charset_connection= get_charset_by_csname("utf8", charset_connection= get_charset_by_csname("utf8",

View File

@ -2348,7 +2348,7 @@ static int open_ndb_binlog_index(THD *thd, TABLE **ndb_binlog_index)
tables->required_type= FRMTYPE_TABLE; tables->required_type= FRMTYPE_TABLE;
uint counter; uint counter;
thd->clear_error(); thd->clear_error();
if (simple_open_n_lock_tables(thd, tables)) if (open_and_lock_tables(thd, tables, FALSE, 0))
{ {
if (thd->killed) if (thd->killed)
sql_print_error("NDB Binlog: Opening ndb_binlog_index: killed"); sql_print_error("NDB Binlog: Opening ndb_binlog_index: killed");
@ -3675,6 +3675,8 @@ pthread_handler_t ndb_binlog_thread_func(void *arg)
my_net_init(&thd->net, 0); my_net_init(&thd->net, 0);
thd->main_security_ctx.master_access= ~0; thd->main_security_ctx.master_access= ~0;
thd->main_security_ctx.priv_user= 0; thd->main_security_ctx.priv_user= 0;
/* Do not use user-supplied timeout value for system threads. */
thd->variables.lock_wait_timeout= LONG_TIMEOUT;
/* /*
Set up ndb binlog Set up ndb binlog

View File

@ -251,6 +251,7 @@ static void reset_lock_data_and_free(MYSQL_LOCK **mysql_lock)
MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK Ignore a global read lock MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK Ignore a global read lock
MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY Ignore SET GLOBAL READ_ONLY MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY Ignore SET GLOBAL READ_ONLY
MYSQL_LOCK_IGNORE_FLUSH Ignore a flush tables. MYSQL_LOCK_IGNORE_FLUSH Ignore a flush tables.
MYSQL_LOCK_IGNORE_TIMEOUT Use maximum timeout value.
@param need_reopen Out parameter, TRUE if some tables were altered @param need_reopen Out parameter, TRUE if some tables were altered
or deleted and should be reopened by caller. or deleted and should be reopened by caller.
@ -277,6 +278,9 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
if (mysql_lock_tables_check(thd, tables, count, flags)) if (mysql_lock_tables_check(thd, tables, count, flags))
DBUG_RETURN (NULL); DBUG_RETURN (NULL);
ulong timeout= (flags & MYSQL_LOCK_IGNORE_TIMEOUT) ?
LONG_TIMEOUT : thd->variables.lock_wait_timeout;
for (;;) for (;;)
{ {
if (! (sql_lock= get_lock_data(thd, tables, count, GET_LOCK_STORE_LOCKS, if (! (sql_lock= get_lock_data(thd, tables, count, GET_LOCK_STORE_LOCKS,
@ -336,8 +340,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
rc= thr_lock_errno_to_mysql[(int) thr_multi_lock(sql_lock->locks + rc= thr_lock_errno_to_mysql[(int) thr_multi_lock(sql_lock->locks +
sql_lock->lock_count, sql_lock->lock_count,
sql_lock->lock_count, sql_lock->lock_count,
thd->lock_id, thd->lock_id, timeout)];
thd->variables.lock_wait_timeout)];
if (rc > 1) /* a timeout or a deadlock */ if (rc > 1) /* a timeout or a deadlock */
{ {
if (sql_lock->table_count) if (sql_lock->table_count)

View File

@ -7480,7 +7480,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
/* A small test to verify that objects have consistent types */ /* A small test to verify that objects have consistent types */
DBUG_ASSERT(sizeof(thd->variables.option_bits) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS)); DBUG_ASSERT(sizeof(thd->variables.option_bits) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
if (simple_open_n_lock_tables(thd, rli->tables_to_lock)) if (open_and_lock_tables(thd, rli->tables_to_lock, FALSE, 0))
{ {
uint actual_error= thd->stmt_da->sql_errno(); uint actual_error= thd->stmt_da->sql_errno();
if (thd->is_slave_error || thd->is_fatal_error) if (thd->is_slave_error || thd->is_fatal_error)

View File

@ -73,7 +73,7 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, const Relay_log_info
*/ */
thd->lex->set_stmt_row_injection(); thd->lex->set_stmt_row_injection();
if (simple_open_n_lock_tables(thd, rli->tables_to_lock)) if (open_and_lock_tables(thd, rli->tables_to_lock, FALSE, 0))
{ {
uint actual_error= thd->stmt_da->sql_errno(); uint actual_error= thd->stmt_da->sql_errno();
if (thd->is_slave_error || thd->is_fatal_error) if (thd->is_slave_error || thd->is_fatal_error)

View File

@ -1562,27 +1562,17 @@ open_tables(THD *thd, TABLE_LIST **tables, uint *counter, uint flags)
return open_tables(thd, tables, counter, flags, &prelocking_strategy); return open_tables(thd, tables, counter, flags, &prelocking_strategy);
} }
/* open_and_lock_tables with optional derived handling */ /* open_and_lock_tables with optional derived handling */
bool open_and_lock_tables_derived(THD *thd, TABLE_LIST *tables, bool open_and_lock_tables(THD *thd, TABLE_LIST *tables,
bool derived, uint flags, bool derived, uint flags,
Prelocking_strategy *prelocking_strategy); Prelocking_strategy *prelocking_strategy);
inline bool open_and_lock_tables_derived(THD *thd, TABLE_LIST *tables, inline bool open_and_lock_tables(THD *thd, TABLE_LIST *tables,
bool derived, uint flags) bool derived, uint flags)
{ {
DML_prelocking_strategy prelocking_strategy; DML_prelocking_strategy prelocking_strategy;
return open_and_lock_tables_derived(thd, tables, derived, flags, return open_and_lock_tables(thd, tables, derived, flags,
&prelocking_strategy); &prelocking_strategy);
} }
/* simple open_and_lock_tables without derived handling */
inline bool simple_open_n_lock_tables(THD *thd, TABLE_LIST *tables)
{
return open_and_lock_tables_derived(thd, tables, FALSE, 0);
}
/* open_and_lock_tables with derived handling */
inline bool open_and_lock_tables(THD *thd, TABLE_LIST *tables)
{
return open_and_lock_tables_derived(thd, tables, TRUE, 0);
}
/* simple open_and_lock_tables without derived handling for single table */ /* simple open_and_lock_tables without derived handling for single table */
TABLE *open_n_lock_single_table(THD *thd, TABLE_LIST *table_l, TABLE *open_n_lock_single_table(THD *thd, TABLE_LIST *table_l,
thr_lock_type lock_type, uint flags); thr_lock_type lock_type, uint flags);
@ -2171,11 +2161,17 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **table, uint count,
in parser. in parser.
*/ */
#define MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL 0x0800 #define MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL 0x0800
/**
When opening or locking the table, use the maximum timeout
(LONG_TIMEOUT = 1 year) rather than the user-supplied timeout value.
*/
#define MYSQL_LOCK_IGNORE_TIMEOUT 0x1000
/** Please refer to the internals manual. */ /** Please refer to the internals manual. */
#define MYSQL_OPEN_REOPEN (MYSQL_LOCK_IGNORE_FLUSH |\ #define MYSQL_OPEN_REOPEN (MYSQL_LOCK_IGNORE_FLUSH |\
MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK |\ MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK |\
MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY |\ MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY |\
MYSQL_LOCK_IGNORE_TIMEOUT |\
MYSQL_OPEN_GET_NEW_TABLE |\ MYSQL_OPEN_GET_NEW_TABLE |\
MYSQL_OPEN_SKIP_TEMPORARY |\ MYSQL_OPEN_SKIP_TEMPORARY |\
MYSQL_OPEN_HAS_MDL_LOCK) MYSQL_OPEN_HAS_MDL_LOCK)

View File

@ -2030,6 +2030,8 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
thd_proc_info(thd, "Waiting for master update"); thd_proc_info(thd, "Waiting for master update");
thd->version=refresh_version; thd->version=refresh_version;
thd->set_time(); thd->set_time();
/* Do not use user-supplied timeout value for system threads. */
thd->variables.lock_wait_timeout= LONG_TIMEOUT;
DBUG_RETURN(0); DBUG_RETURN(0);
} }

View File

@ -2825,7 +2825,7 @@ int sp_instr::exec_open_and_lock_tables(THD *thd, TABLE_LIST *tables)
and open and lock them before executing instructions core function. and open and lock them before executing instructions core function.
*/ */
if (check_table_access(thd, SELECT_ACL, tables, FALSE, UINT_MAX, FALSE) if (check_table_access(thd, SELECT_ACL, tables, FALSE, UINT_MAX, FALSE)
|| open_and_lock_tables(thd, tables)) || open_and_lock_tables(thd, tables, TRUE, 0))
result= -1; result= -1;
else else
result= 0; result= 0;

View File

@ -675,7 +675,7 @@ my_bool acl_reload(THD *thd)
tables[0].open_type= tables[1].open_type= tables[2].open_type= OT_BASE_ONLY; tables[0].open_type= tables[1].open_type= tables[2].open_type= OT_BASE_ONLY;
init_mdl_requests(tables); init_mdl_requests(tables);
if (simple_open_n_lock_tables(thd, tables)) if (open_and_lock_tables(thd, tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
{ {
/* /*
Execution might have been interrupted; only print the error message Execution might have been interrupted; only print the error message
@ -1602,7 +1602,7 @@ bool change_password(THD *thd, const char *host, const char *user,
} }
#endif #endif
if (!(table= open_ltable(thd, &tables, TL_WRITE, 0))) if (!(table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT)))
DBUG_RETURN(1); DBUG_RETURN(1);
mysql_mutex_lock(&acl_cache->lock); mysql_mutex_lock(&acl_cache->lock);
@ -3040,7 +3040,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
class LEX_COLUMN *column; class LEX_COLUMN *column;
List_iterator <LEX_COLUMN> column_iter(columns); List_iterator <LEX_COLUMN> column_iter(columns);
if (open_and_lock_tables(thd, table_list)) if (open_and_lock_tables(thd, table_list, TRUE, 0))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
while ((column = column_iter++)) while ((column = column_iter++))
@ -3146,7 +3146,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
*/ */
Query_tables_list backup; Query_tables_list backup;
thd->lex->reset_n_backup_query_tables_list(&backup); thd->lex->reset_n_backup_query_tables_list(&backup);
if (simple_open_n_lock_tables(thd,tables)) if (open_and_lock_tables(thd, tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
{ // Should never happen { // Should never happen
close_thread_tables(thd); /* purecov: deadcode */ close_thread_tables(thd); /* purecov: deadcode */
/* Restore the state of binlog format */ /* Restore the state of binlog format */
@ -3374,7 +3374,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
} }
#endif #endif
if (simple_open_n_lock_tables(thd,tables)) if (open_and_lock_tables(thd, tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
{ // Should never happen { // Should never happen
close_thread_tables(thd); close_thread_tables(thd);
/* Restore the state of binlog format */ /* Restore the state of binlog format */
@ -3531,7 +3531,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
} }
#endif #endif
if (simple_open_n_lock_tables(thd,tables)) if (open_and_lock_tables(thd, tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
{ // This should never happen { // This should never happen
close_thread_tables(thd); /* purecov: deadcode */ close_thread_tables(thd); /* purecov: deadcode */
/* Restore the state of binlog format */ /* Restore the state of binlog format */
@ -3853,7 +3853,7 @@ static my_bool grant_reload_procs_priv(THD *thd)
TL_READ); TL_READ);
table.open_type= OT_BASE_ONLY; table.open_type= OT_BASE_ONLY;
if (simple_open_n_lock_tables(thd, &table)) if (open_and_lock_tables(thd, &table, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
{ {
close_thread_tables(thd); close_thread_tables(thd);
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
@ -3924,7 +3924,7 @@ my_bool grant_reload(THD *thd)
To avoid deadlocks we should obtain table locks before To avoid deadlocks we should obtain table locks before
obtaining LOCK_grant rwlock. obtaining LOCK_grant rwlock.
*/ */
if (simple_open_n_lock_tables(thd, tables)) if (open_and_lock_tables(thd, tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
goto end; goto end;
mysql_rwlock_wrlock(&LOCK_grant); mysql_rwlock_wrlock(&LOCK_grant);
@ -5227,7 +5227,7 @@ int open_grant_tables(THD *thd, TABLE_LIST *tables)
} }
#endif #endif
if (simple_open_n_lock_tables(thd, tables)) if (open_and_lock_tables(thd, tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
{ // This should never happen { // This should never happen
close_thread_tables(thd); close_thread_tables(thd);
DBUG_RETURN(-1); DBUG_RETURN(-1);

View File

@ -122,7 +122,8 @@ static bool open_table_entry_fini(THD *thd, TABLE_SHARE *share, TABLE *entry);
static bool auto_repair_table(THD *thd, TABLE_LIST *table_list); static bool auto_repair_table(THD *thd, TABLE_LIST *table_list);
static void free_cache_entry(TABLE *entry); static void free_cache_entry(TABLE *entry);
static bool tdc_wait_for_old_versions(THD *thd, static bool tdc_wait_for_old_versions(THD *thd,
MDL_request_list *mdl_requests); MDL_request_list *mdl_requests,
ulong timeout);
static bool static bool
has_write_table_with_auto_increment(TABLE_LIST *tables); has_write_table_with_auto_increment(TABLE_LIST *tables);
@ -2363,8 +2364,7 @@ open_table_get_mdl_lock(THD *thd, TABLE_LIST *table_list,
mdl_requests.push_front(mdl_request); mdl_requests.push_front(mdl_request);
mdl_requests.push_front(global_request); mdl_requests.push_front(global_request);
if (thd->mdl_context.acquire_locks(&mdl_requests, if (thd->mdl_context.acquire_locks(&mdl_requests, ot_ctx->get_timeout()))
thd->variables.lock_wait_timeout))
return 1; return 1;
} }
else else
@ -3308,7 +3308,7 @@ unlink_all_closed_tables(THD *thd, MYSQL_LOCK *lock, size_t reopen_count)
bool bool
Locked_tables_list::reopen_tables(THD *thd) Locked_tables_list::reopen_tables(THD *thd)
{ {
Open_table_context ot_ctx_unused(thd); Open_table_context ot_ctx_unused(thd, LONG_TIMEOUT);
bool lt_refresh_unused; bool lt_refresh_unused;
size_t reopen_count= 0; size_t reopen_count= 0;
MYSQL_LOCK *lock; MYSQL_LOCK *lock;
@ -3744,13 +3744,14 @@ end_with_lock_open:
/** Open_table_context */ /** Open_table_context */
Open_table_context::Open_table_context(THD *thd) Open_table_context::Open_table_context(THD *thd, ulong timeout)
:m_action(OT_NO_ACTION), :m_action(OT_NO_ACTION),
m_start_of_statement_svp(thd->mdl_context.mdl_savepoint()), m_start_of_statement_svp(thd->mdl_context.mdl_savepoint()),
m_has_locks((thd->in_multi_stmt_transaction() && m_has_locks((thd->in_multi_stmt_transaction() &&
thd->mdl_context.has_locks()) || thd->mdl_context.has_locks()) ||
thd->mdl_context.trans_sentinel()), thd->mdl_context.trans_sentinel()),
m_global_mdl_request(NULL) m_global_mdl_request(NULL),
m_timeout(timeout)
{} {}
@ -3845,11 +3846,10 @@ recover_from_failed_open(THD *thd, MDL_request *mdl_request,
switch (m_action) switch (m_action)
{ {
case OT_WAIT_MDL_LOCK: case OT_WAIT_MDL_LOCK:
result= thd->mdl_context.wait_for_lock(mdl_request, result= thd->mdl_context.wait_for_lock(mdl_request, get_timeout());
thd->variables.lock_wait_timeout);
break; break;
case OT_WAIT_TDC: case OT_WAIT_TDC:
result= tdc_wait_for_old_versions(thd, &m_mdl_requests); result= tdc_wait_for_old_versions(thd, &m_mdl_requests, get_timeout());
DBUG_ASSERT(thd->mysys_var->current_mutex == NULL); DBUG_ASSERT(thd->mysys_var->current_mutex == NULL);
break; break;
case OT_DISCOVER: case OT_DISCOVER:
@ -3866,8 +3866,7 @@ recover_from_failed_open(THD *thd, MDL_request *mdl_request,
mdl_requests.push_front(&mdl_global_request); mdl_requests.push_front(&mdl_global_request);
if ((result= if ((result=
thd->mdl_context.acquire_locks(&mdl_requests, thd->mdl_context.acquire_locks(&mdl_requests, get_timeout())))
thd->variables.lock_wait_timeout)))
break; break;
DBUG_ASSERT(mdl_request->key.mdl_namespace() == MDL_key::TABLE); DBUG_ASSERT(mdl_request->key.mdl_namespace() == MDL_key::TABLE);
@ -3899,8 +3898,7 @@ recover_from_failed_open(THD *thd, MDL_request *mdl_request,
mdl_requests.push_front(&mdl_global_request); mdl_requests.push_front(&mdl_global_request);
if ((result= if ((result=
thd->mdl_context.acquire_locks(&mdl_requests, thd->mdl_context.acquire_locks(&mdl_requests, get_timeout())))
thd->variables.lock_wait_timeout)))
break; break;
DBUG_ASSERT(mdl_request->key.mdl_namespace() == MDL_key::TABLE); DBUG_ASSERT(mdl_request->key.mdl_namespace() == MDL_key::TABLE);
@ -4397,8 +4395,7 @@ open_tables_acquire_upgradable_mdl(THD *thd, TABLE_LIST *tables_start,
mdl_requests.push_front(global_request); mdl_requests.push_front(global_request);
} }
if (thd->mdl_context.acquire_locks(&mdl_requests, if (thd->mdl_context.acquire_locks(&mdl_requests, ot_ctx->get_timeout()))
thd->variables.lock_wait_timeout))
return TRUE; return TRUE;
for (table= tables_start; table && table != tables_end; for (table= tables_start; table && table != tables_end;
@ -4457,7 +4454,8 @@ bool open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags,
TABLE_LIST **table_to_open; TABLE_LIST **table_to_open;
Sroutine_hash_entry **sroutine_to_open; Sroutine_hash_entry **sroutine_to_open;
TABLE_LIST *tables; TABLE_LIST *tables;
Open_table_context ot_ctx(thd); Open_table_context ot_ctx(thd, (flags & MYSQL_LOCK_IGNORE_TIMEOUT) ?
LONG_TIMEOUT : thd->variables.lock_wait_timeout);
bool error= FALSE; bool error= FALSE;
MEM_ROOT new_frm_mem; MEM_ROOT new_frm_mem;
bool has_prelocking_list; bool has_prelocking_list;
@ -4961,7 +4959,7 @@ TABLE *open_n_lock_single_table(THD *thd, TABLE_LIST *table_l,
table_l->required_type= FRMTYPE_TABLE; table_l->required_type= FRMTYPE_TABLE;
/* Open the table. */ /* Open the table. */
if (open_and_lock_tables_derived(thd, table_l, FALSE, flags)) if (open_and_lock_tables(thd, table_l, FALSE, flags))
table_l->table= NULL; /* Just to be sure. */ table_l->table= NULL; /* Just to be sure. */
/* Restore list. */ /* Restore list. */
@ -4999,7 +4997,8 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type,
uint lock_flags) uint lock_flags)
{ {
TABLE *table; TABLE *table;
Open_table_context ot_ctx(thd); Open_table_context ot_ctx(thd, (lock_flags & MYSQL_LOCK_IGNORE_TIMEOUT) ?
LONG_TIMEOUT : thd->variables.lock_wait_timeout);
bool refresh; bool refresh;
bool error; bool error;
DBUG_ENTER("open_ltable"); DBUG_ENTER("open_ltable");
@ -5098,18 +5097,11 @@ end:
@note @note
The lock will automaticaly be freed by close_thread_tables() The lock will automaticaly be freed by close_thread_tables()
@note
There are several convenience functions, e.g. :
- simple_open_n_lock_tables(thd, tables) without derived handling
- open_and_lock_tables(thd, tables) with derived handling
Both inline functions call open_and_lock_tables_derived() with
the third argument set appropriately.
@retval FALSE OK. @retval FALSE OK.
@retval TRUE Error @retval TRUE Error
*/ */
bool open_and_lock_tables_derived(THD *thd, TABLE_LIST *tables, bool open_and_lock_tables(THD *thd, TABLE_LIST *tables,
bool derived, uint flags, bool derived, uint flags,
Prelocking_strategy *prelocking_strategy) Prelocking_strategy *prelocking_strategy)
{ {
@ -5125,7 +5117,7 @@ bool open_and_lock_tables_derived(THD *thd, TABLE_LIST *tables,
statement. statement.
*/ */
MDL_ticket *start_of_statement_svp= thd->mdl_context.mdl_savepoint(); MDL_ticket *start_of_statement_svp= thd->mdl_context.mdl_savepoint();
DBUG_ENTER("open_and_lock_tables_derived"); DBUG_ENTER("open_and_lock_tables");
DBUG_PRINT("enter", ("derived handling: %d", derived)); DBUG_PRINT("enter", ("derived handling: %d", derived));
for ( ; ; ) for ( ; ; )
@ -8536,16 +8528,18 @@ void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
@param thd Thread context @param thd Thread context
@param context Metadata locking context with locks. @param context Metadata locking context with locks.
@param timeout Seconds to wait before reporting ER_LOCK_WAIT_TIMEOUT.
*/ */
static bool static bool
tdc_wait_for_old_versions(THD *thd, MDL_request_list *mdl_requests) tdc_wait_for_old_versions(THD *thd, MDL_request_list *mdl_requests,
ulong timeout)
{ {
TABLE_SHARE *share; TABLE_SHARE *share;
const char *old_msg; const char *old_msg;
MDL_request *mdl_request; MDL_request *mdl_request;
struct timespec abstime; struct timespec abstime;
set_timespec(abstime, thd->variables.lock_wait_timeout); set_timespec(abstime, timeout);
int wait_result= 0; int wait_result= 0;
while (!thd->killed) while (!thd->killed)
@ -8812,8 +8806,9 @@ open_system_tables_for_read(THD *thd, TABLE_LIST *table_list,
lex->reset_n_backup_query_tables_list(&query_tables_list_backup); lex->reset_n_backup_query_tables_list(&query_tables_list_backup);
thd->reset_n_backup_open_tables_state(backup); thd->reset_n_backup_open_tables_state(backup);
if (open_and_lock_tables_derived(thd, table_list, FALSE, if (open_and_lock_tables(thd, table_list, FALSE,
MYSQL_LOCK_IGNORE_FLUSH)) MYSQL_LOCK_IGNORE_FLUSH |
MYSQL_LOCK_IGNORE_TIMEOUT))
{ {
lex->restore_backup_query_tables_list(&query_tables_list_backup); lex->restore_backup_query_tables_list(&query_tables_list_backup);
goto error; goto error;
@ -8875,7 +8870,8 @@ open_system_table_for_update(THD *thd, TABLE_LIST *one_table)
{ {
DBUG_ENTER("open_system_table_for_update"); DBUG_ENTER("open_system_table_for_update");
TABLE *table= open_ltable(thd, one_table, one_table->lock_type, 0); TABLE *table= open_ltable(thd, one_table, one_table->lock_type,
MYSQL_LOCK_IGNORE_TIMEOUT);
if (table) if (table)
{ {
DBUG_ASSERT(table->s->table_category == TABLE_CATEGORY_SYSTEM); DBUG_ASSERT(table->s->table_category == TABLE_CATEGORY_SYSTEM);
@ -8902,6 +8898,7 @@ open_log_table(THD *thd, TABLE_LIST *one_table, Open_tables_backup *backup)
uint flags= ( MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK | uint flags= ( MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK |
MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY | MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY |
MYSQL_LOCK_IGNORE_FLUSH | MYSQL_LOCK_IGNORE_FLUSH |
MYSQL_LOCK_IGNORE_TIMEOUT |
MYSQL_LOCK_PERF_SCHEMA); MYSQL_LOCK_PERF_SCHEMA);
TABLE *table; TABLE *table;
/* Save value that is changed in mysql_lock_tables() */ /* Save value that is changed in mysql_lock_tables() */

View File

@ -1280,7 +1280,7 @@ public:
OT_DISCOVER, OT_DISCOVER,
OT_REPAIR OT_REPAIR
}; };
Open_table_context(THD *thd); Open_table_context(THD *thd, ulong timeout);
bool recover_from_failed_open(THD *thd, MDL_request *mdl_request, bool recover_from_failed_open(THD *thd, MDL_request *mdl_request,
TABLE_LIST *table); TABLE_LIST *table);
@ -1305,6 +1305,11 @@ public:
MDL_request *get_global_mdl_request(THD *thd); MDL_request *get_global_mdl_request(THD *thd);
inline ulong get_timeout() const
{
return m_timeout;
}
private: private:
/** List of requests for all locks taken so far. Used for waiting on locks. */ /** List of requests for all locks taken so far. Used for waiting on locks. */
MDL_request_list m_mdl_requests; MDL_request_list m_mdl_requests;
@ -1322,6 +1327,11 @@ private:
opening tables for statements which take upgradable shared metadata locks. opening tables for statements which take upgradable shared metadata locks.
*/ */
MDL_request *m_global_mdl_request; MDL_request *m_global_mdl_request;
/**
Lock timeout in seconds. Initialized to LONG_TIMEOUT when opening system
tables or to the "lock_wait_timeout" system variable for regular tables.
*/
uint m_timeout;
}; };

View File

@ -57,7 +57,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
THD::STMT_QUERY_TYPE : THD::STMT_QUERY_TYPE :
THD::ROW_QUERY_TYPE; THD::ROW_QUERY_TYPE;
if (open_and_lock_tables(thd, table_list)) if (open_and_lock_tables(thd, table_list, TRUE, 0))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
if (!(table= table_list->table)) if (!(table= table_list->table))
{ {

View File

@ -545,7 +545,7 @@ bool open_and_lock_for_insert_delayed(THD *thd, TABLE_LIST *table_list)
Open tables used for sub-selects or in stored functions, will also Open tables used for sub-selects or in stored functions, will also
cache these functions. cache these functions.
*/ */
if (open_and_lock_tables(thd, table_list->next_global)) if (open_and_lock_tables(thd, table_list->next_global, TRUE, 0))
{ {
end_delayed_insert(thd); end_delayed_insert(thd);
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
@ -569,7 +569,7 @@ bool open_and_lock_for_insert_delayed(THD *thd, TABLE_LIST *table_list)
Use a normal insert. Use a normal insert.
*/ */
table_list->lock_type= TL_WRITE; table_list->lock_type= TL_WRITE;
DBUG_RETURN(open_and_lock_tables(thd, table_list)); DBUG_RETURN(open_and_lock_tables(thd, table_list, TRUE, 0));
} }
@ -646,7 +646,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
} }
else else
{ {
if (open_and_lock_tables(thd, table_list)) if (open_and_lock_tables(thd, table_list, TRUE, 0))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
lock_type= table_list->lock_type; lock_type= table_list->lock_type;
@ -3619,7 +3619,7 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE)) if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
{ {
Open_table_context ot_ctx_unused(thd); Open_table_context ot_ctx_unused(thd, LONG_TIMEOUT);
/* /*
Here we open the destination table, on which we already have Here we open the destination table, on which we already have
an exclusive metadata lock. an exclusive metadata lock.
@ -3638,7 +3638,7 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
} }
else else
{ {
Open_table_context ot_ctx_unused(thd); Open_table_context ot_ctx_unused(thd, LONG_TIMEOUT);
if (open_table(thd, create_table, thd->mem_root, &ot_ctx_unused, if (open_table(thd, create_table, thd->mem_root, &ot_ctx_unused,
MYSQL_OPEN_TEMPORARY_ONLY)) MYSQL_OPEN_TEMPORARY_ONLY))
{ {

View File

@ -195,7 +195,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
ER(WARN_NON_ASCII_SEPARATOR_NOT_IMPLEMENTED)); ER(WARN_NON_ASCII_SEPARATOR_NOT_IMPLEMENTED));
} }
if (open_and_lock_tables(thd, table_list)) if (open_and_lock_tables(thd, table_list, TRUE, 0))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context, if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
&thd->lex->select_lex.top_join_list, &thd->lex->select_lex.top_join_list,

View File

@ -2077,7 +2077,7 @@ case SQLCOM_PREPARE:
} }
case SQLCOM_DO: case SQLCOM_DO:
if (check_table_access(thd, SELECT_ACL, all_tables, FALSE, UINT_MAX, FALSE) if (check_table_access(thd, SELECT_ACL, all_tables, FALSE, UINT_MAX, FALSE)
|| open_and_lock_tables(thd, all_tables)) || open_and_lock_tables(thd, all_tables, TRUE, 0))
goto error; goto error;
res= mysql_do(thd, *lex->insert_list); res= mysql_do(thd, *lex->insert_list);
@ -2414,7 +2414,7 @@ case SQLCOM_PREPARE:
create_table->open_type= OT_BASE_ONLY; create_table->open_type= OT_BASE_ONLY;
} }
if (!(res= open_and_lock_tables_derived(thd, lex->query_tables, TRUE, 0))) if (!(res= open_and_lock_tables(thd, lex->query_tables, TRUE, 0)))
{ {
/* /*
Is table which we are changing used somewhere in other parts Is table which we are changing used somewhere in other parts
@ -3007,7 +3007,7 @@ end_with_restore_list:
unit->set_limit(select_lex); unit->set_limit(select_lex);
if (!(res= open_and_lock_tables(thd, all_tables))) if (!(res= open_and_lock_tables(thd, all_tables, TRUE, 0)))
{ {
MYSQL_INSERT_SELECT_START(thd->query()); MYSQL_INSERT_SELECT_START(thd->query());
/* Skip first table, which is the table we are inserting in */ /* Skip first table, which is the table we are inserting in */
@ -3109,7 +3109,7 @@ end_with_restore_list:
goto error; goto error;
thd_proc_info(thd, "init"); thd_proc_info(thd, "init");
if ((res= open_and_lock_tables(thd, all_tables))) if ((res= open_and_lock_tables(thd, all_tables, TRUE, 0)))
break; break;
MYSQL_MULTI_DELETE_START(thd->query()); MYSQL_MULTI_DELETE_START(thd->query());
@ -3237,7 +3237,7 @@ end_with_restore_list:
List<set_var_base> *lex_var_list= &lex->var_list; List<set_var_base> *lex_var_list= &lex->var_list;
if ((check_table_access(thd, SELECT_ACL, all_tables, FALSE, UINT_MAX, FALSE) if ((check_table_access(thd, SELECT_ACL, all_tables, FALSE, UINT_MAX, FALSE)
|| open_and_lock_tables(thd, all_tables))) || open_and_lock_tables(thd, all_tables, TRUE, 0)))
goto error; goto error;
if (!(res= sql_set_variables(thd, lex_var_list))) if (!(res= sql_set_variables(thd, lex_var_list)))
{ {
@ -3303,7 +3303,7 @@ end_with_restore_list:
{ {
Lock_tables_prelocking_strategy lock_tables_prelocking_strategy; Lock_tables_prelocking_strategy lock_tables_prelocking_strategy;
res= (open_and_lock_tables_derived(thd, all_tables, FALSE, res= (open_and_lock_tables(thd, all_tables, FALSE,
MYSQL_OPEN_TAKE_UPGRADABLE_MDL, MYSQL_OPEN_TAKE_UPGRADABLE_MDL,
&lock_tables_prelocking_strategy) || &lock_tables_prelocking_strategy) ||
thd->locked_tables_list.init_locked_tables(thd)); thd->locked_tables_list.init_locked_tables(thd));
@ -4008,7 +4008,7 @@ create_sp_error:
*/ */
if (check_table_access(thd, SELECT_ACL, all_tables, FALSE, if (check_table_access(thd, SELECT_ACL, all_tables, FALSE,
UINT_MAX, FALSE) || UINT_MAX, FALSE) ||
open_and_lock_tables(thd, all_tables)) open_and_lock_tables(thd, all_tables, TRUE, 0))
goto error; goto error;
/* /*
@ -4510,7 +4510,7 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
param->select_limit= param->select_limit=
new Item_int((ulonglong) thd->variables.select_limit); new Item_int((ulonglong) thd->variables.select_limit);
} }
if (!(res= open_and_lock_tables(thd, all_tables))) if (!(res= open_and_lock_tables(thd, all_tables, TRUE, 0)))
{ {
if (lex->describe) if (lex->describe)
{ {

View File

@ -1469,7 +1469,7 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv)
goto end; goto end;
#endif /* EMBEDDED_LIBRARY */ #endif /* EMBEDDED_LIBRARY */
if (simple_open_n_lock_tables(new_thd, &tables)) if (open_and_lock_tables(new_thd, &tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
{ {
DBUG_PRINT("error",("Can't open plugin table")); DBUG_PRINT("error",("Can't open plugin table"));
sql_print_error("Can't open the mysql.plugin table. Please " sql_print_error("Can't open the mysql.plugin table. Please "
@ -1746,7 +1746,8 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING *dl
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
/* need to open before acquiring LOCK_plugin or it will deadlock */ /* need to open before acquiring LOCK_plugin or it will deadlock */
if (! (table = open_ltable(thd, &tables, TL_WRITE, 0))) if (! (table = open_ltable(thd, &tables, TL_WRITE,
MYSQL_LOCK_IGNORE_TIMEOUT)))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
mysql_mutex_lock(&LOCK_plugin); mysql_mutex_lock(&LOCK_plugin);
@ -1817,7 +1818,7 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name)
tables.init_one_table("mysql", 5, "plugin", 6, "plugin", TL_WRITE); tables.init_one_table("mysql", 5, "plugin", 6, "plugin", TL_WRITE);
/* need to open before acquiring LOCK_plugin or it will deadlock */ /* need to open before acquiring LOCK_plugin or it will deadlock */
if (! (table= open_ltable(thd, &tables, TL_WRITE, 0))) if (! (table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT)))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
mysql_mutex_lock(&LOCK_plugin); mysql_mutex_lock(&LOCK_plugin);

View File

@ -253,7 +253,7 @@ bool servers_reload(THD *thd)
tables[0].init_one_table("mysql", 5, "servers", 7, "servers", TL_READ); tables[0].init_one_table("mysql", 5, "servers", 7, "servers", TL_READ);
if (simple_open_n_lock_tables(thd, tables)) if (open_and_lock_tables(thd, tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
{ {
/* /*
Execution might have been interrupted; only print the error message Execution might have been interrupted; only print the error message
@ -390,7 +390,7 @@ insert_server(THD *thd, FOREIGN_SERVER *server)
tables.init_one_table("mysql", 5, "servers", 7, "servers", TL_WRITE); tables.init_one_table("mysql", 5, "servers", 7, "servers", TL_WRITE);
/* need to open before acquiring THR_LOCK_plugin or it will deadlock */ /* need to open before acquiring THR_LOCK_plugin or it will deadlock */
if (! (table= open_ltable(thd, &tables, TL_WRITE, 0))) if (! (table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT)))
goto end; goto end;
/* insert the server into the table */ /* insert the server into the table */
@ -611,7 +611,7 @@ int drop_server(THD *thd, LEX_SERVER_OPTIONS *server_options)
if ((error= delete_server_record_in_cache(server_options))) if ((error= delete_server_record_in_cache(server_options)))
goto end; goto end;
if (! (table= open_ltable(thd, &tables, TL_WRITE, 0))) if (! (table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT)))
{ {
error= my_errno; error= my_errno;
goto end; goto end;
@ -728,7 +728,7 @@ int update_server(THD *thd, FOREIGN_SERVER *existing, FOREIGN_SERVER *altered)
tables.init_one_table("mysql", 5, "servers", 7, "servers", tables.init_one_table("mysql", 5, "servers", 7, "servers",
TL_WRITE); TL_WRITE);
if (!(table= open_ltable(thd, &tables, TL_WRITE, 0))) if (!(table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT)))
{ {
error= my_errno; error= my_errno;
goto end; goto end;

View File

@ -4227,8 +4227,7 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
/* /*
Open or obtain an exclusive metadata lock on table being created. Open or obtain an exclusive metadata lock on table being created.
*/ */
if (open_and_lock_tables_derived(thd, thd->lex->query_tables, FALSE, if (open_and_lock_tables(thd, thd->lex->query_tables, FALSE, 0))
0))
{ {
result= TRUE; result= TRUE;
goto unlock; goto unlock;
@ -4427,7 +4426,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
char from[FN_REFLEN],tmp[FN_REFLEN+32]; char from[FN_REFLEN],tmp[FN_REFLEN+32];
const char **ext; const char **ext;
MY_STAT stat_info; MY_STAT stat_info;
Open_table_context ot_ctx_unused(thd); Open_table_context ot_ctx_unused(thd, LONG_TIMEOUT);
DBUG_ENTER("prepare_for_repair"); DBUG_ENTER("prepare_for_repair");
uint reopen_for_repair_flags= (MYSQL_LOCK_IGNORE_FLUSH | uint reopen_for_repair_flags= (MYSQL_LOCK_IGNORE_FLUSH |
MYSQL_OPEN_HAS_MDL_LOCK); MYSQL_OPEN_HAS_MDL_LOCK);
@ -4679,7 +4678,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
if (view_operator_func == NULL) if (view_operator_func == NULL)
table->required_type=FRMTYPE_TABLE; table->required_type=FRMTYPE_TABLE;
open_error= open_and_lock_tables_derived(thd, table, TRUE, open_error= open_and_lock_tables(thd, table, TRUE,
MYSQL_OPEN_TAKE_UPGRADABLE_MDL); MYSQL_OPEN_TAKE_UPGRADABLE_MDL);
thd->no_warnings_for_error= 0; thd->no_warnings_for_error= 0;
table->next_global= save_next_global; table->next_global= save_next_global;
@ -5349,7 +5348,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
char buf[2048]; char buf[2048];
String query(buf, sizeof(buf), system_charset_info); String query(buf, sizeof(buf), system_charset_info);
query.length(0); // Have to zero it since constructor doesn't query.length(0); // Have to zero it since constructor doesn't
Open_table_context ot_ctx_unused(thd); Open_table_context ot_ctx_unused(thd, LONG_TIMEOUT);
/* /*
The condition avoids a crash as described in BUG#48506. Other The condition avoids a crash as described in BUG#48506. Other
@ -6558,7 +6557,7 @@ view_err:
Alter_table_prelocking_strategy alter_prelocking_strategy(alter_info); Alter_table_prelocking_strategy alter_prelocking_strategy(alter_info);
error= open_and_lock_tables_derived(thd, table_list, FALSE, error= open_and_lock_tables(thd, table_list, FALSE,
MYSQL_OPEN_TAKE_UPGRADABLE_MDL, MYSQL_OPEN_TAKE_UPGRADABLE_MDL,
&alter_prelocking_strategy); &alter_prelocking_strategy);
@ -7148,7 +7147,7 @@ view_err:
{ {
if (table->s->tmp_table) if (table->s->tmp_table)
{ {
Open_table_context ot_ctx_unused(thd); Open_table_context ot_ctx_unused(thd, LONG_TIMEOUT);
TABLE_LIST tbl; TABLE_LIST tbl;
bzero((void*) &tbl, sizeof(tbl)); bzero((void*) &tbl, sizeof(tbl));
tbl.db= new_db; tbl.db= new_db;
@ -7433,7 +7432,7 @@ view_err:
To do this we need to obtain a handler object for it. To do this we need to obtain a handler object for it.
NO need to tamper with MERGE tables. The real open is done later. NO need to tamper with MERGE tables. The real open is done later.
*/ */
Open_table_context ot_ctx_unused(thd); Open_table_context ot_ctx_unused(thd, LONG_TIMEOUT);
TABLE *t_table; TABLE *t_table;
if (new_name != table_name || new_db != db) if (new_name != table_name || new_db != db)
{ {

View File

@ -163,7 +163,7 @@ void udf_init()
tables.init_one_table(db, sizeof(db)-1, "func", 4, "func", TL_READ); tables.init_one_table(db, sizeof(db)-1, "func", 4, "func", TL_READ);
if (simple_open_n_lock_tables(new_thd, &tables)) if (open_and_lock_tables(new_thd, &tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
{ {
DBUG_PRINT("error",("Can't open udf table")); DBUG_PRINT("error",("Can't open udf table"));
sql_print_error("Can't open the mysql.func table. Please " sql_print_error("Can't open the mysql.func table. Please "
@ -505,7 +505,7 @@ int mysql_create_function(THD *thd,udf_func *udf)
tables.init_one_table("mysql", 5, "func", 4, "func", TL_WRITE); tables.init_one_table("mysql", 5, "func", 4, "func", TL_WRITE);
/* Allow creation of functions even if we can't open func table */ /* Allow creation of functions even if we can't open func table */
if (!(table = open_ltable(thd, &tables, TL_WRITE, 0))) if (!(table = open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT)))
goto err; goto err;
table->use_all_columns(); table->use_all_columns();
restore_record(table, s->default_values); // Default values for fields restore_record(table, s->default_values); // Default values for fields
@ -596,7 +596,7 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name)
tables.init_one_table("mysql", 5, "func", 4, "func", TL_WRITE); tables.init_one_table("mysql", 5, "func", 4, "func", TL_WRITE);
if (!(table = open_ltable(thd, &tables, TL_WRITE, 0))) if (!(table = open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT)))
goto err; goto err;
table->use_all_columns(); table->use_all_columns();
table->field[0]->store(exact_name_str, exact_name_len, &my_charset_bin); table->field[0]->store(exact_name_str, exact_name_len, &my_charset_bin);

View File

@ -396,7 +396,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
view->lock_strategy= TABLE_LIST::EXCLUSIVE_MDL; view->lock_strategy= TABLE_LIST::EXCLUSIVE_MDL;
view->open_type= OT_BASE_ONLY; view->open_type= OT_BASE_ONLY;
if (open_and_lock_tables(thd, lex->query_tables)) if (open_and_lock_tables(thd, lex->query_tables, TRUE, 0))
{ {
view= lex->unlink_first_table(&link_to_local); view= lex->unlink_first_table(&link_to_local);
res= TRUE; res= TRUE;

View File

@ -1667,8 +1667,8 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap)
We need to open only mysql.time_zone_leap_second, but we try to We need to open only mysql.time_zone_leap_second, but we try to
open all time zone tables to see if they exist. open all time zone tables to see if they exist.
*/ */
if (open_and_lock_tables_derived(thd, tz_tables, FALSE, if (open_and_lock_tables(thd, tz_tables, FALSE,
MYSQL_LOCK_IGNORE_FLUSH)) MYSQL_LOCK_IGNORE_FLUSH | MYSQL_LOCK_IGNORE_TIMEOUT))
{ {
sql_print_warning("Can't open and lock time zone table: %s " sql_print_warning("Can't open and lock time zone table: %s "
"trying to live without them", thd->stmt_da->message()); "trying to live without them", thd->stmt_da->message());

View File

@ -128,7 +128,7 @@ void PFS_engine_table_share::check_one_table(THD *thd)
thd->lex= &dummy_lex; thd->lex= &dummy_lex;
lex_start(thd); lex_start(thd);
if (! simple_open_n_lock_tables(thd, &tables)) if (! open_and_lock_tables(thd, &tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
{ {
PFS_check_intact checker; PFS_check_intact checker;