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 1dd2f90faf
commit e60ef89317
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);
if (simple_open_n_lock_tables(thd, &tables))
if (open_and_lock_tables(thd, &tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
{
close_thread_tables(thd);
DBUG_RETURN(TRUE);
@ -1129,11 +1129,10 @@ Event_db_repository::check_system_tables(THD *thd)
DBUG_ENTER("Event_db_repository::check_system_tables");
DBUG_PRINT("enter", ("thd: 0x%lx", (long) thd));
/* Check mysql.db */
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;
sql_print_error("Cannot open mysql.db");
@ -1148,7 +1147,7 @@ Event_db_repository::check_system_tables(THD *thd)
/* Check mysql.user */
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;
sql_print_error("Cannot open mysql.user");
@ -1168,7 +1167,7 @@ Event_db_repository::check_system_tables(THD *thd)
/* Check mysql.event */
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;
sql_print_error("Cannot open mysql.event");

View file

@ -203,6 +203,9 @@ pre_init_event_thread(THD* thd)
thd->version= refresh_version;
thd->set_time();
/* Do not use user-supplied timeout value for system threads. */
thd->variables.lock_wait_timeout= LONG_TIMEOUT;
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);
thd->main_security_ctx.master_access= ~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_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;
uint counter;
thd->clear_error();
if (simple_open_n_lock_tables(thd, tables))
if (open_and_lock_tables(thd, tables, FALSE, 0))
{
if (thd->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);
thd->main_security_ctx.master_access= ~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

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_ONLY Ignore SET GLOBAL READ_ONLY
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
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))
DBUG_RETURN (NULL);
ulong timeout= (flags & MYSQL_LOCK_IGNORE_TIMEOUT) ?
LONG_TIMEOUT : thd->variables.lock_wait_timeout;
for (;;)
{
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 +
sql_lock->lock_count,
sql_lock->lock_count,
thd->lock_id,
thd->variables.lock_wait_timeout)];
thd->lock_id, timeout)];
if (rc > 1) /* a timeout or a deadlock */
{
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 */
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();
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();
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();
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);
}
/* 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,
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)
{
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);
}
/* 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 */
TABLE *open_n_lock_single_table(THD *thd, TABLE_LIST *table_l,
thr_lock_type lock_type, uint flags);
@ -2171,11 +2161,17 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **table, uint count,
in parser.
*/
#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. */
#define MYSQL_OPEN_REOPEN (MYSQL_LOCK_IGNORE_FLUSH |\
MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK |\
MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY |\
MYSQL_LOCK_IGNORE_TIMEOUT |\
MYSQL_OPEN_GET_NEW_TABLE |\
MYSQL_OPEN_SKIP_TEMPORARY |\
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->version=refresh_version;
thd->set_time();
/* Do not use user-supplied timeout value for system threads. */
thd->variables.lock_wait_timeout= LONG_TIMEOUT;
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.
*/
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;
else
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;
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
@ -1602,7 +1602,7 @@ bool change_password(THD *thd, const char *host, const char *user,
}
#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);
mysql_mutex_lock(&acl_cache->lock);
@ -3040,7 +3040,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
class LEX_COLUMN *column;
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);
while ((column = column_iter++))
@ -3146,7 +3146,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
*/
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
close_thread_tables(thd); /* purecov: deadcode */
/* Restore the state of binlog format */
@ -3374,7 +3374,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
}
#endif
if (simple_open_n_lock_tables(thd,tables))
if (open_and_lock_tables(thd, tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
{ // Should never happen
close_thread_tables(thd);
/* Restore the state of binlog format */
@ -3531,7 +3531,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
}
#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
close_thread_tables(thd); /* purecov: deadcode */
/* Restore the state of binlog format */
@ -3853,7 +3853,7 @@ static my_bool grant_reload_procs_priv(THD *thd)
TL_READ);
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);
DBUG_RETURN(TRUE);
@ -3924,7 +3924,7 @@ my_bool grant_reload(THD *thd)
To avoid deadlocks we should obtain table locks before
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;
mysql_rwlock_wrlock(&LOCK_grant);
@ -5227,7 +5227,7 @@ int open_grant_tables(THD *thd, TABLE_LIST *tables)
}
#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
close_thread_tables(thd);
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 void free_cache_entry(TABLE *entry);
static bool tdc_wait_for_old_versions(THD *thd,
MDL_request_list *mdl_requests);
MDL_request_list *mdl_requests,
ulong timeout);
static bool
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(global_request);
if (thd->mdl_context.acquire_locks(&mdl_requests,
thd->variables.lock_wait_timeout))
if (thd->mdl_context.acquire_locks(&mdl_requests, ot_ctx->get_timeout()))
return 1;
}
else
@ -3308,7 +3308,7 @@ unlink_all_closed_tables(THD *thd, MYSQL_LOCK *lock, size_t reopen_count)
bool
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;
size_t reopen_count= 0;
MYSQL_LOCK *lock;
@ -3744,13 +3744,14 @@ end_with_lock_open:
/** 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_start_of_statement_svp(thd->mdl_context.mdl_savepoint()),
m_has_locks((thd->in_multi_stmt_transaction() &&
thd->mdl_context.has_locks()) ||
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)
{
case OT_WAIT_MDL_LOCK:
result= thd->mdl_context.wait_for_lock(mdl_request,
thd->variables.lock_wait_timeout);
result= thd->mdl_context.wait_for_lock(mdl_request, get_timeout());
break;
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);
break;
case OT_DISCOVER:
@ -3866,8 +3866,7 @@ recover_from_failed_open(THD *thd, MDL_request *mdl_request,
mdl_requests.push_front(&mdl_global_request);
if ((result=
thd->mdl_context.acquire_locks(&mdl_requests,
thd->variables.lock_wait_timeout)))
thd->mdl_context.acquire_locks(&mdl_requests, get_timeout())))
break;
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);
if ((result=
thd->mdl_context.acquire_locks(&mdl_requests,
thd->variables.lock_wait_timeout)))
thd->mdl_context.acquire_locks(&mdl_requests, get_timeout())))
break;
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);
}
if (thd->mdl_context.acquire_locks(&mdl_requests,
thd->variables.lock_wait_timeout))
if (thd->mdl_context.acquire_locks(&mdl_requests, ot_ctx->get_timeout()))
return TRUE;
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;
Sroutine_hash_entry **sroutine_to_open;
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;
MEM_ROOT new_frm_mem;
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;
/* 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. */
/* Restore list. */
@ -4999,7 +4997,8 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type,
uint lock_flags)
{
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 error;
DBUG_ENTER("open_ltable");
@ -5098,18 +5097,11 @@ end:
@note
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 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,
Prelocking_strategy *prelocking_strategy)
{
@ -5125,7 +5117,7 @@ bool open_and_lock_tables_derived(THD *thd, TABLE_LIST *tables,
statement.
*/
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));
for ( ; ; )
@ -8536,16 +8528,18 @@ void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
@param thd Thread context
@param context Metadata locking context with locks.
@param timeout Seconds to wait before reporting ER_LOCK_WAIT_TIMEOUT.
*/
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;
const char *old_msg;
MDL_request *mdl_request;
struct timespec abstime;
set_timespec(abstime, thd->variables.lock_wait_timeout);
set_timespec(abstime, timeout);
int wait_result= 0;
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);
thd->reset_n_backup_open_tables_state(backup);
if (open_and_lock_tables_derived(thd, table_list, FALSE,
MYSQL_LOCK_IGNORE_FLUSH))
if (open_and_lock_tables(thd, table_list, FALSE,
MYSQL_LOCK_IGNORE_FLUSH |
MYSQL_LOCK_IGNORE_TIMEOUT))
{
lex->restore_backup_query_tables_list(&query_tables_list_backup);
goto error;
@ -8875,7 +8870,8 @@ open_system_table_for_update(THD *thd, TABLE_LIST *one_table)
{
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)
{
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 |
MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY |
MYSQL_LOCK_IGNORE_FLUSH |
MYSQL_LOCK_IGNORE_TIMEOUT |
MYSQL_LOCK_PERF_SCHEMA);
TABLE *table;
/* Save value that is changed in mysql_lock_tables() */

View file

@ -1280,7 +1280,7 @@ public:
OT_DISCOVER,
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,
TABLE_LIST *table);
@ -1305,6 +1305,11 @@ public:
MDL_request *get_global_mdl_request(THD *thd);
inline ulong get_timeout() const
{
return m_timeout;
}
private:
/** List of requests for all locks taken so far. Used for waiting on locks. */
MDL_request_list m_mdl_requests;
@ -1322,6 +1327,11 @@ private:
opening tables for statements which take upgradable shared metadata locks.
*/
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::ROW_QUERY_TYPE;
if (open_and_lock_tables(thd, table_list))
if (open_and_lock_tables(thd, table_list, TRUE, 0))
DBUG_RETURN(TRUE);
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
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);
DBUG_RETURN(TRUE);
@ -569,7 +569,7 @@ bool open_and_lock_for_insert_delayed(THD *thd, TABLE_LIST *table_list)
Use a normal insert.
*/
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
{
if (open_and_lock_tables(thd, table_list))
if (open_and_lock_tables(thd, table_list, TRUE, 0))
DBUG_RETURN(TRUE);
}
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))
{
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
an exclusive metadata lock.
@ -3638,7 +3638,7 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
}
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,
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));
}
if (open_and_lock_tables(thd, table_list))
if (open_and_lock_tables(thd, table_list, TRUE, 0))
DBUG_RETURN(TRUE);
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
&thd->lex->select_lex.top_join_list,

View file

@ -2077,7 +2077,7 @@ case SQLCOM_PREPARE:
}
case SQLCOM_DO:
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;
res= mysql_do(thd, *lex->insert_list);
@ -2414,7 +2414,7 @@ case SQLCOM_PREPARE:
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
@ -3007,7 +3007,7 @@ end_with_restore_list:
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());
/* Skip first table, which is the table we are inserting in */
@ -3109,7 +3109,7 @@ end_with_restore_list:
goto error;
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;
MYSQL_MULTI_DELETE_START(thd->query());
@ -3237,7 +3237,7 @@ end_with_restore_list:
List<set_var_base> *lex_var_list= &lex->var_list;
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;
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;
res= (open_and_lock_tables_derived(thd, all_tables, FALSE,
res= (open_and_lock_tables(thd, all_tables, FALSE,
MYSQL_OPEN_TAKE_UPGRADABLE_MDL,
&lock_tables_prelocking_strategy) ||
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,
UINT_MAX, FALSE) ||
open_and_lock_tables(thd, all_tables))
open_and_lock_tables(thd, all_tables, TRUE, 0))
goto error;
/*
@ -4510,7 +4510,7 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
param->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)
{

View file

@ -1469,7 +1469,7 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv)
goto end;
#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"));
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);
/* 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);
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);
/* 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);
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);
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
@ -390,7 +390,7 @@ insert_server(THD *thd, FOREIGN_SERVER *server)
tables.init_one_table("mysql", 5, "servers", 7, "servers", TL_WRITE);
/* 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;
/* 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)))
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;
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",
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;
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.
*/
if (open_and_lock_tables_derived(thd, thd->lex->query_tables, FALSE,
0))
if (open_and_lock_tables(thd, thd->lex->query_tables, FALSE, 0))
{
result= TRUE;
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];
const char **ext;
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");
uint reopen_for_repair_flags= (MYSQL_LOCK_IGNORE_FLUSH |
MYSQL_OPEN_HAS_MDL_LOCK);
@ -4679,7 +4678,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
if (view_operator_func == NULL)
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);
thd->no_warnings_for_error= 0;
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];
String query(buf, sizeof(buf), system_charset_info);
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
@ -6558,7 +6557,7 @@ view_err:
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,
&alter_prelocking_strategy);
@ -7148,7 +7147,7 @@ view_err:
{
if (table->s->tmp_table)
{
Open_table_context ot_ctx_unused(thd);
Open_table_context ot_ctx_unused(thd, LONG_TIMEOUT);
TABLE_LIST tbl;
bzero((void*) &tbl, sizeof(tbl));
tbl.db= new_db;
@ -7433,7 +7432,7 @@ view_err:
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.
*/
Open_table_context ot_ctx_unused(thd);
Open_table_context ot_ctx_unused(thd, LONG_TIMEOUT);
TABLE *t_table;
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);
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"));
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);
/* 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;
table->use_all_columns();
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);
if (!(table = open_ltable(thd, &tables, TL_WRITE, 0)))
if (!(table = open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT)))
goto err;
table->use_all_columns();
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->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);
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
open all time zone tables to see if they exist.
*/
if (open_and_lock_tables_derived(thd, tz_tables, FALSE,
MYSQL_LOCK_IGNORE_FLUSH))
if (open_and_lock_tables(thd, tz_tables, FALSE,
MYSQL_LOCK_IGNORE_FLUSH | MYSQL_LOCK_IGNORE_TIMEOUT))
{
sql_print_warning("Can't open and lock time zone table: %s "
"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;
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;