mirror of
https://github.com/MariaDB/server.git
synced 2025-07-17 12:02:09 +03:00
Handle errors from external_unlock & mysql_unlock_tables
Other things: - Handler errors from ha_maria::implict_commit - Disable DBUG in safe_mutex_lock to get trace file easier to read
This commit is contained in:
@ -38,7 +38,9 @@ insert t1 values (1),(2),(1);
|
|||||||
set @old_dbug=@@debug_dbug;
|
set @old_dbug=@@debug_dbug;
|
||||||
SET debug_dbug='+d,mi_lock_database_failure';
|
SET debug_dbug='+d,mi_lock_database_failure';
|
||||||
unlock tables;
|
unlock tables;
|
||||||
Warnings:
|
ERROR HY000: Index for table './test/t1.MYI' is corrupt; try to repair it
|
||||||
|
SHOW WARNINGS;
|
||||||
|
Level Code Message
|
||||||
Error 126 Index for table './test/t1.MYI' is corrupt; try to repair it
|
Error 126 Index for table './test/t1.MYI' is corrupt; try to repair it
|
||||||
Error 1030 Got error 22 "Invalid argument" from storage engine MyISAM
|
Error 1030 Got error 22 "Invalid argument" from storage engine MyISAM
|
||||||
SET debug_dbug=@old_dbug;
|
SET debug_dbug=@old_dbug;
|
||||||
|
@ -67,6 +67,8 @@ lock tables t1 write;
|
|||||||
insert t1 values (1),(2),(1);
|
insert t1 values (1),(2),(1);
|
||||||
set @old_dbug=@@debug_dbug;
|
set @old_dbug=@@debug_dbug;
|
||||||
SET debug_dbug='+d,mi_lock_database_failure';
|
SET debug_dbug='+d,mi_lock_database_failure';
|
||||||
|
--error HA_ERR_CRASHED
|
||||||
unlock tables;
|
unlock tables;
|
||||||
|
SHOW WARNINGS;
|
||||||
SET debug_dbug=@old_dbug;
|
SET debug_dbug=@old_dbug;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
@ -233,6 +233,7 @@ int safe_mutex_lock(safe_mutex_t *mp, myf my_flags, const char *file,
|
|||||||
int error;
|
int error;
|
||||||
DBUG_PRINT("mutex", ("%s (0x%lx) locking", mp->name ? mp->name : "Null",
|
DBUG_PRINT("mutex", ("%s (0x%lx) locking", mp->name ? mp->name : "Null",
|
||||||
(ulong) mp));
|
(ulong) mp));
|
||||||
|
DBUG_PUSH("");
|
||||||
|
|
||||||
pthread_mutex_lock(&mp->global);
|
pthread_mutex_lock(&mp->global);
|
||||||
if (!mp->file)
|
if (!mp->file)
|
||||||
@ -283,7 +284,7 @@ int safe_mutex_lock(safe_mutex_t *mp, myf my_flags, const char *file,
|
|||||||
{
|
{
|
||||||
error= pthread_mutex_trylock(&mp->mutex);
|
error= pthread_mutex_trylock(&mp->mutex);
|
||||||
if (error == EBUSY)
|
if (error == EBUSY)
|
||||||
return error;
|
goto end;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
error= pthread_mutex_lock(&mp->mutex);
|
error= pthread_mutex_lock(&mp->mutex);
|
||||||
@ -393,6 +394,9 @@ int safe_mutex_lock(safe_mutex_t *mp, myf my_flags, const char *file,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
DBUG_POP();
|
||||||
|
if (!error)
|
||||||
DBUG_PRINT("mutex", ("%s (0x%lx) locked", mp->name, (ulong) mp));
|
DBUG_PRINT("mutex", ("%s (0x%lx) locked", mp->name, (ulong) mp));
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
@ -1532,7 +1532,13 @@ int ha_commit_trans(THD *thd, bool all)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_ARIA_STORAGE_ENGINE
|
#ifdef WITH_ARIA_STORAGE_ENGINE
|
||||||
ha_maria::implicit_commit(thd, TRUE);
|
if ((error= ha_maria::implicit_commit(thd, TRUE)))
|
||||||
|
{
|
||||||
|
my_error(ER_ERROR_DURING_COMMIT, MYF(0), error);
|
||||||
|
ha_rollback_trans(thd, all);
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!ha_info)
|
if (!ha_info)
|
||||||
|
49
sql/lock.cc
49
sql/lock.cc
@ -409,17 +409,18 @@ static int lock_external(THD *thd, TABLE **tables, uint count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock)
|
int mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock)
|
||||||
{
|
{
|
||||||
mysql_unlock_tables(thd, sql_lock,
|
return mysql_unlock_tables(thd, sql_lock,
|
||||||
(thd->variables.option_bits & OPTION_TABLE_LOCK) ||
|
(thd->variables.option_bits & OPTION_TABLE_LOCK) ||
|
||||||
!(sql_lock->flags & GET_LOCK_ON_THD));
|
!(sql_lock->flags & GET_LOCK_ON_THD));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock, bool free_lock)
|
int mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock, bool free_lock)
|
||||||
{
|
{
|
||||||
bool errors= thd->is_error();
|
bool errors= thd->is_error();
|
||||||
|
int error= 0;
|
||||||
PSI_stage_info org_stage;
|
PSI_stage_info org_stage;
|
||||||
DBUG_ENTER("mysql_unlock_tables");
|
DBUG_ENTER("mysql_unlock_tables");
|
||||||
|
|
||||||
@ -427,7 +428,7 @@ void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock, bool free_lock)
|
|||||||
THD_STAGE_INFO(thd, stage_unlocking_tables);
|
THD_STAGE_INFO(thd, stage_unlocking_tables);
|
||||||
|
|
||||||
if (sql_lock->table_count)
|
if (sql_lock->table_count)
|
||||||
unlock_external(thd, sql_lock->table, sql_lock->table_count);
|
error= unlock_external(thd, sql_lock->table, sql_lock->table_count);
|
||||||
if (sql_lock->lock_count)
|
if (sql_lock->lock_count)
|
||||||
thr_multi_unlock(sql_lock->locks, sql_lock->lock_count, 0);
|
thr_multi_unlock(sql_lock->locks, sql_lock->lock_count, 0);
|
||||||
if (free_lock)
|
if (free_lock)
|
||||||
@ -435,10 +436,12 @@ void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock, bool free_lock)
|
|||||||
DBUG_ASSERT(!(sql_lock->flags & GET_LOCK_ON_THD));
|
DBUG_ASSERT(!(sql_lock->flags & GET_LOCK_ON_THD));
|
||||||
my_free(sql_lock);
|
my_free(sql_lock);
|
||||||
}
|
}
|
||||||
if (likely(!errors))
|
if (likely(!errors && !error))
|
||||||
thd->clear_error();
|
thd->clear_error();
|
||||||
THD_STAGE_INFO(thd, org_stage);
|
THD_STAGE_INFO(thd, org_stage);
|
||||||
DBUG_VOID_RETURN;
|
if (error)
|
||||||
|
DBUG_PRINT("exit", ("error: %d", error));
|
||||||
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -447,12 +450,16 @@ void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock, bool free_lock)
|
|||||||
This will work even if get_lock_data fails (next unlock will free all)
|
This will work even if get_lock_data fails (next unlock will free all)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count, uint flag)
|
int mysql_unlock_some_tables(THD *thd, TABLE **table,uint count, uint flag)
|
||||||
{
|
{
|
||||||
MYSQL_LOCK *sql_lock=
|
int error;
|
||||||
get_lock_data(thd, table, count, GET_LOCK_UNLOCK | GET_LOCK_ON_THD | flag);
|
MYSQL_LOCK *sql_lock;
|
||||||
if (sql_lock)
|
if (!(sql_lock= get_lock_data(thd, table, count,
|
||||||
mysql_unlock_tables(thd, sql_lock, 0);
|
GET_LOCK_UNLOCK | GET_LOCK_ON_THD | flag)))
|
||||||
|
error= ER_OUTOFMEMORY;
|
||||||
|
else
|
||||||
|
error= mysql_unlock_tables(thd, sql_lock, 0);
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -460,9 +467,10 @@ void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count, uint flag)
|
|||||||
unlock all tables locked for read.
|
unlock all tables locked for read.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock)
|
int mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock)
|
||||||
{
|
{
|
||||||
uint i,found;
|
uint i,found;
|
||||||
|
int error= 0;
|
||||||
DBUG_ENTER("mysql_unlock_read_tables");
|
DBUG_ENTER("mysql_unlock_read_tables");
|
||||||
|
|
||||||
/* Call external lock for all tables to be unlocked */
|
/* Call external lock for all tables to be unlocked */
|
||||||
@ -482,7 +490,7 @@ void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock)
|
|||||||
/* Unlock all read locked tables */
|
/* Unlock all read locked tables */
|
||||||
if (i != found)
|
if (i != found)
|
||||||
{
|
{
|
||||||
(void) unlock_external(thd,table,i-found);
|
error= unlock_external(thd,table,i-found);
|
||||||
sql_lock->table_count=found;
|
sql_lock->table_count=found;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -517,7 +525,7 @@ void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock)
|
|||||||
found+= tbl->lock_count;
|
found+= tbl->lock_count;
|
||||||
table++;
|
table++;
|
||||||
}
|
}
|
||||||
DBUG_VOID_RETURN;
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -531,8 +539,9 @@ void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock)
|
|||||||
@param table the table to unlock
|
@param table the table to unlock
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table)
|
int mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table)
|
||||||
{
|
{
|
||||||
|
int error= 0;
|
||||||
if (locked)
|
if (locked)
|
||||||
{
|
{
|
||||||
uint i;
|
uint i;
|
||||||
@ -541,13 +550,20 @@ void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table)
|
|||||||
if (locked->table[i] == table)
|
if (locked->table[i] == table)
|
||||||
{
|
{
|
||||||
uint j, removed_locks, old_tables;
|
uint j, removed_locks, old_tables;
|
||||||
|
int tmp_error;
|
||||||
TABLE *tbl;
|
TABLE *tbl;
|
||||||
uint lock_data_end;
|
uint lock_data_end;
|
||||||
|
|
||||||
DBUG_ASSERT(table->lock_position == i);
|
DBUG_ASSERT(table->lock_position == i);
|
||||||
|
|
||||||
/* Unlock the table. */
|
/* Unlock the table. */
|
||||||
mysql_unlock_some_tables(thd, &table, /* table count */ 1, 0);
|
if ((tmp_error= mysql_unlock_some_tables(thd, &table,
|
||||||
|
/* table count */ 1, 0)))
|
||||||
|
{
|
||||||
|
table->file->print_error(tmp_error, MYF(0));
|
||||||
|
if (!error)
|
||||||
|
error= tmp_error;
|
||||||
|
}
|
||||||
|
|
||||||
/* Decrement table_count in advance, making below expressions easier */
|
/* Decrement table_count in advance, making below expressions easier */
|
||||||
old_tables= --locked->table_count;
|
old_tables= --locked->table_count;
|
||||||
@ -589,6 +605,7 @@ void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
10
sql/lock.h
10
sql/lock.h
@ -28,11 +28,11 @@ typedef struct st_mysql_lock MYSQL_LOCK;
|
|||||||
|
|
||||||
MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **table, uint count, uint flags);
|
MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **table, uint count, uint flags);
|
||||||
bool mysql_lock_tables(THD *thd, MYSQL_LOCK *sql_lock, uint flags);
|
bool mysql_lock_tables(THD *thd, MYSQL_LOCK *sql_lock, uint flags);
|
||||||
void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock, bool free_lock);
|
int mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock, bool free_lock);
|
||||||
void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock);
|
int mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock);
|
||||||
void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock);
|
int mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock);
|
||||||
void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count, uint flag);
|
int mysql_unlock_some_tables(THD *thd, TABLE **table,uint count, uint flag);
|
||||||
void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table);
|
int mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table);
|
||||||
bool mysql_lock_abort_for_thread(THD *thd, TABLE *table);
|
bool mysql_lock_abort_for_thread(THD *thd, TABLE *table);
|
||||||
MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b);
|
MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b);
|
||||||
/* Lock based on name */
|
/* Lock based on name */
|
||||||
|
@ -772,9 +772,10 @@ close_all_tables_for_name(THD *thd, TABLE_SHARE *share,
|
|||||||
leave prelocked mode if needed.
|
leave prelocked mode if needed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void close_thread_tables(THD *thd)
|
int close_thread_tables(THD *thd)
|
||||||
{
|
{
|
||||||
TABLE *table;
|
TABLE *table;
|
||||||
|
int error= 0;
|
||||||
DBUG_ENTER("close_thread_tables");
|
DBUG_ENTER("close_thread_tables");
|
||||||
|
|
||||||
THD_STAGE_INFO(thd, stage_closing_tables);
|
THD_STAGE_INFO(thd, stage_closing_tables);
|
||||||
@ -874,7 +875,7 @@ void close_thread_tables(THD *thd)
|
|||||||
we will exit this function a few lines below.
|
we will exit this function a few lines below.
|
||||||
*/
|
*/
|
||||||
if (! thd->lex->requires_prelocking())
|
if (! thd->lex->requires_prelocking())
|
||||||
DBUG_VOID_RETURN;
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We are in the top-level statement of a prelocked statement,
|
We are in the top-level statement of a prelocked statement,
|
||||||
@ -885,7 +886,7 @@ void close_thread_tables(THD *thd)
|
|||||||
thd->locked_tables_mode= LTM_LOCK_TABLES;
|
thd->locked_tables_mode= LTM_LOCK_TABLES;
|
||||||
|
|
||||||
if (thd->locked_tables_mode == LTM_LOCK_TABLES)
|
if (thd->locked_tables_mode == LTM_LOCK_TABLES)
|
||||||
DBUG_VOID_RETURN;
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
thd->leave_locked_tables_mode();
|
thd->leave_locked_tables_mode();
|
||||||
|
|
||||||
@ -904,7 +905,7 @@ void close_thread_tables(THD *thd)
|
|||||||
binlog_query()) or when preparing a pending event.
|
binlog_query()) or when preparing a pending event.
|
||||||
*/
|
*/
|
||||||
(void)thd->binlog_flush_pending_rows_event(TRUE);
|
(void)thd->binlog_flush_pending_rows_event(TRUE);
|
||||||
mysql_unlock_tables(thd, thd->lock);
|
error= mysql_unlock_tables(thd, thd->lock);
|
||||||
thd->lock=0;
|
thd->lock=0;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -914,7 +915,7 @@ void close_thread_tables(THD *thd)
|
|||||||
while (thd->open_tables)
|
while (thd->open_tables)
|
||||||
(void) close_thread_table(thd, &thd->open_tables);
|
(void) close_thread_table(thd, &thd->open_tables);
|
||||||
|
|
||||||
DBUG_VOID_RETURN;
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2320,9 +2321,10 @@ Locked_tables_list::init_locked_tables(THD *thd)
|
|||||||
@note This function is a no-op if we're not in LOCK TABLES.
|
@note This function is a no-op if we're not in LOCK TABLES.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
int
|
||||||
Locked_tables_list::unlock_locked_tables(THD *thd)
|
Locked_tables_list::unlock_locked_tables(THD *thd)
|
||||||
{
|
{
|
||||||
|
int error;
|
||||||
DBUG_ASSERT(!thd->in_sub_stmt &&
|
DBUG_ASSERT(!thd->in_sub_stmt &&
|
||||||
!(thd->state_flags & Open_tables_state::BACKUPS_AVAIL));
|
!(thd->state_flags & Open_tables_state::BACKUPS_AVAIL));
|
||||||
/*
|
/*
|
||||||
@ -2332,7 +2334,7 @@ Locked_tables_list::unlock_locked_tables(THD *thd)
|
|||||||
open tables, e.g. from begin_trans().
|
open tables, e.g. from begin_trans().
|
||||||
*/
|
*/
|
||||||
if (thd->locked_tables_mode != LTM_LOCK_TABLES)
|
if (thd->locked_tables_mode != LTM_LOCK_TABLES)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
for (TABLE_LIST *table_list= m_locked_tables;
|
for (TABLE_LIST *table_list= m_locked_tables;
|
||||||
table_list; table_list= table_list->next_global)
|
table_list; table_list= table_list->next_global)
|
||||||
@ -2349,7 +2351,7 @@ Locked_tables_list::unlock_locked_tables(THD *thd)
|
|||||||
TRANSACT_TRACKER(clear_trx_state(thd, TX_LOCKED_TABLES));
|
TRANSACT_TRACKER(clear_trx_state(thd, TX_LOCKED_TABLES));
|
||||||
|
|
||||||
DBUG_ASSERT(thd->transaction.stmt.is_empty());
|
DBUG_ASSERT(thd->transaction.stmt.is_empty());
|
||||||
close_thread_tables(thd);
|
error= close_thread_tables(thd);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We rely on the caller to implicitly commit the
|
We rely on the caller to implicitly commit the
|
||||||
@ -2361,6 +2363,7 @@ Locked_tables_list::unlock_locked_tables(THD *thd)
|
|||||||
request for metadata locks and TABLE_LIST elements.
|
request for metadata locks and TABLE_LIST elements.
|
||||||
*/
|
*/
|
||||||
reset();
|
reset();
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2369,7 +2372,7 @@ Locked_tables_list::unlock_locked_tables(THD *thd)
|
|||||||
table mode if there is no locked tables anymore
|
table mode if there is no locked tables anymore
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
int
|
||||||
Locked_tables_list::unlock_locked_table(THD *thd, MDL_ticket *mdl_ticket)
|
Locked_tables_list::unlock_locked_table(THD *thd, MDL_ticket *mdl_ticket)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -2378,7 +2381,7 @@ Locked_tables_list::unlock_locked_table(THD *thd, MDL_ticket *mdl_ticket)
|
|||||||
to check this condition here than in the caller.
|
to check this condition here than in the caller.
|
||||||
*/
|
*/
|
||||||
if (thd->locked_tables_mode != LTM_LOCK_TABLES)
|
if (thd->locked_tables_mode != LTM_LOCK_TABLES)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
if (mdl_ticket)
|
if (mdl_ticket)
|
||||||
{
|
{
|
||||||
@ -2391,7 +2394,8 @@ Locked_tables_list::unlock_locked_table(THD *thd, MDL_ticket *mdl_ticket)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (thd->lock->table_count == 0)
|
if (thd->lock->table_count == 0)
|
||||||
unlock_locked_tables(thd);
|
return unlock_locked_tables(thd);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -160,7 +160,7 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table,
|
|||||||
TABLE_LIST *TABLE_LIST::*link,
|
TABLE_LIST *TABLE_LIST::*link,
|
||||||
const LEX_CSTRING *db_name,
|
const LEX_CSTRING *db_name,
|
||||||
const LEX_CSTRING *table_name);
|
const LEX_CSTRING *table_name);
|
||||||
void close_thread_tables(THD *thd);
|
int close_thread_tables(THD *thd);
|
||||||
void switch_to_nullable_trigger_fields(List<Item> &items, TABLE *);
|
void switch_to_nullable_trigger_fields(List<Item> &items, TABLE *);
|
||||||
void switch_defaults_to_nullable_trigger_fields(TABLE *table);
|
void switch_defaults_to_nullable_trigger_fields(TABLE *table);
|
||||||
bool fill_record_n_invoke_before_triggers(THD *thd, TABLE *table,
|
bool fill_record_n_invoke_before_triggers(THD *thd, TABLE *table,
|
||||||
|
@ -1969,8 +1969,8 @@ public:
|
|||||||
init_sql_alloc(key_memory_locked_table_list, &m_locked_tables_root,
|
init_sql_alloc(key_memory_locked_table_list, &m_locked_tables_root,
|
||||||
MEM_ROOT_BLOCK_SIZE, 0, MYF(MY_THREAD_SPECIFIC));
|
MEM_ROOT_BLOCK_SIZE, 0, MYF(MY_THREAD_SPECIFIC));
|
||||||
}
|
}
|
||||||
void unlock_locked_tables(THD *thd);
|
int unlock_locked_tables(THD *thd);
|
||||||
void unlock_locked_table(THD *thd, MDL_ticket *mdl_ticket);
|
int unlock_locked_table(THD *thd, MDL_ticket *mdl_ticket);
|
||||||
~Locked_tables_list()
|
~Locked_tables_list()
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
|
@ -5003,7 +5003,8 @@ mysql_execute_command(THD *thd)
|
|||||||
if (thd->variables.option_bits & OPTION_TABLE_LOCK)
|
if (thd->variables.option_bits & OPTION_TABLE_LOCK)
|
||||||
{
|
{
|
||||||
res= trans_commit_implicit(thd);
|
res= trans_commit_implicit(thd);
|
||||||
thd->locked_tables_list.unlock_locked_tables(thd);
|
if (thd->locked_tables_list.unlock_locked_tables(thd))
|
||||||
|
res= 1;
|
||||||
thd->mdl_context.release_transactional_locks();
|
thd->mdl_context.release_transactional_locks();
|
||||||
thd->variables.option_bits&= ~(OPTION_TABLE_LOCK);
|
thd->variables.option_bits&= ~(OPTION_TABLE_LOCK);
|
||||||
}
|
}
|
||||||
@ -5017,7 +5018,8 @@ mysql_execute_command(THD *thd)
|
|||||||
case SQLCOM_LOCK_TABLES:
|
case SQLCOM_LOCK_TABLES:
|
||||||
/* We must end the transaction first, regardless of anything */
|
/* We must end the transaction first, regardless of anything */
|
||||||
res= trans_commit_implicit(thd);
|
res= trans_commit_implicit(thd);
|
||||||
thd->locked_tables_list.unlock_locked_tables(thd);
|
if (thd->locked_tables_list.unlock_locked_tables(thd))
|
||||||
|
res= 1;
|
||||||
/* Release transactional metadata locks. */
|
/* Release transactional metadata locks. */
|
||||||
thd->mdl_context.release_transactional_locks();
|
thd->mdl_context.release_transactional_locks();
|
||||||
if (res)
|
if (res)
|
||||||
|
@ -6778,20 +6778,21 @@ static bool alter_partition_lock_handling(ALTER_PARTITION_PARAM_TYPE *lpt)
|
|||||||
|
|
||||||
@param lpt Struct carrying parameters
|
@param lpt Struct carrying parameters
|
||||||
|
|
||||||
@return Always 0.
|
@return error code if external_unlock fails
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int alter_close_table(ALTER_PARTITION_PARAM_TYPE *lpt)
|
static int alter_close_table(ALTER_PARTITION_PARAM_TYPE *lpt)
|
||||||
{
|
{
|
||||||
|
int error;
|
||||||
DBUG_ENTER("alter_close_table");
|
DBUG_ENTER("alter_close_table");
|
||||||
|
|
||||||
if (lpt->table->db_stat)
|
if (lpt->table->db_stat)
|
||||||
{
|
{
|
||||||
mysql_lock_remove(lpt->thd, lpt->thd->lock, lpt->table);
|
error= mysql_lock_remove(lpt->thd, lpt->thd->lock, lpt->table);
|
||||||
lpt->table->file->ha_close();
|
error= lpt->table->file->ha_close();
|
||||||
lpt->table->db_stat= 0; // Mark file closed
|
lpt->table->db_stat= 0; // Mark file closed
|
||||||
}
|
}
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2359,9 +2359,10 @@ int JOIN::optimize_stage2()
|
|||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Unlock all tables, except sequences, as accessing these may still
|
Unlock all tables, except sequences, as accessing these may still
|
||||||
require table updates
|
require table updates. It's safe to ignore result code as all
|
||||||
|
tables where opened for read only.
|
||||||
*/
|
*/
|
||||||
mysql_unlock_some_tables(thd, table, const_tables,
|
(void) mysql_unlock_some_tables(thd, table, const_tables,
|
||||||
GET_LOCK_SKIP_SEQUENCES);
|
GET_LOCK_SKIP_SEQUENCES);
|
||||||
}
|
}
|
||||||
if (!conds && outer_join)
|
if (!conds && outer_join)
|
||||||
|
@ -2699,7 +2699,8 @@ err:
|
|||||||
if (thd->lock && thd->lock->table_count == 0 &&
|
if (thd->lock && thd->lock->table_count == 0 &&
|
||||||
non_temp_tables_count > 0 && !dont_free_locks)
|
non_temp_tables_count > 0 && !dont_free_locks)
|
||||||
{
|
{
|
||||||
thd->locked_tables_list.unlock_locked_tables(thd);
|
if (thd->locked_tables_list.unlock_locked_tables(thd))
|
||||||
|
error= 1;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
for (table= tables; table; table= table->next_local)
|
for (table= tables; table; table= table->next_local)
|
||||||
@ -5406,7 +5407,7 @@ err:
|
|||||||
Possible locked table was dropped. We should remove meta data locks
|
Possible locked table was dropped. We should remove meta data locks
|
||||||
associated with it and do UNLOCK_TABLES if no more locked tables.
|
associated with it and do UNLOCK_TABLES if no more locked tables.
|
||||||
*/
|
*/
|
||||||
thd->locked_tables_list.unlock_locked_table(thd, mdl_ticket);
|
(void) thd->locked_tables_list.unlock_locked_table(thd, mdl_ticket);
|
||||||
}
|
}
|
||||||
else if (likely(!result) && create_info->table)
|
else if (likely(!result) && create_info->table)
|
||||||
{
|
{
|
||||||
@ -10608,8 +10609,10 @@ do_continue:;
|
|||||||
if (thd->locked_tables_mode != LTM_LOCK_TABLES &&
|
if (thd->locked_tables_mode != LTM_LOCK_TABLES &&
|
||||||
thd->locked_tables_mode != LTM_PRELOCKED_UNDER_LOCK_TABLES)
|
thd->locked_tables_mode != LTM_PRELOCKED_UNDER_LOCK_TABLES)
|
||||||
{
|
{
|
||||||
mysql_unlock_tables(thd, thd->lock);
|
int tmp_error= mysql_unlock_tables(thd, thd->lock);
|
||||||
thd->lock= NULL;
|
thd->lock= NULL;
|
||||||
|
if (tmp_error)
|
||||||
|
goto err_new_table_cleanup;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -10617,7 +10620,8 @@ do_continue:;
|
|||||||
If LOCK TABLES list is not empty and contains this table,
|
If LOCK TABLES list is not empty and contains this table,
|
||||||
unlock the table and remove the table from this list.
|
unlock the table and remove the table from this list.
|
||||||
*/
|
*/
|
||||||
mysql_lock_remove(thd, thd->lock, table);
|
if (mysql_lock_remove(thd, thd->lock, table))
|
||||||
|
goto err_new_table_cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
new_table->s->table_creation_was_logged=
|
new_table->s->table_creation_was_logged=
|
||||||
|
@ -103,7 +103,8 @@ bool trans_begin(THD *thd, uint flags)
|
|||||||
if (trans_check(thd))
|
if (trans_check(thd))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
thd->locked_tables_list.unlock_locked_tables(thd);
|
if (thd->locked_tables_list.unlock_locked_tables(thd))
|
||||||
|
DBUG_RETURN(true);
|
||||||
|
|
||||||
DBUG_ASSERT(!thd->locked_tables_mode);
|
DBUG_ASSERT(!thd->locked_tables_mode);
|
||||||
|
|
||||||
|
@ -320,7 +320,8 @@ int Wsrep_client_service::bf_rollback()
|
|||||||
int ret= (trans_rollback_stmt(m_thd) || trans_rollback(m_thd));
|
int ret= (trans_rollback_stmt(m_thd) || trans_rollback(m_thd));
|
||||||
if (m_thd->locked_tables_mode && m_thd->lock)
|
if (m_thd->locked_tables_mode && m_thd->lock)
|
||||||
{
|
{
|
||||||
m_thd->locked_tables_list.unlock_locked_tables(m_thd);
|
if (m_thd->locked_tables_list.unlock_locked_tables(m_thd))
|
||||||
|
ret= 1;
|
||||||
m_thd->variables.option_bits&= ~OPTION_TABLE_LOCK;
|
m_thd->variables.option_bits&= ~OPTION_TABLE_LOCK;
|
||||||
}
|
}
|
||||||
if (m_thd->global_read_lock.is_acquired())
|
if (m_thd->global_read_lock.is_acquired())
|
||||||
|
Reference in New Issue
Block a user