diff --git a/include/page0zip.h b/include/page0zip.h index 835f7af5017..1d809aba16d 100644 --- a/include/page0zip.h +++ b/include/page0zip.h @@ -232,6 +232,18 @@ page_zip_dir_add_slot( zero for others */ __attribute__((nonnull)); +/*************************************************************** +Parses a log record of writing to the header of a page. */ + +byte* +page_zip_parse_write_header( +/*========================*/ + /* out: end of log record or NULL */ + byte* ptr, /* in: redo log buffer */ + byte* end_ptr,/* in: redo log buffer end */ + page_t* page, /* in/out: uncompressed page */ + page_zip_des_t* page_zip);/* in/out: compressed page */ + /************************************************************************** Write data to the uncompressed header portion of a page. The data must already have been written to the uncompressed page. diff --git a/log/log0recv.c b/log/log0recv.c index 1f9ab4f56bd..8bc2d59c7eb 100644 --- a/log/log0recv.c +++ b/log/log0recv.c @@ -898,7 +898,8 @@ recv_parse_or_apply_log_rec_body( ptr, end_ptr, page, page_zip); break; case MLOG_ZIP_WRITE_HEADER: - ut_error; /* TODO */ + ptr = page_zip_parse_write_header( + ptr, end_ptr, page, page_zip); break; case MLOG_ZIP_COMPRESS: if (NULL != (ptr = mlog_parse_index( diff --git a/page/page0zip.c b/page/page0zip.c index 7aa72692a91..80a9868a731 100644 --- a/page/page0zip.c +++ b/page/page0zip.c @@ -2248,7 +2248,8 @@ page_zip_parse_write_node_ptr( if (UNIV_UNLIKELY(offset < PAGE_ZIP_START) || UNIV_UNLIKELY(offset >= UNIV_PAGE_SIZE) - || UNIV_UNLIKELY(z_offset >= UNIV_PAGE_SIZE)) { + || UNIV_UNLIKELY(z_offset >= UNIV_PAGE_SIZE) + || UNIV_UNLIKELY(!page_zip)) { corrupt: recv_sys->found_corrupt_log = TRUE; @@ -2712,6 +2713,60 @@ page_zip_dir_add_slot( memmove(stored - PAGE_ZIP_DIR_SLOT_SIZE, stored, dir - stored); } +/*************************************************************** +Parses a log record of writing to the header of a page. */ + +byte* +page_zip_parse_write_header( +/*========================*/ + /* out: end of log record or NULL */ + byte* ptr, /* in: redo log buffer */ + byte* end_ptr,/* in: redo log buffer end */ + page_t* page, /* in/out: uncompressed page */ + page_zip_des_t* page_zip)/* in/out: compressed page */ +{ + ulint offset; + ulint len; + + ut_ad(!page == !page_zip); + + if (UNIV_UNLIKELY(end_ptr < ptr + (2 + 1))) { + + return(NULL); + } + + offset = mach_read_from_2(ptr); + ptr += 2; + len = (ulint) *ptr++; + + if (UNIV_UNLIKELY(!len) || UNIV_UNLIKELY(offset + len >= PAGE_DATA) + || UNIV_UNLIKELY(!page_zip)) { + recv_sys->found_corrupt_log = TRUE; + + return(NULL); + } + + if (UNIV_UNLIKELY(end_ptr < ptr + len)) { + + return(NULL); + } + + if (page) { +#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG + ut_a(page_zip_validate(page_zip, page)); +#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */ + + memcpy(page + offset, ptr, len); + memcpy(page_zip->data + offset, ptr, len); + +#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG + ut_a(page_zip_validate(page_zip, page)); +#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */ + } + + return(ptr + len); +} + /************************************************************************** Write a log record of writing to the uncompressed header portion of a page. */