diff --git a/buf/buf0buf.c b/buf/buf0buf.c
index 3ae4a96e88c..86275b65650 100644
--- a/buf/buf0buf.c
+++ b/buf/buf0buf.c
@@ -2002,15 +2002,14 @@ buf_page_io_complete(
 		/* If this page is not uninitialized and not in the
 		doublewrite buffer, then the page number and space id
 		should be the same as in block. */
-		read_page_no = mach_read_from_4((block->frame)
-					+ FIL_PAGE_OFFSET);
+		read_page_no = mach_read_from_4(frame + FIL_PAGE_OFFSET);
 		switch (fil_page_get_type(frame)) {
 		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);
 			break;
 		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);
 		}
 
diff --git a/dict/dict0load.c b/dict/dict0load.c
index 08aa280b88d..9ccec589d42 100644
--- a/dict/dict0load.c
+++ b/dict/dict0load.c
@@ -837,7 +837,7 @@ dict_load_table(
 
 	/* Check if the tablespace exists and has the right name */
 	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);
 
 		if (fil_space_for_table_exists_in_mem(space, name, FALSE,
@@ -863,6 +863,8 @@ dict_load_table(
 				ibd_file_missing = TRUE;
 			}
 		}
+	} else {
+		zip_size = 0;
 	}
 
 	ut_a(0 == ut_strcmp("N_COLS",
@@ -872,7 +874,7 @@ dict_load_table(
 	field = rec_get_nth_field_old(rec, 4, &len);
 	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. */
 	if (n_cols & 0x80000000UL) {
diff --git a/include/mtr0log.h b/include/mtr0log.h
index 6e94ae99da8..29d996859ec 100644
--- a/include/mtr0log.h
+++ b/include/mtr0log.h
@@ -170,7 +170,8 @@ mlog_parse_nbytes(
 	ulint	type,	/* in: log record type: MLOG_1BYTE, ... */
 	byte*	ptr,	/* in: buffer */
 	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. */
 
@@ -181,7 +182,8 @@ mlog_parse_string(
 			record */
 	byte*	ptr,	/* in: buffer */
 	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 */
 
 
 /************************************************************
diff --git a/include/page0page.h b/include/page0page.h
index a09bc09df1c..0bef44df1eb 100644
--- a/include/page0page.h
+++ b/include/page0page.h
@@ -792,7 +792,8 @@ page_parse_delete_rec_list(
 	byte*		ptr,	/* in: buffer */
 	byte*		end_ptr,/* in: buffer end */
 	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 */
 /***************************************************************
 Parses a redo log record of creating a page. */
diff --git a/log/log0recv.c b/log/log0recv.c
index ecfdc798fc1..4f36ce565df 100644
--- a/log/log0recv.c
+++ b/log/log0recv.c
@@ -764,8 +764,7 @@ recv_parse_or_apply_log_rec_body(
 
 	switch (type) {
 	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);
+		ptr = mlog_parse_nbytes(type, ptr, end_ptr, page, page_zip);
 		break;
 	case MLOG_REC_INSERT: case MLOG_COMP_REC_INSERT:
 		if (NULL != (ptr = mlog_parse_index(ptr, end_ptr,
@@ -791,6 +790,7 @@ recv_parse_or_apply_log_rec_body(
 		/* This log record type is obsolete, but we process it for
 		backward compatibility with MySQL 5.0.3 and 5.0.4. */
 		ut_a(!page || page_is_comp(page));
+		ut_a(!page_zip);
 		ptr = mlog_parse_index(ptr, end_ptr, TRUE, &index);
 		if (!ptr) {
 			break;
@@ -819,7 +819,7 @@ recv_parse_or_apply_log_rec_body(
 				|| (ibool)!!page_is_comp(page)
 				== dict_table_is_comp(index->table));
 			ptr = page_parse_delete_rec_list(type, ptr, end_ptr,
-							index, page, mtr);
+						index, page, page_zip, mtr);
 		}
 		break;
 	case MLOG_LIST_END_COPY_CREATED: case MLOG_COMP_LIST_END_COPY_CREATED:
@@ -843,6 +843,7 @@ recv_parse_or_apply_log_rec_body(
 		}
 		break;
 	case MLOG_PAGE_CREATE: case MLOG_COMP_PAGE_CREATE:
+		ut_a(!page_zip);
 		ptr = page_parse_create(ptr, end_ptr,
 				type == MLOG_COMP_PAGE_CREATE,
 				page, mtr);
@@ -865,6 +866,7 @@ recv_parse_or_apply_log_rec_body(
 								page, mtr);
 		break;
 	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,
 				type == MLOG_COMP_REC_MIN_MARK, page, mtr);
 		break;
@@ -886,8 +888,7 @@ recv_parse_or_apply_log_rec_body(
 		ptr = fsp_parse_init_file_page(ptr, end_ptr, page);
 		break;
 	case MLOG_WRITE_STRING:
-		ut_a(!page_zip || fil_page_get_type(page) != FIL_PAGE_INDEX);
-		ptr = mlog_parse_string(ptr, end_ptr, page);
+		ptr = mlog_parse_string(ptr, end_ptr, page, page_zip);
 		break;
 	case MLOG_FILE_CREATE:
 	case MLOG_FILE_RENAME:
diff --git a/mtr/mtr0log.c b/mtr/mtr0log.c
index cc9afc4127e..a61b40f4ca0 100644
--- a/mtr/mtr0log.c
+++ b/mtr/mtr0log.c
@@ -128,13 +128,15 @@ mlog_parse_nbytes(
 	ulint	type,	/* in: log record type: MLOG_1BYTE, ... */
 	byte*	ptr,	/* in: buffer */
 	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	val;
 	dulint	dval;
 
 	ut_a(type <= MLOG_8BYTES);
+	ut_a(!page || !page_zip || fil_page_get_type(page) != FIL_PAGE_INDEX);
 
 	if (end_ptr < ptr + 2) {
 
@@ -159,6 +161,11 @@ mlog_parse_nbytes(
 		}
 
 		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);
 		}
 
@@ -172,35 +179,47 @@ mlog_parse_nbytes(
 		return(NULL);
 	}
 
-	if (type == MLOG_1BYTE) {
-		if (val > 0xFFUL) {
-			recv_sys->found_corrupt_log = TRUE;
-
-			return(NULL);
+	switch (type) {
+	case MLOG_1BYTE:
+		if (UNIV_UNLIKELY(val > 0xFFUL)) {
+			goto corrupt;
 		}
-	} else if (type == MLOG_2BYTES) {
-		if (val > 0xFFFFUL) {
-			recv_sys->found_corrupt_log = TRUE;
-
-			return(NULL);
-		}
-	} else {
-		if (type != MLOG_4BYTES) {
-			recv_sys->found_corrupt_log = TRUE;
-
-			return(NULL);
-		}
-	}
-
-	if (page) {
-		if (type == MLOG_1BYTE) {
+		if (page) {
+			if (UNIV_LIKELY_NULL(page_zip)) {
+				mach_write_to_1(
+					((page_zip_des_t*) page_zip)->data
+					+ offset, val);
+			}
 			mach_write_to_1(page + offset, val);
-		} else if (type == MLOG_2BYTES) {
+		}
+		break;
+	case MLOG_2BYTES:
+		if (UNIV_UNLIKELY(val > 0xFFFFUL)) {
+			goto corrupt;
+		}
+		if (page) {
+			if (UNIV_LIKELY_NULL(page_zip)) {
+				mach_write_to_2(
+					((page_zip_des_t*) page_zip)->data
+					+ 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);
 		}
+		break;
+	default:
+	corrupt:
+		recv_sys->found_corrupt_log = TRUE;
+		ptr = NULL;
 	}
 
 	return(ptr);
@@ -374,11 +393,14 @@ mlog_parse_string(
 			record */
 	byte*	ptr,	/* in: buffer */
 	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	len;
 
+	ut_a(!page || !page_zip || fil_page_get_type(page) != FIL_PAGE_INDEX);
+
 	if (end_ptr < ptr + 4) {
 
 		return(NULL);
@@ -386,25 +408,27 @@ mlog_parse_string(
 
 	offset = mach_read_from_2(ptr);
 	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;
 
 		return(NULL);
 	}
 
-	len = mach_read_from_2(ptr);
-	ptr += 2;
-
-	ut_a(len + offset <= UNIV_PAGE_SIZE);
-
 	if (end_ptr < ptr + len) {
 
 		return(NULL);
 	}
 
 	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);
diff --git a/page/page0page.c b/page/page0page.c
index 483dc24c39d..e568a3d56bb 100644
--- a/page/page0page.c
+++ b/page/page0page.c
@@ -800,11 +800,11 @@ page_parse_delete_rec_list(
 	byte*		ptr,	/* in: buffer */
 	byte*		end_ptr,/* in: buffer end */
 	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 */
 {
 	ulint		offset;
-	page_zip_des_t*	page_zip;
 
 	ut_ad(type == MLOG_LIST_END_DELETE
 		|| type == MLOG_LIST_START_DELETE
@@ -828,8 +828,6 @@ page_parse_delete_rec_list(
 
 	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
 			|| type == MLOG_COMP_LIST_END_DELETE) {
 		page_delete_rec_list_end(page + offset, index,