MySQL 8.0.39
Source Code Documentation
lock.cc File Reference

Locking functions. More...

#include "sql/lock.h"
#include <fcntl.h>
#include <string.h>
#include <algorithm>
#include <atomic>
#include "lex_string.h"
#include "m_ctype.h"
#include "m_string.h"
#include "my_base.h"
#include "my_dbug.h"
#include "my_inttypes.h"
#include "my_sqlcommand.h"
#include "my_sys.h"
#include "mysql/service_mysql_alloc.h"
#include "mysql_com.h"
#include "mysqld_error.h"
#include "sql/auth/auth_common.h"
#include "sql/dd/types/event.h"
#include "sql/dd/types/function.h"
#include "sql/dd/types/procedure.h"
#include "sql/dd/types/resource_group.h"
#include "sql/debug_sync.h"
#include "sql/handler.h"
#include "sql/mysqld.h"
#include "sql/psi_memory_key.h"
#include "sql/session_tracker.h"
#include "sql/sql_base.h"
#include "sql/sql_class.h"
#include "sql/sql_const.h"
#include "sql/sql_db.h"
#include "sql/sql_lex.h"
#include "sql/sql_parse.h"
#include "sql/system_variables.h"
#include "sql/table.h"
#include "thr_lock.h"

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...
 

Variables

static int thr_lock_errno_to_mysql []
 

Detailed Description

Locking functions.

Because of the new concurrent inserts, we must first get external locks before getting internal locks. If we do it in the other order, the status information is not up to date when called from the lock handler.

GENERAL DESCRIPTION OF LOCKING

When not using LOCK TABLES:

  • For each SQL statement mysql_lock_tables() is called for all involved tables.
    • mysql_lock_tables() will call table_handler->external_lock(thd,locktype) for each table. This is followed by a call to thr_multi_lock() for all tables.
  • When statement is done, we call mysql_unlock_tables(). This will call thr_multi_unlock() followed by table_handler->external_lock(thd, F_UNLCK) for each table.
  • Note that mysql_unlock_tables() may be called several times as MySQL in some cases can free some tables earlier than others.
  • The above is true both for normal and temporary tables.
  • Temporary non transactional tables are never passed to thr_multi_lock() and we never call external_lock(thd, F_UNLOCK) on these.

When using LOCK TABLES:

  • LOCK TABLE will call mysql_lock_tables() for all tables. mysql_lock_tables() will call table_handler->external_lock(thd,locktype) for each table. This is followed by a call to thr_multi_lock() for all tables.
  • For each statement, we will call table_handler->start_stmt(THD) to inform the table handler that we are using the table.

    The tables used can only be tables used in LOCK TABLES or a temporary table.

  • When statement is done, we will call ha_commit_stmt(thd);
  • When calling UNLOCK TABLES we call mysql_unlock_tables() for all tables used in LOCK TABLES

If table_handler->external_lock(thd, locktype) fails, we call table_handler->external_lock(thd, F_UNLCK) for each table that was locked, excluding one that caused failure. That means handler must cleanup itself in case external_lock() fails.