diff options
author | Eugene Kosov <claprix@yandex.ru> | 2020-05-15 18:39:05 +0300 |
---|---|---|
committer | Eugene Kosov <eugene.kosov@mariadb.com> | 2020-06-23 23:34:54 +0300 |
commit | dbe15e9e5a57d3212f8fd3d78c5cebd22d180853 (patch) | |
tree | 2bf7fccdbe7da54b8c1f3a05d53dcd6ae6c76e32 | |
parent | d712956526236867de3239c18b789f5c7b497ac7 (diff) | |
download | mariadb-git-dbe15e9e5a57d3212f8fd3d78c5cebd22d180853.tar.gz |
MDEV-19749 MDL scalability regression after backup locks
MDL_lock::Ticket_list::remove_ticket(): reduce algoritmic
complexity from O(N) to O(1)
MDL_lock::Ticket_list::clear_bit_if_not_in_list(): removed
MDL_lock::Ticket_list::m_type_counters: a map of ticket type
to count. Initialization is memset(0) which takes time.
-rw-r--r-- | sql/mdl.cc | 32 |
1 files changed, 6 insertions, 26 deletions
diff --git a/sql/mdl.cc b/sql/mdl.cc index 51387fb0f9a..6cdea8c3ebd 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -29,6 +29,7 @@ #include <pfs_metadata_provider.h> #include <mysql/psi/mysql_mdl.h> #include <algorithm> +#include <array> static PSI_memory_key key_memory_MDL_context_acquire_locks; @@ -344,7 +345,7 @@ public: { using List= ilist<MDL_ticket>; public: - Ticket_list() :m_bitmap(0) {} + Ticket_list() :m_bitmap(0) { m_type_counters.fill(0); } void add_ticket(MDL_ticket *ticket); void remove_ticket(MDL_ticket *ticket); @@ -353,12 +354,11 @@ public: List::const_iterator begin() const { return m_list.begin(); } List::const_iterator end() const { return m_list.end(); } private: - void clear_bit_if_not_in_list(enum_mdl_type type); - private: /** List of tickets. */ List m_list; /** Bitmap of types of tickets in this list. */ bitmap_t m_bitmap; + std::array<uint32_t, MDL_BACKUP_END> m_type_counters; // hash table }; @@ -1197,24 +1197,6 @@ MDL_wait::timed_wait(MDL_context_owner *owner, struct timespec *abs_timeout, /** - Clear bit corresponding to the type of metadata lock in bitmap representing - set of such types if list of tickets does not contain ticket with such type. - - @param[in,out] bitmap Bitmap representing set of types of locks. - @param[in] list List to inspect. - @param[in] type Type of metadata lock to look up in the list. -*/ - -void MDL_lock::Ticket_list::clear_bit_if_not_in_list(enum_mdl_type type) -{ - for (const auto &ticket : m_list) - if (ticket.get_type() == type) - return; - m_bitmap&= ~ MDL_BIT(type); -} - - -/** Add ticket to MDL_lock's list of waiting requests and update corresponding bitmap of lock types. */ @@ -1251,6 +1233,7 @@ void MDL_lock::Ticket_list::add_ticket(MDL_ticket *ticket) m_list.push_back(*ticket); } m_bitmap|= MDL_BIT(ticket->get_type()); + m_type_counters[ticket->get_type()]++; } @@ -1267,12 +1250,9 @@ void MDL_lock::Ticket_list::remove_ticket(MDL_ticket *ticket) one which was removed. If there is no such ticket, i.e. we have removed last ticket of particular type, then we need to update bitmap of waiting ticket's types. - Note that in most common case, i.e. when shared lock is removed - from waiting queue, we are likely to find ticket of the same - type early without performing full iteration through the list. - So this method should not be too expensive. */ - clear_bit_if_not_in_list(ticket->get_type()); + if (--m_type_counters[ticket->get_type()] == 0) + m_bitmap&= ~MDL_BIT(ticket->get_type()); } |