1
0
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:
Konstantin Osipov
2009-12-08 12:57:07 +03:00
parent 4a8a1c568d
commit a66a2608ae
30 changed files with 566 additions and 733 deletions

View File

@ -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;