Backport of:
---------------------------------------------------------- revno: 2630.4.26 committer: Konstantin Osipov <konstantin@mysql.com> branch nick: mysql-6.0-prelocked_mode-to-push timestamp: Fri 2008-06-06 23:19:04 +0400 message: WL#3726: work on review comments. Remove thd->locked_tables. Always store MYSQL_LOCK instances in thd->lock. Rename thd->prelocked_mode to thd->locked_tables_mode. Use thd->locked_tables_mode to determine if we are under LOCK TABLES. Update the code to not assume that if thd->lock is set, LOCK TABLES mode is off. Review comments. sql/ha_ndbcluster_binlog.cc: Don't unlock the lock under LOCK TABLES (safety). sql/handler.cc: There is no thd->locked_tables any more. Update comments. sql/lock.cc: There is no thd->locked_tables any more. sql/log.cc: Rename thd->prelocked_mode to thd->locked_tables_mode. sql/set_var.cc: Use thd->locked_tables_mode to determine if we are under LOCK TABLES. sql/sp_head.cc: Rename thd->prelocked_mode to thd->locked_tables_mode. sql/sql_base.cc: Use thd->locked_tables_mode to determine if we are under LOCK TABLES. Remove thd->locked_tables. sql/sql_cache.cc: Use thd->locked_tables_mode to determine if we are under LOCK TABLES. sql/sql_class.cc: Avoid code duplication. Do not release the table locks prematurely if we're under LOCK TABLES. Use thd->locked_tables_mode instead of thd->locked_tables. sql/sql_class.h: Remove thd->locked_tables. Make prelocked mode a kind of LOCK TABLES mode. Update comments. sql/sql_cursor.cc: Update comments. sql/sql_insert.cc: Use thd->locked_tables_mode to determine if we are under LOCK TABLES. Rename thd->prelocked_mode to thd->locked_tables_mode. sql/sql_load.cc: Rename thd->prelocked_mode to thd->locked_tables_mode. sql/sql_parse.cc: Use thd->locked_tables_mode to determine if we are under LOCK TABLES. Remove thd->locked_tables. sql/sql_partition.cc: Use thd->locked_tables_mode to determine if we are under LOCK TABLES. sql/sql_rename.cc: Use thd->locked_tables_mode to determine if we are under LOCK TABLES. sql/sql_select.cc: Use thd->locked_tables_mode to determine if we are under LOCK TABLES. sql/sql_table.cc: Use thd->locked_tables_mode to determine if we are under LOCK TABLES. sql/sql_trigger.cc: Use thd->locked_tables_mode to determine if we are under LOCK TABLES. sql/sql_update.cc: Use thd->locked_tables_mode to determine if we are under LOCK TABLES. sql/sql_view.cc: Use thd->locked_tables_mode to determine if we are under LOCK TABLES. storage/myisam/ha_myisam.cc: Use thd->locked_tables_mode to determine if we are under LOCK TABLES.
This commit is contained in:
parent
1b078b3f2d
commit
5969dcda21
@ -264,7 +264,7 @@ static void run_query(THD *thd, char *buf, char *end,
|
||||
DBUG_PRINT("query", ("%s", thd->query()));
|
||||
|
||||
DBUG_ASSERT(!thd->in_sub_stmt);
|
||||
DBUG_ASSERT(!thd->prelocked_mode);
|
||||
DBUG_ASSERT(!thd->locked_tables_mode);
|
||||
|
||||
mysql_parse(thd, thd->query(), thd->query_length(), &found_semicolon);
|
||||
|
||||
@ -2429,8 +2429,12 @@ int ndb_add_ndb_binlog_index(THD *thd, void *_row)
|
||||
goto add_ndb_binlog_index_err;
|
||||
}
|
||||
|
||||
mysql_unlock_tables(thd, thd->lock);
|
||||
thd->lock= 0;
|
||||
|
||||
if (! thd->locked_tables_mode) /* Is always TRUE */
|
||||
{
|
||||
mysql_unlock_tables(thd, thd->lock);
|
||||
thd->lock= 0;
|
||||
}
|
||||
thd->options= saved_options;
|
||||
return 0;
|
||||
add_ndb_binlog_index_err:
|
||||
|
@ -4527,9 +4527,7 @@ static bool check_table_binlog_row_based(THD *thd, TABLE *table)
|
||||
|
||||
DESCRIPTION
|
||||
This function will generate and write table maps for all tables
|
||||
that are locked by the thread 'thd'. Either manually locked
|
||||
(stored in THD::locked_tables) and automatically locked (stored
|
||||
in THD::lock) are considered.
|
||||
that are locked by the thread 'thd'.
|
||||
|
||||
RETURN VALUE
|
||||
0 All OK
|
||||
@ -4537,25 +4535,22 @@ static bool check_table_binlog_row_based(THD *thd, TABLE *table)
|
||||
|
||||
SEE ALSO
|
||||
THD::lock
|
||||
THD::locked_tables
|
||||
*/
|
||||
|
||||
static int write_locked_table_maps(THD *thd)
|
||||
{
|
||||
DBUG_ENTER("write_locked_table_maps");
|
||||
DBUG_PRINT("enter", ("thd: 0x%lx thd->lock: 0x%lx thd->locked_tables: 0x%lx "
|
||||
DBUG_PRINT("enter", ("thd: 0x%lx thd->lock: 0x%lx "
|
||||
"thd->extra_lock: 0x%lx",
|
||||
(long) thd, (long) thd->lock,
|
||||
(long) thd->locked_tables, (long) thd->extra_lock));
|
||||
(long) thd, (long) thd->lock, (long) thd->extra_lock));
|
||||
|
||||
DBUG_PRINT("debug", ("get_binlog_table_maps(): %d", thd->get_binlog_table_maps()));
|
||||
|
||||
if (thd->get_binlog_table_maps() == 0)
|
||||
{
|
||||
MYSQL_LOCK *locks[3];
|
||||
MYSQL_LOCK *locks[2];
|
||||
locks[0]= thd->extra_lock;
|
||||
locks[1]= thd->lock;
|
||||
locks[2]= thd->locked_tables;
|
||||
for (uint i= 0 ; i < sizeof(locks)/sizeof(*locks) ; ++i )
|
||||
{
|
||||
MYSQL_LOCK const *const lock= locks[i];
|
||||
|
@ -754,7 +754,7 @@ TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
|
||||
goto end;
|
||||
|
||||
/* Get command lock or LOCK TABLES lock. Maybe empty for INSERT DELAYED. */
|
||||
if (! (mylock= thd->lock ? thd->lock : thd->locked_tables))
|
||||
if (! (mylock= thd->lock))
|
||||
goto end;
|
||||
|
||||
/* If we have less than two tables, we cannot have duplicates. */
|
||||
|
@ -4060,7 +4060,7 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
|
||||
this will close all tables on the slave.
|
||||
*/
|
||||
bool const end_stmt=
|
||||
thd->prelocked_mode && thd->lex->requires_prelocking();
|
||||
thd->locked_tables_mode && thd->lex->requires_prelocking();
|
||||
if (thd->binlog_flush_pending_rows_event(end_stmt))
|
||||
DBUG_RETURN(error);
|
||||
|
||||
|
@ -4292,7 +4292,7 @@ bool sys_var_opt_readonly::update(THD *thd, set_var *var)
|
||||
DBUG_ENTER("sys_var_opt_readonly::update");
|
||||
|
||||
/* Prevent self dead-lock */
|
||||
if (thd->locked_tables || thd->active_transaction())
|
||||
if (thd->locked_tables_mode || thd->active_transaction())
|
||||
{
|
||||
my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
|
||||
DBUG_RETURN(true);
|
||||
|
@ -1257,7 +1257,7 @@ sp_head::execute(THD *thd)
|
||||
Will write this SP statement into binlog separately
|
||||
(TODO: consider changing the condition to "not inside event union")
|
||||
*/
|
||||
if (thd->prelocked_mode == NON_PRELOCKED)
|
||||
if (thd->locked_tables_mode == LTM_NONE)
|
||||
thd->user_var_events_alloc= thd->mem_root;
|
||||
|
||||
err_status= i->execute(thd, &ip);
|
||||
@ -1269,7 +1269,7 @@ sp_head::execute(THD *thd)
|
||||
If we've set thd->user_var_events_alloc to mem_root of this SP
|
||||
statement, clean all the events allocated in it.
|
||||
*/
|
||||
if (thd->prelocked_mode == NON_PRELOCKED)
|
||||
if (thd->locked_tables_mode == LTM_NONE)
|
||||
{
|
||||
reset_dynamic(&thd->user_var_events);
|
||||
thd->user_var_events_alloc= NULL;//DEBUG
|
||||
@ -2740,7 +2740,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
|
||||
thd->query_id= next_query_id();
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
if (thd->prelocked_mode == NON_PRELOCKED)
|
||||
if (thd->locked_tables_mode == LTM_NONE)
|
||||
{
|
||||
/*
|
||||
This statement will enter/leave prelocked mode on its own.
|
||||
|
165
sql/sql_base.cc
165
sql/sql_base.cc
@ -1025,7 +1025,7 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock,
|
||||
DBUG_ASSERT(!have_lock);
|
||||
pthread_mutex_unlock(&LOCK_open);
|
||||
|
||||
if (thd->locked_tables)
|
||||
if (thd->locked_tables_mode)
|
||||
{
|
||||
/*
|
||||
If we are under LOCK TABLES we need to reopen tables without
|
||||
@ -1141,7 +1141,7 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock,
|
||||
}
|
||||
|
||||
err_with_reopen:
|
||||
if (thd->locked_tables)
|
||||
if (thd->locked_tables_mode)
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_open);
|
||||
/*
|
||||
@ -1375,7 +1375,6 @@ void close_thread_tables(THD *thd,
|
||||
bool skip_mdl)
|
||||
{
|
||||
TABLE *table;
|
||||
prelocked_mode_type prelocked_mode= thd->prelocked_mode;
|
||||
DBUG_ENTER("close_thread_tables");
|
||||
|
||||
#ifdef EXTRA_DEBUG
|
||||
@ -1433,11 +1432,12 @@ void close_thread_tables(THD *thd,
|
||||
Reset transaction state, but only if we're not inside a
|
||||
sub-statement of a prelocked statement.
|
||||
*/
|
||||
if (! prelocked_mode || thd->lex->requires_prelocking())
|
||||
if (thd->locked_tables_mode <= LTM_LOCK_TABLES ||
|
||||
thd->lex->requires_prelocking())
|
||||
thd->transaction.stmt.reset();
|
||||
}
|
||||
|
||||
if (thd->locked_tables || prelocked_mode)
|
||||
if (thd->locked_tables_mode)
|
||||
{
|
||||
|
||||
/* Ensure we are calling ha_reset() for all used tables */
|
||||
@ -1447,7 +1447,7 @@ void close_thread_tables(THD *thd,
|
||||
We are under simple LOCK TABLES or we're inside a sub-statement
|
||||
of a prelocked statement, so should not do anything else.
|
||||
*/
|
||||
if (!prelocked_mode || !thd->lex->requires_prelocking())
|
||||
if (! thd->lex->requires_prelocking())
|
||||
DBUG_VOID_RETURN;
|
||||
|
||||
/*
|
||||
@ -1455,18 +1455,19 @@ void close_thread_tables(THD *thd,
|
||||
so we have to leave the prelocked mode now with doing implicit
|
||||
UNLOCK TABLES if needed.
|
||||
*/
|
||||
DBUG_PRINT("info",("thd->prelocked_mode= NON_PRELOCKED"));
|
||||
thd->prelocked_mode= NON_PRELOCKED;
|
||||
if (thd->locked_tables_mode == LTM_PRELOCKED_UNDER_LOCK_TABLES)
|
||||
thd->locked_tables_mode= LTM_LOCK_TABLES;
|
||||
|
||||
if (prelocked_mode == PRELOCKED_UNDER_LOCK_TABLES)
|
||||
if (thd->locked_tables_mode == LTM_LOCK_TABLES)
|
||||
DBUG_VOID_RETURN;
|
||||
|
||||
thd->locked_tables_mode= LTM_NONE;
|
||||
thd->options&= ~OPTION_TABLE_LOCK;
|
||||
|
||||
/*
|
||||
Note that we are leaving prelocked mode so we don't need
|
||||
to care about THD::locked_tables_root.
|
||||
*/
|
||||
thd->lock= thd->locked_tables;
|
||||
thd->locked_tables= 0;
|
||||
/* Fallthrough */
|
||||
}
|
||||
|
||||
@ -1501,16 +1502,6 @@ void close_thread_tables(THD *thd,
|
||||
mdl_remove_all_locks(&thd->mdl_context);
|
||||
}
|
||||
|
||||
if (prelocked_mode == PRELOCKED)
|
||||
{
|
||||
/*
|
||||
If we are here then we are leaving normal prelocked mode, so it is
|
||||
good idea to turn off OPTION_TABLE_LOCK flag.
|
||||
*/
|
||||
DBUG_ASSERT(thd->lex->requires_prelocking());
|
||||
thd->options&= ~(OPTION_TABLE_LOCK);
|
||||
}
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
@ -1951,9 +1942,10 @@ TABLE *find_temporary_table(THD *thd, TABLE_LIST *table_list)
|
||||
Try to locate the table in the list of thd->temporary_tables.
|
||||
If the table is found:
|
||||
- if the table is being used by some outer statement, fail.
|
||||
- if the table is in thd->locked_tables, unlock it and
|
||||
remove it from the list of locked tables. Currently only transactional
|
||||
temporary tables are present in the locked_tables list.
|
||||
- if the table is locked with LOCK TABLES or by prelocking,
|
||||
unlock it and remove it from the list of locked tables
|
||||
(THD::lock). Currently only transactional temporary tables
|
||||
are locked.
|
||||
- Close the temporary table, remove its .FRM
|
||||
- remove the table from the list of temporary tables
|
||||
|
||||
@ -1992,7 +1984,7 @@ int drop_temporary_table(THD *thd, TABLE_LIST *table_list)
|
||||
If LOCK TABLES list is not empty and contains this table,
|
||||
unlock the table and remove the table from this list.
|
||||
*/
|
||||
mysql_lock_remove(thd, thd->locked_tables, table, FALSE);
|
||||
mysql_lock_remove(thd, thd->lock, table, FALSE);
|
||||
close_temporary_table(thd, table, 1, 1);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
@ -2265,7 +2257,7 @@ bool close_cached_table(THD *thd, TABLE *table)
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
/* Close lock if this is not got with LOCK TABLES */
|
||||
if (thd->lock)
|
||||
if (! thd->locked_tables_mode)
|
||||
{
|
||||
mysql_unlock_tables(thd, thd->lock);
|
||||
thd->lock=0; // Start locked threads
|
||||
@ -2318,8 +2310,8 @@ void unlink_open_table(THD *thd, TABLE *find, bool unlock)
|
||||
if (list->s->table_cache_key.length == key_length &&
|
||||
!memcmp(list->s->table_cache_key.str, key, key_length))
|
||||
{
|
||||
if (unlock && thd->locked_tables)
|
||||
mysql_lock_remove(thd, thd->locked_tables,
|
||||
if (unlock && thd->locked_tables_mode)
|
||||
mysql_lock_remove(thd, thd->lock,
|
||||
list->parent ? list->parent : list, TRUE);
|
||||
|
||||
/* Prepare MERGE table for close. Close parent if necessary. */
|
||||
@ -2690,7 +2682,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
||||
open not pre-opened tables in pre-locked/LOCK TABLES mode.
|
||||
TODO: move this block into a separate function.
|
||||
*/
|
||||
if (thd->locked_tables || thd->prelocked_mode)
|
||||
if (thd->locked_tables_mode)
|
||||
{ // Using table locks
|
||||
TABLE *best_table= 0;
|
||||
int best_distance= INT_MIN;
|
||||
@ -2705,7 +2697,8 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
||||
*/
|
||||
if (!my_strcasecmp(system_charset_info, table->alias, alias) &&
|
||||
table->query_id != thd->query_id && /* skip tables already used */
|
||||
!(thd->prelocked_mode && table->query_id) &&
|
||||
(thd->locked_tables_mode == LTM_LOCK_TABLES ||
|
||||
table->query_id == 0) &&
|
||||
!table->parent)
|
||||
{
|
||||
int distance= ((int) table->reginfo.lock_type -
|
||||
@ -2788,7 +2781,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
||||
so we may only end up here if the table did not exist when
|
||||
locked tables list was created.
|
||||
*/
|
||||
if (thd->prelocked_mode == PRELOCKED)
|
||||
if (thd->locked_tables_mode == LTM_PRELOCKED)
|
||||
my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->alias);
|
||||
else
|
||||
my_error(ER_TABLE_NOT_LOCKED, MYF(0), alias);
|
||||
@ -3329,7 +3322,7 @@ void close_data_files_and_leave_as_placeholders(THD *thd, const char *db,
|
||||
|
||||
safe_mutex_assert_owner(&LOCK_open);
|
||||
|
||||
if (thd->lock)
|
||||
if (! thd->locked_tables_mode)
|
||||
{
|
||||
/*
|
||||
If we are not under LOCK TABLES we should have only one table
|
||||
@ -3344,7 +3337,7 @@ void close_data_files_and_leave_as_placeholders(THD *thd, const char *db,
|
||||
if (!strcmp(table->s->table_name.str, table_name) &&
|
||||
!strcmp(table->s->db.str, db))
|
||||
{
|
||||
if (thd->locked_tables)
|
||||
if (thd->locked_tables_mode)
|
||||
{
|
||||
if (table->parent)
|
||||
{
|
||||
@ -3354,11 +3347,11 @@ void close_data_files_and_leave_as_placeholders(THD *thd, const char *db,
|
||||
the parent and close it. OTOH in most cases a MERGE table
|
||||
won't have multiple children with the same db.table_name.
|
||||
*/
|
||||
mysql_lock_remove(thd, thd->locked_tables, table->parent, TRUE);
|
||||
mysql_lock_remove(thd, thd->lock, table->parent, TRUE);
|
||||
close_handle_and_leave_table_as_placeholder(table->parent);
|
||||
}
|
||||
else
|
||||
mysql_lock_remove(thd, thd->locked_tables, table, TRUE);
|
||||
mysql_lock_remove(thd, thd->lock, table, TRUE);
|
||||
}
|
||||
table->s->version= 0;
|
||||
close_handle_and_leave_table_as_placeholder(table);
|
||||
@ -3554,7 +3547,7 @@ bool reopen_tables(THD *thd, bool get_locks)
|
||||
if ((lock= mysql_lock_tables(thd, tables, (uint) (tables_ptr - tables),
|
||||
flags, ¬_used)))
|
||||
{
|
||||
thd->locked_tables=mysql_lock_merge(thd->locked_tables,lock);
|
||||
thd->lock= mysql_lock_merge(thd->lock, lock);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3587,17 +3580,22 @@ void unlock_locked_tables(THD *thd)
|
||||
DBUG_ASSERT(!thd->in_sub_stmt &&
|
||||
!(thd->state_flags & Open_tables_state::BACKUPS_AVAIL));
|
||||
|
||||
if (thd->locked_tables)
|
||||
{
|
||||
thd->lock= thd->locked_tables;
|
||||
thd->locked_tables=0;
|
||||
close_thread_tables(thd);
|
||||
/*
|
||||
After closing tables we can free memory used for storing lock
|
||||
request objects for metadata locks
|
||||
*/
|
||||
free_root(&thd->locked_tables_root, MYF(MY_MARK_BLOCKS_FREE));
|
||||
}
|
||||
/*
|
||||
Sic: we must be careful to not close open tables if
|
||||
we're not in LOCK TABLES mode: unlock_locked_tables() is
|
||||
sometimes called implicitly, expecting no effect on
|
||||
open tables, e.g. from begin_trans().
|
||||
*/
|
||||
if (thd->locked_tables_mode != LTM_LOCK_TABLES)
|
||||
return;
|
||||
|
||||
thd->locked_tables_mode= LTM_NONE;
|
||||
close_thread_tables(thd);
|
||||
/*
|
||||
After closing tables we can free memory used for storing lock
|
||||
request objects for metadata locks
|
||||
*/
|
||||
free_root(&thd->locked_tables_root, MYF(MY_MARK_BLOCKS_FREE));
|
||||
}
|
||||
|
||||
|
||||
@ -4494,11 +4492,6 @@ thr_lock_type read_lock_type_for_table(THD *thd, TABLE *table)
|
||||
prelocking it won't do such precaching and will simply reuse table list
|
||||
which is already built.
|
||||
|
||||
If any table has a trigger and start->trg_event_map is non-zero
|
||||
the final lock will end up in thd->locked_tables, otherwise, the
|
||||
lock will be placed in thd->lock. See also comments in
|
||||
st_lex::set_trg_event_type_for_tables().
|
||||
|
||||
RETURN
|
||||
0 - OK
|
||||
-1 - error
|
||||
@ -4543,10 +4536,10 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
|
||||
If we are not already executing prelocked statement and don't have
|
||||
statement for which table list for prelocking is already built, let
|
||||
us cache routines and try to build such table list.
|
||||
|
||||
*/
|
||||
|
||||
if (!thd->prelocked_mode && !thd->lex->requires_prelocking() &&
|
||||
if (thd->locked_tables_mode <= LTM_LOCK_TABLES &&
|
||||
!thd->lex->requires_prelocking() &&
|
||||
thd->lex->uses_stored_routines())
|
||||
{
|
||||
bool first_no_prelocking, need_prelocking;
|
||||
@ -4759,7 +4752,8 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
|
||||
If we lock table for reading we won't update it so there is no need to
|
||||
process its triggers since they never will be activated.
|
||||
*/
|
||||
if (!thd->prelocked_mode && !thd->lex->requires_prelocking() &&
|
||||
if (thd->locked_tables_mode <= LTM_LOCK_TABLES &&
|
||||
!thd->lex->requires_prelocking() &&
|
||||
tables->trg_event_map && tables->table->triggers &&
|
||||
tables->lock_type >= TL_WRITE_ALLOW_WRITE)
|
||||
{
|
||||
@ -4780,7 +4774,7 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
|
||||
free_root(&new_frm_mem, MYF(MY_KEEP_PREALLOC));
|
||||
}
|
||||
|
||||
if (tables->lock_type != TL_UNLOCK && ! thd->locked_tables)
|
||||
if (tables->lock_type != TL_UNLOCK && ! thd->locked_tables_mode)
|
||||
{
|
||||
if (tables->lock_type == TL_WRITE_DEFAULT)
|
||||
tables->table->reginfo.lock_type= thd->update_lock_default;
|
||||
@ -4803,10 +4797,7 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
|
||||
DBUG_PRINT("tcache", ("is parent: %d is child: %d",
|
||||
test(tables->table->child_l),
|
||||
test(tables->parent_l)));
|
||||
DBUG_PRINT("tcache", ("in lock tables: %d in prelock mode: %d",
|
||||
test(thd->locked_tables), test(thd->prelocked_mode)));
|
||||
if (((!thd->locked_tables && !thd->prelocked_mode) ||
|
||||
tables->table->s->tmp_table) &&
|
||||
if ((!thd->locked_tables_mode || tables->table->s->tmp_table) &&
|
||||
((tables->table->child_l &&
|
||||
add_merge_table_list(tables)) ||
|
||||
(tables->parent_l &&
|
||||
@ -4822,7 +4813,8 @@ process_view_routines:
|
||||
Again we may need cache all routines used by this view and add
|
||||
tables used by them to table list.
|
||||
*/
|
||||
if (tables->view && !thd->prelocked_mode &&
|
||||
if (tables->view &&
|
||||
thd->locked_tables_mode <= LTM_LOCK_TABLES &&
|
||||
!thd->lex->requires_prelocking() &&
|
||||
tables->view->uses_stored_routines())
|
||||
{
|
||||
@ -4996,7 +4988,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type,
|
||||
DBUG_ENTER("open_ltable");
|
||||
|
||||
/* should not be used in a prelocked_mode context, see NOTE above */
|
||||
DBUG_ASSERT(!thd->prelocked_mode);
|
||||
DBUG_ASSERT(thd->locked_tables_mode < LTM_PRELOCKED);
|
||||
|
||||
thd_proc_info(thd, "Opening table");
|
||||
thd->current_tablenr= 0;
|
||||
@ -5033,7 +5025,7 @@ retry:
|
||||
table_list->lock_type= lock_type;
|
||||
table_list->table= table;
|
||||
table->grant= table_list->grant;
|
||||
if (thd->locked_tables)
|
||||
if (thd->locked_tables_mode)
|
||||
{
|
||||
if (check_lock_and_start_stmt(thd, table, lock_type))
|
||||
table= 0;
|
||||
@ -5355,9 +5347,9 @@ int decide_logging_format(THD *thd, TABLE_LIST *tables)
|
||||
handling thr_lock gives us. You most always get all needed locks at
|
||||
once.
|
||||
|
||||
If query for which we are calling this function marked as requring
|
||||
prelocking, this function will do implicit LOCK TABLES and change
|
||||
thd::prelocked_mode accordingly.
|
||||
If query for which we are calling this function marked as requiring
|
||||
prelocking, this function will change locked_tables_mode to
|
||||
LTM_PRELOCKED.
|
||||
|
||||
RETURN VALUES
|
||||
0 ok
|
||||
@ -5374,22 +5366,24 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count,
|
||||
We can't meet statement requiring prelocking if we already
|
||||
in prelocked mode.
|
||||
*/
|
||||
DBUG_ASSERT(!thd->prelocked_mode || !thd->lex->requires_prelocking());
|
||||
DBUG_ASSERT(thd->locked_tables_mode <= LTM_LOCK_TABLES ||
|
||||
!thd->lex->requires_prelocking());
|
||||
*need_reopen= FALSE;
|
||||
|
||||
if (!tables && !thd->lex->requires_prelocking())
|
||||
DBUG_RETURN(decide_logging_format(thd, tables));
|
||||
|
||||
/*
|
||||
We need this extra check for thd->prelocked_mode because we want to avoid
|
||||
attempts to lock tables in substatements. Checking for thd->locked_tables
|
||||
is not enough in some situations. For example for SP containing
|
||||
Check for thd->locked_tables_mode to avoid a redundant
|
||||
and harmful attempt to lock the already locked tables again.
|
||||
Checking for thd->lock is not enough in some situations. For example,
|
||||
if a stored function contains
|
||||
"drop table t3; create temporary t3 ..; insert into t3 ...;"
|
||||
thd->locked_tables may be 0 after drop tables, and without this extra
|
||||
check insert will try to lock temporary table t3, that will lead
|
||||
to memory leak...
|
||||
thd->lock may be 0 after drop tables, whereas locked_tables_mode
|
||||
is still on. In this situation an attempt to lock temporary
|
||||
table t3 will lead to a memory leak.
|
||||
*/
|
||||
if (!thd->locked_tables && !thd->prelocked_mode)
|
||||
if (! thd->locked_tables_mode)
|
||||
{
|
||||
DBUG_ASSERT(thd->lock == 0); // You must lock everything at once
|
||||
TABLE **start,**ptr;
|
||||
@ -5443,15 +5437,8 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count,
|
||||
We just have done implicit LOCK TABLES, and now we have
|
||||
to emulate first open_and_lock_tables() after it.
|
||||
|
||||
Note that "LOCK TABLES" can also be marked as requiring prelocking
|
||||
(e.g. if one locks view which uses functions). We should not emulate
|
||||
such open_and_lock_tables() in this case. We also should not set
|
||||
THD::prelocked_mode or first close_thread_tables() call will do
|
||||
"UNLOCK TABLES".
|
||||
*/
|
||||
thd->locked_tables= thd->lock;
|
||||
thd->lock= 0;
|
||||
thd->in_lock_tables=0;
|
||||
thd->in_lock_tables= 0;
|
||||
|
||||
/*
|
||||
When open_and_lock_tables() is called for a single table out of
|
||||
@ -5474,8 +5461,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count,
|
||||
This was an attempt to enter prelocked mode so there is no
|
||||
need to care about THD::locked_tables_root here.
|
||||
*/
|
||||
mysql_unlock_tables(thd, thd->locked_tables);
|
||||
thd->locked_tables= 0;
|
||||
mysql_unlock_tables(thd, thd->lock);
|
||||
thd->options&= ~(OPTION_TABLE_LOCK);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
@ -5486,8 +5472,8 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count,
|
||||
and was marked as occupied during open_tables() as free for reuse.
|
||||
*/
|
||||
mark_real_tables_as_free_for_reuse(first_not_own);
|
||||
DBUG_PRINT("info",("prelocked_mode= PRELOCKED"));
|
||||
thd->prelocked_mode= PRELOCKED;
|
||||
DBUG_PRINT("info",("locked_tables_mode= PRELOCKED"));
|
||||
thd->locked_tables_mode= LTM_PRELOCKED;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -5512,7 +5498,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count,
|
||||
In a stored function or trigger we should ensure that we won't change
|
||||
a table that is already used by the calling statement.
|
||||
*/
|
||||
if (thd->prelocked_mode &&
|
||||
if (thd->locked_tables_mode >= LTM_PRELOCKED &&
|
||||
table->lock_type >= TL_WRITE_ALLOW_WRITE)
|
||||
{
|
||||
for (TABLE* opentab= thd->open_tables; opentab; opentab= opentab->next)
|
||||
@ -5540,8 +5526,9 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count,
|
||||
if (thd->lex->requires_prelocking())
|
||||
{
|
||||
mark_real_tables_as_free_for_reuse(first_not_own);
|
||||
DBUG_PRINT("info", ("thd->prelocked_mode= PRELOCKED_UNDER_LOCK_TABLES"));
|
||||
thd->prelocked_mode= PRELOCKED_UNDER_LOCK_TABLES;
|
||||
DBUG_PRINT("info",
|
||||
("thd->locked_tables_mode= LTM_PRELOCKED_UNDER_LOCK_TABLES"));
|
||||
thd->locked_tables_mode= LTM_PRELOCKED_UNDER_LOCK_TABLES;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1136,7 +1136,7 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
|
||||
|
||||
See also a note on double-check locking usage above.
|
||||
*/
|
||||
if (thd->locked_tables || query_cache_size == 0)
|
||||
if (thd->locked_tables_mode || query_cache_size == 0)
|
||||
DBUG_VOID_RETURN;
|
||||
uint8 tables_type= 0;
|
||||
|
||||
@ -1364,7 +1364,7 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
|
||||
|
||||
See also a note on double-check locking usage above.
|
||||
*/
|
||||
if (is_disabled() || thd->locked_tables ||
|
||||
if (is_disabled() || thd->locked_tables_mode ||
|
||||
thd->variables.query_cache_type == 0 || query_cache_size == 0)
|
||||
goto err;
|
||||
|
||||
|
@ -995,11 +995,7 @@ void THD::cleanup(void)
|
||||
ha_rollback(this);
|
||||
xid_cache_delete(&transaction.xid_state);
|
||||
}
|
||||
if (locked_tables)
|
||||
{
|
||||
lock=locked_tables; locked_tables=0;
|
||||
close_thread_tables(this);
|
||||
}
|
||||
unlock_locked_tables(this);
|
||||
|
||||
#if defined(ENABLED_DEBUG_SYNC)
|
||||
/* End the Debug Sync Facility. See debug_sync.cc. */
|
||||
@ -1742,7 +1738,7 @@ bool select_send::send_eof()
|
||||
ha_release_temporary_latches(thd);
|
||||
|
||||
/* Unlock tables before sending packet to gain some speed */
|
||||
if (thd->lock)
|
||||
if (thd->lock && ! thd->locked_tables_mode)
|
||||
{
|
||||
mysql_unlock_tables(thd, thd->lock);
|
||||
thd->lock=0;
|
||||
@ -3036,8 +3032,8 @@ void THD::restore_backup_open_tables_state(Open_tables_state *backup)
|
||||
*/
|
||||
DBUG_ASSERT(open_tables == 0 && temporary_tables == 0 &&
|
||||
handler_tables == 0 && derived_tables == 0 &&
|
||||
lock == 0 && locked_tables == 0 &&
|
||||
prelocked_mode == NON_PRELOCKED &&
|
||||
lock == 0 &&
|
||||
locked_tables_mode == LTM_NONE &&
|
||||
m_reprepare_observer == NULL);
|
||||
mdl_context_destroy(&mdl_context);
|
||||
mdl_context_destroy(&handler_mdl_context);
|
||||
@ -3912,7 +3908,7 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg,
|
||||
If we are in prelocked mode, the flushing will be done inside the
|
||||
top-most close_thread_tables().
|
||||
*/
|
||||
if (this->prelocked_mode == NON_PRELOCKED)
|
||||
if (this->locked_tables_mode <= LTM_LOCK_TABLES)
|
||||
if (int error= binlog_flush_pending_rows_event(TRUE))
|
||||
DBUG_RETURN(error);
|
||||
|
||||
|
@ -862,12 +862,17 @@ typedef I_List<Item_change_record> Item_change_list;
|
||||
|
||||
|
||||
/**
|
||||
Type of prelocked mode.
|
||||
See comment for THD::prelocked_mode for complete description.
|
||||
Type of locked tables mode.
|
||||
See comment for THD::locked_tables_mode for complete description.
|
||||
*/
|
||||
|
||||
enum prelocked_mode_type {NON_PRELOCKED= 0, PRELOCKED= 1,
|
||||
PRELOCKED_UNDER_LOCK_TABLES= 2};
|
||||
enum enum_locked_tables_mode
|
||||
{
|
||||
LTM_NONE= 0,
|
||||
LTM_LOCK_TABLES,
|
||||
LTM_PRELOCKED,
|
||||
LTM_PRELOCKED_UNDER_LOCK_TABLES
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
@ -920,19 +925,13 @@ public:
|
||||
statement ends.
|
||||
Manual mode comes into play when a user issues a 'LOCK TABLES'
|
||||
statement. In this mode the user can only use the locked tables.
|
||||
Trying to use any other tables will give an error. The locked tables are
|
||||
stored in 'locked_tables' member. Manual locking is described in
|
||||
Trying to use any other tables will give an error.
|
||||
The locked tables are also stored in this member, however,
|
||||
thd->locked_tables_mode is turned on. Manual locking is described in
|
||||
the 'LOCK_TABLES' chapter of the MySQL manual.
|
||||
See also lock_tables() for details.
|
||||
*/
|
||||
MYSQL_LOCK *lock;
|
||||
/*
|
||||
Tables that were locked with explicit or implicit LOCK TABLES.
|
||||
(Implicit LOCK TABLES happens when we are prelocking tables for
|
||||
execution of statement which uses stored routines. See description
|
||||
THD::prelocked_mode for more info.)
|
||||
*/
|
||||
MYSQL_LOCK *locked_tables;
|
||||
|
||||
/*
|
||||
CREATE-SELECT keeps an extra lock for the table being
|
||||
@ -942,29 +941,34 @@ public:
|
||||
MYSQL_LOCK *extra_lock;
|
||||
|
||||
/*
|
||||
prelocked_mode_type enum and prelocked_mode member are used for
|
||||
indicating whenever "prelocked mode" is on, and what type of
|
||||
"prelocked mode" is it.
|
||||
Enum enum_locked_tables_mode and locked_tables_mode member are
|
||||
used to indicate whether the so-called "locked tables mode" is on,
|
||||
and what kind of mode is active.
|
||||
|
||||
Prelocked mode is used for execution of queries which explicitly
|
||||
or implicitly (via views or triggers) use functions, thus may need
|
||||
some additional tables (mentioned in query table list) for their
|
||||
execution.
|
||||
Locked tables mode is used when it's necessary to open and
|
||||
lock many tables at once, for usage across multiple
|
||||
(sub-)statements.
|
||||
This may be necessary either for queries that use stored functions
|
||||
and triggers, in which case the statements inside functions and
|
||||
triggers may be executed many times, or for implementation of
|
||||
LOCK TABLES, in which case the opened tables are reused by all
|
||||
subsequent statements until a call to UNLOCK TABLES.
|
||||
|
||||
First open_tables() call for such query will analyse all functions
|
||||
used by it and add all additional tables to table its list. It will
|
||||
also mark this query as requiring prelocking. After that lock_tables()
|
||||
will issue implicit LOCK TABLES for the whole table list and change
|
||||
thd::prelocked_mode to non-0. All queries called in functions invoked
|
||||
by the main query will use prelocked tables. Non-0 prelocked_mode
|
||||
will also surpress mentioned analysys in those queries thus saving
|
||||
cycles. Prelocked mode will be turned off once close_thread_tables()
|
||||
for the main query will be called.
|
||||
|
||||
Note: Since not all "tables" present in table list are really locked
|
||||
thd::prelocked_mode does not imply thd::locked_tables.
|
||||
The kind of locked tables mode employed for stored functions and
|
||||
triggers is also called "prelocked mode".
|
||||
In this mode, first open_tables() call to open the tables used
|
||||
in a statement analyses all functions used by the statement
|
||||
and adds all indirectly used tables to the list of tables to
|
||||
open and lock.
|
||||
It also marks the parse tree of the statement as requiring
|
||||
prelocking. After that, lock_tables() locks the entire list
|
||||
of tables and changes THD::locked_tables_modeto LTM_PRELOCKED.
|
||||
All statements executed inside functions or triggers
|
||||
use the prelocked tables, instead of opening their own ones.
|
||||
Prelocked mode is turned off automatically once close_thread_tables()
|
||||
of the main statement is called.
|
||||
*/
|
||||
prelocked_mode_type prelocked_mode;
|
||||
enum enum_locked_tables_mode locked_tables_mode;
|
||||
ulong version;
|
||||
uint current_tablenr;
|
||||
|
||||
@ -996,8 +1000,8 @@ public:
|
||||
void reset_open_tables_state(THD *thd)
|
||||
{
|
||||
open_tables= temporary_tables= handler_tables= derived_tables= 0;
|
||||
extra_lock= lock= locked_tables= 0;
|
||||
prelocked_mode= NON_PRELOCKED;
|
||||
extra_lock= lock= 0;
|
||||
locked_tables_mode= LTM_NONE;
|
||||
state_flags= 0U;
|
||||
m_reprepare_observer= NULL;
|
||||
mdl_context_init(&mdl_context, thd);
|
||||
|
@ -289,7 +289,6 @@ Sensitive_cursor::Sensitive_cursor(THD *thd, select_result *result_arg)
|
||||
Save THD state into cursor.
|
||||
|
||||
@todo
|
||||
- XXX: thd->locked_tables is not changed.
|
||||
- What problems can we have with it if cursor is open?
|
||||
- TODO: must be fixed because of the prelocked mode.
|
||||
*/
|
||||
@ -342,7 +341,6 @@ Sensitive_cursor::post_open(THD *thd)
|
||||
}
|
||||
}
|
||||
/*
|
||||
XXX: thd->locked_tables is not changed.
|
||||
What problems can we have with it if cursor is open?
|
||||
TODO: must be fixed because of the prelocked mode.
|
||||
*/
|
||||
|
@ -441,7 +441,7 @@ void upgrade_lock_type(THD *thd, thr_lock_type *lock_type,
|
||||
*/
|
||||
if (specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE) ||
|
||||
thd->variables.max_insert_delayed_threads == 0 ||
|
||||
thd->prelocked_mode ||
|
||||
thd->locked_tables_mode > LTM_LOCK_TABLES ||
|
||||
thd->lex->uses_stored_routines())
|
||||
{
|
||||
*lock_type= TL_WRITE;
|
||||
@ -611,7 +611,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
never be able to get a lock on the table. QQQ: why not
|
||||
upgrade the lock here instead?
|
||||
*/
|
||||
if (table_list->lock_type == TL_WRITE_DELAYED && thd->locked_tables &&
|
||||
if (table_list->lock_type == TL_WRITE_DELAYED &&
|
||||
thd->locked_tables_mode &&
|
||||
find_locked_table(thd->open_tables, table_list->db,
|
||||
table_list->table_name))
|
||||
{
|
||||
@ -741,7 +742,14 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
{
|
||||
if (duplic != DUP_ERROR || ignore)
|
||||
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
|
||||
if (!thd->prelocked_mode)
|
||||
/**
|
||||
This is a simple check for the case when the table has a trigger
|
||||
that reads from it, or when the statement invokes a stored function
|
||||
that reads from the table being inserted to.
|
||||
Engines can't handle a bulk insert in parallel with a read form the
|
||||
same table in the same connection.
|
||||
*/
|
||||
if (thd->locked_tables_mode <= LTM_LOCK_TABLES)
|
||||
table->file->ha_start_bulk_insert(values_list.elements);
|
||||
}
|
||||
|
||||
@ -856,7 +864,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
auto_inc values from the delayed_insert thread as they share TABLE.
|
||||
*/
|
||||
table->file->ha_release_auto_increment();
|
||||
if (!thd->prelocked_mode && table->file->ha_end_bulk_insert() && !error)
|
||||
if (thd->locked_tables_mode <= LTM_LOCK_TABLES &&
|
||||
table->file->ha_end_bulk_insert() && !error)
|
||||
{
|
||||
table->file->print_error(my_errno,MYF(0));
|
||||
error=1;
|
||||
@ -3076,7 +3085,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
||||
lex->current_select->join->select_options|= OPTION_BUFFER_RESULT;
|
||||
}
|
||||
else if (!(lex->current_select->options & OPTION_BUFFER_RESULT) &&
|
||||
!thd->prelocked_mode)
|
||||
thd->locked_tables_mode <= LTM_LOCK_TABLES)
|
||||
{
|
||||
/*
|
||||
We must not yet prepare the result table if it is the same as one of the
|
||||
@ -3142,7 +3151,7 @@ int select_insert::prepare2(void)
|
||||
{
|
||||
DBUG_ENTER("select_insert::prepare2");
|
||||
if (thd->lex->current_select->options & OPTION_BUFFER_RESULT &&
|
||||
!thd->prelocked_mode)
|
||||
thd->locked_tables_mode <= LTM_LOCK_TABLES)
|
||||
table->file->ha_start_bulk_insert((ha_rows) 0);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
@ -3269,7 +3278,8 @@ bool select_insert::send_eof()
|
||||
DBUG_PRINT("enter", ("trans_table=%d, table_type='%s'",
|
||||
trans_table, table->file->table_type()));
|
||||
|
||||
error= (!thd->prelocked_mode) ? table->file->ha_end_bulk_insert():0;
|
||||
error= (thd->locked_tables_mode <= LTM_LOCK_TABLES ?
|
||||
table->file->ha_end_bulk_insert() : 0);
|
||||
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
|
||||
table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
|
||||
|
||||
@ -3349,7 +3359,7 @@ void select_insert::abort() {
|
||||
If we are not in prelocked mode, we end the bulk insert started
|
||||
before.
|
||||
*/
|
||||
if (!thd->prelocked_mode)
|
||||
if (thd->locked_tables_mode <= LTM_LOCK_TABLES)
|
||||
table->file->ha_end_bulk_insert();
|
||||
|
||||
/*
|
||||
@ -3730,7 +3740,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
||||
table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
|
||||
if (info.handle_duplicates == DUP_UPDATE)
|
||||
table->file->extra(HA_EXTRA_INSERT_WITH_UPDATE);
|
||||
if (!thd->prelocked_mode)
|
||||
if (thd->locked_tables_mode <= LTM_LOCK_TABLES)
|
||||
table->file->ha_start_bulk_insert((ha_rows) 0);
|
||||
thd->abort_on_warning= (!info.ignore &&
|
||||
(thd->variables.sql_mode &
|
||||
|
@ -448,7 +448,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
||||
(!table->triggers ||
|
||||
!table->triggers->has_delete_triggers()))
|
||||
table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
|
||||
if (!thd->prelocked_mode)
|
||||
if (thd->locked_tables_mode <= LTM_LOCK_TABLES)
|
||||
table->file->ha_start_bulk_insert((ha_rows) 0);
|
||||
table->copy_blobs=1;
|
||||
|
||||
@ -469,7 +469,8 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
||||
error= read_sep_field(thd, info, table_list, fields_vars,
|
||||
set_fields, set_values, read_info,
|
||||
*enclosed, skip_lines, ignore);
|
||||
if (!thd->prelocked_mode && table->file->ha_end_bulk_insert() && !error)
|
||||
if (thd->locked_tables_mode <= LTM_LOCK_TABLES &&
|
||||
table->file->ha_end_bulk_insert() && !error)
|
||||
{
|
||||
table->file->print_error(my_errno, MYF(0));
|
||||
error= 1;
|
||||
|
@ -163,7 +163,7 @@ bool end_active_trans(THD *thd)
|
||||
{
|
||||
DBUG_PRINT("info",("options: 0x%llx", thd->options));
|
||||
/* Safety if one did "drop table" on locked tables */
|
||||
if (!thd->locked_tables)
|
||||
if (!thd->locked_tables_mode)
|
||||
thd->options&= ~OPTION_TABLE_LOCK;
|
||||
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
|
||||
if (ha_commit(thd))
|
||||
@ -2211,7 +2211,7 @@ mysql_execute_command(THD *thd)
|
||||
if (res)
|
||||
break;
|
||||
|
||||
if (!thd->locked_tables && lex->protect_against_global_read_lock &&
|
||||
if (!thd->locked_tables_mode && lex->protect_against_global_read_lock &&
|
||||
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
|
||||
break;
|
||||
|
||||
@ -2553,7 +2553,7 @@ case SQLCOM_PREPARE:
|
||||
TABLE in the same way. That way we avoid that a new table is
|
||||
created during a gobal read lock.
|
||||
*/
|
||||
if (!thd->locked_tables &&
|
||||
if (!thd->locked_tables_mode &&
|
||||
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
|
||||
{
|
||||
res= 1;
|
||||
@ -2779,7 +2779,8 @@ end_with_restore_list:
|
||||
To prevent that, refuse SLAVE STOP if the
|
||||
client thread has locked tables
|
||||
*/
|
||||
if (thd->locked_tables || thd->active_transaction() || thd->global_read_lock)
|
||||
if (thd->locked_tables_mode ||
|
||||
thd->active_transaction() || thd->global_read_lock)
|
||||
{
|
||||
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
|
||||
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
|
||||
@ -2855,7 +2856,7 @@ end_with_restore_list:
|
||||
if (end_active_trans(thd))
|
||||
goto error;
|
||||
|
||||
if (!thd->locked_tables &&
|
||||
if (!thd->locked_tables_mode &&
|
||||
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
|
||||
{
|
||||
res= 1;
|
||||
@ -3089,7 +3090,7 @@ end_with_restore_list:
|
||||
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
||||
if (update_precheck(thd, all_tables))
|
||||
break;
|
||||
if (!thd->locked_tables &&
|
||||
if (!thd->locked_tables_mode &&
|
||||
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
|
||||
goto error;
|
||||
DBUG_ASSERT(select_lex->offset_limit == 0);
|
||||
@ -3126,7 +3127,7 @@ end_with_restore_list:
|
||||
Protection might have already been risen if its a fall through
|
||||
from the SQLCOM_UPDATE case above.
|
||||
*/
|
||||
if (!thd->locked_tables &&
|
||||
if (!thd->locked_tables_mode &&
|
||||
lex->sql_command == SQLCOM_UPDATE_MULTI &&
|
||||
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
|
||||
goto error;
|
||||
@ -3230,7 +3231,7 @@ end_with_restore_list:
|
||||
if ((res= insert_precheck(thd, all_tables)))
|
||||
break;
|
||||
|
||||
if (!thd->locked_tables &&
|
||||
if (!thd->locked_tables_mode &&
|
||||
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
|
||||
{
|
||||
res= 1;
|
||||
@ -3270,7 +3271,7 @@ end_with_restore_list:
|
||||
|
||||
unit->set_limit(select_lex);
|
||||
|
||||
if (! thd->locked_tables &&
|
||||
if (! thd->locked_tables_mode &&
|
||||
! (need_start_waiting= ! wait_if_global_read_lock(thd, 0, 1)))
|
||||
{
|
||||
res= 1;
|
||||
@ -3340,7 +3341,7 @@ end_with_restore_list:
|
||||
Don't allow this within a transaction because we want to use
|
||||
re-generate table
|
||||
*/
|
||||
if (thd->locked_tables || thd->active_transaction())
|
||||
if (thd->locked_tables_mode || thd->active_transaction())
|
||||
{
|
||||
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
|
||||
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
|
||||
@ -3358,7 +3359,7 @@ end_with_restore_list:
|
||||
DBUG_ASSERT(select_lex->offset_limit == 0);
|
||||
unit->set_limit(select_lex);
|
||||
|
||||
if (!thd->locked_tables &&
|
||||
if (!thd->locked_tables_mode &&
|
||||
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
|
||||
{
|
||||
res= 1;
|
||||
@ -3379,7 +3380,7 @@ end_with_restore_list:
|
||||
(TABLE_LIST *)thd->lex->auxiliary_table_list.first;
|
||||
multi_delete *del_result;
|
||||
|
||||
if (!thd->locked_tables &&
|
||||
if (!thd->locked_tables_mode &&
|
||||
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
|
||||
{
|
||||
res= 1;
|
||||
@ -3526,7 +3527,7 @@ end_with_restore_list:
|
||||
if (check_one_table_access(thd, privilege, all_tables))
|
||||
goto error;
|
||||
|
||||
if (!thd->locked_tables &&
|
||||
if (!thd->locked_tables_mode &&
|
||||
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
|
||||
goto error;
|
||||
|
||||
@ -3615,8 +3616,7 @@ end_with_restore_list:
|
||||
if (thd->variables.query_cache_wlock_invalidate)
|
||||
query_cache.invalidate_locked_for_write(first_table);
|
||||
#endif /*HAVE_QUERY_CACHE*/
|
||||
thd->locked_tables=thd->lock;
|
||||
thd->lock=0;
|
||||
thd->locked_tables_mode= LTM_LOCK_TABLES;
|
||||
my_ok(thd);
|
||||
}
|
||||
else
|
||||
@ -3707,7 +3707,7 @@ end_with_restore_list:
|
||||
if (check_access(thd,DROP_ACL,lex->name.str,0,1,0,
|
||||
is_schema_db(lex->name.str)))
|
||||
break;
|
||||
if (thd->locked_tables || thd->active_transaction())
|
||||
if (thd->locked_tables_mode || thd->active_transaction())
|
||||
{
|
||||
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
|
||||
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
|
||||
@ -3746,7 +3746,7 @@ end_with_restore_list:
|
||||
res= 1;
|
||||
break;
|
||||
}
|
||||
if (thd->locked_tables || thd->active_transaction())
|
||||
if (thd->locked_tables_mode || thd->active_transaction())
|
||||
{
|
||||
res= 1;
|
||||
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
|
||||
@ -3786,7 +3786,7 @@ end_with_restore_list:
|
||||
#endif
|
||||
if (check_access(thd, ALTER_ACL, db->str, 0, 1, 0, is_schema_db(db->str)))
|
||||
break;
|
||||
if (thd->locked_tables || thd->active_transaction())
|
||||
if (thd->locked_tables_mode || thd->active_transaction())
|
||||
{
|
||||
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
|
||||
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
|
||||
@ -4776,7 +4776,7 @@ create_sp_error:
|
||||
xa_state_names[thd->transaction.xid_state.xa_state]);
|
||||
break;
|
||||
}
|
||||
if (thd->active_transaction() || thd->locked_tables)
|
||||
if (thd->locked_tables_mode || thd->active_transaction())
|
||||
{
|
||||
my_error(ER_XAER_OUTSIDE, MYF(0));
|
||||
break;
|
||||
@ -7078,7 +7078,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
|
||||
if we have a write locked table as this would lead to a deadlock
|
||||
when trying to reopen (and re-lock) the table after the flush.
|
||||
*/
|
||||
if (thd->locked_tables)
|
||||
if (thd->locked_tables_mode)
|
||||
{
|
||||
my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
|
||||
return 1;
|
||||
@ -7103,7 +7103,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (thd && thd->locked_tables)
|
||||
if (thd && thd->locked_tables_mode)
|
||||
{
|
||||
/*
|
||||
If we are under LOCK TABLES we should have a write
|
||||
|
@ -6216,7 +6216,7 @@ static void release_log_entries(partition_info *part_info)
|
||||
static void alter_partition_lock_handling(ALTER_PARTITION_PARAM_TYPE *lpt)
|
||||
{
|
||||
int err;
|
||||
if (lpt->thd->locked_tables)
|
||||
if (lpt->thd->locked_tables_mode)
|
||||
{
|
||||
/*
|
||||
When we have the table locked, it is necessary to reopen the table
|
||||
|
@ -44,7 +44,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
|
||||
if the user is trying to to do this in a transcation context
|
||||
*/
|
||||
|
||||
if (thd->locked_tables || thd->active_transaction())
|
||||
if (thd->locked_tables_mode || thd->active_transaction())
|
||||
{
|
||||
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
|
||||
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
|
||||
|
@ -1019,7 +1019,7 @@ JOIN::optimize()
|
||||
error= -1;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (const_tables && !thd->locked_tables &&
|
||||
if (const_tables && !thd->locked_tables_mode &&
|
||||
!(select_options & SELECT_NO_UNLOCK))
|
||||
mysql_unlock_some_tables(thd, all_tables, const_tables);
|
||||
if (!conds && outer_join)
|
||||
@ -6930,7 +6930,7 @@ void JOIN::join_free()
|
||||
We are not using tables anymore
|
||||
Unlock all tables. We may be in an INSERT .... SELECT statement.
|
||||
*/
|
||||
if (can_unlock && lock && thd->lock &&
|
||||
if (can_unlock && lock && thd->lock && ! thd->locked_tables_mode &&
|
||||
!(select_options & SELECT_NO_UNLOCK) &&
|
||||
!select_lex->subquery_in_having &&
|
||||
(select_lex == (thd->lex->unit.fake_select_lex ?
|
||||
|
@ -1786,7 +1786,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
|
||||
|
||||
if (!drop_temporary)
|
||||
{
|
||||
if (!thd->locked_tables &&
|
||||
if (!thd->locked_tables_mode &&
|
||||
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
@ -1891,7 +1891,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
|
||||
|
||||
if (!drop_temporary)
|
||||
{
|
||||
if (!thd->locked_tables)
|
||||
if (!thd->locked_tables_mode)
|
||||
{
|
||||
if (lock_table_names(thd, tables))
|
||||
DBUG_RETURN(1);
|
||||
@ -1900,7 +1900,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
|
||||
expel_table_from_cache(0, table->db, table->table_name);
|
||||
pthread_mutex_unlock(&LOCK_open);
|
||||
}
|
||||
else if (thd->locked_tables)
|
||||
else
|
||||
{
|
||||
for (table= tables; table; table= table->next_local)
|
||||
if (find_temporary_table(thd, table->db, table->table_name))
|
||||
@ -2001,7 +2001,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
|
||||
table_type= table->db_type;
|
||||
if (!drop_temporary)
|
||||
{
|
||||
if (thd->locked_tables)
|
||||
if (thd->locked_tables_mode)
|
||||
{
|
||||
if (close_cached_table(thd, table->table))
|
||||
{
|
||||
@ -2192,8 +2192,8 @@ err_with_placeholders:
|
||||
locked. Additional check for 'non_temp_tables_count' is to avoid
|
||||
leaving LOCK TABLES mode if we have dropped only temporary tables.
|
||||
*/
|
||||
if (thd->locked_tables && thd->locked_tables->table_count == 0 &&
|
||||
non_temp_tables_count > 0)
|
||||
if (thd->locked_tables_mode &&
|
||||
thd->lock && thd->lock->table_count == 0 && non_temp_tables_count > 0)
|
||||
{
|
||||
unlock_locked_tables(thd);
|
||||
goto end;
|
||||
@ -6571,7 +6571,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
if the user is trying to to do this in a transcation context
|
||||
*/
|
||||
|
||||
if (thd->locked_tables || thd->active_transaction())
|
||||
if (thd->locked_tables_mode || thd->active_transaction())
|
||||
{
|
||||
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
|
||||
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
|
||||
@ -6620,7 +6620,7 @@ view_err:
|
||||
set of tables from the old table or to open a new TABLE object for
|
||||
an extended list and verify that they belong to locked tables.
|
||||
*/
|
||||
if (thd->locked_tables &&
|
||||
if (thd->locked_tables_mode &&
|
||||
(create_info->used_fields & HA_CREATE_USED_UNION) &&
|
||||
(table->s->tmp_table == NO_TMP_TABLE))
|
||||
{
|
||||
@ -6847,7 +6847,7 @@ view_err:
|
||||
table_list->table= NULL; // For query cache
|
||||
query_cache_invalidate3(thd, table_list, 0);
|
||||
|
||||
if (thd->locked_tables)
|
||||
if (thd->locked_tables_mode)
|
||||
{
|
||||
/*
|
||||
Under LOCK TABLES we should adjust meta-data locks before finishing
|
||||
@ -7330,7 +7330,7 @@ view_err:
|
||||
if (table->s->tmp_table != NO_TMP_TABLE)
|
||||
{
|
||||
/* Close lock if this is a transactional table */
|
||||
if (thd->lock)
|
||||
if (thd->lock && ! thd->locked_tables_mode)
|
||||
{
|
||||
mysql_unlock_tables(thd, thd->lock);
|
||||
thd->lock=0;
|
||||
@ -7467,7 +7467,7 @@ view_err:
|
||||
if (t_table->file->ha_create_handler_files(path, NULL, CHF_INDEX_FLAG,
|
||||
create_info))
|
||||
goto err_with_placeholders;
|
||||
if (thd->locked_tables)
|
||||
if (thd->locked_tables_mode)
|
||||
{
|
||||
if (new_name == table_name && new_db == db)
|
||||
{
|
||||
@ -7489,7 +7489,7 @@ view_err:
|
||||
|
||||
(void) quick_rm_table(old_db_type, db, old_name, FN_IS_TMP);
|
||||
|
||||
if (thd->locked_tables && new_name == table_name && new_db == db)
|
||||
if (thd->locked_tables_mode && new_name == table_name && new_db == db)
|
||||
{
|
||||
thd->in_lock_tables= 1;
|
||||
error= reopen_tables(thd, 1);
|
||||
@ -7536,7 +7536,7 @@ view_err:
|
||||
table_list->table=0; // For query cache
|
||||
query_cache_invalidate3(thd, table_list, 0);
|
||||
|
||||
if (thd->locked_tables)
|
||||
if (thd->locked_tables_mode)
|
||||
{
|
||||
if ((new_name != table_name || new_db != db))
|
||||
{
|
||||
|
@ -383,7 +383,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
|
||||
LOCK_open is not enough because global read lock is held without holding
|
||||
LOCK_open).
|
||||
*/
|
||||
if (!thd->locked_tables &&
|
||||
if (!thd->locked_tables_mode &&
|
||||
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
@ -444,7 +444,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
|
||||
/* Keep consistent with respect to other DDL statements */
|
||||
mysql_ha_rm_tables(thd, tables);
|
||||
|
||||
if (thd->locked_tables)
|
||||
if (thd->locked_tables_mode)
|
||||
{
|
||||
/* Under LOCK TABLES we must only accept write locked tables. */
|
||||
if (!(tables->table= find_write_locked_table(thd->open_tables, tables->db,
|
||||
@ -493,7 +493,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
|
||||
table->triggers->drop_trigger(thd, tables, &stmt_query));
|
||||
|
||||
/* Under LOCK TABLES we must reopen the table to activate the trigger. */
|
||||
if (!result && thd->locked_tables)
|
||||
if (!result && thd->locked_tables_mode)
|
||||
{
|
||||
/* Make table suitable for reopening */
|
||||
close_data_files_and_leave_as_placeholders(thd, tables->db,
|
||||
@ -527,7 +527,7 @@ end:
|
||||
locks. Otherwise call to close_thread_tables() will take care about both
|
||||
TABLE instance created by reopen_name_locked_table() and metadata lock.
|
||||
*/
|
||||
if (thd->locked_tables && tables && tables->table)
|
||||
if (thd->locked_tables_mode && tables && tables->table)
|
||||
mdl_downgrade_exclusive_lock(&thd->mdl_context,
|
||||
tables->table->mdl_lock_data);
|
||||
|
||||
|
@ -978,7 +978,7 @@ int mysql_multi_update_prepare(THD *thd)
|
||||
count in open_tables()
|
||||
*/
|
||||
uint table_count= lex->table_count;
|
||||
const bool using_lock_tables= thd->locked_tables != 0;
|
||||
const bool using_lock_tables= thd->locked_tables_mode != LTM_NONE;
|
||||
bool original_multiupdate= (thd->lex->sql_command == SQLCOM_UPDATE_MULTI);
|
||||
bool need_reopen= FALSE;
|
||||
DBUG_ENTER("mysql_multi_update_prepare");
|
||||
|
@ -384,7 +384,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
|
||||
alteration of views under LOCK TABLES.
|
||||
*/
|
||||
|
||||
if (thd->locked_tables)
|
||||
if (thd->locked_tables_mode)
|
||||
{
|
||||
my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
|
||||
res= TRUE;
|
||||
@ -1583,7 +1583,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
|
||||
TABLES we have to simply prohibit dropping of views.
|
||||
*/
|
||||
|
||||
if (thd->locked_tables)
|
||||
if (thd->locked_tables_mode)
|
||||
{
|
||||
my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
|
||||
DBUG_RETURN(TRUE);
|
||||
|
@ -1109,7 +1109,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool do_optimize)
|
||||
ha_release_temporary_latches(thd);
|
||||
|
||||
// Don't lock tables if we have used LOCK TABLE
|
||||
if (!thd->locked_tables &&
|
||||
if (! thd->locked_tables_mode &&
|
||||
mi_lock_database(file, table->s->tmp_table ? F_EXTRA_LCK : F_WRLCK))
|
||||
{
|
||||
mi_check_print_error(¶m,ER(ER_CANT_LOCK),my_errno);
|
||||
@ -1219,7 +1219,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool do_optimize)
|
||||
update_state_info(¶m, file, 0);
|
||||
}
|
||||
thd_proc_info(thd, old_proc_info);
|
||||
if (!thd->locked_tables)
|
||||
if (! thd->locked_tables_mode)
|
||||
mi_lock_database(file,F_UNLCK);
|
||||
DBUG_RETURN(error ? HA_ADMIN_FAILED :
|
||||
!optimize_done ? HA_ADMIN_ALREADY_DONE : HA_ADMIN_OK);
|
||||
|
Loading…
x
Reference in New Issue
Block a user