Skip to content

Commit

Permalink
MDEV-27183 optimize std::map lookup in during crash recovery
Browse files Browse the repository at this point in the history
This is a low hanging fruit. Before this patch std::map::emplace() was
a ~50% of the whole recv_sys_t::parse() operation in by test.
After the fix it's only ~20%.

recv_sys_t::parse() recv_sys_t::pages is a collection of all pages
to recovery. Often, there are multiple changes for a single page.
Often, they go in a row and for such cases let's avoid
lookup in a std::map. cached_pages_it serves as a cache
of size 1.

recv_sys_t::add(): replace page_id argument with a std::map::iterator
  • Loading branch information
kevgs committed Dec 7, 2021
1 parent 0064316 commit 890c551
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 11 deletions.
4 changes: 2 additions & 2 deletions storage/innobase/include/log0recv.h
Original file line number Diff line number Diff line change
Expand Up @@ -332,12 +332,12 @@ struct recv_sys_t
bool is_initialised() const { return last_stored_lsn != 0; }

/** Register a redo log snippet for a page.
@param page_id page identifier
@param it page iterator
@param start_lsn start LSN of the mini-transaction
@param lsn @see mtr_t::commit_lsn()
@param l redo log snippet @see log_t::FORMAT_10_5
@param len length of l, in bytes */
inline void add(const page_id_t page_id, lsn_t start_lsn, lsn_t lsn,
inline void add(map::iterator it, lsn_t start_lsn, lsn_t lsn,
const byte *l, size_t len);

/** Parse and register one mini-transaction in log_t::FORMAT_10_5.
Expand Down
20 changes: 11 additions & 9 deletions storage/innobase/log/log0recv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1664,20 +1664,17 @@ inline void page_recv_t::will_not_read()


/** Register a redo log snippet for a page.
@param page_id page identifier
@param it page iterator
@param start_lsn start LSN of the mini-transaction
@param lsn @see mtr_t::commit_lsn()
@param recs redo log snippet @see log_t::FORMAT_10_5
@param len length of l, in bytes */
inline void recv_sys_t::add(const page_id_t page_id,
lsn_t start_lsn, lsn_t lsn, const byte *l,
size_t len)
inline void recv_sys_t::add(map::iterator it, lsn_t start_lsn, lsn_t lsn,
const byte *l, size_t len)
{
ut_ad(mutex_own(&mutex));
std::pair<map::iterator, bool> p= pages.emplace(map::value_type
(page_id, page_recv_t()));
page_recv_t& recs= p.first->second;
ut_ad(p.second == recs.log.empty());
page_id_t page_id = it->first;
page_recv_t &recs= it->second;

switch (*l & 0x70) {
case FREE_PAGE: case INIT_PAGE:
Expand Down Expand Up @@ -1769,6 +1766,7 @@ bool recv_sys_t::parse(lsn_t checkpoint_lsn, store_t *store, bool apply)
loop:
const byte *const log= buf + recovered_offset;
const lsn_t start_lsn= recovered_lsn;
map::iterator cached_pages_it = pages.end();

/* Check that the entire mini-transaction is included within the buffer */
const byte *l;
Expand Down Expand Up @@ -2092,8 +2090,12 @@ bool recv_sys_t::parse(lsn_t checkpoint_lsn, store_t *store, bool apply)
/* fall through */
case STORE_YES:
if (!mlog_init.will_avoid_read(id, start_lsn))
add(id, start_lsn, end_lsn, recs,
{
if (cached_pages_it == pages.end() || cached_pages_it->first != id)
cached_pages_it= pages.emplace(id, page_recv_t()).first;
add(cached_pages_it, start_lsn, end_lsn, recs,
static_cast<size_t>(l + rlen - recs));
}
continue;
case STORE_NO:
if (!is_init)
Expand Down

0 comments on commit 890c551

Please sign in to comment.