Skip to content
  • Marko Mäkelä's avatar
    c998472c
    Bug#20691930 5.7.6 CRASH WHEN RUNNING MYSQL_UPGRADE AFTER BINARY UPGRADE · c998472c
    Marko Mäkelä authored
    
    This is a regression from
    Bug#17345513 CHECKING FIL_PAGE_TYPE BREAKS COMPATIBILITY WITH
    OLD INNODB DATA FILES
    
    This affected a production environment where the data files were
    originally created with MySQL 5.0 or earlier. Originally, InnoDB only
    initialized FIL_PAGE_TYPE on two types of pages:
    
    #define FIL_PAGE_INDEX		17855	/*!< B-tree node */
    #define FIL_PAGE_UNDO_LOG	2	/*!< Undo log page */
    
    When files were allocated in the file system, the field was
    initialized to 0. When a page was initialized in the buffer pool, the
    field would be left uninitialized, reusing whatever value happened to
    be at that address (typically one of the 3 values).
    
    In the originally reported incident, page 32768 in the system
    tablespace is an allocation bitmap page, but the uninitialized
    FIL_PAGE_TYPE field on it happened to be FIL_PAGE_INDEX, which caused
    the flush-time check to fail.
    
    Our fix comprises the following parts:
    
    1. Reset wrong page type on allocation bitmap pages and change buffer bitmap
    pages based on the page number, without checking the page contents and
    without writing redo log.
    
    #define FIL_PAGE_IBUF_BITMAP	5	/*!< Insert buffer bitmap */
    #define FIL_PAGE_TYPE_FSP_HDR	8	/*!< File space header */
    #define FIL_PAGE_TYPE_XDES	9	/*!< Extent descriptor page */
    
    2. On database startup, reset the page types on the following pages
    in the system tablespace, writing redo log:
    
    #define FSP_IBUF_HEADER_PAGE_NO	3	// init to 6=FIL_PAGE_TYPE_SYS
    #define FSP_TRX_SYS_PAGE_NO	5	// init to 7=FIL_PAGE_TYPE_TRX_SYS
    #define FSP_FIRST_RSEG_PAGE_NO	6	// init to 6=FIL_PAGE_TYPE_SYS
    #define FSP_DICT_HDR_PAGE_NO	7	// init to 6=FIL_PAGE_TYPE_SYS
    
    3. Whenever we modify other types of pages, we reset the FIL_PAGE_TYPE
    within the same mini-transaction, to one of the following values:
    
    #define FIL_PAGE_INODE		3	/*!< Index node */
    #define FIL_PAGE_TYPE_SYS	6	/*!< System page */
    #define FIL_PAGE_TYPE_FSP_HDR	8	/*!< File space header */
    #define FIL_PAGE_TYPE_XDES	9	/*!< Extent descriptor page */
    
    Note: Some page types are initialized immediately after page
    allocation, and the pages are not modified further without changing
    the page type first.  Nothing needs to be done for these page types,
    if the requirement is to have valid page type when we are writing back
    pages from the buffer pool to files.
    
    #define FIL_PAGE_IBUF_FREE_LIST	4	/*!< Insert buffer free list */
    #define FIL_PAGE_TYPE_BLOB	10	/*!< Uncompressed BLOB page */
    #define FIL_PAGE_TYPE_ZBLOB	11	/*!< First compressed BLOB page */
    #define FIL_PAGE_TYPE_ZBLOB2	12	/*!< Subsequent compressed BLOB page */
    
    Because MySQL does not officially support upgrade following by a
    server crash, there should be no legitimate usage scenario where such
    pages with an incorrect page type would be written out as a result of
    applying redo log during crash recovery.
    
    BLOB pages created before MySQL 5.1 could carry any page type
    (including FIL_PAGE_INDEX), but this should not be an issue, because
    existing BLOB pages are never updated in place. The BLOB columns are
    always updated by copy-on-write, with a valid FIL_PAGE_TYPE.
    
    Note: InnoDB never modifies BLOB pages in place. If BLOB data is modified,
    entirely new pages will be initialized and rewritten. Thus, no logic
    is implemented to update FIL_PAGE_TYPE on BLOB pages. This means that
    even after this fix, subsequent versions of MySQL must be prepared
    to read BLOB pages that contain anything in FIL_PAGE_TYPE.
    
    RB: 8314
    Reviewed-by: default avatarKevin Lewis <kevin.lewis@oracle.com>
    Reviewed-by: default avatarVasil Dimov <vasil.dimov@oracle.com>
    Reviewed-by: default avatarSunny Bains <sunny.bains@oracle.com>
    c998472c
    Bug#20691930 5.7.6 CRASH WHEN RUNNING MYSQL_UPGRADE AFTER BINARY UPGRADE
    Marko Mäkelä authored
    
    This is a regression from
    Bug#17345513 CHECKING FIL_PAGE_TYPE BREAKS COMPATIBILITY WITH
    OLD INNODB DATA FILES
    
    This affected a production environment where the data files were
    originally created with MySQL 5.0 or earlier. Originally, InnoDB only
    initialized FIL_PAGE_TYPE on two types of pages:
    
    #define FIL_PAGE_INDEX		17855	/*!< B-tree node */
    #define FIL_PAGE_UNDO_LOG	2	/*!< Undo log page */
    
    When files were allocated in the file system, the field was
    initialized to 0. When a page was initialized in the buffer pool, the
    field would be left uninitialized, reusing whatever value happened to
    be at that address (typically one of the 3 values).
    
    In the originally reported incident, page 32768 in the system
    tablespace is an allocation bitmap page, but the uninitialized
    FIL_PAGE_TYPE field on it happened to be FIL_PAGE_INDEX, which caused
    the flush-time check to fail.
    
    Our fix comprises the following parts:
    
    1. Reset wrong page type on allocation bitmap pages and change buffer bitmap
    pages based on the page number, without checking the page contents and
    without writing redo log.
    
    #define FIL_PAGE_IBUF_BITMAP	5	/*!< Insert buffer bitmap */
    #define FIL_PAGE_TYPE_FSP_HDR	8	/*!< File space header */
    #define FIL_PAGE_TYPE_XDES	9	/*!< Extent descriptor page */
    
    2. On database startup, reset the page types on the following pages
    in the system tablespace, writing redo log:
    
    #define FSP_IBUF_HEADER_PAGE_NO	3	// init to 6=FIL_PAGE_TYPE_SYS
    #define FSP_TRX_SYS_PAGE_NO	5	// init to 7=FIL_PAGE_TYPE_TRX_SYS
    #define FSP_FIRST_RSEG_PAGE_NO	6	// init to 6=FIL_PAGE_TYPE_SYS
    #define FSP_DICT_HDR_PAGE_NO	7	// init to 6=FIL_PAGE_TYPE_SYS
    
    3. Whenever we modify other types of pages, we reset the FIL_PAGE_TYPE
    within the same mini-transaction, to one of the following values:
    
    #define FIL_PAGE_INODE		3	/*!< Index node */
    #define FIL_PAGE_TYPE_SYS	6	/*!< System page */
    #define FIL_PAGE_TYPE_FSP_HDR	8	/*!< File space header */
    #define FIL_PAGE_TYPE_XDES	9	/*!< Extent descriptor page */
    
    Note: Some page types are initialized immediately after page
    allocation, and the pages are not modified further without changing
    the page type first.  Nothing needs to be done for these page types,
    if the requirement is to have valid page type when we are writing back
    pages from the buffer pool to files.
    
    #define FIL_PAGE_IBUF_FREE_LIST	4	/*!< Insert buffer free list */
    #define FIL_PAGE_TYPE_BLOB	10	/*!< Uncompressed BLOB page */
    #define FIL_PAGE_TYPE_ZBLOB	11	/*!< First compressed BLOB page */
    #define FIL_PAGE_TYPE_ZBLOB2	12	/*!< Subsequent compressed BLOB page */
    
    Because MySQL does not officially support upgrade following by a
    server crash, there should be no legitimate usage scenario where such
    pages with an incorrect page type would be written out as a result of
    applying redo log during crash recovery.
    
    BLOB pages created before MySQL 5.1 could carry any page type
    (including FIL_PAGE_INDEX), but this should not be an issue, because
    existing BLOB pages are never updated in place. The BLOB columns are
    always updated by copy-on-write, with a valid FIL_PAGE_TYPE.
    
    Note: InnoDB never modifies BLOB pages in place. If BLOB data is modified,
    entirely new pages will be initialized and rewritten. Thus, no logic
    is implemented to update FIL_PAGE_TYPE on BLOB pages. This means that
    even after this fix, subsequent versions of MySQL must be prepared
    to read BLOB pages that contain anything in FIL_PAGE_TYPE.
    
    RB: 8314
    Reviewed-by: default avatarKevin Lewis <kevin.lewis@oracle.com>
    Reviewed-by: default avatarVasil Dimov <vasil.dimov@oracle.com>
    Reviewed-by: default avatarSunny Bains <sunny.bains@oracle.com>
Loading