MySQL 8.0.40
Source Code Documentation
Locking

Macros

#define GET_LOCK_UNLOCK   1
 
#define GET_LOCK_STORE_LOCKS   2
 

Functions

static MYSQL_LOCKget_lock_data (THD *thd, TABLE **table_ptr, size_t count, uint flags)
 Get lock structures from table structs and initialize locks. More...
 
static int lock_external (THD *thd, TABLE **table, uint count)
 
static int unlock_external (THD *thd, TABLE **table, uint count)
 Unlock a set of external. More...
 
static void print_lock_error (int error, const char *)
 
static int lock_tables_check (THD *thd, TABLE **tables, size_t count, uint flags)
 Perform semantic checks for mysql_lock_tables. More...
 
static void reset_lock_data (MYSQL_LOCK *sql_lock)
 Reset lock type in lock data. More...
 
static void track_table_access (THD *thd, TABLE **tables, size_t count)
 Scan array of tables for access types; update transaction tracker accordingly. More...
 
static void reset_lock_data_and_free (MYSQL_LOCK **mysql_lock)
 Reset lock type in lock data and free. More...
 
MYSQL_LOCKmysql_lock_tables (THD *thd, TABLE **tables, size_t count, uint flags)
 Lock tables. More...
 
void mysql_unlock_tables (THD *thd, MYSQL_LOCK *sql_lock)
 
void mysql_unlock_some_tables (THD *thd, TABLE **table, uint count)
 Unlock some of the tables locked by mysql_lock_tables. More...
 
void mysql_unlock_read_tables (THD *thd, MYSQL_LOCK *sql_lock)
 unlock all tables locked for read. More...
 
void mysql_lock_remove (THD *thd, MYSQL_LOCK *locked, TABLE *table)
 Try to find the table in the list of locked tables. More...
 
void mysql_lock_abort_for_thread (THD *thd, TABLE *table)
 Abort one thread / table combination. More...
 
MYSQL_LOCKmysql_lock_merge (MYSQL_LOCK *a, MYSQL_LOCK *b)
 
bool lock_schema_name (THD *thd, const char *db)
 Obtain an exclusive metadata lock on a schema name. More...
 
bool lock_tablespace_names (THD *thd, Tablespace_hash_set *tablespace_set, ulong lock_wait_timeout, MEM_ROOT *mem_root)
 Acquire IX MDL lock each tablespace name from the given set. More...
 
bool lock_object_name (THD *thd, MDL_key::enum_mdl_namespace mdl_type, const char *db, const char *name)
 Obtain an exclusive metadata lock on an object name. More...
 
bool acquire_shared_global_read_lock (THD *thd, unsigned long lock_wait_timeout)
 Acquire protection against the global read lock. More...
 
bool Global_read_lock::lock_global_read_lock (THD *thd)
 Take global read lock, wait if there is protection against lock. More...
 
void Global_read_lock::unlock_global_read_lock (THD *thd)
 Unlock global read lock. More...
 
bool Global_read_lock::make_global_read_lock_block_commit (THD *thd)
 Make global read lock also block commits. More...
 
void Global_read_lock::set_explicit_lock_duration (THD *thd)
 Set explicit duration for metadata locks which are used to implement GRL. More...
 

Variables

static int thr_lock_errno_to_mysql []
 
static std::atomic< int32Global_read_lock::m_atomic_active_requests
 

Detailed Description

Macro Definition Documentation

◆ GET_LOCK_STORE_LOCKS

#define GET_LOCK_STORE_LOCKS   2

◆ GET_LOCK_UNLOCK

#define GET_LOCK_UNLOCK   1

Function Documentation

◆ acquire_shared_global_read_lock()

bool acquire_shared_global_read_lock ( THD thd,
unsigned long  lock_wait_timeout 
)

Acquire protection against the global read lock.

Acquire an intention exclusive lock to protect against others setting the global read lock. We follow the naming used by the backup lock help functions when naming this function.

Parameters
thdThread context.
lock_wait_timeoutTime to wait for lock acquisition.
Return values
falseNo error, meta data lock acquired.
trueError, meta data lock not acquired.

◆ get_lock_data()

static MYSQL_LOCK * get_lock_data ( THD thd,
TABLE **  table_ptr,
size_t  count,
uint  flags 
)
static

Get lock structures from table structs and initialize locks.

Parameters
thdThread handler
table_ptrPointer to tables that should be locks
countNumber of tables
flagsOne of:
  • GET_LOCK_UNLOCK : If we should send TL_IGNORE to store lock
  • GET_LOCK_STORE_LOCKS : Store lock info in TABLE

◆ lock_external()

static int lock_external ( THD thd,
TABLE **  table,
uint  count 
)
static

◆ lock_global_read_lock()

bool Global_read_lock::lock_global_read_lock ( THD thd)

Take global read lock, wait if there is protection against lock.

If the global read lock is already taken by this thread, then nothing is done.

See also "Handling of global read locks" above.

Parameters
thdReference to thread.
Return values
FalseSuccess, global read lock set, commits are NOT blocked.
TrueFailure, thread was killed.

◆ lock_object_name()

bool lock_object_name ( THD thd,
MDL_key::enum_mdl_namespace  mdl_type,
const char *  db,
const char *  name 
)

Obtain an exclusive metadata lock on an object name.

Parameters
thdThread handle.
mdl_typeObject type (currently functions, procedures and events can be name-locked).
dbThe schema the object belongs to.
nameObject name in the schema.

This function cannot be called while holding LOCK_open_mutex. This invariant is enforced by asserts in MDL_context::acquire_locks. To avoid deadlocks, we do not try to obtain exclusive metadata locks in LOCK TABLES mode, since in this mode there may be other metadata locks already taken by the current connection, and we must not wait for MDL locks while holding locks.

Note
name is converted to lowercase before the lock is acquired since stored routine and event names are case insensitive.
Return values
falseSuccess.
trueFailure: we're in LOCK TABLES mode, or out of memory, or this connection was killed.

◆ lock_schema_name()

bool lock_schema_name ( THD thd,
const char *  db 
)

Obtain an exclusive metadata lock on a schema name.

Parameters
thdThread handle.
dbThe database name.

This function cannot be called while holding LOCK_open mutex. To avoid deadlocks, we do not try to obtain exclusive metadata locks in LOCK TABLES mode, since in this mode there may be other metadata locks already taken by the current connection, and we must not wait for MDL locks while holding locks.

Return values
falseSuccess.
trueFailure: we're in LOCK TABLES mode, or out of memory, or this connection was killed.

◆ lock_tables_check()

static int lock_tables_check ( THD thd,
TABLE **  tables,
size_t  count,
uint  flags 
)
static

Perform semantic checks for mysql_lock_tables.

Parameters
thdThe current thread
tablesThe tables to lock
countThe number of tables to lock
flagsLock flags
Returns
0 if all the check passed, non zero if a check failed.

◆ lock_tablespace_names()

bool lock_tablespace_names ( THD thd,
Tablespace_hash_set tablespace_set,
ulong  lock_wait_timeout,
MEM_ROOT mem_root 
)

Acquire IX MDL lock each tablespace name from the given set.

Parameters
thd- Thread invoking this function.
tablespace_set- Set of tablespace names to be lock.
lock_wait_timeout- Lock timeout.
mem_root- Memory root on which MDL_request objects can be allocated.
Returns
true - On failure
false - On Success.

◆ make_global_read_lock_block_commit()

bool Global_read_lock::make_global_read_lock_block_commit ( THD thd)

Make global read lock also block commits.

The scenario is:

  • This thread has the global read lock.
  • Global read lock blocking of commits is not set.

See also "Handling of global read locks" above.

Parameters
thdReference to thread.
Return values
FalseSuccess, global read lock set, commits are blocked.
TrueFailure, thread was killed.

◆ mysql_lock_abort_for_thread()

void mysql_lock_abort_for_thread ( THD thd,
TABLE table 
)

Abort one thread / table combination.

Parameters
thdThread handler
tableTable that should be removed from lock queue

◆ mysql_lock_merge()

MYSQL_LOCK * mysql_lock_merge ( MYSQL_LOCK a,
MYSQL_LOCK b 
)

◆ mysql_lock_remove()

void mysql_lock_remove ( THD thd,
MYSQL_LOCK locked,
TABLE table 
)

Try to find the table in the list of locked tables.

In case of success, unlock the table and remove it from this list. If a table has more than one lock instance, removes them all.

Parameters
thdthread context
lockedlist of locked tables
tablethe table to unlock

◆ mysql_lock_tables()

MYSQL_LOCK * mysql_lock_tables ( THD thd,
TABLE **  tables,
size_t  count,
uint  flags 
)

Lock tables.

Parameters
thdThe current thread.
tablesAn array of pointers to the tables to lock.
countThe number of tables to lock.
flagsOptions: MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY Ignore SET GLOBAL READ_ONLY MYSQL_LOCK_IGNORE_TIMEOUT Use maximum timeout value.
Return values
Alock structure pointer on success.
NULLif an error or if wait on a lock was killed.

◆ mysql_unlock_read_tables()

void mysql_unlock_read_tables ( THD thd,
MYSQL_LOCK sql_lock 
)

unlock all tables locked for read.

◆ mysql_unlock_some_tables()

void mysql_unlock_some_tables ( THD thd,
TABLE **  table,
uint  count 
)

Unlock some of the tables locked by mysql_lock_tables.

This will work even if get_lock_data fails (next unlock will free all)

◆ mysql_unlock_tables()

void mysql_unlock_tables ( THD thd,
MYSQL_LOCK sql_lock 
)

◆ print_lock_error()

static void print_lock_error ( int  error,
const char *  table 
)
static

◆ reset_lock_data()

static void reset_lock_data ( MYSQL_LOCK sql_lock)
static

Reset lock type in lock data.

Parameters
sql_lockLock structures to reset.
Note
After a locking error we want to quit the locking of the table(s). The test case in the bug report for Bug #18544 has the following cases: 1. Locking error in lock_external() due to InnoDB timeout.
  1. Locking error in get_lock_data() due to missing write permission.
  2. Locking error in wait_if_global_read_lock() due to lock conflict.
In all these cases we have already set the lock type into the lock data of the open table(s). If the table(s) are in the open table cache, they could be reused with the non-zero lock type set. This could lead to ignoring a different lock type with the next lock.
Clear the lock type of all lock data. This ensures that the next lock request will set its lock type properly.

◆ reset_lock_data_and_free()

static void reset_lock_data_and_free ( MYSQL_LOCK **  mysql_lock)
static

Reset lock type in lock data and free.

Parameters
mysql_lockLock structures to reset.

◆ set_explicit_lock_duration()

void Global_read_lock::set_explicit_lock_duration ( THD thd)

Set explicit duration for metadata locks which are used to implement GRL.

Parameters
thdReference to thread.

◆ track_table_access()

static void track_table_access ( THD thd,
TABLE **  tables,
size_t  count 
)
static

Scan array of tables for access types; update transaction tracker accordingly.

Parameters
thdThe current thread.
tablesAn array of pointers to the tables to lock.
countThe number of tables to lock.

◆ unlock_external()

static int unlock_external ( THD thd,
TABLE **  table,
uint  count 
)
static

Unlock a set of external.

◆ unlock_global_read_lock()

void Global_read_lock::unlock_global_read_lock ( THD thd)

Unlock global read lock.

Commits may or may not be blocked when this function is called.

See also "Handling of global read locks" above.

Parameters
thdReference to thread.

Variable Documentation

◆ m_atomic_active_requests

std::atomic< int32 > Global_read_lock::m_atomic_active_requests
staticprivate

◆ thr_lock_errno_to_mysql

int thr_lock_errno_to_mysql[]
static
Initial value:
= {0, ER_LOCK_ABORTED,
ER_LOCK_WAIT_TIMEOUT, ER_LOCK_DEADLOCK}