• Marko Mäkelä's avatar
    MDEV-33588 buf::Block_hint is a performance hog · a4cda66e
    Marko Mäkelä authored
    In so-called optimistic buffer pool lookups, we must not
    dereference a block descriptor before we have made sure that
    it is accessible. While buf_pool_t::resize() is running,
    block descriptors could become invalid.
    
    The buf::Block_hint class was essentially duplicating
    a buf_pool.page_hash lookup that was executed in
    buf_page_optimistic_get() anyway. For better locality of
    reference, we had better execute that lookup only once.
    
    buf_page_optimistic_fix(): Prepare for buf_page_optimistic_get().
    This basically is a simpler version of Buf::Block_hint.
    
    buf_page_optimistic_get(): Assume that buf_page_optimistic_fix()
    has been called and the page identifier verified. Should the block
    be evicted, the block->modify_clock will be invalidated; we do not
    need to check the block->page.id() again. It suffices to check
    the block->modify_clock after acquiring the page latch.
    
    btr_pcur_t::old_page_id: Store the expected page identifier
    for buf_page_optimistic_fix().
    
    btr_pcur_t::block_when_stored: Remove. This was duplicating
    page_cur_t::block.
    
    btr_pcur_optimistic_latch_leaves(): Remove redundant parameters.
    First, invoke buf_page_optimistic_fix() on the requested page.
    If needed, acquire a latch on the left page. Finally, acquire
    a latch on the target page and recheck the block->modify_clock.
    If the page had been freed while we were not holding a page latch,
    fall back to the slow path. Validate the FIL_PAGE_PREV after
    acquiring a latch on the current page. The block->modify_clock
    is only being incremented when records are deleted or pages
    reorganized or evicted; it does not guard against concurrent
    page splits.
    
    Reviewed by: Debarun Banerjee
    a4cda66e
buf0buf.cc 118 KB