Commit b355bd0f authored by marko's avatar marko

branches/zip: Fix some crash recovery bugs.

dict_load_table(): Initialize table->flags with zip_size.

mlog_parse_nbytes(), mlog_parse_string(): Add parameter page_zip and
write the changes also to the compressed page if one is specified.
Assert that these functions are not called on FIL_PAGE_INDEX pages.

buf_page_io_complete(): Replace block->frame with frame where appropriate.

recv_parse_or_apply_log_rec_body(): Add ut_a(!page_zip) where appropriate.

page_parse_delete_rec_list(): Add parameter page_zip.
parent fbce3ef8
...@@ -2002,15 +2002,14 @@ buf_page_io_complete( ...@@ -2002,15 +2002,14 @@ buf_page_io_complete(
/* If this page is not uninitialized and not in the /* If this page is not uninitialized and not in the
doublewrite buffer, then the page number and space id doublewrite buffer, then the page number and space id
should be the same as in block. */ should be the same as in block. */
read_page_no = mach_read_from_4((block->frame) read_page_no = mach_read_from_4(frame + FIL_PAGE_OFFSET);
+ FIL_PAGE_OFFSET);
switch (fil_page_get_type(frame)) { switch (fil_page_get_type(frame)) {
case FIL_PAGE_TYPE_ZBLOB: case FIL_PAGE_TYPE_ZBLOB:
read_space_id = mach_read_from_4(block->frame read_space_id = mach_read_from_4(frame
+ FIL_PAGE_ZBLOB_SPACE_ID); + FIL_PAGE_ZBLOB_SPACE_ID);
break; break;
default: default:
read_space_id = mach_read_from_4(block->frame read_space_id = mach_read_from_4(frame
+ FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
} }
......
...@@ -837,7 +837,7 @@ dict_load_table( ...@@ -837,7 +837,7 @@ dict_load_table(
/* Check if the tablespace exists and has the right name */ /* Check if the tablespace exists and has the right name */
if (space != 0) { if (space != 0) {
ulint zip_size = dict_sys_tables_get_zip_size(rec); zip_size = dict_sys_tables_get_zip_size(rec);
ut_a(zip_size != ULINT_UNDEFINED); ut_a(zip_size != ULINT_UNDEFINED);
if (fil_space_for_table_exists_in_mem(space, name, FALSE, if (fil_space_for_table_exists_in_mem(space, name, FALSE,
...@@ -863,6 +863,8 @@ dict_load_table( ...@@ -863,6 +863,8 @@ dict_load_table(
ibd_file_missing = TRUE; ibd_file_missing = TRUE;
} }
} }
} else {
zip_size = 0;
} }
ut_a(0 == ut_strcmp("N_COLS", ut_a(0 == ut_strcmp("N_COLS",
...@@ -872,7 +874,7 @@ dict_load_table( ...@@ -872,7 +874,7 @@ dict_load_table(
field = rec_get_nth_field_old(rec, 4, &len); field = rec_get_nth_field_old(rec, 4, &len);
n_cols = mach_read_from_4(field); n_cols = mach_read_from_4(field);
flags = 0; flags = zip_size << DICT_TF_COMPRESSED_SHIFT;
/* The high-order bit of N_COLS is the "compact format" flag. */ /* The high-order bit of N_COLS is the "compact format" flag. */
if (n_cols & 0x80000000UL) { if (n_cols & 0x80000000UL) {
......
...@@ -170,7 +170,8 @@ mlog_parse_nbytes( ...@@ -170,7 +170,8 @@ mlog_parse_nbytes(
ulint type, /* in: log record type: MLOG_1BYTE, ... */ ulint type, /* in: log record type: MLOG_1BYTE, ... */
byte* ptr, /* in: buffer */ byte* ptr, /* in: buffer */
byte* end_ptr,/* in: buffer end */ byte* end_ptr,/* in: buffer end */
byte* page); /* in: page where to apply the log record, or NULL */ byte* page, /* in: page where to apply the log record, or NULL */
void* page_zip);/* in/out: compressed page, or NULL */
/************************************************************ /************************************************************
Parses a log record written by mlog_write_string. */ Parses a log record written by mlog_write_string. */
...@@ -181,7 +182,8 @@ mlog_parse_string( ...@@ -181,7 +182,8 @@ mlog_parse_string(
record */ record */
byte* ptr, /* in: buffer */ byte* ptr, /* in: buffer */
byte* end_ptr,/* in: buffer end */ byte* end_ptr,/* in: buffer end */
byte* page); /* in: page where to apply the log record, or NULL */ byte* page, /* in: page where to apply the log record, or NULL */
void* page_zip);/* in/out: compressed page, or NULL */
/************************************************************ /************************************************************
......
...@@ -792,7 +792,8 @@ page_parse_delete_rec_list( ...@@ -792,7 +792,8 @@ page_parse_delete_rec_list(
byte* ptr, /* in: buffer */ byte* ptr, /* in: buffer */
byte* end_ptr,/* in: buffer end */ byte* end_ptr,/* in: buffer end */
dict_index_t* index, /* in: record descriptor */ dict_index_t* index, /* in: record descriptor */
page_t* page, /* in: page or NULL */ page_t* page, /* in/out: page or NULL */
page_zip_des_t* page_zip,/* in/out: compressed page or NULL */
mtr_t* mtr); /* in: mtr or NULL */ mtr_t* mtr); /* in: mtr or NULL */
/*************************************************************** /***************************************************************
Parses a redo log record of creating a page. */ Parses a redo log record of creating a page. */
......
...@@ -764,8 +764,7 @@ recv_parse_or_apply_log_rec_body( ...@@ -764,8 +764,7 @@ recv_parse_or_apply_log_rec_body(
switch (type) { switch (type) {
case MLOG_1BYTE: case MLOG_2BYTES: case MLOG_4BYTES: case MLOG_8BYTES: case MLOG_1BYTE: case MLOG_2BYTES: case MLOG_4BYTES: case MLOG_8BYTES:
ut_a(!page_zip || fil_page_get_type(page) != FIL_PAGE_INDEX); ptr = mlog_parse_nbytes(type, ptr, end_ptr, page, page_zip);
ptr = mlog_parse_nbytes(type, ptr, end_ptr, page);
break; break;
case MLOG_REC_INSERT: case MLOG_COMP_REC_INSERT: case MLOG_REC_INSERT: case MLOG_COMP_REC_INSERT:
if (NULL != (ptr = mlog_parse_index(ptr, end_ptr, if (NULL != (ptr = mlog_parse_index(ptr, end_ptr,
...@@ -791,6 +790,7 @@ recv_parse_or_apply_log_rec_body( ...@@ -791,6 +790,7 @@ recv_parse_or_apply_log_rec_body(
/* This log record type is obsolete, but we process it for /* This log record type is obsolete, but we process it for
backward compatibility with MySQL 5.0.3 and 5.0.4. */ backward compatibility with MySQL 5.0.3 and 5.0.4. */
ut_a(!page || page_is_comp(page)); ut_a(!page || page_is_comp(page));
ut_a(!page_zip);
ptr = mlog_parse_index(ptr, end_ptr, TRUE, &index); ptr = mlog_parse_index(ptr, end_ptr, TRUE, &index);
if (!ptr) { if (!ptr) {
break; break;
...@@ -819,7 +819,7 @@ recv_parse_or_apply_log_rec_body( ...@@ -819,7 +819,7 @@ recv_parse_or_apply_log_rec_body(
|| (ibool)!!page_is_comp(page) || (ibool)!!page_is_comp(page)
== dict_table_is_comp(index->table)); == dict_table_is_comp(index->table));
ptr = page_parse_delete_rec_list(type, ptr, end_ptr, ptr = page_parse_delete_rec_list(type, ptr, end_ptr,
index, page, mtr); index, page, page_zip, mtr);
} }
break; break;
case MLOG_LIST_END_COPY_CREATED: case MLOG_COMP_LIST_END_COPY_CREATED: case MLOG_LIST_END_COPY_CREATED: case MLOG_COMP_LIST_END_COPY_CREATED:
...@@ -843,6 +843,7 @@ recv_parse_or_apply_log_rec_body( ...@@ -843,6 +843,7 @@ recv_parse_or_apply_log_rec_body(
} }
break; break;
case MLOG_PAGE_CREATE: case MLOG_COMP_PAGE_CREATE: case MLOG_PAGE_CREATE: case MLOG_COMP_PAGE_CREATE:
ut_a(!page_zip);
ptr = page_parse_create(ptr, end_ptr, ptr = page_parse_create(ptr, end_ptr,
type == MLOG_COMP_PAGE_CREATE, type == MLOG_COMP_PAGE_CREATE,
page, mtr); page, mtr);
...@@ -865,6 +866,7 @@ recv_parse_or_apply_log_rec_body( ...@@ -865,6 +866,7 @@ recv_parse_or_apply_log_rec_body(
page, mtr); page, mtr);
break; break;
case MLOG_REC_MIN_MARK: case MLOG_COMP_REC_MIN_MARK: case MLOG_REC_MIN_MARK: case MLOG_COMP_REC_MIN_MARK:
ut_a(!page_zip);
ptr = btr_parse_set_min_rec_mark(ptr, end_ptr, ptr = btr_parse_set_min_rec_mark(ptr, end_ptr,
type == MLOG_COMP_REC_MIN_MARK, page, mtr); type == MLOG_COMP_REC_MIN_MARK, page, mtr);
break; break;
...@@ -886,8 +888,7 @@ recv_parse_or_apply_log_rec_body( ...@@ -886,8 +888,7 @@ recv_parse_or_apply_log_rec_body(
ptr = fsp_parse_init_file_page(ptr, end_ptr, page); ptr = fsp_parse_init_file_page(ptr, end_ptr, page);
break; break;
case MLOG_WRITE_STRING: case MLOG_WRITE_STRING:
ut_a(!page_zip || fil_page_get_type(page) != FIL_PAGE_INDEX); ptr = mlog_parse_string(ptr, end_ptr, page, page_zip);
ptr = mlog_parse_string(ptr, end_ptr, page);
break; break;
case MLOG_FILE_CREATE: case MLOG_FILE_CREATE:
case MLOG_FILE_RENAME: case MLOG_FILE_RENAME:
......
...@@ -128,13 +128,15 @@ mlog_parse_nbytes( ...@@ -128,13 +128,15 @@ mlog_parse_nbytes(
ulint type, /* in: log record type: MLOG_1BYTE, ... */ ulint type, /* in: log record type: MLOG_1BYTE, ... */
byte* ptr, /* in: buffer */ byte* ptr, /* in: buffer */
byte* end_ptr,/* in: buffer end */ byte* end_ptr,/* in: buffer end */
byte* page) /* in: page where to apply the log record, or NULL */ byte* page, /* in: page where to apply the log record, or NULL */
void* page_zip)/* in/out: compressed page, or NULL */
{ {
ulint offset; ulint offset;
ulint val; ulint val;
dulint dval; dulint dval;
ut_a(type <= MLOG_8BYTES); ut_a(type <= MLOG_8BYTES);
ut_a(!page || !page_zip || fil_page_get_type(page) != FIL_PAGE_INDEX);
if (end_ptr < ptr + 2) { if (end_ptr < ptr + 2) {
...@@ -159,6 +161,11 @@ mlog_parse_nbytes( ...@@ -159,6 +161,11 @@ mlog_parse_nbytes(
} }
if (page) { if (page) {
if (UNIV_LIKELY_NULL(page_zip)) {
mach_write_to_8(
((page_zip_des_t*) page_zip)->data
+ offset, dval);
}
mach_write_to_8(page + offset, dval); mach_write_to_8(page + offset, dval);
} }
...@@ -172,35 +179,47 @@ mlog_parse_nbytes( ...@@ -172,35 +179,47 @@ mlog_parse_nbytes(
return(NULL); return(NULL);
} }
if (type == MLOG_1BYTE) { switch (type) {
if (val > 0xFFUL) { case MLOG_1BYTE:
recv_sys->found_corrupt_log = TRUE; if (UNIV_UNLIKELY(val > 0xFFUL)) {
goto corrupt;
return(NULL);
} }
} else if (type == MLOG_2BYTES) { if (page) {
if (val > 0xFFFFUL) { if (UNIV_LIKELY_NULL(page_zip)) {
recv_sys->found_corrupt_log = TRUE; mach_write_to_1(
((page_zip_des_t*) page_zip)->data
return(NULL); + offset, val);
} }
} else { mach_write_to_1(page + offset, val);
if (type != MLOG_4BYTES) {
recv_sys->found_corrupt_log = TRUE;
return(NULL);
} }
break;
case MLOG_2BYTES:
if (UNIV_UNLIKELY(val > 0xFFFFUL)) {
goto corrupt;
} }
if (page) { if (page) {
if (type == MLOG_1BYTE) { if (UNIV_LIKELY_NULL(page_zip)) {
mach_write_to_1(page + offset, val); mach_write_to_2(
} else if (type == MLOG_2BYTES) { ((page_zip_des_t*) page_zip)->data
+ offset, val);
}
mach_write_to_2(page + offset, val); mach_write_to_2(page + offset, val);
} else { }
ut_a(type == MLOG_4BYTES); break;
case MLOG_4BYTES:
if (page) {
if (UNIV_LIKELY_NULL(page_zip)) {
mach_write_to_4(
((page_zip_des_t*) page_zip)->data
+ offset, val);
}
mach_write_to_4(page + offset, val); mach_write_to_4(page + offset, val);
} }
break;
default:
corrupt:
recv_sys->found_corrupt_log = TRUE;
ptr = NULL;
} }
return(ptr); return(ptr);
...@@ -374,11 +393,14 @@ mlog_parse_string( ...@@ -374,11 +393,14 @@ mlog_parse_string(
record */ record */
byte* ptr, /* in: buffer */ byte* ptr, /* in: buffer */
byte* end_ptr,/* in: buffer end */ byte* end_ptr,/* in: buffer end */
byte* page) /* in: page where to apply the log record, or NULL */ byte* page, /* in: page where to apply the log record, or NULL */
void* page_zip)/* in/out: compressed page, or NULL */
{ {
ulint offset; ulint offset;
ulint len; ulint len;
ut_a(!page || !page_zip || fil_page_get_type(page) != FIL_PAGE_INDEX);
if (end_ptr < ptr + 4) { if (end_ptr < ptr + 4) {
return(NULL); return(NULL);
...@@ -386,25 +408,27 @@ mlog_parse_string( ...@@ -386,25 +408,27 @@ mlog_parse_string(
offset = mach_read_from_2(ptr); offset = mach_read_from_2(ptr);
ptr += 2; ptr += 2;
len = mach_read_from_2(ptr);
ptr += 2;
if (offset >= UNIV_PAGE_SIZE) { if (UNIV_UNLIKELY(offset >= UNIV_PAGE_SIZE)
|| UNIV_UNLIKELY(len + offset) > UNIV_PAGE_SIZE) {
recv_sys->found_corrupt_log = TRUE; recv_sys->found_corrupt_log = TRUE;
return(NULL); return(NULL);
} }
len = mach_read_from_2(ptr);
ptr += 2;
ut_a(len + offset <= UNIV_PAGE_SIZE);
if (end_ptr < ptr + len) { if (end_ptr < ptr + len) {
return(NULL); return(NULL);
} }
if (page) { if (page) {
ut_memcpy(page + offset, ptr, len); if (UNIV_LIKELY_NULL(page_zip)) {
memcpy(((page_zip_des_t*) page_zip)->data
+ offset, ptr, len);
}
memcpy(page + offset, ptr, len);
} }
return(ptr + len); return(ptr + len);
......
...@@ -800,11 +800,11 @@ page_parse_delete_rec_list( ...@@ -800,11 +800,11 @@ page_parse_delete_rec_list(
byte* ptr, /* in: buffer */ byte* ptr, /* in: buffer */
byte* end_ptr,/* in: buffer end */ byte* end_ptr,/* in: buffer end */
dict_index_t* index, /* in: record descriptor */ dict_index_t* index, /* in: record descriptor */
page_t* page, /* in: page or NULL */ page_t* page, /* in/out: page or NULL */
page_zip_des_t* page_zip,/* in/out: compressed page or NULL */
mtr_t* mtr) /* in: mtr or NULL */ mtr_t* mtr) /* in: mtr or NULL */
{ {
ulint offset; ulint offset;
page_zip_des_t* page_zip;
ut_ad(type == MLOG_LIST_END_DELETE ut_ad(type == MLOG_LIST_END_DELETE
|| type == MLOG_LIST_START_DELETE || type == MLOG_LIST_START_DELETE
...@@ -828,8 +828,6 @@ page_parse_delete_rec_list( ...@@ -828,8 +828,6 @@ page_parse_delete_rec_list(
ut_ad(!!page_is_comp(page) == dict_table_is_comp(index->table)); ut_ad(!!page_is_comp(page) == dict_table_is_comp(index->table));
page_zip = buf_block_get_page_zip(buf_block_align(page));
if (type == MLOG_LIST_END_DELETE if (type == MLOG_LIST_END_DELETE
|| type == MLOG_COMP_LIST_END_DELETE) { || type == MLOG_COMP_LIST_END_DELETE) {
page_delete_rec_list_end(page + offset, index, page_delete_rec_list_end(page + offset, index,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment