mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Patch that changes metadata locking subsystem to use mutex per lock and
condition variable per context instead of one mutex and one conditional variable for the whole subsystem. This should increase concurrency in this subsystem. It also opens the way for further changes which are necessary to solve such bugs as bug #46272 "MySQL 5.4.4, new MDL: unnecessary deadlock" and bug #37346 "innodb does not detect deadlock between update and alter table". Two other notable changes done by this patch: - MDL subsystem no longer implicitly acquires global intention exclusive metadata lock when per-object metadata lock is acquired. Now this has to be done by explicit calls outside of MDL subsystem. - Instead of using separate MDL_context for opening system tables/tables for purposes of I_S we now create MDL savepoint in the main context before opening tables and rollback to this savepoint after closing them. This means that it is now possible to get ER_LOCK_DEADLOCK error even not inside a transaction. This might happen in unlikely case when one runs DDL on one of system tables while also running DDL on some other tables. Cases when this ER_LOCK_DEADLOCK error is not justified will be addressed by advanced deadlock detector for MDL subsystem which we plan to implement.
This commit is contained in:
@ -978,9 +978,6 @@ public:
|
||||
Flags with information about the open tables state.
|
||||
*/
|
||||
uint state_flags;
|
||||
|
||||
MDL_context mdl_context;
|
||||
|
||||
/**
|
||||
This constructor initializes Open_tables_state instance which can only
|
||||
be used as backup storage. To prepare Open_tables_state instance for
|
||||
@ -1010,21 +1007,29 @@ public:
|
||||
locked_tables_mode= LTM_NONE;
|
||||
state_flags= 0U;
|
||||
m_reprepare_observer= NULL;
|
||||
mdl_context.init(thd);
|
||||
}
|
||||
void enter_locked_tables_mode(enum_locked_tables_mode mode_arg)
|
||||
{
|
||||
DBUG_ASSERT(locked_tables_mode == LTM_NONE);
|
||||
mdl_context.set_lt_or_ha_sentinel();
|
||||
locked_tables_mode= mode_arg;
|
||||
}
|
||||
void leave_locked_tables_mode()
|
||||
{
|
||||
locked_tables_mode= LTM_NONE;
|
||||
mdl_context.clear_lt_or_ha_sentinel();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Storage for backup of Open_tables_state. Must
|
||||
be used only to open system tables (TABLE_CATEGORY_SYSTEM
|
||||
and TABLE_CATEGORY_LOG).
|
||||
*/
|
||||
|
||||
class Open_tables_backup: public Open_tables_state
|
||||
{
|
||||
public:
|
||||
/**
|
||||
When we backup the open tables state to open a system
|
||||
table or tables, points at the last metadata lock
|
||||
acquired before the backup. Is used to release
|
||||
metadata locks on system tables after they are
|
||||
no longer used.
|
||||
*/
|
||||
MDL_ticket *mdl_system_tables_svp;
|
||||
};
|
||||
|
||||
/**
|
||||
@class Sub_statement_state
|
||||
@brief Used to save context when executing a function or trigger
|
||||
@ -1308,6 +1313,9 @@ public:
|
||||
{
|
||||
return m_start_of_statement_svp;
|
||||
}
|
||||
|
||||
MDL_request *get_global_mdl_request(THD *thd);
|
||||
|
||||
private:
|
||||
/** List of requests for all locks taken so far. Used for waiting on locks. */
|
||||
MDL_request_list m_mdl_requests;
|
||||
@ -1320,6 +1328,11 @@ private:
|
||||
and we can't safely do back-off (and release them).
|
||||
*/
|
||||
bool m_has_locks;
|
||||
/**
|
||||
Request object for global intention exclusive lock which is acquired during
|
||||
opening tables for statements which take upgradable shared metadata locks.
|
||||
*/
|
||||
MDL_request *m_global_mdl_request;
|
||||
};
|
||||
|
||||
|
||||
@ -1426,6 +1439,8 @@ class THD :public Statement,
|
||||
public Open_tables_state
|
||||
{
|
||||
public:
|
||||
MDL_context mdl_context;
|
||||
|
||||
/* Used to execute base64 coded binlog events in MySQL server */
|
||||
Relay_log_info* rli_fake;
|
||||
|
||||
@ -2314,8 +2329,8 @@ public:
|
||||
void set_status_var_init();
|
||||
bool is_context_analysis_only()
|
||||
{ return stmt_arena->is_stmt_prepare() || lex->view_prepare_mode; }
|
||||
void reset_n_backup_open_tables_state(Open_tables_state *backup);
|
||||
void restore_backup_open_tables_state(Open_tables_state *backup);
|
||||
void reset_n_backup_open_tables_state(Open_tables_backup *backup);
|
||||
void restore_backup_open_tables_state(Open_tables_backup *backup);
|
||||
void reset_sub_statement_state(Sub_statement_state *backup, uint new_state);
|
||||
void restore_sub_statement_state(Sub_statement_state *backup);
|
||||
void set_n_backup_active_arena(Query_arena *set, Query_arena *backup);
|
||||
@ -2567,6 +2582,19 @@ public:
|
||||
Protected with LOCK_thd_data mutex.
|
||||
*/
|
||||
void set_query(char *query_arg, uint32 query_length_arg);
|
||||
void enter_locked_tables_mode(enum_locked_tables_mode mode_arg)
|
||||
{
|
||||
DBUG_ASSERT(locked_tables_mode == LTM_NONE);
|
||||
DBUG_ASSERT(! mdl_context.lt_or_ha_sentinel() ||
|
||||
mdl_context.is_global_lock_owner(MDL_SHARED));
|
||||
mdl_context.set_lt_or_ha_sentinel();
|
||||
locked_tables_mode= mode_arg;
|
||||
}
|
||||
void leave_locked_tables_mode()
|
||||
{
|
||||
locked_tables_mode= LTM_NONE;
|
||||
mdl_context.clear_lt_or_ha_sentinel();
|
||||
}
|
||||
private:
|
||||
/** The current internal error handler for this thread, or NULL. */
|
||||
Internal_error_handler *m_internal_handler;
|
||||
|
Reference in New Issue
Block a user