Skip to content

Commit dbe15e9

Browse files
committed
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.
1 parent d712956 commit dbe15e9

File tree

1 file changed

+6
-26
lines changed

1 file changed

+6
-26
lines changed

sql/mdl.cc

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <pfs_metadata_provider.h>
3030
#include <mysql/psi/mysql_mdl.h>
3131
#include <algorithm>
32+
#include <array>
3233

3334
static PSI_memory_key key_memory_MDL_context_acquire_locks;
3435

@@ -344,21 +345,20 @@ class MDL_lock
344345
{
345346
using List= ilist<MDL_ticket>;
346347
public:
347-
Ticket_list() :m_bitmap(0) {}
348+
Ticket_list() :m_bitmap(0) { m_type_counters.fill(0); }
348349

349350
void add_ticket(MDL_ticket *ticket);
350351
void remove_ticket(MDL_ticket *ticket);
351352
bool is_empty() const { return m_list.empty(); }
352353
bitmap_t bitmap() const { return m_bitmap; }
353354
List::const_iterator begin() const { return m_list.begin(); }
354355
List::const_iterator end() const { return m_list.end(); }
355-
private:
356-
void clear_bit_if_not_in_list(enum_mdl_type type);
357356
private:
358357
/** List of tickets. */
359358
List m_list;
360359
/** Bitmap of types of tickets in this list. */
361360
bitmap_t m_bitmap;
361+
std::array<uint32_t, MDL_BACKUP_END> m_type_counters; // hash table
362362
};
363363

364364

@@ -1196,24 +1196,6 @@ MDL_wait::timed_wait(MDL_context_owner *owner, struct timespec *abs_timeout,
11961196
}
11971197

11981198

1199-
/**
1200-
Clear bit corresponding to the type of metadata lock in bitmap representing
1201-
set of such types if list of tickets does not contain ticket with such type.
1202-
1203-
@param[in,out] bitmap Bitmap representing set of types of locks.
1204-
@param[in] list List to inspect.
1205-
@param[in] type Type of metadata lock to look up in the list.
1206-
*/
1207-
1208-
void MDL_lock::Ticket_list::clear_bit_if_not_in_list(enum_mdl_type type)
1209-
{
1210-
for (const auto &ticket : m_list)
1211-
if (ticket.get_type() == type)
1212-
return;
1213-
m_bitmap&= ~ MDL_BIT(type);
1214-
}
1215-
1216-
12171199
/**
12181200
Add ticket to MDL_lock's list of waiting requests and
12191201
update corresponding bitmap of lock types.
@@ -1251,6 +1233,7 @@ void MDL_lock::Ticket_list::add_ticket(MDL_ticket *ticket)
12511233
m_list.push_back(*ticket);
12521234
}
12531235
m_bitmap|= MDL_BIT(ticket->get_type());
1236+
m_type_counters[ticket->get_type()]++;
12541237
}
12551238

12561239

@@ -1267,12 +1250,9 @@ void MDL_lock::Ticket_list::remove_ticket(MDL_ticket *ticket)
12671250
one which was removed. If there is no such ticket, i.e. we have
12681251
removed last ticket of particular type, then we need to update
12691252
bitmap of waiting ticket's types.
1270-
Note that in most common case, i.e. when shared lock is removed
1271-
from waiting queue, we are likely to find ticket of the same
1272-
type early without performing full iteration through the list.
1273-
So this method should not be too expensive.
12741253
*/
1275-
clear_bit_if_not_in_list(ticket->get_type());
1254+
if (--m_type_counters[ticket->get_type()] == 0)
1255+
m_bitmap&= ~MDL_BIT(ticket->get_type());
12761256
}
12771257

12781258

0 commit comments

Comments
 (0)