@ -2421,7 +2421,7 @@ open_table_get_mdl_lock(THD *thd, TABLE_LIST *table_list,
required to remedy problem appeared during attempt
required to remedy problem appeared during attempt
to open table .
to open table .
flags Bitmap of flags to modify how open works :
flags Bitmap of flags to modify how open works :
MYSQL_LOCK _IGNORE_FLUSH - Open table even if
MYSQL_OPEN _IGNORE_FLUSH - Open table even if
someone has done a flush or there is a pending
someone has done a flush or there is a pending
exclusive metadata lock requests against it
exclusive metadata lock requests against it
( i . e . request high priority metadata lock ) .
( i . e . request high priority metadata lock ) .
@ -2479,6 +2479,31 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
key_length = ( create_table_def_key ( thd , key , table_list , 1 ) -
key_length = ( create_table_def_key ( thd , key , table_list , 1 ) -
TMP_TABLE_KEY_EXTRA ) ;
TMP_TABLE_KEY_EXTRA ) ;
/*
We need this to work for all tables , including temporary
tables , for backwards compatibility . But not under LOCK
TABLES , since under LOCK TABLES one can ' t use a non - prelocked
table . This code only works for updates done inside DO / SELECT
f1 ( ) statements , normal DML is handled by means of
sql_command_flags .
*/
if ( global_read_lock & & table_list - > lock_type > = TL_WRITE_ALLOW_WRITE & &
! ( flags & MYSQL_OPEN_IGNORE_GLOBAL_READ_LOCK ) & &
! thd - > locked_tables_mode )
{
/*
Someone has issued FLUSH TABLES WITH READ LOCK and we want
a write lock . Wait until the lock is gone .
*/
if ( thd - > global_read_lock . wait_if_global_read_lock ( thd , 1 , 1 ) )
DBUG_RETURN ( TRUE ) ;
if ( thd - > version ! = refresh_version )
{
( void ) ot_ctx - > request_backoff_action ( Open_table_context : : OT_WAIT_TDC ) ;
DBUG_RETURN ( TRUE ) ;
}
}
/*
/*
Unless requested otherwise , try to resolve this table in the list
Unless requested otherwise , try to resolve this table in the list
of temporary tables of this thread . In MySQL temporary tables
of temporary tables of this thread . In MySQL temporary tables
@ -2680,7 +2705,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
if ( ! thd - > open_tables )
if ( ! thd - > open_tables )
thd - > version = refresh_version ;
thd - > version = refresh_version ;
else if ( ( thd - > version ! = refresh_version ) & &
else if ( ( thd - > version ! = refresh_version ) & &
! ( flags & MYSQL_LOCK _IGNORE_FLUSH ) )
! ( flags & MYSQL_OPEN _IGNORE_FLUSH ) )
{
{
/* Someone did a refresh while thread was opening tables */
/* Someone did a refresh while thread was opening tables */
mysql_mutex_unlock ( & LOCK_open ) ;
mysql_mutex_unlock ( & LOCK_open ) ;
@ -2811,7 +2836,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
if ( share - > version ! = refresh_version )
if ( share - > version ! = refresh_version )
{
{
if ( ! ( flags & MYSQL_LOCK _IGNORE_FLUSH ) )
if ( ! ( flags & MYSQL_OPEN _IGNORE_FLUSH ) )
{
{
/*
/*
We already have an MDL lock . But we have encountered an old
We already have an MDL lock . But we have encountered an old
@ -3293,7 +3318,6 @@ bool
Locked_tables_list : : reopen_tables ( THD * thd )
Locked_tables_list : : reopen_tables ( THD * thd )
{
{
Open_table_context ot_ctx_unused ( thd , LONG_TIMEOUT ) ;
Open_table_context ot_ctx_unused ( thd , LONG_TIMEOUT ) ;
bool lt_refresh_unused ;
size_t reopen_count = 0 ;
size_t reopen_count = 0 ;
MYSQL_LOCK * lock ;
MYSQL_LOCK * lock ;
MYSQL_LOCK * merged_lock ;
MYSQL_LOCK * merged_lock ;
@ -3333,7 +3357,7 @@ Locked_tables_list::reopen_tables(THD *thd)
break something else .
break something else .
*/
*/
lock = mysql_lock_tables ( thd , m_reopen_array , reopen_count ,
lock = mysql_lock_tables ( thd , m_reopen_array , reopen_count ,
MYSQL_OPEN_REOPEN , & lt_refresh_unused ) ;
MYSQL_OPEN_REOPEN ) ;
thd - > in_lock_tables = 0 ;
thd - > in_lock_tables = 0 ;
if ( lock = = NULL | | ( merged_lock =
if ( lock = = NULL | | ( merged_lock =
mysql_lock_merge ( thd - > lock , lock ) ) = = NULL )
mysql_lock_merge ( thd - > lock , lock ) ) = = NULL )
@ -5061,7 +5085,6 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type,
TABLE * table ;
TABLE * table ;
Open_table_context ot_ctx ( thd , ( lock_flags & MYSQL_LOCK_IGNORE_TIMEOUT ) ?
Open_table_context ot_ctx ( thd , ( lock_flags & MYSQL_LOCK_IGNORE_TIMEOUT ) ?
LONG_TIMEOUT : thd - > variables . lock_wait_timeout ) ;
LONG_TIMEOUT : thd - > variables . lock_wait_timeout ) ;
bool refresh ;
bool error ;
bool error ;
DBUG_ENTER ( " open_ltable " ) ;
DBUG_ENTER ( " open_ltable " ) ;
@ -5073,8 +5096,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type,
/* open_ltable can be used only for BASIC TABLEs */
/* open_ltable can be used only for BASIC TABLEs */
table_list - > required_type = FRMTYPE_TABLE ;
table_list - > required_type = FRMTYPE_TABLE ;
retry :
while ( ( error = open_table ( thd , table_list , thd - > mem_root , & ot_ctx , 0 ) ) & &
while ( ( error = open_table ( thd , table_list , thd - > mem_root , & ot_ctx , lock_flags ) ) & &
ot_ctx . can_recover_from_failed_open ( ) )
ot_ctx . can_recover_from_failed_open ( ) )
{
{
/*
/*
@ -5120,17 +5142,8 @@ retry:
DBUG_ASSERT ( thd - > lock = = 0 ) ; // You must lock everything at once
DBUG_ASSERT ( thd - > lock = = 0 ) ; // You must lock everything at once
if ( ( table - > reginfo . lock_type = lock_type ) ! = TL_UNLOCK )
if ( ( table - > reginfo . lock_type = lock_type ) ! = TL_UNLOCK )
if ( ! ( thd - > lock = mysql_lock_tables ( thd , & table_list - > table , 1 ,
if ( ! ( thd - > lock = mysql_lock_tables ( thd , & table_list - > table , 1 ,
lock_flags , & refresh ) ) )
{
if ( refresh )
lock_flags ) ) )
{
{
close_thread_tables ( thd ) ;
table_list - > table = NULL ;
table_list - > mdl_request . ticket = NULL ;
thd - > mdl_context . rollback_to_savepoint ( ot_ctx . start_of_statement_svp ( ) ) ;
goto retry ;
}
else
table = 0 ;
table = 0 ;
}
}
}
}
@ -5168,42 +5181,27 @@ bool open_and_lock_tables(THD *thd, TABLE_LIST *tables,
Prelocking_strategy * prelocking_strategy )
Prelocking_strategy * prelocking_strategy )
{
{
uint counter ;
uint counter ;
bool need_reopen ;
/*
Remember the set of metadata locks which this connection
managed to acquire before the start of the current statement .
It can be either transaction - scope locks , or HANDLER locks ,
or LOCK TABLES locks . If mysql_lock_tables ( ) fails with
need_reopen request , we ' ll use it to instruct
close_tables_for_reopen ( ) to release all locks of this
statement .
*/
MDL_ticket * start_of_statement_svp = thd - > mdl_context . mdl_savepoint ( ) ;
DBUG_ENTER ( " open_and_lock_tables " ) ;
DBUG_ENTER ( " open_and_lock_tables " ) ;
DBUG_PRINT ( " enter " , ( " derived handling: %d " , derived ) ) ;
DBUG_PRINT ( " enter " , ( " derived handling: %d " , derived ) ) ;
for ( ; ; )
{
if ( open_tables ( thd , & tables , & counter , flags , prelocking_strategy ) )
if ( open_tables ( thd , & tables , & counter , flags , prelocking_strategy ) )
DBUG_RETURN ( TRUE ) ;
DBUG_RETURN ( TRUE ) ;
DBUG_EXECUTE_IF ( " sleep_open_and_lock_after_open " , {
DBUG_EXECUTE_IF ( " sleep_open_and_lock_after_open " , {
const char * old_proc_info = thd - > proc_info ;
const char * old_proc_info = thd - > proc_info ;
thd - > proc_info = " DBUG sleep " ;
thd - > proc_info = " DBUG sleep " ;
my_sleep ( 6000000 ) ;
my_sleep ( 6000000 ) ;
thd - > proc_info = old_proc_info ; } ) ;
thd - > proc_info = old_proc_info ; } ) ;
if ( ! lock_tables ( thd , tables , counter , flags ,
& need_reopen ) )
break ;
if ( ! need_reopen )
if ( lock_tables ( thd , tables , counter , flags ) )
DBUG_RETURN ( TRUE ) ;
DBUG_RETURN ( TRUE ) ;
close_tables_for_reopen ( thd , & tables , start_of_statement_svp ) ;
}
if ( derived & &
if ( derived & &
( mysql_handle_derived ( thd - > lex , & mysql_derived_prepare ) | |
( mysql_handle_derived ( thd - > lex , & mysql_derived_prepare ) | |
( thd - > fill_derived_tables ( ) & &
( thd - > fill_derived_tables ( ) & &
mysql_handle_derived ( thd - > lex , & mysql_derived_filling ) ) ) )
mysql_handle_derived ( thd - > lex , & mysql_derived_filling ) ) ) )
DBUG_RETURN ( TRUE ) ; /* purecov: inspected */
DBUG_RETURN ( TRUE ) ; /* purecov: inspected */
DBUG_RETURN ( FALSE ) ;
DBUG_RETURN ( FALSE ) ;
}
}
@ -5216,7 +5214,7 @@ bool open_and_lock_tables(THD *thd, TABLE_LIST *tables,
thd - thread handler
thd - thread handler
tables - list of tables for open
tables - list of tables for open
flags - bitmap of flags to modify how the tables will be open :
flags - bitmap of flags to modify how the tables will be open :
MYSQL_LOCK _IGNORE_FLUSH - open table even if someone has
MYSQL_OPEN _IGNORE_FLUSH - open table even if someone has
done a flush or namelock on it .
done a flush or namelock on it .
RETURN
RETURN
@ -5261,37 +5259,28 @@ static void mark_real_tables_as_free_for_reuse(TABLE_LIST *table)
}
}
/*
Lock all tables in list
/**
Lock all tables in a list .
SYNOPSIS
lock_tables ( )
thd Thread handler
tables Tables to lock
count Number of opened tables
flags Options ( see mysql_lock_tables ( ) for details )
need_reopen Out parameter which if TRUE indicates that some
tables were dropped or altered during this call
and therefore invoker should reopen tables and
try to lock them once again ( in this case
lock_tables ( ) will also return error ) .
@ param thd Thread handler
@ param tables Tables to lock
@ param count Number of opened tables
@ param flags Options ( see mysql_lock_tables ( ) for details )
NOTES
You can ' t call lock_tables twice , as this would break the dead - lock - free
handling thr_lock gives us . You most always get all needed locks at
once .
You can ' t call lock_tables ( ) while holding thr_lock locks , as
this would break the dead - lock - free handling thr_lock gives us .
You must always get all needed locks at once .
If query for which we are calling this function marked as requiring
prelocking , this function will change locked_tables_mode to
LTM_PRELOCKED .
If the query for which we are calling this function is marked as
requiring prelocking , this function will change
locked_tables_mode to LTM_PRELOCKED .
RETURN VALUES
0 ok
- 1 Error
@ retval FALSE Success .
@ retval TRUE A lock wait timeout , deadlock or out of memory .
*/
*/
bool lock_tables ( THD * thd , TABLE_LIST * tables , uint count ,
bool lock_tables ( THD * thd , TABLE_LIST * tables , uint count ,
uint flags , bool * need_reopen )
uint flags )
{
{
TABLE_LIST * table ;
TABLE_LIST * table ;
@ -5302,7 +5291,6 @@ bool lock_tables(THD *thd, TABLE_LIST *tables, uint count,
*/
*/
DBUG_ASSERT ( thd - > locked_tables_mode < = LTM_LOCK_TABLES | |
DBUG_ASSERT ( thd - > locked_tables_mode < = LTM_LOCK_TABLES | |
! thd - > lex - > requires_prelocking ( ) ) ;
! thd - > lex - > requires_prelocking ( ) ) ;
* need_reopen = FALSE ;
if ( ! tables & & ! thd - > lex - > requires_prelocking ( ) )
if ( ! tables & & ! thd - > lex - > requires_prelocking ( ) )
DBUG_RETURN ( thd - > decide_logging_format ( tables ) ) ;
DBUG_RETURN ( thd - > decide_logging_format ( tables ) ) ;
@ -5347,7 +5335,7 @@ bool lock_tables(THD *thd, TABLE_LIST *tables, uint count,
DEBUG_SYNC ( thd , " before_lock_tables_takes_lock " ) ;
DEBUG_SYNC ( thd , " before_lock_tables_takes_lock " ) ;
if ( ! ( thd - > lock = mysql_lock_tables ( thd , start , ( uint ) ( ptr - start ) ,
if ( ! ( thd - > lock = mysql_lock_tables ( thd , start , ( uint ) ( ptr - start ) ,
flags , need_reopen ) ) )
flags ) ) )
DBUG_RETURN ( TRUE ) ;
DBUG_RETURN ( TRUE ) ;
DEBUG_SYNC ( thd , " after_lock_tables_takes_lock " ) ;
DEBUG_SYNC ( thd , " after_lock_tables_takes_lock " ) ;
@ -8869,7 +8857,7 @@ open_system_tables_for_read(THD *thd, TABLE_LIST *table_list,
thd - > reset_n_backup_open_tables_state ( backup ) ;
thd - > reset_n_backup_open_tables_state ( backup ) ;
if ( open_and_lock_tables ( thd , table_list , FALSE ,
if ( open_and_lock_tables ( thd , table_list , FALSE ,
MYSQL_LOCK _IGNORE_FLUSH |
MYSQL_OPEN _IGNORE_FLUSH |
MYSQL_LOCK_IGNORE_TIMEOUT ) )
MYSQL_LOCK_IGNORE_TIMEOUT ) )
{
{
lex - > restore_backup_query_tables_list ( & query_tables_list_backup ) ;
lex - > restore_backup_query_tables_list ( & query_tables_list_backup ) ;
@ -8957,11 +8945,11 @@ open_system_table_for_update(THD *thd, TABLE_LIST *one_table)
TABLE *
TABLE *
open_log_table ( THD * thd , TABLE_LIST * one_table , Open_tables_backup * backup )
open_log_table ( THD * thd , TABLE_LIST * one_table , Open_tables_backup * backup )
{
{
uint flags = ( MYSQL_LOCK _IGNORE_GLOBAL_READ_LOCK |
uint flags = ( MYSQL_OPEN _IGNORE_GLOBAL_READ_LOCK |
MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY |
MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY |
MYSQL_LOCK _IGNORE_FLUSH |
MYSQL_OPEN _IGNORE_FLUSH |
MYSQL_LOCK_IGNORE_TIMEOUT |
MYSQL_LOCK_IGNORE_TIMEOUT |
MYSQL_LOCK_PERF_SCHEMA ) ;
MYSQL_LOCK_LOG_TABLE ) ;
TABLE * table ;
TABLE * table ;
/* Save value that is changed in mysql_lock_tables() */
/* Save value that is changed in mysql_lock_tables() */
ulonglong save_utime_after_lock = thd - > utime_after_lock ;
ulonglong save_utime_after_lock = thd - > utime_after_lock ;
@ -8989,7 +8977,6 @@ open_log_table(THD *thd, TABLE_LIST *one_table, Open_tables_backup *backup)
open tables cannot be accepted when restoring the open tables
open tables cannot be accepted when restoring the open tables
state .
state .
*/
*/
if ( thd - > killed )
close_thread_tables ( thd ) ;
close_thread_tables ( thd ) ;
thd - > restore_backup_open_tables_state ( backup ) ;
thd - > restore_backup_open_tables_state ( backup ) ;
}
}