• Daniel Black's avatar
    MDEV-27891: SIGSEGV in InnoDB buffer pool resize · b6a24724
    Daniel Black authored
    During an increase in resize, the new curr_size got a value
    less than old_size.
    
    As n_chunks_new and n_chunks have a strong correlation to the
    resizing operation in progress, we can use them and remove the
    need for old_size.
    
    For convienece the n_chunks_new < n_chunks is now the is_shrinking
    function.
    
    The volatile compiler optimization on n_chunks{,_new} is removed
    as real mutex uses are needed.
    
    Other n_chunks_new/n_chunks methods:
    
    n_chunks_new and n_chunks almost always read and altered under
    the pool mutex.
    
    Exceptions are:
    * i_s_innodb_buffer_page_fill,
    * buf_pool_t::is_uncompressed (via is_blocked_field)
    These need reexamining for the need of a mutex, however comments
    indicates this already.
    
    get_n_pages has uses in buffer pool load, recover log memory
    exhaustion estimates and innodb status so take the minimum number
    of chunks for safety.
    
    The buf_pool_t::running_out function also uses curr_size/old_size.
    We replace this hot function calculation with just n_chunks_new.
    This is the new size of the chunks before the resizing occurs.
    
    If we are resizing down, we've already got the case we had previously
    (as the minimum). If we are resizing upwards, we are taking an
    optimistic view that there will be buffer chunks available for locks.
    As this memory allocation is occurring immediately next the resizing
    function it seems likely.
    
    Compiler hint UNIV_UNLIKELY removed to leave it to the branch
    predictor to make an informed decision.
    
    Added test case of a smaller size than the Marko/Roel original
    in JIRA reducing the size to 256M. SEGV hits roughly 1/10 times
    but its better than a 21G memory size.
    
    Reviewer: Marko
    b6a24724
buf0flu.cc 75.9 KB