• Marko Mäkelä's avatar
    MDEV-11799 Doublewrite recovery can corrupt data pages · 879ba197
    Marko Mäkelä authored
    The purpose of the InnoDB doublewrite buffer is to make InnoDB
    tolerant against cases where the server was killed in the middle
    of a page write. (In Linux, killing a process may interrupt a
    write system call, typically on a 4096-byte boundary.)
    
    There may exist multiple copies of a page number in the doublewrite
    buffer. Recovery should choose the latest valid copy of the page.
    By design, the FIL_PAGE_LSN must not precede the latest checkpoint LSN
    nor be later than the end of the recovered log.
    
    For page_compressed and encrypted pages, we were missing proper
    consistency checks. In the 10.4 data set generated for in MDEV-23231,
    the data file contained a valid page_compressed page, and an
    identical copy of that page was also present in the doublewrite
    buffer. But, recovery would incorrectly consider the page invalid
    and restore an uncompressed copy of the same page that had been
    written before the log checkpoint. (In fact, no redo log was to
    be applied to that page.)
    
    buf_dblwr_process(): Validate the FIL_PAGE_LSN in the doublewrite
    buffer pages, and always skip page 0, because those pages should
    have been recovered by Datafile::restore_from_doublewrite() if
    necessary.
    
    Datafile::restore_from_doublewrite(): Choose the latest applicable
    page from the doublewrite buffer.
    
    recv_dblwr_t::find_page(): Also validate encrypted or
    page_compressed pages.
    
    recv_dblwr_t::validate_page(): New function to validate a page,
    either a copy in a data file or in the doublewrite buffer.
    Also validate encrypted or page_compressed pages.
    
    This is joint work with Thirunarayanan Balathandayuthapani.
    879ba197
log0recv.cc 118 KB