summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Kosov <claprix@yandex.ru>2020-05-15 18:39:05 +0300
committerEugene Kosov <eugene.kosov@mariadb.com>2020-06-23 23:34:54 +0300
commitdbe15e9e5a57d3212f8fd3d78c5cebd22d180853 (patch)
tree2bf7fccdbe7da54b8c1f3a05d53dcd6ae6c76e32
parentd712956526236867de3239c18b789f5c7b497ac7 (diff)
downloadmariadb-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.cc32
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());
}