Commit dbe15e9e authored by Eugene Kosov's avatar Eugene Kosov Committed by Eugene Kosov

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.
parent d7129565
......@@ -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 @@ class MDL_lock
{
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);
......@@ -352,13 +353,12 @@ class MDL_lock
bitmap_t bitmap() const { return m_bitmap; }
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
};
......@@ -1196,24 +1196,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());
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment