mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 19:11:46 +01:00
branches/zip: Implement the crash recovery of MLOG_ZIP_WRITE_NODE_PTR.
page_zip_parse_write_node_ptr(): New function to apply a redo log of MLOG_ZIP_WRITE_NODE_PTR. page_zip_write_node_ptr(): Write all needed information to the redo log. page_zip_write_header_log(): Write all necessary information to the redo log.
This commit is contained in:
parent
a1661efb8d
commit
52b7eb50c2
3 changed files with 109 additions and 7 deletions
|
@ -134,6 +134,18 @@ page_zip_write_blob_ptr(
|
||||||
or NULL if no logging is needed */
|
or NULL if no logging is needed */
|
||||||
__attribute__((nonnull(1,2,3,4)));
|
__attribute__((nonnull(1,2,3,4)));
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
Parses a log record of writing the node pointer of a record. */
|
||||||
|
|
||||||
|
byte*
|
||||||
|
page_zip_parse_write_node_ptr(
|
||||||
|
/*==========================*/
|
||||||
|
/* 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 the node pointer of a record on a non-leaf compressed page. */
|
Write the node pointer of a record on a non-leaf compressed page. */
|
||||||
|
|
||||||
|
|
|
@ -894,6 +894,9 @@ recv_parse_or_apply_log_rec_body(
|
||||||
ULINT_UNDEFINED);
|
ULINT_UNDEFINED);
|
||||||
break;
|
break;
|
||||||
case MLOG_ZIP_WRITE_NODE_PTR:
|
case MLOG_ZIP_WRITE_NODE_PTR:
|
||||||
|
ptr = page_zip_parse_write_node_ptr(
|
||||||
|
ptr, end_ptr, page, page_zip);
|
||||||
|
break;
|
||||||
case MLOG_ZIP_WRITE_HEADER:
|
case MLOG_ZIP_WRITE_HEADER:
|
||||||
ut_error; /* TODO */
|
ut_error; /* TODO */
|
||||||
break;
|
break;
|
||||||
|
|
101
page/page0zip.c
101
page/page0zip.c
|
@ -19,6 +19,7 @@ Created June 2005 by Marko Makela
|
||||||
#include "dict0dict.h"
|
#include "dict0dict.h"
|
||||||
#include "btr0cur.h"
|
#include "btr0cur.h"
|
||||||
#include "page0types.h"
|
#include "page0types.h"
|
||||||
|
#include "log0recv.h"
|
||||||
#include "zlib.h"
|
#include "zlib.h"
|
||||||
|
|
||||||
/* Please refer to ../include/page0zip.ic for a description of the
|
/* Please refer to ../include/page0zip.ic for a description of the
|
||||||
|
@ -2220,6 +2221,85 @@ page_zip_write_blob_ptr(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
Parses a log record of writing the node pointer of a record. */
|
||||||
|
|
||||||
|
byte*
|
||||||
|
page_zip_parse_write_node_ptr(
|
||||||
|
/*==========================*/
|
||||||
|
/* 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 z_offset;
|
||||||
|
|
||||||
|
ut_ad(!page == !page_zip);
|
||||||
|
|
||||||
|
if (UNIV_UNLIKELY(end_ptr < ptr + (2 + 2 + 4))) {
|
||||||
|
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
offset = mach_read_from_2(ptr);
|
||||||
|
z_offset = mach_read_from_2(ptr + 2);
|
||||||
|
|
||||||
|
if (UNIV_UNLIKELY(offset < PAGE_ZIP_START)
|
||||||
|
|| UNIV_UNLIKELY(offset >= UNIV_PAGE_SIZE)
|
||||||
|
|| UNIV_UNLIKELY(z_offset >= UNIV_PAGE_SIZE)) {
|
||||||
|
corrupt:
|
||||||
|
recv_sys->found_corrupt_log = TRUE;
|
||||||
|
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (page) {
|
||||||
|
byte* storage_end;
|
||||||
|
byte* field;
|
||||||
|
byte* storage;
|
||||||
|
ulint heap_no;
|
||||||
|
|
||||||
|
#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
|
||||||
|
ut_a(page_zip_validate(page_zip, page));
|
||||||
|
#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
|
||||||
|
|
||||||
|
if (UNIV_UNLIKELY(page_is_leaf(page))) {
|
||||||
|
|
||||||
|
goto corrupt;
|
||||||
|
}
|
||||||
|
|
||||||
|
field = page + offset;
|
||||||
|
storage = page_zip->data + z_offset;
|
||||||
|
|
||||||
|
storage_end = page_zip->data + page_zip->size
|
||||||
|
- (page_dir_get_n_heap(page) - 2)
|
||||||
|
* PAGE_ZIP_DIR_SLOT_SIZE;
|
||||||
|
|
||||||
|
heap_no = 1 + (storage_end - storage) / REC_NODE_PTR_SIZE;
|
||||||
|
|
||||||
|
if (UNIV_UNLIKELY((storage_end - storage) % REC_NODE_PTR_SIZE)
|
||||||
|
|| UNIV_UNLIKELY(heap_no < 2)
|
||||||
|
|| UNIV_UNLIKELY(heap_no >= page_dir_get_n_heap(page))) {
|
||||||
|
|
||||||
|
goto corrupt;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if REC_NODE_PTR_SIZE != 4
|
||||||
|
# error "REC_NODE_PTR_SIZE != 4"
|
||||||
|
#endif
|
||||||
|
memcpy(field, ptr + 4, REC_NODE_PTR_SIZE);
|
||||||
|
memcpy(storage, ptr + 4, REC_NODE_PTR_SIZE);
|
||||||
|
|
||||||
|
#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
|
||||||
|
ut_a(page_zip_validate(page_zip, page));
|
||||||
|
#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
|
||||||
|
}
|
||||||
|
|
||||||
|
return(ptr + 6);
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
Write the node pointer of a record on a non-leaf compressed page. */
|
Write the node pointer of a record on a non-leaf compressed page. */
|
||||||
|
|
||||||
|
@ -2263,8 +2343,18 @@ page_zip_write_node_ptr(
|
||||||
memcpy(storage, field, REC_NODE_PTR_SIZE);
|
memcpy(storage, field, REC_NODE_PTR_SIZE);
|
||||||
|
|
||||||
if (mtr) {
|
if (mtr) {
|
||||||
mlog_write_initial_log_record(
|
byte* log_ptr = mlog_open(mtr, 11 + 4 + 2);
|
||||||
rec, MLOG_ZIP_WRITE_NODE_PTR, mtr);
|
if (UNIV_UNLIKELY(!log_ptr)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_ptr = mlog_write_initial_log_record_fast(field,
|
||||||
|
MLOG_ZIP_WRITE_NODE_PTR, log_ptr, mtr);
|
||||||
|
mach_write_to_2(log_ptr, storage - page_zip->data);
|
||||||
|
log_ptr += 2;
|
||||||
|
mach_write_to_4(log_ptr, ptr);
|
||||||
|
log_ptr += 4;
|
||||||
|
mlog_close(mtr, log_ptr + 6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2633,7 +2723,7 @@ page_zip_write_header_log(
|
||||||
ulint length, /* in: length of the data */
|
ulint length, /* in: length of the data */
|
||||||
mtr_t* mtr) /* in: mini-transaction */
|
mtr_t* mtr) /* in: mini-transaction */
|
||||||
{
|
{
|
||||||
byte* log_ptr = mlog_open(mtr, 11 + 2 + 1);
|
byte* log_ptr = mlog_open(mtr, 11 + 1);
|
||||||
ut_ad(offset < PAGE_DATA);
|
ut_ad(offset < PAGE_DATA);
|
||||||
ut_ad(offset + length < PAGE_DATA);
|
ut_ad(offset + length < PAGE_DATA);
|
||||||
#if PAGE_DATA > 255
|
#if PAGE_DATA > 255
|
||||||
|
@ -2649,10 +2739,7 @@ page_zip_write_header_log(
|
||||||
|
|
||||||
log_ptr = mlog_write_initial_log_record_fast(page_zip->data + offset,
|
log_ptr = mlog_write_initial_log_record_fast(page_zip->data + offset,
|
||||||
MLOG_ZIP_WRITE_HEADER, log_ptr, mtr);
|
MLOG_ZIP_WRITE_HEADER, log_ptr, mtr);
|
||||||
mach_write_to_2(log_ptr, offset);
|
*log_ptr++ = (byte) length;
|
||||||
log_ptr += 2;
|
|
||||||
|
|
||||||
mach_write_to_1(log_ptr, length);
|
|
||||||
mlog_close(mtr, log_ptr);
|
mlog_close(mtr, log_ptr);
|
||||||
|
|
||||||
mlog_catenate_string(mtr, page_zip->data + offset, length);
|
mlog_catenate_string(mtr, page_zip->data + offset, length);
|
||||||
|
|
Loading…
Add table
Reference in a new issue