diff options
author | Konstantin Osipov <kostja@sun.com> | 2009-12-08 12:57:07 +0300 |
---|---|---|
committer | Konstantin Osipov <kostja@sun.com> | 2009-12-08 12:57:07 +0300 |
commit | a66a2608ae4d70a3f9b3d41e38cfb97eb616bed3 (patch) | |
tree | b2b94a32418f0728974d2bad4d3fa70acc2d75ef /sql/mdl.h | |
parent | 4a8a1c568d8785dc608cc111e74e1ed389f1353e (diff) | |
download | mariadb-git-a66a2608ae4d70a3f9b3d41e38cfb97eb616bed3.tar.gz |
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.
Diffstat (limited to 'sql/mdl.h')
-rw-r--r-- | sql/mdl.h | 85 |
1 files changed, 50 insertions, 35 deletions
diff --git a/sql/mdl.h b/sql/mdl.h index e3e41652bf4..dc6f0a34443 100644 --- a/sql/mdl.h +++ b/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; |