mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Backport of:
---------------------------------------------------------- revno: 2617.69.20 committer: Konstantin Osipov <kostja@sun.com> branch nick: 5.4-4284-1-assert timestamp: Thu 2009-08-13 18:29:55 +0400 message: WL#4284 "Transactional DDL locking" A review fix. Since WL#4284 implementation separated MDL_request and MDL_ticket, MDL_request becamse a utility object necessary only to get a ticket. Store it by-value in TABLE_LIST with the intent to merge MDL_request::key with table_list->table_name and table_list->db in future. Change the MDL subsystem to not require MDL_requests to stay around till close_thread_tables(). Remove the list of requests from the MDL context. Requests for shared metadata locks acquired in open_tables() are only used as a list in recover_from_failed_open_table_attempt(), which calls mdl_context.wait_for_locks() for this list. To keep such list for recover_from_failed_open_table_attempt(), introduce a context class (Open_table_context), that collects all requests. A lot of minor cleanups and simplications that became possible with this change.
This commit is contained in:
85
sql/mdl.h
85
sql/mdl.h
@ -109,7 +109,6 @@ public:
|
||||
mdl_key_init(type_arg, db_arg, name_arg);
|
||||
}
|
||||
MDL_key() {} /* To use when part of MDL_request. */
|
||||
|
||||
private:
|
||||
char m_ptr[MAX_MDLKEY_LENGTH];
|
||||
uint m_length;
|
||||
@ -157,12 +156,20 @@ public:
|
||||
/**
|
||||
Pointers for participating in the list of lock requests for this context.
|
||||
*/
|
||||
MDL_request *next_in_context;
|
||||
MDL_request **prev_in_context;
|
||||
MDL_request *next_in_list;
|
||||
MDL_request **prev_in_list;
|
||||
/**
|
||||
Pointer to the lock ticket object for this lock request.
|
||||
Valid only if this lock request is satisfied.
|
||||
*/
|
||||
MDL_ticket *ticket;
|
||||
|
||||
/** A lock is requested based on a fully qualified name and type. */
|
||||
MDL_key key;
|
||||
|
||||
void init(unsigned char type_arg, const char *db_arg, const char *name_arg);
|
||||
public:
|
||||
void init(unsigned char type_arg, const char *db_arg, const char *name_arg,
|
||||
enum_mdl_type mdl_type_arg);
|
||||
/** Set type of lock request. Can be only applied to pending locks. */
|
||||
inline void set_type(enum_mdl_type type_arg)
|
||||
{
|
||||
@ -171,15 +178,37 @@ public:
|
||||
}
|
||||
bool is_shared() const { return type < MDL_EXCLUSIVE; }
|
||||
|
||||
/**
|
||||
Pointer to the lock ticket object for this lock request.
|
||||
Valid only if this lock request is satisfied.
|
||||
*/
|
||||
MDL_ticket *ticket;
|
||||
|
||||
static MDL_request *create(unsigned char type, const char *db,
|
||||
const char *name, MEM_ROOT *root);
|
||||
const char *name, enum_mdl_type mdl_type,
|
||||
MEM_ROOT *root);
|
||||
|
||||
/*
|
||||
This is to work around the ugliness of TABLE_LIST
|
||||
compiler-generated assignment operator. It is currently used
|
||||
in several places to quickly copy "most" of the members of the
|
||||
table list. These places currently never assume that the mdl
|
||||
request is carried over to the new TABLE_LIST, or shared
|
||||
between lists.
|
||||
|
||||
This method does not initialize the instance being assigned!
|
||||
Use of init() for initialization after this assignment operator
|
||||
is mandatory. Can only be used before the request has been
|
||||
granted.
|
||||
*/
|
||||
MDL_request& operator=(const MDL_request &rhs)
|
||||
{
|
||||
ticket= NULL;
|
||||
/* Do nothing, in particular, don't try to copy the key. */
|
||||
return *this;
|
||||
}
|
||||
/* Another piece of ugliness for TABLE_LIST constructor */
|
||||
MDL_request() {}
|
||||
|
||||
MDL_request(const MDL_request *rhs)
|
||||
:type(rhs->type),
|
||||
ticket(NULL),
|
||||
key(&rhs->key)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
@ -248,6 +277,11 @@ private:
|
||||
};
|
||||
|
||||
|
||||
typedef I_P_List<MDL_request, I_P_List_adapter<MDL_request,
|
||||
&MDL_request::next_in_list,
|
||||
&MDL_request::prev_in_list> >
|
||||
MDL_request_list;
|
||||
|
||||
/**
|
||||
Context of the owner of metadata locks. I.e. each server
|
||||
connection has such a context.
|
||||
@ -256,14 +290,6 @@ private:
|
||||
class MDL_context
|
||||
{
|
||||
public:
|
||||
typedef I_P_List<MDL_request,
|
||||
I_P_List_adapter<MDL_request,
|
||||
&MDL_request::next_in_context,
|
||||
&MDL_request::prev_in_context> >
|
||||
Request_list;
|
||||
|
||||
typedef Request_list::Iterator Request_iterator;
|
||||
|
||||
typedef I_P_List<MDL_ticket,
|
||||
I_P_List_adapter<MDL_ticket,
|
||||
&MDL_ticket::next_in_context,
|
||||
@ -279,16 +305,13 @@ public:
|
||||
void restore_from_backup(MDL_context *backup);
|
||||
void merge(MDL_context *source);
|
||||
|
||||
void add_request(MDL_request *mdl_request);
|
||||
void remove_request(MDL_request *mdl_request);
|
||||
void remove_all_requests();
|
||||
|
||||
bool acquire_shared_lock(MDL_request *mdl_request, bool *retry);
|
||||
bool acquire_exclusive_locks();
|
||||
bool try_acquire_exclusive_lock(MDL_request *mdl_request, bool *conflict);
|
||||
bool try_acquire_shared_lock(MDL_request *mdl_request);
|
||||
bool acquire_exclusive_lock(MDL_request *mdl_request);
|
||||
bool acquire_exclusive_locks(MDL_request_list *requests);
|
||||
bool try_acquire_exclusive_lock(MDL_request *mdl_request);
|
||||
bool acquire_global_shared_lock();
|
||||
|
||||
bool wait_for_locks();
|
||||
bool wait_for_locks(MDL_request_list *requests);
|
||||
|
||||
void release_all_locks();
|
||||
void release_all_locks_for_name(MDL_ticket *ticket);
|
||||
@ -312,16 +335,8 @@ public:
|
||||
|
||||
void rollback_to_savepoint(MDL_ticket *mdl_savepoint);
|
||||
|
||||
/**
|
||||
Get iterator for walking through all lock requests in the context.
|
||||
*/
|
||||
inline Request_iterator get_requests()
|
||||
{
|
||||
return Request_iterator(m_requests);
|
||||
}
|
||||
inline THD *get_thd() const { return m_thd; }
|
||||
private:
|
||||
Request_list m_requests;
|
||||
Ticket_list m_tickets;
|
||||
bool m_has_global_shared_lock;
|
||||
THD *m_thd;
|
||||
|
Reference in New Issue
Block a user