[Commits] af2e970561b: MDEV-13443: Port innochecksum tests from 10.2 innodb_zip suite to 10.1

jan jan.lindstrom at mariadb.com
Fri Aug 4 13:14:05 EEST 2017


revision-id: af2e970561b82bd52e91c95bc864d5e3018ae9bb (mariadb-10.1.25-14-gaf2e970561b)
parent(s): 8b019f87dd51b1d2755655d2f136d5429fc47e1f
author: Jan Lindström
committer: Jan Lindström
timestamp: 2017-08-04 13:11:05 +0300
message:

MDEV-13443: Port innochecksum tests from 10.2 innodb_zip suite to 10.1

This is basically port of WL6045:Improve Innochecksum with some
code refactoring on innochecksum.

Added page0size.h include from 10.2 to make 10.1 vrs 10.2 innochecksum
as identical as possible.

Added page 0 checksum checking and if that fails whole test fails.

---
 extra/innochecksum.cc                              | 473 ++++++++++++++-------
 mysql-test/suite/innodb/include/innodb-wl6045.inc  |  22 +
 .../suite/innodb/r/innodb_zip_innochecksum.result  |  91 ++++
 .../suite/innodb/r/innodb_zip_innochecksum2.result | 160 +++++++
 .../suite/innodb/r/innodb_zip_innochecksum3.result | 227 ++++++++++
 .../suite/innodb/t/innodb_zip_innochecksum.opt     |   4 +
 .../suite/innodb/t/innodb_zip_innochecksum.test    | 239 +++++++++++
 .../suite/innodb/t/innodb_zip_innochecksum2.opt    |   4 +
 .../suite/innodb/t/innodb_zip_innochecksum2.test   | 118 +++++
 .../suite/innodb/t/innodb_zip_innochecksum3.opt    |   2 +
 .../suite/innodb/t/innodb_zip_innochecksum3.test   | 406 ++++++++++++++++++
 storage/innobase/include/page0size.h               | 200 +++++++++
 storage/innobase/include/univ.i                    |   2 +
 13 files changed, 1793 insertions(+), 155 deletions(-)

diff --git a/extra/innochecksum.cc b/extra/innochecksum.cc
index e258a8c1d08..e9002ab73d9 100644
--- a/extra/innochecksum.cc
+++ b/extra/innochecksum.cc
@@ -67,6 +67,7 @@ typedef void fil_space_t;
 #include "ut0crc32.h"            /* ut_crc32_init() */
 #include "fsp0pagecompress.h"    /* fil_get_compression_alg_name */
 #include "fil0crypt.h"           /* fil_space_verify_crypt_checksum */
+#include "page0size.h"
 
 #include <string.h>
 
@@ -95,6 +96,7 @@ extern ulong			srv_checksum_algorithm;
 static ulong physical_page_size;  /* Page size in bytes on disk. */
 static ulong logical_page_size;   /* Page size when uncompressed. */
 ulong srv_page_size;
+page_size_t			univ_page_size(0, 0, false);
 /* Current page number (0 based). */
 ulint			cur_page_num;
 /* Skip the checksum verification. */
@@ -296,6 +298,31 @@ void print_leaf_stats(
 	}
 }
 
+/** Get the page size of the filespace from the filespace header.
+ at param[in]	buf	buffer used to read the page.
+ at return page size */
+static
+const page_size_t
+get_page_size(
+	byte*	buf)
+{
+	const ulint	flags = mach_read_from_4(buf + FIL_PAGE_DATA
+						 + FSP_SPACE_FLAGS);
+
+	const ulint	ssize = FSP_FLAGS_GET_PAGE_SSIZE(flags);
+
+	if (ssize == 0) {
+		srv_page_size = UNIV_PAGE_SIZE_ORIG;
+	} else {
+		srv_page_size = ((UNIV_ZIP_SIZE_MIN >> 1) << ssize);
+	}
+
+	univ_page_size.copy_from(
+		page_size_t(srv_page_size, srv_page_size, false));
+
+	return(page_size_t(flags));
+}
+
 #ifdef _WIN32
 /***********************************************//*
  @param		[in] error	error no. from the getLastError().
@@ -426,7 +453,6 @@ ulong read_file(
 /** Check if page is corrupted or not.
 @param[in]	buf		page frame
 @param[in]	page_size	page size
- at param[in]	zip_size	!= if page row compressed
 @param[in]	is_encrypted	true if page0 contained cryp_data
 				with crypt_scheme encrypted
 @param[in]	is_compressed	true if page0 fsp_flags contained
@@ -436,8 +462,7 @@ static
 bool
 is_page_corrupted(
 	byte*		buf,
-	ulint		page_size,
-	ulint		zip_size,
+	const page_size_t&	page_size,
 	bool		is_encrypted,
 	bool		is_compressed)
 {
@@ -462,13 +487,13 @@ is_page_corrupted(
 		return (false);
 	}
 
-	if (!zip_size) {
+	if (page_size.is_compressed()) {
 		/* check the stored log sequence numbers
 		for uncompressed tablespace. */
 		logseq = mach_read_from_4(buf + FIL_PAGE_LSN + 4);
 		logseqfield = mach_read_from_4(
-				buf + page_size -
-				FIL_PAGE_END_LSN_OLD_CHKSUM + 4);
+			buf + page_size.logical() -
+			FIL_PAGE_END_LSN_OLD_CHKSUM + 4);
 
 		if (is_log_enabled) {
 			fprintf(log_file,
@@ -488,13 +513,23 @@ is_page_corrupted(
 
 	/* Again we can't trust only FIL_PAGE_FILE_FLUSH_LSN field
 	now repurposed as FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,
-	we need to check also crypt_data contents. */
+	we need to check also crypt_data contents.
+
+	If page is encrypted, use different checksum calculation
+	as innochecksum can't decrypt pages. Note that some old InnoDB
+	versions did not initialize FIL_PAGE_FILE_FLUSH_LSN field
+	so if crypt checksum does not match we verify checksum using
+	normal method. */
 	if (is_encrypted && key_version != 0) {
 		is_corrupted = !fil_space_verify_crypt_checksum(buf,
-			zip_size, NULL, cur_page_num);
+			page_size.is_compressed() ? page_size.physical() : 0, NULL, cur_page_num);
 	} else {
+		is_corrupted = true;
+	}
+
+	if (is_corrupted) {
 		is_corrupted = buf_page_is_corrupted(
-			true, buf, zip_size, NULL);
+			true, buf, page_size.is_compressed() ? page_size.physical() : 0, NULL);
 	}
 
 	return(is_corrupted);
@@ -643,7 +678,7 @@ update_checksum(
 
 	}
 
-	func_exit:
+func_exit:
 	/* The following code is to check the stored checksum with the
 	calculated checksum. If it matches, then return FALSE to skip
 	the rewrite of checksum, otherwise return TRUE. */
@@ -734,12 +769,14 @@ Parse the page and collect/dump the information about page type
 @param [in] page	buffer page
 @param [out] xdes	extend descriptor page
 @param [in] file	file for diagnosis.
+ at param [in] page_size	page_size
 */
 void
 parse_page(
 	const byte*	page,
 	byte*		xdes,
-	FILE*		file)
+	FILE*		file,
+	const page_size_t& page_size)
 {
 	unsigned long long id;
 	ulint undo_page_type;
@@ -761,64 +798,75 @@ parse_page(
 
 	switch (mach_read_from_2(page + FIL_PAGE_TYPE)) {
 
-	case FIL_PAGE_INDEX:
+	case FIL_PAGE_INDEX: {
 		page_type.n_fil_page_index++;
 		id = mach_read_from_8(page + PAGE_HEADER + PAGE_INDEX_ID);
 		n_recs = page_get_n_recs(page);
-		page_no = page_get_page_no(page);
+		page_no = mach_read_from_4(page + FIL_PAGE_OFFSET);
 		left_page_no = mach_read_from_4(page + FIL_PAGE_PREV);
 		right_page_no = mach_read_from_4(page + FIL_PAGE_NEXT);
-		data_bytes = page_get_data_size(page);
+		ulint key_version = mach_read_from_4(page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
+
+		/* If page is encrypted we can't read index header */
+		if (!key_version) {
+			data_bytes = page_get_data_size(page);
+		} else {
+			data_bytes = 0;
+		}
+
 		is_leaf = page_is_leaf(page);
 		size_range_id = (data_bytes * SIZE_RANGES_FOR_PAGE
-                                + logical_page_size - 1) /
-                                logical_page_size;
-               if (size_range_id > SIZE_RANGES_FOR_PAGE + 1) {
-		       /* data_bytes is bigger than logical_page_size */
-		       size_range_id = SIZE_RANGES_FOR_PAGE + 1;
-               }
-               if (per_page_details) {
-		       printf("index %llu page %lu leaf %u n_recs %lu data_bytes %lu"
-			       "\n", id, page_no, is_leaf, n_recs, data_bytes);
-               }
-               /* update per-index statistics */
-               {
-		       if (index_ids.count(id) == 0) {
-			       index_ids[id] = per_index_stats();
-		       }
-		       std::map<unsigned long long, per_index_stats>::iterator it;
-		       it = index_ids.find(id);
-		       per_index_stats &index = (it->second);
-		       const byte* des = xdes + XDES_ARR_OFFSET
-			       + XDES_SIZE * ((page_no & (physical_page_size - 1))
-				       / FSP_EXTENT_SIZE);
-		       if (xdes_get_bit(des, XDES_FREE_BIT,
-				       page_no % FSP_EXTENT_SIZE)) {
-			       index.free_pages++;
-			       return;
-		       }
-		       index.pages++;
-		       if (is_leaf) {
-			       index.leaf_pages++;
-			       if (data_bytes > index.max_data_size) {
-				       index.max_data_size = data_bytes;
-			       }
-			       struct per_page_stats pp(n_recs, data_bytes,
-				       left_page_no, right_page_no);
-
-			       index.leaves[page_no] = pp;
-
-			       if (left_page_no == ULINT32_UNDEFINED) {
-				       index.first_leaf_page = page_no;
-				       index.count++;
-			       }
-		       }
-		       index.total_n_recs += n_recs;
-		       index.total_data_bytes += data_bytes;
-		       index.pages_in_size_range[size_range_id] ++;
-               }
-
-	       if (page_type_dump) {
+			+ page_size.logical() - 1) /
+			page_size.logical();
+
+		if (size_range_id > SIZE_RANGES_FOR_PAGE + 1) {
+			/* data_bytes is bigger than logical_page_size */
+			size_range_id = SIZE_RANGES_FOR_PAGE + 1;
+		}
+
+		if (per_page_details) {
+			printf("index %llu page %lu leaf %u n_recs %lu data_bytes %lu"
+				"\n", id, page_no, is_leaf, n_recs, data_bytes);
+		}
+
+		/* update per-index statistics */
+		{
+			if (index_ids.count(id) == 0) {
+				index_ids[id] = per_index_stats();
+			}
+			std::map<unsigned long long, per_index_stats>::iterator it;
+			it = index_ids.find(id);
+			per_index_stats &index = (it->second);
+			const byte* des = xdes + XDES_ARR_OFFSET
+				+ XDES_SIZE * ((page_no & (page_size.physical() - 1))
+					/ FSP_EXTENT_SIZE);
+			if (xdes_get_bit(des, XDES_FREE_BIT,
+					page_no % FSP_EXTENT_SIZE)) {
+				index.free_pages++;
+				return;
+			}
+			index.pages++;
+			if (is_leaf) {
+				index.leaf_pages++;
+				if (data_bytes > index.max_data_size) {
+					index.max_data_size = data_bytes;
+				}
+				struct per_page_stats pp(n_recs, data_bytes,
+					left_page_no, right_page_no);
+
+				index.leaves[page_no] = pp;
+
+				if (left_page_no == ULINT32_UNDEFINED) {
+					index.first_leaf_page = page_no;
+					index.count++;
+				}
+			}
+			index.total_n_recs += n_recs;
+			index.total_data_bytes += data_bytes;
+			index.pages_in_size_range[size_range_id] ++;
+		}
+
+		if (page_type_dump) {
 			fprintf(file, "#::%8" PRIuMAX "\t\t|\t\tIndex page\t\t\t|"
 				"\tindex id=%llu,", cur_page_num, id);
 
@@ -829,9 +877,9 @@ parse_page(
 				page_header_get_field(page, PAGE_LEVEL),
 				page_header_get_field(page, PAGE_N_RECS),
 				page_header_get_field(page, PAGE_GARBAGE), str);
-	       }
-	       break;
-
+		}
+		break;
+	}
 	case FIL_PAGE_UNDO_LOG:
 		page_type.n_fil_page_undo_log++;
 		undo_page_type = mach_read_from_2(page +
@@ -958,7 +1006,7 @@ parse_page(
 
 	case FIL_PAGE_TYPE_FSP_HDR:
 		page_type.n_fil_page_type_fsp_hdr++;
-		memcpy(xdes, page, physical_page_size);
+		memcpy(xdes, page, page_size.physical());
 		if (page_type_dump) {
 			fprintf(file, "#::%8" PRIuMAX "\t\t|\t\tFile Space "
 				"Header\t\t|\t%s\n", cur_page_num, str);
@@ -967,7 +1015,7 @@ parse_page(
 
 	case FIL_PAGE_TYPE_XDES:
 		page_type.n_fil_page_type_xdes++;
-		memcpy(xdes, page, physical_page_size);
+		memcpy(xdes, page, page_size.physical());
 		if (page_type_dump) {
 			fprintf(file, "#::%8" PRIuMAX "\t\t|\t\tExtent descriptor "
 				"page\t\t|\t%s\n", cur_page_num, str);
@@ -1096,12 +1144,12 @@ print_summary(
 		page_type.n_fil_page_type_blob);
 	fprintf(fil_out, "%8d\tCompressed BLOB page\n",
 		page_type.n_fil_page_type_zblob);
-	fprintf(fil_out, "%8d\tOther type of page\n",
-		page_type.n_fil_page_type_other);
 	fprintf(fil_out, "%8d\tPage compressed page\n",
 		page_type.n_fil_page_type_page_compressed);
 	fprintf(fil_out, "%8d\tPage compressed encrypted page\n",
 		page_type.n_fil_page_type_page_compressed_encrypted);
+	fprintf(fil_out, "%8d\tOther type of page\n",
+		page_type.n_fil_page_type_other);
 	fprintf(fil_out, "\n===============================================\n");
 	fprintf(fil_out, "Additional information:\n");
 	fprintf(fil_out, "Undo page type: %d insert, %d update, %d other\n",
@@ -1256,6 +1304,7 @@ innochecksum_get_one_option(
 		break;
 	case 'V':
 		print_version();
+		my_end(0);
 		exit(EXIT_SUCCESS);
 		break;
 	case 'C':
@@ -1328,15 +1377,20 @@ get_options(
 	return (false);
 }
 
-/** Check from page 0 if table is encrypted. */
+/** Check from page 0 if table is encrypted.
+ at param[in]	filename	Filename
+ at param[in]	page_size	page size
+ at param[in]	page		Page 0
+ at retval true if tablespace is encrypted, false if not
+*/
 static
 bool check_encryption(
 	const char* filename,
-	ulint zip_size,
+	const page_size_t& page_size,
 	byte * page)
 {
 	ulint offset = (FSP_HEADER_OFFSET + (XDES_ARR_OFFSET + XDES_SIZE *
-			(zip_size ? zip_size : UNIV_PAGE_SIZE) / FSP_EXTENT_SIZE));
+			(page_size.physical()) / FSP_EXTENT_SIZE));
 
 	if (memcmp(page + offset, CRYPT_MAGIC, MAGIC_SZ) != 0) {
 		return false;
@@ -1361,16 +1415,96 @@ bool check_encryption(
 	uint key_id = mach_read_from_4
 		(page + offset + MAGIC_SZ + 2 + iv_length + 4);
 
-	if (type == CRYPT_SCHEME_1) {
-		if (is_log_enabled) {
-			fprintf(log_file,"Tablespace %s encrypted key_version %u key_id %u\n",
-				filename, min_key_version, key_id);
-		}
+	if (type == CRYPT_SCHEME_1 && is_log_enabled) {
+		fprintf(log_file,"Tablespace %s encrypted key_version %u key_id %u\n",
+			filename, min_key_version, key_id);
 	}
 
 	return (type == CRYPT_SCHEME_1);
 }
 
+/**
+Verify page checksum.
+ at param[in] buf			page to verify
+ at param[in] page_size		page size
+ at param[in] is_encrypted		true if tablespace is encrypted
+ at param[in] is_compressed	true if tablespace is page compressed
+ at param[in,out] mismatch_count	Number of pages failed in checksum verify
+ at retval 0 if page checksum matches or 1 if it does not match
+*/
+static
+int verify_checksum(
+	byte* buf,
+	const page_size_t& page_size,
+	bool is_encrypted,
+	bool is_compressed,
+	ulint* mismatch_count)
+{
+	int exit_status = 0;
+	bool is_corrupted = false;
+
+	is_corrupted = is_page_corrupted(
+		buf, page_size, is_encrypted, is_compressed);
+
+	if (is_corrupted) {
+		fprintf(stderr, "Fail: page "
+			"%" PRIuMAX " invalid\n",
+			cur_page_num);
+
+		(*mismatch_count)++;
+
+		if (*mismatch_count > allow_mismatches) {
+			fprintf(stderr,
+				"Exceeded the "
+				"maximum allowed "
+				"checksum mismatch "
+				"count::%" PRIuMAX " current %" PRIuMAX "\n",
+				*mismatch_count,
+				allow_mismatches);
+
+			exit_status = 1;
+		}
+	}
+
+	return (exit_status);
+}
+
+/** Rewrite page checksum if needed.
+ at param[in]	filename	File name
+ at param[in]	fil_in		File pointer
+ at param[in]	buf		page
+ at param[in]	page_size	page size
+ at param[in]	pos		File position
+ at param[in]	is_encrypted	true if tablespace is encrypted
+ at param[in]	is_compressed	true if tablespace is page compressed
+ at retval 0 if checksum rewrite was successful, 1 if error was detected */
+static
+int
+rewrite_checksum(
+	const char*	filename,
+	FILE*		fil_in,
+	byte*		buf,
+	const page_size_t& page_size,
+	fpos_t*		pos,
+	bool is_encrypted,
+	bool is_compressed)
+{
+	int exit_status = 0;
+	/* Rewrite checksum. Note that for encrypted and
+	page compressed tables this is not currently supported. */
+	if (do_write &&
+		!is_encrypted &&
+		!is_compressed
+		&& !write_file(filename, fil_in, buf,
+			page_size.is_compressed(), pos,
+			static_cast<ulong>(page_size.physical()))) {
+
+		exit_status = 1;
+	}
+
+	return (exit_status);
+}
+
 int main(
 	int	argc,
 	char	**argv)
@@ -1380,6 +1514,8 @@ int main(
 	/* our input filename. */
 	char*		filename;
 	/* Buffer to store pages read. */
+	byte*		buf_ptr = NULL;
+	byte*		xdes_ptr = NULL;
 	byte*		buf = NULL;
 	byte*		xdes = NULL;
 	/* bytes read count */
@@ -1405,8 +1541,6 @@ int main(
 	off_t		offset			= 0;
 	/* count the no. of page corrupted. */
 	ulint		mismatch_count		= 0;
-	/* Variable to ack the page is corrupted or not. */
-	bool		is_corrupted		= false;
 
 	bool		partial_page_read	= false;
 	/* Enabled when read from stdin is done. */
@@ -1465,16 +1599,16 @@ int main(
 		my_print_variables(innochecksum_options);
 	}
 
-
-	buf = (byte*) malloc(UNIV_PAGE_SIZE_MAX * 2);
-	xdes = (byte*)malloc(UNIV_PAGE_SIZE_MAX * 2);
+	buf_ptr = (byte*) malloc(UNIV_PAGE_SIZE_MAX * 2);
+	xdes_ptr = (byte*)malloc(UNIV_PAGE_SIZE_MAX * 2);
+	buf = (byte *) ut_align(buf_ptr, UNIV_PAGE_SIZE_MAX);
+	xdes = (byte *) ut_align(xdes_ptr, UNIV_PAGE_SIZE_MAX);
 
 	/* The file name is not optional. */
 	for (int i = 0; i < argc; ++i) {
 		/* Reset parameters for each file. */
 		filename = argv[i];
 		memset(&page_type, 0, sizeof(innodb_page_type));
-		is_corrupted = false;
 		partial_page_read = false;
 		skip_page = false;
 
@@ -1542,23 +1676,23 @@ int main(
 
 		/* Determine page size, zip_size and page compression
 		from fsp_flags and encryption metadata from page 0 */
+		const page_size_t&	page_size = get_page_size(buf);
 		ulint flags = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + buf);
-		ulint page_size = fsp_flags_get_page_size(flags);
-		ulint zip_size = fsp_flags_get_zip_size(flags);
-		logical_page_size = zip_size;
-		physical_page_size = page_size;
-		srv_page_size = page_size;
+		ulint zip_size = page_size.is_compressed() ? page_size.logical() : 0;
+		logical_page_size = page_size.is_compressed() ? zip_size : 0;
+		physical_page_size = page_size.physical();
+		srv_page_size = page_size.logical();
 		bool is_compressed = FSP_FLAGS_HAS_PAGE_COMPRESSION(flags);
 
-		if (page_size > UNIV_ZIP_SIZE_MIN) {
+		if (page_size.physical() > UNIV_ZIP_SIZE_MIN) {
 			/* Read rest of the page 0 to determine crypt_data */
-			bytes = ulong(read_file(buf, partial_page_read, page_size, fil_in));
+			bytes = ulong(read_file(buf, partial_page_read, page_size.physical(), fil_in));
 
-			if (bytes != page_size) {
+			if (bytes != page_size.physical()) {
 				fprintf(stderr, "Error: Was not able to read the "
 					"rest of the page ");
 				fprintf(stderr, "of %lu bytes.  Bytes read was %lu\n",
-					page_size - UNIV_ZIP_SIZE_MIN, bytes);
+					page_size.physical() - UNIV_ZIP_SIZE_MIN, bytes);
 
 				exit_status = 1;
 				goto my_exit;
@@ -1567,9 +1701,52 @@ int main(
 		}
 
 		/* Now that we have full page 0 in buffer, check encryption */
-		bool is_encrypted = check_encryption(filename, zip_size, buf);
+		bool is_encrypted = check_encryption(filename, page_size, buf);
+
+		/* Verify page 0 contents. Note that we can't allow
+		checksum mismatch on page 0, because that would mean we
+		could not trust it content. */
+		if (!no_check) {
+			ulint tmp_allow_mismatches = allow_mismatches;
+			allow_mismatches = 0;
+
+			exit_status = verify_checksum(buf, page_size, is_encrypted, is_compressed, &mismatch_count);
+
+			if (exit_status) {
+				fprintf(stderr, "Error: Page 0 checksum mismatch, can't continue. \n");
+				goto my_exit;
+			}
+			allow_mismatches = tmp_allow_mismatches;
+		}
+
+		if ((exit_status = rewrite_checksum(filename, fil_in, buf,
+					page_size, &pos, is_encrypted, is_compressed))) {
+			goto my_exit;
+		}
+
+		if (page_type_dump) {
+			fprintf(fil_page_type,
+				"\n\nFilename::%s\n", filename);
+			fprintf(fil_page_type,
+				"========================================"
+				"======================================\n");
+			fprintf(fil_page_type,
+				"\tPAGE_NO\t\t|\t\tPAGE_TYPE\t\t"
+				"\t|\tEXTRA INFO\n");
+			fprintf(fil_page_type,
+				"========================================"
+				"======================================\n");
+		}
+
+		if (per_page_details) {
+			printf("page %ld ", cur_page_num);
+		}
+
+		if (page_type_summary || page_type_dump) {
+			parse_page(buf, xdes, fil_page_type, page_size);
+		}
 
-		pages = (ulint) (size / page_size);
+		pages = (ulint) (size / page_size.physical());
 
 		if (just_count) {
 			if (read_from_stdin) {
@@ -1606,7 +1783,7 @@ int main(
 				partial_page_read = false;
 
 				offset = (off_t) start_page
-					* (off_t) page_size;
+					* (off_t) page_size.physical();
 #ifdef _WIN32
 				if (_fseeki64(fil_in, offset, SEEK_SET)) {
 #else
@@ -1644,7 +1821,7 @@ int main(
 					bytes = read_file(buf,
 							  partial_page_read,
 							  static_cast<ulong>(
-							  page_size),
+								  page_size.physical()),
 							  fil_in);
 
 					partial_page_read = false;
@@ -1662,28 +1839,14 @@ int main(
 			}
 		}
 
-		if (page_type_dump) {
-			fprintf(fil_page_type,
-				"\n\nFilename::%s\n", filename);
-			fprintf(fil_page_type,
-				"========================================"
-				"======================================\n");
-			fprintf(fil_page_type,
-				"\tPAGE_NO\t\t|\t\tPAGE_TYPE\t\t"
-				"\t|\tEXTRA INFO\n");
-			fprintf(fil_page_type,
-				"========================================"
-				"======================================\n");
-		}
-
 		/* main checksumming loop */
-		cur_page_num = start_page;
+		cur_page_num = start_page ? start_page : cur_page_num + 1;
 		lastt = 0;
 		while (!feof(fil_in)) {
 
 			bytes = read_file(buf, partial_page_read,
 					  static_cast<ulong>(
-					  page_size), fil_in);
+						  page_size.physical()), fil_in);
 			partial_page_read = false;
 
 			if (!bytes && feof(fil_in)) {
@@ -1692,17 +1855,17 @@ int main(
 
 			if (ferror(fil_in)) {
 				fprintf(stderr, "Error reading " ULINTPF " bytes",
-					page_size);
+					page_size.physical());
 				perror(" ");
 
 				exit_status = 1;
 				goto my_exit;
 			}
 
-			if (bytes != page_size) {
+			if (bytes != page_size.physical()) {
 				fprintf(stderr, "Error: bytes read (%lu) "
 					"doesn't match page size (" ULINTPF ")\n",
-					bytes, page_size);
+					bytes, page_size.physical());
 				exit_status = 1;
 				goto my_exit;
 			}
@@ -1714,46 +1877,26 @@ int main(
 				skip_page = false;
 			}
 
+			ulint cur_page_type = mach_read_from_2(buf+FIL_PAGE_TYPE);
+
+			/* FIXME: Page compressed or Page compressed and encrypted
+			pages do not contain checksum. */
+			if (cur_page_type == FIL_PAGE_PAGE_COMPRESSED ||
+			    cur_page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED) {
+				skip_page = true;
+			}
+
 			/* If no-check is enabled, skip the
 			checksum verification.*/
-			if (!no_check) {
-				/* Checksum verification */
-				if (!skip_page) {
-					is_corrupted = is_page_corrupted(
-						buf, page_size, zip_size, is_encrypted, is_compressed);
-
-					if (is_corrupted) {
-						fprintf(stderr, "Fail: page "
-							"%" PRIuMAX " invalid\n",
-							cur_page_num);
-
-						mismatch_count++;
-
-						if(mismatch_count > allow_mismatches) {
-							fprintf(stderr,
-								"Exceeded the "
-								"maximum allowed "
-								"checksum mismatch "
-								"count::%" PRIuMAX "\n",
-								allow_mismatches);
-
-							exit_status = 1;
-							goto my_exit;
-						}
-					}
-				}
+			if (!no_check
+			    && !skip_page
+			    && (exit_status = verify_checksum(buf, page_size,
+					    is_encrypted, is_compressed, &mismatch_count))) {
+				goto my_exit;
 			}
 
-			/* Rewrite checksum. Note that for encrypted and
-			page compressed tables this is not currently supported. */
-			if (do_write &&
-			    !is_encrypted &&
-			    !is_compressed
-			    && !write_file(filename, fil_in, buf,
-					   zip_size != 0, &pos,
-					   static_cast<ulong>(page_size))) {
-
-				exit_status = 1;
+			if ((exit_status = rewrite_checksum(filename, fil_in, buf,
+						page_size, &pos, is_encrypted, is_compressed))) {
 				goto my_exit;
 			}
 
@@ -1767,11 +1910,12 @@ int main(
 			}
 
 			if (page_type_summary || page_type_dump) {
-				parse_page(buf, xdes, fil_page_type);
+				parse_page(buf, xdes, fil_page_type, page_size);
 			}
 
 			/* do counter increase and progress printing */
 			cur_page_num++;
+
 			if (verbose && !read_from_stdin) {
 				if ((cur_page_num % 64) == 0) {
 					now = time(0);
@@ -1811,10 +1955,29 @@ int main(
 		fclose(log_file);
 	}
 
+	free(buf_ptr);
+	free(xdes_ptr);
+
+	my_end(exit_status);
+	DBUG_RETURN(exit_status);
+
 my_exit:
-	if (buf) {
-		free(buf);
+	if (buf_ptr) {
+		free(buf_ptr);
 	}
+
+	if (xdes_ptr) {
+		free(xdes_ptr);
+	}
+
+	if (!read_from_stdin && fil_in) {
+		fclose(fil_in);
+	}
+
+	if (log_file) {
+		fclose(log_file);
+	}
+
 	my_end(exit_status);
-	exit(exit_status);
+	DBUG_RETURN(exit_status);
 }
diff --git a/mysql-test/suite/innodb/include/innodb-wl6045.inc b/mysql-test/suite/innodb/include/innodb-wl6045.inc
new file mode 100644
index 00000000000..33a2ecd731f
--- /dev/null
+++ b/mysql-test/suite/innodb/include/innodb-wl6045.inc
@@ -0,0 +1,22 @@
+--echo ===> Testing  size=$size
+--disable_warnings
+--eval CREATE TABLE t1(id INT AUTO_INCREMENT PRIMARY KEY, msg VARCHAR(255)) ENGINE=INNODB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=$size
+--enable_warnings
+
+insert into t1 values(1,"I");
+insert into t1 values(2,"AM");
+insert into t1 values(3,"COMPRESSED");
+
+--source include/shutdown_mysqld.inc
+
+#STOP;
+
+--exec $INNOCHECKSUM $MYSQLD_DATADIR/test/t1.ibd
+--exec $INNOCHECKSUM --write=crc32 $MYSQLD_DATADIR/test/t1.ibd
+--exec $INNOCHECKSUM --strict-check=crc32 $MYSQLD_DATADIR/test/t1.ibd
+--exec $INNOCHECKSUM --write=none $MYSQLD_DATADIR/test/t1.ibd
+--exec $INNOCHECKSUM --strict-check=none $MYSQLD_DATADIR/test/t1.ibd
+
+--source include/start_mysqld.inc
+select * from t1;
+drop table t1;
diff --git a/mysql-test/suite/innodb/r/innodb_zip_innochecksum.result b/mysql-test/suite/innodb/r/innodb_zip_innochecksum.result
new file mode 100644
index 00000000000..ff1bccfb60c
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb_zip_innochecksum.result
@@ -0,0 +1,91 @@
+# Set the environmental variables
+call mtr.add_suppression("InnoDB: Unable to read tablespace .* page no .* into the buffer pool after 100 attempts");
+call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed");
+CREATE TABLE tab1(c1 INT PRIMARY KEY,c2 VARCHAR(20)) ENGINE=InnoDB;
+CREATE INDEX idx1 ON tab1(c2(10));
+INSERT INTO tab1 VALUES(1, 'Innochecksum InnoDB1');
+CREATE TABLE t1(id INT AUTO_INCREMENT PRIMARY KEY, msg VARCHAR(255)) ENGINE=INNODB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4;
+insert into t1 values(1,"i");
+insert into t1 values(2,"am");
+insert into t1 values(3,"compressed table");
+# Shutdown the Server
+# Server Default checksum = innodb
+[1b]: check the innochecksum without --strict-check
+[2]: check the innochecksum with full form --strict-check=crc32
+[3]: check the innochecksum with short form -C crc32
+[4]: check the innochecksum with --no-check ignores algorithm check, warning is expected
+FOUND /Error: --no-check must be associated with --write option./ in my_restart.err
+[5]: check the innochecksum with short form --no-check ignores algorithm check, warning is expected
+FOUND /Error: --no-check must be associated with --write option./ in my_restart.err
+[6]: check the innochecksum with full form strict-check & no-check , an error is expected
+FOUND /Error: --strict-check option cannot be used together with --no-check option./ in my_restart.err
+[7]: check the innochecksum with short form strict-check & no-check , an error is expected
+FOUND /Error: --strict-check option cannot be used together with --no-check option./ in my_restart.err
+[8]: check the innochecksum with short & full form combination
+# strict-check & no-check, an error is expected
+FOUND /Error: --strict-check option cannot be used together with --no-check option./ in my_restart.err
+[9]: check the innochecksum with full form --strict-check=innodb
+[10]: check the innochecksum with full form --strict-check=none
+# when server Default checksum=crc32
+[11]: check the innochecksum with short form -C innodb
+# when server Default checksum=crc32
+[12]: check the innochecksum with short form -C none
+# when server Default checksum=crc32
+[13]: check strict-check with invalid values
+FOUND /Error while setting value \'strict_innodb\' to \'strict-check\'/ in my_restart.err
+FOUND /Error while setting value \'strict_innodb\' to \'strict-check\'/ in my_restart.err
+FOUND /Error while setting value \'strict_crc32\' to \'strict-check\'/ in my_restart.err
+FOUND /Error while setting value \'strict_crc32\' to \'strict-check\'/ in my_restart.err
+FOUND /Error while setting value \'strict_none\' to \'strict-check\'/ in my_restart.err
+FOUND /Error while setting value \'strict_none\' to \'strict-check\'/ in my_restart.err
+FOUND /Error while setting value \'InnoBD\' to \'strict-check\'/ in my_restart.err
+FOUND /Error while setting value \'InnoBD\' to \'strict-check\'/ in my_restart.err
+FOUND /Error while setting value \'crc\' to \'strict-check\'/ in my_restart.err
+FOUND /Error while setting value \'no\' to \'strict-check\'/ in my_restart.err
+[14a]: when server default checksum=crc32 rewrite new checksum=crc32 with innochecksum
+# Also check the long form of write option.
+[14b]: when server default checksum=crc32 rewrite new checksum=innodb with innochecksum
+# Also check the long form of write option.
+# start the server with innodb_checksum_algorithm=InnoDB
+INSERT INTO tab1 VALUES(2, 'Innochecksum CRC32');
+SELECT c1,c2 FROM tab1 order by c1,c2;
+c1	c2
+1	Innochecksum InnoDB1
+2	Innochecksum CRC32
+# Stop the server
+[15]: when server default checksum=crc32 rewrite new checksum=none with innochecksum
+# Also check the short form of write option.
+# Start the server with checksum algorithm=none
+INSERT INTO tab1 VALUES(3, 'Innochecksum None');
+SELECT c1,c2 FROM tab1 order by c1,c2;
+c1	c2
+1	Innochecksum InnoDB1
+2	Innochecksum CRC32
+3	Innochecksum None
+DROP TABLE t1;
+# Stop the server
+[16]: rewrite into new checksum=crc32 with innochecksum
+# Restart the DB server with  innodb_checksum_algorithm=crc32
+SELECT * FROM tab1;
+c1	c2
+1	Innochecksum InnoDB1
+2	Innochecksum CRC32
+3	Innochecksum None
+DELETE FROM tab1 where c1=3;
+SELECT c1,c2 FROM tab1 order by c1,c2;
+c1	c2
+1	Innochecksum InnoDB1
+2	Innochecksum CRC32
+# Stop server
+[17]: rewrite into new checksum=InnoDB
+# Restart the DB server with innodb_checksum_algorithm=InnoDB
+DELETE FROM tab1 where c1=2;
+SELECT * FROM tab1;
+c1	c2
+1	Innochecksum InnoDB1
+# Stop server
+[18]:check Innochecksum with invalid write options
+FOUND /Error while setting value \'strict_crc32\' to \'write\'/ in my_restart.err
+FOUND /Error while setting value \'strict_innodb\' to \'write\'/ in my_restart.err
+FOUND /Error while setting value \'crc23\' to \'write\'/ in my_restart.err
+DROP TABLE tab1;
diff --git a/mysql-test/suite/innodb/r/innodb_zip_innochecksum2.result b/mysql-test/suite/innodb/r/innodb_zip_innochecksum2.result
new file mode 100644
index 00000000000..582bb42f0cb
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb_zip_innochecksum2.result
@@ -0,0 +1,160 @@
+SET GLOBAL innodb_compression_level=0;
+SELECT @@innodb_compression_level;
+@@innodb_compression_level
+0
+CREATE TABLE t1 (j LONGBLOB) ENGINE = InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1;
+INSERT INTO t1 VALUES (repeat('abcdefghijklmnopqrstuvwxyz',200));
+INSERT INTO t1 SELECT * from t1;
+INSERT INTO t1 SELECT * from t1;
+INSERT INTO t1 SELECT * from t1;
+INSERT INTO t1 SELECT * from t1;
+INSERT INTO t1 SELECT * from t1;
+INSERT INTO t1 SELECT * from t1;
+INSERT INTO t1 SELECT * from t1;
+INSERT INTO t1 SELECT * from t1;
+INSERT INTO t1 SELECT * from t1;
+INSERT INTO t1 SELECT * from t1;
+# stop the server
+
+Variables (--variable-name=value)
+and boolean options {FALSE|TRUE}  Value (after reading options)
+--------------------------------- ----------------------------------------
+verbose                           TRUE
+debug                             FALSE
+count                             FALSE
+start-page                        0
+end-page                          0
+page                              0
+strict-check                      crc32
+no-check                          FALSE
+allow-mismatches                  0
+write                             crc32
+page-type-summary                 FALSE
+page-type-dump                    MYSQLTEST_VARDIR/tmp/dump.txt
+per-page-details                  FALSE
+log                               (No default value)
+leaf                              FALSE
+merge                             0
+[1]:# check the both short and long options for "help"
+[2]:# Run the innochecksum when file isn't provided.
+# It will print the innochecksum usage similar to --help option.
+innochecksum Ver #.#.#
+Copyright (c) YEAR, YEAR , Oracle, MariaDB Corporation Ab and others.
+
+InnoDB offline file checksum utility.
+Usage: innochecksum [-c] [-s <start page>] [-e <end page>] [-p <page>] [-i] [-v]  [-a <allow mismatches>] [-n] [-C <strict-check>] [-w <write>] [-S] [-D <page type dump>] [-l <log>] [-l] [-m <merge pages>] <filename or [-]>
+  -?, --help          Displays this help and exits.
+  -I, --info          Synonym for --help.
+  -V, --version       Displays version information and exits.
+  -v, --verbose       Verbose (prints progress every 5 seconds).
+  -c, --count         Print the count of pages in the file and exits.
+  -s, --start-page=#  Start on this page number (0 based).
+  -e, --end-page=#    End at this page number (0 based).
+  -p, --page=#        Check only this page (0 based).
+  -C, --strict-check=name 
+                      Specify the strict checksum algorithm by the user.. One
+                      of: crc32, crc32, innodb, innodb, none, none
+  -n, --no-check      Ignore the checksum verification.
+  -a, --allow-mismatches=# 
+                      Maximum checksum mismatch allowed.
+  -w, --write=name    Rewrite the checksum algorithm by the user.. One of: 
+                      crc32, crc32, innodb, innodb, none, none
+  -S, --page-type-summary 
+                      Display a count of each page type in a tablespace.
+  -D, --page-type-dump=name 
+                      Dump the page type info for each page in a tablespace.
+  -i, --per-page-details 
+                      Print out per-page detail information.
+  -l, --log=name      log output.
+  -f, --leaf          Examine leaf index pages
+  -m, --merge=#       leaf page count if merge given number of consecutive
+                      pages
+
+Variables (--variable-name=value)
+and boolean options {FALSE|TRUE}  Value (after reading options)
+--------------------------------- ----------------------------------------
+verbose                           FALSE
+count                             FALSE
+start-page                        0
+end-page                          0
+page                              0
+strict-check                      crc32
+no-check                          FALSE
+allow-mismatches                  0
+write                             crc32
+page-type-summary                 FALSE
+page-type-dump                    (No default value)
+per-page-details                  FALSE
+log                               (No default value)
+leaf                              FALSE
+merge                             0
+[3]:# check the both short and long options for "count" and exit
+Number of pages:#
+Number of pages:#
+[4]:# Print the version of innochecksum and exit
+innochecksum Ver #.#.## Restart the DB server
+DROP TABLE t1;
+[5]:# Check the innochecksum for compressed table t1 with different key_block_size
+# Test for KEY_BLOCK_SIZE=1
+===> Testing  size=1
+CREATE TABLE t1(id INT AUTO_INCREMENT PRIMARY KEY, msg VARCHAR(255)) ENGINE=INNODB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1;
+insert into t1 values(1,"I");
+insert into t1 values(2,"AM");
+insert into t1 values(3,"COMPRESSED");
+select * from t1;
+id	msg
+1	I
+2	AM
+3	COMPRESSED
+drop table t1;
+# Test for KEY_BLOCK_SIZE=2
+===> Testing  size=2
+CREATE TABLE t1(id INT AUTO_INCREMENT PRIMARY KEY, msg VARCHAR(255)) ENGINE=INNODB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2;
+insert into t1 values(1,"I");
+insert into t1 values(2,"AM");
+insert into t1 values(3,"COMPRESSED");
+select * from t1;
+id	msg
+1	I
+2	AM
+3	COMPRESSED
+drop table t1;
+# Test for for KEY_BLOCK_SIZE=4
+===> Testing  size=4
+CREATE TABLE t1(id INT AUTO_INCREMENT PRIMARY KEY, msg VARCHAR(255)) ENGINE=INNODB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4;
+insert into t1 values(1,"I");
+insert into t1 values(2,"AM");
+insert into t1 values(3,"COMPRESSED");
+select * from t1;
+id	msg
+1	I
+2	AM
+3	COMPRESSED
+drop table t1;
+set innodb_strict_mode=off;
+# Test for for KEY_BLOCK_SIZE=8
+===> Testing  size=8
+CREATE TABLE t1(id INT AUTO_INCREMENT PRIMARY KEY, msg VARCHAR(255)) ENGINE=INNODB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;
+insert into t1 values(1,"I");
+insert into t1 values(2,"AM");
+insert into t1 values(3,"COMPRESSED");
+select * from t1;
+id	msg
+1	I
+2	AM
+3	COMPRESSED
+drop table t1;
+set innodb_strict_mode=off;
+# Test for KEY_BLOCK_SIZE=16
+===> Testing  size=16
+CREATE TABLE t1(id INT AUTO_INCREMENT PRIMARY KEY, msg VARCHAR(255)) ENGINE=INNODB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=16;
+insert into t1 values(1,"I");
+insert into t1 values(2,"AM");
+insert into t1 values(3,"COMPRESSED");
+select * from t1;
+id	msg
+1	I
+2	AM
+3	COMPRESSED
+drop table t1;
+# Test[5] completed
diff --git a/mysql-test/suite/innodb/r/innodb_zip_innochecksum3.result b/mysql-test/suite/innodb/r/innodb_zip_innochecksum3.result
new file mode 100644
index 00000000000..9ff3d89cda1
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb_zip_innochecksum3.result
@@ -0,0 +1,227 @@
+# Set the environmental variables
+call mtr.add_suppression("InnoDB: Unable to read tablespace .* page no .* into the buffer pool after 100 attempts");
+call mtr.add_suppression("InnoDB: innodb_checksum_algorithm is set to.*");
+[1]: Further Test are for rewrite checksum (innodb|crc32|none) for all ibd file & start the server.
+CREATE TABLE tab1 (pk INTEGER NOT NULL PRIMARY KEY,
+linestring_key GEOMETRY NOT NULL,
+linestring_nokey GEOMETRY NOT NULL)
+ENGINE=InnoDB ;
+INSERT INTO tab1 (pk, linestring_key, linestring_nokey)
+VALUES (1, ST_GeomFromText('POINT(10 10) '), ST_GeomFromText('POINT(10 10) '));
+CREATE INDEX linestring_index ON tab1(linestring_nokey(5));
+ALTER TABLE tab1 ADD  KEY (linestring_key(5));
+# create a compressed table
+CREATE TABLE tab2(col_1 CHAR (255) ,
+col_2 VARCHAR (255), col_3 longtext,
+col_4 longtext,col_5 longtext,
+col_6 longtext , col_7 int )
+engine = innodb row_format=compressed key_block_size=4;
+CREATE INDEX idx1 ON tab2(col_3(10));
+CREATE INDEX idx2 ON tab2(col_4(10));
+CREATE INDEX idx3 ON tab2(col_5(10));
+SET @col_1 = repeat('a', 5);
+SET @col_2 = repeat('b', 20);
+SET @col_3 = repeat('c', 100);
+SET @col_4 = repeat('d', 100);
+SET @col_5 = repeat('e', 100);
+SET @col_6 = repeat('f', 100);
+INSERT INTO tab2(col_1,col_2,col_3,col_4,col_5,col_6,col_7)
+VALUES (@col_1, at col_2, at col_3, at col_4, at cl_5, at col_6,5);
+INSERT INTO tab2(col_1,col_2,col_3,col_4,col_5,col_6,col_7)
+VALUES (@col_1, at col_2, at col_3, at col_4, at cl_5, at col_6,4);
+INSERT INTO tab2(col_1,col_2,col_3,col_4,col_5,col_6,col_7)
+VALUES (@col_1, at col_2, at col_3, at col_4, at cl_5, at col_6,3);
+INSERT INTO tab2(col_1,col_2,col_3,col_4,col_5,col_6,col_7)
+VALUES (@col_1, at col_2, at col_3, at col_4, at cl_5, at col_6,2);
+INSERT INTO tab2(col_1,col_2,col_3,col_4,col_5,col_6,col_7)
+VALUES (@col_1, at col_2, at col_3, at col_4, at cl_5, at col_6,1);
+SELECT * FROM tab2 ORDER BY col_7;
+# stop the server
+[1(a)]: Rewrite into new checksum=InnoDB for all *.ibd file and ibdata1
+: start the server with innodb_checksum_algorithm=strict_innodb
+INSERT INTO tab1 (pk, linestring_key, linestring_nokey)
+VALUES (2, ST_GeomFromText('LINESTRING(10 10,20 20,30 30)'), ST_GeomFromText('LINESTRING(10 10,20 20,30 30)'));
+SET @col_1 = repeat('a', 5);
+SET @col_2 = repeat('b', 20);
+SET @col_3 = repeat('c', 100);
+SET @col_4 = repeat('d', 100);
+SET @col_5 = repeat('e', 100);
+SET @col_6 = repeat('f', 100);
+INSERT INTO tab2(col_1,col_2,col_3,col_4,col_5,col_6,col_7)
+VALUES (@col_1, at col_2, at col_3, at col_4, at cl_5, at col_6,6);
+SELECT pk,ST_AsText(linestring_key),ST_AsText(linestring_nokey)
+FROM tab1 ORDER BY pk;
+SELECT * FROM tab2 ORDER BY col_7;
+# stop the server
+[1(b)]: Rewrite into new checksum=crc32 for all *.ibd file and ibdata1
+# start the server with innodb_checksum_algorithm=strict_crc32
+INSERT INTO tab1 (pk, linestring_key, linestring_nokey)
+VALUES (3, ST_GeomFromText('POLYGON((0 0,5 5,10 10,15 15,0 0),(10 10,20 20,30 30,40 40,10 10))'),
+ST_GeomFromText('POLYGON((0 0,5 5,10 10,15 15,0 0),(10 10,20 20,30 30,40 40,10 10))'));
+SET @col_1 = repeat('g', 5);
+SET @col_2 = repeat('h', 20);
+SET @col_3 = repeat('i', 100);
+SET @col_4 = repeat('j', 100);
+SET @col_5 = repeat('k', 100);
+SET @col_6 = repeat('l', 100);
+INSERT INTO tab2(col_1,col_2,col_3,col_4,col_5,col_6,col_7)
+VALUES (@col_1, at col_2, at col_3, at col_4, at cl_5, at col_6,7);
+SELECT pk,ST_AsText(linestring_key),ST_AsText(linestring_nokey)
+FROM tab1 ORDER BY pk;
+SELECT * FROM tab2 ORDER BY col_7;
+# stop the server
+[1(c)]: Rewrite into new checksum=none for all *.ibd file and ibdata1
+INSERT INTO tab1 (pk, linestring_key, linestring_nokey)
+VALUES (4, ST_GeomFromText('MULTIPOINT(0 0,5 5,10 10,20 20) '), ST_GeomFromText('MULTIPOINT(0 0,5 5,10 10,20 20) '));
+SET @col_1 = repeat('m', 5);
+SET @col_2 = repeat('n', 20);
+SET @col_3 = repeat('o', 100);
+SET @col_4 = repeat('p', 100);
+SET @col_5 = repeat('q', 100);
+SET @col_6 = repeat('r', 100);
+INSERT INTO tab2(col_1,col_2,col_3,col_4,col_5,col_6,col_7)
+VALUES (@col_1, at col_2, at col_3, at col_4, at cl_5, at col_6,8);
+SELECT pk,ST_AsText(linestring_key),ST_AsText(linestring_nokey)
+FROM tab1 ORDER BY pk;
+SELECT * FROM tab2 ORDER BY col_7;
+# stop the server
+[2]: Check the page type summary with shortform for tab1.ibd
+
+File::tab#.ibd
+================PAGE TYPE SUMMARY==============
+#PAGE_COUNT	PAGE_TYPE
+===============================================
+       #	Index page
+       #	Undo log page
+       #	Inode page
+       #	Insert buffer free list page
+       #	Freshly allocated page
+       #	Insert buffer bitmap
+       #	System page
+       #	Transaction system page
+       #	File Space Header
+       #	Extent descriptor page
+       #	BLOB page
+       #	Compressed BLOB page
+       #	Page compressed page
+       #	Page compressed encrypted page
+       #	Other type of page
+
+===============================================
+Additional information:
+Undo page type: # insert, # update, # other
+Undo page state: # active, # cached, # to_free, # to_purge, # prepared, # other
+index_id	#pages		#leaf_pages	#recs_per_page	#bytes_per_page
+#		#		#		#		#
+#		#		#		#		#
+#		#		#		#		#
+
+index_id	page_data_bytes_histgram(empty,...,oversized)
+#		#	#	#	#	#	#	#	#	#	#	#	#
+#		#	#	#	#	#	#	#	#	#	#	#	#
+#		#	#	#	#	#	#	#	#	#	#	#	#
+[3]: Check the page type summary with longform for tab1.ibd
+
+File::tab#.ibd
+================PAGE TYPE SUMMARY==============
+#PAGE_COUNT	PAGE_TYPE
+===============================================
+       #	Index page
+       #	Undo log page
+       #	Inode page
+       #	Insert buffer free list page
+       #	Freshly allocated page
+       #	Insert buffer bitmap
+       #	System page
+       #	Transaction system page
+       #	File Space Header
+       #	Extent descriptor page
+       #	BLOB page
+       #	Compressed BLOB page
+       #	Page compressed page
+       #	Page compressed encrypted page
+       #	Other type of page
+
+===============================================
+Additional information:
+Undo page type: # insert, # update, # other
+Undo page state: # active, # cached, # to_free, # to_purge, # prepared, # other
+index_id	#pages		#leaf_pages	#recs_per_page	#bytes_per_page
+#		#		#		#		#
+#		#		#		#		#
+#		#		#		#		#
+
+index_id	page_data_bytes_histgram(empty,...,oversized)
+#		#	#	#	#	#	#	#	#	#	#	#	#
+#		#	#	#	#	#	#	#	#	#	#	#	#
+#		#	#	#	#	#	#	#	#	#	#	#	#
+[4]: Page type dump for  with longform for tab1.ibd
+# Print the contents stored in dump.txt
+
+
+Filename::tab#.ibd
+==============================================================================
+	PAGE_NO		|		PAGE_TYPE			|	EXTRA INFO
+==============================================================================
+#::       #		|		File Space Header		|	-
+#::       #		|		Insert Buffer Bitmap		|	-
+#::       #		|		Inode page			|	-
+#::       #		|		Index page			|	index id=#, page level=#, No. of records=#, garbage=#, -
+#::       #		|		Index page			|	index id=#, page level=#, No. of records=#, garbage=#, -
+#::       #		|		Index page			|	index id=#, page level=#, No. of records=#, garbage=#, -
+#::       #		|		Freshly allocated page		|	-
+#::       #		|		Freshly allocated page		|	-
+# Variables used by page type dump for ibdata1
+
+Variables (--variable-name=value)
+and boolean options {FALSE|TRUE}  Value (after reading options)
+--------------------------------- ----------------------------------------
+verbose                           TRUE
+count                             FALSE
+start-page                        0
+end-page                          0
+page                              0
+strict-check                      crc32
+no-check                          FALSE
+allow-mismatches                  0
+write                             crc32
+page-type-summary                 FALSE
+page-type-dump                    MYSQLTEST_VARDIR/tmp/dump.txt
+per-page-details                  FALSE
+log                               (No default value)
+leaf                              FALSE
+merge                             0
+[5]: Page type dump for with shortform for tab1.ibd
+
+
+Filename::tab#.ibd
+==============================================================================
+	PAGE_NO		|		PAGE_TYPE			|	EXTRA INFO
+==============================================================================
+#::       #		|		File Space Header		|	-
+#::       #		|		Insert Buffer Bitmap		|	-
+#::       #		|		Inode page			|	-
+#::       #		|		Index page			|	index id=#, page level=#, No. of records=#, garbage=#, -
+#::       #		|		Index page			|	index id=#, page level=#, No. of records=#, garbage=#, -
+#::       #		|		Index page			|	index id=#, page level=#, No. of records=#, garbage=#, -
+#::       #		|		Freshly allocated page		|	-
+#::       #		|		Freshly allocated page		|	-
+[6]: check the valid lower bound values for option
+# allow-mismatches,page,start-page,end-page
+[9]: check the both short and long options "page" and "start-page" when
+# seek value is larger than file size.
+FOUND /Error: Unable to seek to necessary offset: Invalid argument/ in my_restart.err
+FOUND /Error: Unable to seek to necessary offset: Invalid argument/ in my_restart.err
+FOUND /Error: Unable to seek to necessary offset: Invalid argument/ in my_restart.err
+FOUND /Error: Unable to seek to necessary offset: Invalid argument/ in my_restart.err
+[34]: check the invalid upper bound values for options, allow-mismatches, end-page, start-page and page.
+# innochecksum will fail with error code: 1
+NOT FOUND /Incorrect unsigned integer value: '18446744073709551616'/ in my_restart.err
+NOT FOUND /Incorrect unsigned integer value: '18446744073709551616'/ in my_restart.err
+NOT FOUND /Incorrect unsigned integer value: '18446744073709551616'/ in my_restart.err
+NOT FOUND /Incorrect unsigned integer value: '18446744073709551616'/ in my_restart.err
+NOT FOUND /Incorrect unsigned integer value: '18446744073709551616'/ in my_restart.err
+NOT FOUND /Incorrect unsigned integer value: '18446744073709551616'/ in my_restart.err
+NOT FOUND /Incorrect unsigned integer value: '18446744073709551616'/ in my_restart.err
+NOT FOUND /Incorrect unsigned integer value: '18446744073709551616'/ in my_restart.err
+DROP TABLE tab1,tab2;
diff --git a/mysql-test/suite/innodb/t/innodb_zip_innochecksum.opt b/mysql-test/suite/innodb/t/innodb_zip_innochecksum.opt
new file mode 100644
index 00000000000..f8c8c9d247d
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_zip_innochecksum.opt
@@ -0,0 +1,4 @@
+--skip-innodb-doublewrite
+--innodb-file-per-table
+--innodb-file-format=Barracuda
+
diff --git a/mysql-test/suite/innodb/t/innodb_zip_innochecksum.test b/mysql-test/suite/innodb/t/innodb_zip_innochecksum.test
new file mode 100644
index 00000000000..63a4b418677
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_zip_innochecksum.test
@@ -0,0 +1,239 @@
+#************************************************************
+# WL6045:Improve Innochecksum
+#************************************************************
+--source include/innodb_page_size_small.inc
+--source include/no_valgrind_without_big.inc
+# Embedded server does not support crashing.
+--source include/not_embedded.inc
+
+# Avoid CrashReporter popup on Mac.
+--source include/not_crashrep.inc
+
+--echo # Set the environmental variables
+let MYSQLD_BASEDIR= `SELECT @@basedir`;
+let MYSQLD_DATADIR= `SELECT @@datadir`;
+let SEARCH_FILE= $MYSQLTEST_VARDIR/log/my_restart.err;
+call mtr.add_suppression("InnoDB: Unable to read tablespace .* page no .* into the buffer pool after 100 attempts");
+call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed");
+
+CREATE TABLE tab1(c1 INT PRIMARY KEY,c2 VARCHAR(20)) ENGINE=InnoDB;
+CREATE INDEX idx1 ON tab1(c2(10));
+INSERT INTO tab1 VALUES(1, 'Innochecksum InnoDB1');
+CREATE TABLE t1(id INT AUTO_INCREMENT PRIMARY KEY, msg VARCHAR(255)) ENGINE=INNODB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4;
+insert into t1 values(1,"i");
+insert into t1 values(2,"am");
+insert into t1 values(3,"compressed table");
+
+--echo # Shutdown the Server
+--source include/shutdown_mysqld.inc
+--echo # Server Default checksum = innodb
+
+#
+# Not repeatable with --parallel= >1
+#
+#--echo [1a]: check the innochecksum when file doesn't exists
+#--error 1
+#--exec $INNOCHECKSUM  $MYSQLD_DATADIR/test/aa.ibd 2> $SEARCH_FILE
+#let SEARCH_PATTERN= Error: $MYSQLD_DATADIR/test/aa.ibd cannot be found;
+#--source include/search_pattern_in_file.inc
+
+--echo [1b]: check the innochecksum without --strict-check
+--exec $INNOCHECKSUM  $MYSQLD_DATADIR/test/tab1.ibd
+
+--echo [2]: check the innochecksum with full form --strict-check=crc32
+--exec $INNOCHECKSUM  --strict-check=crc32 $MYSQLD_DATADIR/test/tab1.ibd
+
+--echo [3]: check the innochecksum with short form -C crc32
+--exec $INNOCHECKSUM  -C crc32 $MYSQLD_DATADIR/test/tab1.ibd
+
+--echo [4]: check the innochecksum with --no-check ignores algorithm check, warning is expected
+--error 1
+--exec $INNOCHECKSUM --no-check $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+let SEARCH_PATTERN= Error: --no-check must be associated with --write option.;
+--source include/search_pattern_in_file.inc
+
+--echo [5]: check the innochecksum with short form --no-check ignores algorithm check, warning is expected
+--error 1
+--exec $INNOCHECKSUM  -n $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+let SEARCH_PATTERN= Error: --no-check must be associated with --write option.;
+--source include/search_pattern_in_file.inc
+
+--echo [6]: check the innochecksum with full form strict-check & no-check , an error is expected
+--error 1
+--exec $INNOCHECKSUM --strict-check=innodb  --no-check $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+let SEARCH_PATTERN= Error: --strict-check option cannot be used together with --no-check option.;
+--source include/search_pattern_in_file.inc
+
+--echo [7]: check the innochecksum with short form strict-check & no-check , an error is expected
+--error 1
+--exec $INNOCHECKSUM -C innodb -n $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+let SEARCH_PATTERN= Error: --strict-check option cannot be used together with --no-check option.;
+--source include/search_pattern_in_file.inc
+
+--echo [8]: check the innochecksum with short & full form combination
+--echo # strict-check & no-check, an error is expected
+--error 1
+--exec $INNOCHECKSUM --strict-check=innodb -n $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+let SEARCH_PATTERN= Error: --strict-check option cannot be used together with --no-check option.;
+--source include/search_pattern_in_file.inc
+
+--echo [9]: check the innochecksum with full form --strict-check=innodb
+# Server Default checksum = crc32
+--exec $INNOCHECKSUM  --strict-check=innodb $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+
+--echo [10]: check the innochecksum with full form --strict-check=none
+--echo # when server Default checksum=crc32
+--exec $INNOCHECKSUM  --strict-check=none $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+
+--echo [11]: check the innochecksum with short form -C innodb
+--echo # when server Default checksum=crc32
+--exec $INNOCHECKSUM  -C innodb $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+
+--echo [12]: check the innochecksum with short form -C none
+--echo # when server Default checksum=crc32
+--exec $INNOCHECKSUM  -C none $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+
+--echo [13]: check strict-check with invalid values
+--error 1
+--exec $INNOCHECKSUM --strict-check=strict_innodb $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+let SEARCH_PATTERN= Error while setting value \'strict_innodb\' to \'strict-check\';
+--source include/search_pattern_in_file.inc
+
+--error 1
+--exec $INNOCHECKSUM -C strict_innodb $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+let SEARCH_PATTERN= Error while setting value \'strict_innodb\' to \'strict-check\';
+--source include/search_pattern_in_file.inc
+
+--error 1
+--exec $INNOCHECKSUM --strict-check=strict_crc32 $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+let SEARCH_PATTERN= Error while setting value \'strict_crc32\' to \'strict-check\';
+--source include/search_pattern_in_file.inc
+
+--error 1
+--exec $INNOCHECKSUM -C strict_crc32 $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+let SEARCH_PATTERN= Error while setting value \'strict_crc32\' to \'strict-check\';
+--source include/search_pattern_in_file.inc
+
+--error 1
+--exec $INNOCHECKSUM --strict-check=strict_none $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+let SEARCH_PATTERN= Error while setting value \'strict_none\' to \'strict-check\';
+--source include/search_pattern_in_file.inc
+
+--error 1
+--exec $INNOCHECKSUM -C strict_none $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+let SEARCH_PATTERN= Error while setting value \'strict_none\' to \'strict-check\';
+--source include/search_pattern_in_file.inc
+
+--error 1
+--exec $INNOCHECKSUM --strict-check=InnoBD $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+let SEARCH_PATTERN= Error while setting value \'InnoBD\' to \'strict-check\';
+--source include/search_pattern_in_file.inc
+
+--error 1
+--exec $INNOCHECKSUM -C InnoBD $MYSQLD_DATADIR/test/tab1.ibd 2>$SEARCH_FILE
+let SEARCH_PATTERN= Error while setting value \'InnoBD\' to \'strict-check\';
+--source include/search_pattern_in_file.inc
+
+--error 1
+--exec $INNOCHECKSUM --strict-check=crc $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+let SEARCH_PATTERN= Error while setting value \'crc\' to \'strict-check\';
+--source include/search_pattern_in_file.inc
+
+--error 1
+--exec $INNOCHECKSUM --strict-check=no $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+let SEARCH_PATTERN= Error while setting value \'no\' to \'strict-check\';
+--source include/search_pattern_in_file.inc
+
+--echo [14a]: when server default checksum=crc32 rewrite new checksum=crc32 with innochecksum
+--echo # Also check the long form of write option.
+--exec $INNOCHECKSUM --strict-check=crc32 --write=crc32 $MYSQLD_DATADIR/test/tab1.ibd
+--exec $INNOCHECKSUM --strict-check=crc32 --write=crc32 $MYSQLD_DATADIR/test/t1.ibd
+# Rewrite done, verify with --strict-check=crc32
+--exec $INNOCHECKSUM --strict-check=crc32 $MYSQLD_DATADIR/test/tab1.ibd
+--exec $INNOCHECKSUM --strict-check=crc32 $MYSQLD_DATADIR/test/t1.ibd
+
+--echo [14b]: when server default checksum=crc32 rewrite new checksum=innodb with innochecksum
+--echo # Also check the long form of write option.
+--exec $INNOCHECKSUM --no-check --write=innodb $MYSQLD_DATADIR/test/tab1.ibd
+--exec $INNOCHECKSUM --strict-check=crc32 --write=innodb $MYSQLD_DATADIR/test/t1.ibd
+# Rewrite done, verify with --strict-check=innodb
+--exec $INNOCHECKSUM --strict-check=innodb $MYSQLD_DATADIR/test/tab1.ibd
+
+--echo # start the server with innodb_checksum_algorithm=InnoDB
+--let $restart_parameters= --innodb_checksum_algorithm=innodb
+--source include/start_mysqld.inc
+
+INSERT INTO tab1 VALUES(2, 'Innochecksum CRC32');
+SELECT c1,c2 FROM tab1 order by c1,c2;
+
+--echo # Stop the server
+--source include/shutdown_mysqld.inc
+
+--echo [15]: when server default checksum=crc32 rewrite new checksum=none with innochecksum
+--echo # Also check the short form of write option.
+--exec $INNOCHECKSUM --no-check -w none $MYSQLD_DATADIR/test/tab1.ibd
+--exec $INNOCHECKSUM --no-check -w none $MYSQLD_DATADIR/test/t1.ibd
+# Rewrite done, verify with --strict-check=none
+--exec $INNOCHECKSUM --strict-check=none $MYSQLD_DATADIR/test/tab1.ibd
+--exec $INNOCHECKSUM --strict-check=none $MYSQLD_DATADIR/test/t1.ibd
+
+--echo # Start the server with checksum algorithm=none
+--let $restart_parameters= --innodb_checksum_algorithm=none
+--source include/start_mysqld.inc
+
+INSERT INTO tab1 VALUES(3, 'Innochecksum None');
+SELECT c1,c2 FROM tab1 order by c1,c2;
+DROP TABLE t1;
+
+--echo # Stop the server
+--source include/shutdown_mysqld.inc
+
+--echo [16]: rewrite into new checksum=crc32 with innochecksum
+--exec $INNOCHECKSUM --no-check --write=crc32 $MYSQLD_DATADIR/test/tab1.ibd
+
+--echo # Restart the DB server with  innodb_checksum_algorithm=crc32
+--let $restart_parameters= --innodb_checksum_algorithm=crc32
+--source include/start_mysqld.inc
+
+SELECT * FROM tab1;
+DELETE FROM tab1 where c1=3;
+SELECT c1,c2 FROM tab1 order by c1,c2;
+
+--echo # Stop server
+--source include/shutdown_mysqld.inc
+
+--echo [17]: rewrite into new checksum=InnoDB
+--exec $INNOCHECKSUM --no-check --write=InnoDB $MYSQLD_DATADIR/test/tab1.ibd
+
+--echo # Restart the DB server with innodb_checksum_algorithm=InnoDB
+--let $restart_parameters= --innodb_checksum_algorithm=innodb
+--source include/start_mysqld.inc
+
+DELETE FROM tab1 where c1=2;
+SELECT * FROM tab1;
+
+--echo # Stop server
+--source include/shutdown_mysqld.inc
+
+--echo [18]:check Innochecksum with invalid write options
+--error 1
+--exec $INNOCHECKSUM --no-check --write=strict_crc32 $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+let SEARCH_PATTERN=Error while setting value \'strict_crc32\' to \'write\';
+--source include/search_pattern_in_file.inc
+
+--error 1
+--exec $INNOCHECKSUM --no-check --write=strict_innodb $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+let SEARCH_PATTERN=Error while setting value \'strict_innodb\' to \'write\';
+--source include/search_pattern_in_file.inc
+
+--error 1
+--exec $INNOCHECKSUM --no-check --write=crc23 $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+let SEARCH_PATTERN=Error while setting value \'crc23\' to \'write\';
+--source include/search_pattern_in_file.inc
+--remove_file $SEARCH_FILE
+
+# Cleanup
+--let $restart_parameters=
+--source include/start_mysqld.inc
+
+DROP TABLE tab1;
diff --git a/mysql-test/suite/innodb/t/innodb_zip_innochecksum2.opt b/mysql-test/suite/innodb/t/innodb_zip_innochecksum2.opt
new file mode 100644
index 00000000000..39d5c6d577c
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_zip_innochecksum2.opt
@@ -0,0 +1,4 @@
+--skip-innodb-doublewrite
+--innodb-file-per-table
+--innodb-file-format=Barracuda
+--innodb-change-buffering=none
diff --git a/mysql-test/suite/innodb/t/innodb_zip_innochecksum2.test b/mysql-test/suite/innodb/t/innodb_zip_innochecksum2.test
new file mode 100644
index 00000000000..330bb81ba75
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_zip_innochecksum2.test
@@ -0,0 +1,118 @@
+#************************************************************
+# WL6045:Improve Innochecksum
+#************************************************************
+--source include/innodb_page_size_small.inc
+--source include/have_debug.inc
+--source include/no_valgrind_without_big.inc
+# Avoid CrashReporter popup on Mac.
+--source include/not_crashrep.inc
+
+--source include/not_embedded.inc
+-- source include/big_test.inc
+
+--disable_query_log
+# This warning occurs due to small buffer pool size(i.e. 8MB). It doesn't occur
+# with --mysqld=--innodb_buffer_pool_size=10MB
+call mtr.add_suppression("\\[Warning\\] InnoDB: Difficult to find free blocks in the buffer pool.*");
+--enable_query_log
+let MYSQLD_BASEDIR= `SELECT @@basedir`;
+let MYSQLD_DATADIR= `SELECT @@datadir`;
+let SEARCH_FILE= $MYSQLTEST_VARDIR/log/my_restart.err;
+
+SET GLOBAL innodb_compression_level=0;
+SELECT @@innodb_compression_level;
+
+CREATE TABLE t1 (j LONGBLOB) ENGINE = InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1;
+INSERT INTO t1 VALUES (repeat('abcdefghijklmnopqrstuvwxyz',200));
+let $i=10;
+while ($i > 0) {
+  INSERT INTO t1 SELECT * from t1;
+  dec $i;
+}
+
+--echo # stop the server
+--source include/shutdown_mysqld.inc
+
+# Page_type_dump for t1
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--exec $INNOCHECKSUM -v --page-type-dump $MYSQLTEST_VARDIR/tmp/dump.txt $MYSQLD_DATADIR/test/t1.ibd
+--file_exists $MYSQLTEST_VARDIR/tmp/dump.txt
+--remove_file $MYSQLTEST_VARDIR/tmp/dump.txt
+
+--echo [1]:# check the both short and long options for "help"
+--exec $INNOCHECKSUM --help $MYSQLD_DATADIR/test/t1.ibd > $MYSQLTEST_VARDIR/tmp/help_output_long.txt
+--exec $INNOCHECKSUM -I $MYSQLD_DATADIR/test/t1.ibd > $MYSQLTEST_VARDIR/tmp/help_output_short.txt
+--diff_files $MYSQLTEST_VARDIR/tmp/help_output_long.txt $MYSQLTEST_VARDIR/tmp/help_output_short.txt
+
+--echo [2]:# Run the innochecksum when file isn't provided.
+--echo # It will print the innochecksum usage similar to --help option.
+--error 1
+--exec $INNOCHECKSUM > $MYSQLTEST_VARDIR/tmp/usage.txt
+--diff_files $MYSQLTEST_VARDIR/tmp/help_output_long.txt $MYSQLTEST_VARDIR/tmp/usage.txt
+--remove_file $MYSQLTEST_VARDIR/tmp/usage.txt
+
+perl;
+use strict;
+use warnings;
+use File::Copy;
+my $dir = $ENV{'MYSQLTEST_VARDIR'};
+my $file= 'help_output_long.txt';
+# open file in write mode
+open IN_FILE,"<", "$dir/tmp/$file" or die $!;
+open OUT_FILE, ">", "$dir/tmp/tmpfile" or die $!;
+while(<IN_FILE>) {
+ unless ($_=~ /^debug.*$/ || $_=~ /\-#, \-\-debug.*$/ || $_=~ /http:.*html/) {
+    $_=~ s/^\S*innochecksum.+Ver.+[0-9]*\.[0-9]*\.[0-9]*.+$/innochecksum Ver #.#.#/g;
+    $_=~ s/(Copyright\s\(c\))\s([0-9]*),\s([0-9]*)(.*)/$1 YEAR, YEAR $4/g;
+    $_=~ s/Usage:.*\[-c/Usage: innochecksum [-c/g;
+    print OUT_FILE $_;
+ }
+}
+close(IN_FILE);
+close(OUT_FILE);
+# move the new content from tmp file to the orginal file.
+move ("$dir/tmp/tmpfile", "$dir/tmp/$file");
+EOF
+
+--cat_file $MYSQLTEST_VARDIR/tmp/help_output_long.txt
+--remove_file $MYSQLTEST_VARDIR/tmp/help_output_long.txt
+--remove_file $MYSQLTEST_VARDIR/tmp/help_output_short.txt
+
+--echo [3]:# check the both short and long options for "count" and exit
+--replace_regex /[0-9]+/#/
+--exec $INNOCHECKSUM --count $MYSQLD_DATADIR/test/t1.ibd
+--replace_regex /[0-9]+/#/
+--exec $INNOCHECKSUM -c $MYSQLD_DATADIR/test/t1.ibd
+
+--echo [4]:# Print the version of innochecksum and exit
+--replace_regex /.*innochecksum.*Ver.*[0-9]*.[0-9]*.[0-9]*.*/innochecksum Ver #.#.#/
+--exec $INNOCHECKSUM -V $MYSQLD_DATADIR/test/t1.ibd
+
+--echo # Restart the DB server
+--source include/start_mysqld.inc
+
+DROP TABLE t1;
+
+--echo [5]:# Check the innochecksum for compressed table t1 with different key_block_size
+--echo # Test for KEY_BLOCK_SIZE=1
+--let $size=1
+--source ../include/innodb-wl6045.inc
+
+--echo # Test for KEY_BLOCK_SIZE=2
+--let $size=2
+--source ../include/innodb-wl6045.inc
+
+--echo # Test for for KEY_BLOCK_SIZE=4
+--let $size=4
+--source ../include/innodb-wl6045.inc
+
+set innodb_strict_mode=off;
+--echo # Test for for KEY_BLOCK_SIZE=8
+--let $size=8
+--source ../include/innodb-wl6045.inc
+
+set innodb_strict_mode=off;
+--echo # Test for KEY_BLOCK_SIZE=16
+--let $size=16
+--source ../include/innodb-wl6045.inc
+--echo # Test[5] completed
diff --git a/mysql-test/suite/innodb/t/innodb_zip_innochecksum3.opt b/mysql-test/suite/innodb/t/innodb_zip_innochecksum3.opt
new file mode 100644
index 00000000000..828a7cd67c8
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_zip_innochecksum3.opt
@@ -0,0 +1,2 @@
+--innodb-file-per-table
+--innodb-file-format=Barracuda
diff --git a/mysql-test/suite/innodb/t/innodb_zip_innochecksum3.test b/mysql-test/suite/innodb/t/innodb_zip_innochecksum3.test
new file mode 100644
index 00000000000..dab10dcc997
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_zip_innochecksum3.test
@@ -0,0 +1,406 @@
+#************************************************************
+# WL6045:Improve Innochecksum
+#************************************************************
+--source include/innodb_page_size_small.inc
+
+--source include/no_valgrind_without_big.inc
+
+# Embedded server does not support crashing.
+--source include/not_embedded.inc
+
+# Avoid CrashReporter popup on Mac.
+--source include/not_crashrep.inc
+
+--echo # Set the environmental variables
+let MYSQLD_BASEDIR= `SELECT @@basedir`;
+let MYSQLD_DATADIR= `SELECT @@datadir`;
+let SEARCH_FILE= $MYSQLTEST_VARDIR/log/my_restart.err;
+
+call mtr.add_suppression("InnoDB: Unable to read tablespace .* page no .* into the buffer pool after 100 attempts");
+call mtr.add_suppression("InnoDB: innodb_checksum_algorithm is set to.*");
+
+--echo [1]: Further Test are for rewrite checksum (innodb|crc32|none) for all ibd file & start the server.
+
+CREATE TABLE tab1 (pk INTEGER NOT NULL PRIMARY KEY,
+linestring_key GEOMETRY NOT NULL,
+linestring_nokey GEOMETRY NOT NULL)
+ENGINE=InnoDB ;
+
+INSERT INTO tab1 (pk, linestring_key, linestring_nokey)
+VALUES (1, ST_GeomFromText('POINT(10 10) '), ST_GeomFromText('POINT(10 10) '));
+
+CREATE INDEX linestring_index ON tab1(linestring_nokey(5));
+ALTER TABLE tab1 ADD  KEY (linestring_key(5));
+
+--echo # create a compressed table
+CREATE TABLE tab2(col_1 CHAR (255) ,
+col_2 VARCHAR (255), col_3 longtext,
+col_4 longtext,col_5 longtext,
+col_6 longtext , col_7 int )
+engine = innodb row_format=compressed key_block_size=4;
+
+CREATE INDEX idx1 ON tab2(col_3(10));
+CREATE INDEX idx2 ON tab2(col_4(10));
+CREATE INDEX idx3 ON tab2(col_5(10));
+
+# load the with repeat function
+SET @col_1 = repeat('a', 5);
+SET @col_2 = repeat('b', 20);
+SET @col_3 = repeat('c', 100);
+SET @col_4 = repeat('d', 100);
+SET @col_5 = repeat('e', 100);
+SET @col_6 = repeat('f', 100);
+
+# insert 5 records
+let $i = 5;
+while ($i) {
+ eval INSERT INTO tab2(col_1,col_2,col_3,col_4,col_5,col_6,col_7)
+ VALUES (@col_1, at col_2, at col_3, at col_4, at cl_5, at col_6,$i);
+ dec $i;
+}
+
+--disable_result_log
+SELECT * FROM tab2 ORDER BY col_7;
+
+--echo # stop the server
+--source include/shutdown_mysqld.inc
+
+--echo [1(a)]: Rewrite into new checksum=InnoDB for all *.ibd file and ibdata1
+--exec $INNOCHECKSUM --write=InnoDB $MYSQLD_DATADIR/test/tab1.ibd
+--exec $INNOCHECKSUM --write=InnoDB $MYSQLD_DATADIR/test/tab2.ibd
+--exec $INNOCHECKSUM --write=InnoDB $MYSQLD_DATADIR/ibdata1
+perl;
+foreach (glob("$ENV{MYSQLD_DATADIR}/*/*.ibd")) {
+	system("$ENV{INNOCHECKSUM} --no-check --write=InnoDB $_")
+}
+EOF
+
+--echo : start the server with innodb_checksum_algorithm=strict_innodb
+--let $restart_parameters= --innodb_checksum_algorithm=strict_innodb
+--source include/start_mysqld.inc
+
+INSERT INTO tab1 (pk, linestring_key, linestring_nokey)
+VALUES (2, ST_GeomFromText('LINESTRING(10 10,20 20,30 30)'), ST_GeomFromText('LINESTRING(10 10,20 20,30 30)'));
+
+# load the with repeat function
+SET @col_1 = repeat('a', 5);
+SET @col_2 = repeat('b', 20);
+SET @col_3 = repeat('c', 100);
+SET @col_4 = repeat('d', 100);
+SET @col_5 = repeat('e', 100);
+SET @col_6 = repeat('f', 100);
+
+# check the table status is GOOD with DML
+let $i = 6;
+eval INSERT INTO tab2(col_1,col_2,col_3,col_4,col_5,col_6,col_7)
+VALUES (@col_1, at col_2, at col_3, at col_4, at cl_5, at col_6,$i);
+
+-- disable_result_log
+SELECT pk,ST_AsText(linestring_key),ST_AsText(linestring_nokey)
+FROM tab1 ORDER BY pk;
+
+-- disable_result_log
+SELECT * FROM tab2 ORDER BY col_7;
+
+--echo # stop the server
+--source include/shutdown_mysqld.inc
+
+--echo [1(b)]: Rewrite into new checksum=crc32 for all *.ibd file and ibdata1
+--exec $INNOCHECKSUM  --write=CRC32 $MYSQLD_DATADIR/test/tab1.ibd
+--exec $INNOCHECKSUM  --write=CRC32 $MYSQLD_DATADIR/test/tab2.ibd
+--exec $INNOCHECKSUM  --write=CRC32 $MYSQLD_DATADIR/ibdata1
+perl;
+foreach (glob("$ENV{MYSQLD_DATADIR}/*/*.ibd")) {
+	system("$ENV{INNOCHECKSUM} --no-check --write=crc32 $_")
+}
+EOF
+
+--echo # start the server with innodb_checksum_algorithm=strict_crc32
+--let $restart_parameters= --innodb_checksum_algorithm=strict_crc32
+--source include/start_mysqld.inc
+
+# check the table status is GOOD with DML
+INSERT INTO tab1 (pk, linestring_key, linestring_nokey)
+VALUES (3, ST_GeomFromText('POLYGON((0 0,5 5,10 10,15 15,0 0),(10 10,20 20,30 30,40 40,10 10))'),
+ST_GeomFromText('POLYGON((0 0,5 5,10 10,15 15,0 0),(10 10,20 20,30 30,40 40,10 10))'));
+
+# load the with repeat function
+SET @col_1 = repeat('g', 5);
+SET @col_2 = repeat('h', 20);
+SET @col_3 = repeat('i', 100);
+SET @col_4 = repeat('j', 100);
+SET @col_5 = repeat('k', 100);
+SET @col_6 = repeat('l', 100);
+
+# check the table status is GOOD with DML
+let $i = 7;
+eval INSERT INTO tab2(col_1,col_2,col_3,col_4,col_5,col_6,col_7)
+VALUES (@col_1, at col_2, at col_3, at col_4, at cl_5, at col_6,$i);
+
+# check the records from table
+-- disable_result_log
+SELECT pk,ST_AsText(linestring_key),ST_AsText(linestring_nokey)
+FROM tab1 ORDER BY pk;
+
+-- disable_result_log
+SELECT * FROM tab2 ORDER BY col_7;
+
+--echo # stop the server
+--source include/shutdown_mysqld.inc
+
+--echo [1(c)]: Rewrite into new checksum=none for all *.ibd file and ibdata1
+--exec $INNOCHECKSUM --write=none  $MYSQLD_DATADIR/test/tab1.ibd
+--exec $INNOCHECKSUM --write=none  $MYSQLD_DATADIR/test/tab2.ibd
+--exec $INNOCHECKSUM --write=none $MYSQLD_DATADIR/ibdata1
+perl;
+foreach (glob("$ENV{MYSQLD_DATADIR}/undo*")) {
+	system("$ENV{INNOCHECKSUM} --no-check --write=NONE $_")
+}
+foreach (glob("$ENV{MYSQLD_DATADIR}/*/*.ibd")) {
+	system("$ENV{INNOCHECKSUM} --no-check --write=NONE $_")
+}
+EOF
+
+--let $restart_parameters= --innodb_checksum_algorithm=strict_none
+--source include/start_mysqld.inc
+--let $restart_parameters=
+# check the table status is GOOD with DML
+INSERT INTO tab1 (pk, linestring_key, linestring_nokey)
+VALUES (4, ST_GeomFromText('MULTIPOINT(0 0,5 5,10 10,20 20) '), ST_GeomFromText('MULTIPOINT(0 0,5 5,10 10,20 20) '));
+
+# load the with repeat function
+SET @col_1 = repeat('m', 5);
+SET @col_2 = repeat('n', 20);
+SET @col_3 = repeat('o', 100);
+SET @col_4 = repeat('p', 100);
+SET @col_5 = repeat('q', 100);
+SET @col_6 = repeat('r', 100);
+
+# check the table status is GOOD with DML
+let $i = 8;
+eval INSERT INTO tab2(col_1,col_2,col_3,col_4,col_5,col_6,col_7)
+VALUES (@col_1, at col_2, at col_3, at col_4, at cl_5, at col_6,$i);
+
+# check the records from table
+-- disable_result_log
+SELECT pk,ST_AsText(linestring_key),ST_AsText(linestring_nokey)
+FROM tab1 ORDER BY pk;
+
+--disable_result_log
+SELECT * FROM tab2 ORDER BY col_7;
+--enable_result_log
+
+--echo # stop the server
+--source include/shutdown_mysqld.inc
+
+--echo [2]: Check the page type summary with shortform for tab1.ibd
+--replace_regex /File.*.ibd/File::tab1.ibd/ /[0-9]+/#/
+--exec $INNOCHECKSUM -S $MYSQLD_DATADIR/test/tab1.ibd 2>$MYSQLTEST_VARDIR/tmp/page_summary_short.txt
+
+--echo [3]: Check the page type summary with longform for tab1.ibd
+--replace_regex /File.*.ibd/File::tab1.ibd/ /[0-9]+/#/
+--exec $INNOCHECKSUM --page-type-summary  $MYSQLD_DATADIR/test/tab1.ibd 2>$MYSQLTEST_VARDIR/tmp/page_summary_long.txt
+
+--remove_file $MYSQLTEST_VARDIR/tmp/page_summary_short.txt
+--remove_file $MYSQLTEST_VARDIR/tmp/page_summary_long.txt
+--echo [4]: Page type dump for  with longform for tab1.ibd
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--exec $INNOCHECKSUM --page-type-dump $MYSQLTEST_VARDIR/tmp/dump.txt $MYSQLD_DATADIR/test/tab1.ibd
+
+perl;
+use strict;
+use warnings;
+use File::Copy;
+my $dir = $ENV{'MYSQLTEST_VARDIR'};
+opendir(DIR, $dir) or die $!;
+my $file= 'dump.txt';
+# open file in write mode
+open IN_FILE,"<", "$dir/tmp/$file" or die $!;
+open OUT_FILE, ">", "$dir/tmp/innochecksum_3_tempfile" or die $!;
+while(<IN_FILE>)
+{
+ # Replace the intergers to # and complete file path to file name only.
+ $_=~ s/Filename.+/Filename::tab1.ibd/g;
+ $_=~ s/\d+/#/g;
+ print OUT_FILE $_;
+}
+close(IN_FILE);
+close(OUT_FILE);
+# move the new content from tmp file to the orginal file.
+move ("$dir/tmp/innochecksum_3_tempfile", "$dir/tmp/$file");
+closedir(DIR);
+EOF
+
+--echo # Print the contents stored in dump.txt
+cat_file $MYSQLTEST_VARDIR/tmp/dump.txt;
+--remove_file $MYSQLTEST_VARDIR/tmp/dump.txt
+
+--echo # Variables used by page type dump for ibdata1
+--exec $INNOCHECKSUM -v --page-type-dump $MYSQLTEST_VARDIR/tmp/dump.txt $MYSQLD_DATADIR/ibdata1 > $MYSQLTEST_VARDIR/tmp/page_verbose_summary.txt
+
+--file_exists $MYSQLTEST_VARDIR/tmp/dump.txt
+--remove_file $MYSQLTEST_VARDIR/tmp/dump.txt
+
+perl;
+use strict;
+use warnings;
+use File::Copy;
+my $dir = $ENV{'MYSQLTEST_VARDIR'};
+opendir(DIR, $dir) or die $!;
+my $file= 'page_verbose_summary.txt';
+# open file in write mode
+open IN_FILE,"<", "$dir/tmp/$file" or die $!;
+open OUT_FILE, ">", "$dir/tmp/innochecksum_3_tempfile" or die $!;
+while(<IN_FILE>)
+{
+ # Replace complete file path to file name only.
+ $_=~ s/$dir/MYSQLTEST_VARDIR/;
+ # Remove debug option, which is not in all builds
+ next if (/debug/);
+ print OUT_FILE $_;
+}
+close(IN_FILE);
+close(OUT_FILE);
+# move the new content from tmp file to the orginal file.
+move ("$dir/tmp/innochecksum_3_tempfile", "$dir/tmp/$file");
+closedir(DIR);
+EOF
+
+cat_file $MYSQLTEST_VARDIR/tmp/page_verbose_summary.txt;
+--remove_file $MYSQLTEST_VARDIR/tmp/page_verbose_summary.txt
+
+--echo [5]: Page type dump for with shortform for tab1.ibd
+--exec $INNOCHECKSUM -D $MYSQLTEST_VARDIR/tmp/dump.txt $MYSQLD_DATADIR/test/tab1.ibd
+
+perl;
+use strict;
+use warnings;
+use File::Copy;
+my $dir = $ENV{'MYSQLTEST_VARDIR'};
+opendir(DIR, $dir) or die $!;
+my $file= 'dump.txt';
+# open file in write mode
+open IN_FILE,"<", "$dir/tmp/$file" or die $!;
+open OUT_FILE, ">", "$dir/tmp/innochecksum_3_tempfile" or die $!;
+while(<IN_FILE>)
+{
+ # Replace the intergers to # and complete file path to file name only.
+ $_=~ s/Filename.+/Filename::tab1.ibd/g;
+ $_=~ s/\d+/#/g;
+ print OUT_FILE $_;
+}
+close(IN_FILE);
+close(OUT_FILE);
+# move the new content from tmp file to the orginal file.
+move ("$dir/tmp/innochecksum_3_tempfile", "$dir/tmp/$file");
+closedir(DIR);
+EOF
+
+# Print the contents stored in dump.txt
+cat_file $MYSQLTEST_VARDIR/tmp/dump.txt;
+--remove_file $MYSQLTEST_VARDIR/tmp/dump.txt
+
+--echo [6]: check the valid lower bound values for option
+--echo # allow-mismatches,page,start-page,end-page
+--exec $INNOCHECKSUM  --allow-mismatches=0 $MYSQLD_DATADIR/test/tab1.ibd
+--exec $INNOCHECKSUM  -a 0 $MYSQLD_DATADIR/test/tab1.ibd
+--exec $INNOCHECKSUM  --page=0 $MYSQLD_DATADIR/test/tab1.ibd
+--exec $INNOCHECKSUM  -p 0 $MYSQLD_DATADIR/test/tab1.ibd
+--exec $INNOCHECKSUM  --start-page=0 $MYSQLD_DATADIR/test/tab1.ibd
+--exec $INNOCHECKSUM  -s 0 $MYSQLD_DATADIR/test/tab1.ibd
+--exec $INNOCHECKSUM  --end-page=0 $MYSQLD_DATADIR/test/tab1.ibd
+--exec $INNOCHECKSUM  -e 0 $MYSQLD_DATADIR/test/tab1.ibd
+
+#
+# These produce now errors
+#
+#--echo [7]: check the negative values for option
+#--echo # allow-mismatches,page,start-page,end-page.
+#--echo # They will reset to zero for negative values.
+#--echo # check the invalid lower bound values
+#--exec $INNOCHECKSUM  --allow-mismatches=-1 $MYSQLD_DATADIR/test/tab1.ibd
+#--exec $INNOCHECKSUM  -a -1 $MYSQLD_DATADIR/test/tab1.ibd
+#--exec $INNOCHECKSUM  --page=-1 $MYSQLD_DATADIR/test/tab1.ibd
+#--exec $INNOCHECKSUM  -p -1 $MYSQLD_DATADIR/test/tab1.ibd
+#--exec $INNOCHECKSUM  --start-page=-1 $MYSQLD_DATADIR/test/tab1.ibd
+#--exec $INNOCHECKSUM  -s -1 $MYSQLD_DATADIR/test/tab1.ibd
+#--exec $INNOCHECKSUM  --end-page=-1 $MYSQLD_DATADIR/test/tab1.ibd
+#--exec $INNOCHECKSUM  -e -1 $MYSQLD_DATADIR/test/tab1.ibd
+#
+#--echo [8]: check the valid upper bound values for
+#--echo # both short and long options "allow-mismatches" and "end-page"
+#
+#--exec $INNOCHECKSUM  --allow-mismatches=18446744073709551615 $MYSQLD_DATADIR/test/tab1.ibd
+#--exec $INNOCHECKSUM  -a 18446744073709551615 $MYSQLD_DATADIR/test/tab1.ibd
+#--exec $INNOCHECKSUM  --end-page=18446744073709551615 $MYSQLD_DATADIR/test/tab1.ibd
+#--exec $INNOCHECKSUM  -e 18446744073709551615 $MYSQLD_DATADIR/test/tab1.ibd
+
+--echo [9]: check the both short and long options "page" and "start-page" when
+--echo # seek value is larger than file size.
+--error 1
+--exec $INNOCHECKSUM --page=18446744073709551615 $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+let SEARCH_PATTERN= Error: Unable to seek to necessary offset: Invalid argument;
+--source include/search_pattern_in_file.inc
+
+--error 1
+--exec $INNOCHECKSUM -p 18446744073709551615 $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+let SEARCH_PATTERN= Error: Unable to seek to necessary offset: Invalid argument;
+--source include/search_pattern_in_file.inc
+
+--error 1
+--exec $INNOCHECKSUM --start-page=18446744073709551615 $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+let SEARCH_PATTERN= Error: Unable to seek to necessary offset: Invalid argument;
+--source include/search_pattern_in_file.inc
+
+--error 1
+--exec $INNOCHECKSUM -s 18446744073709551615 $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+let SEARCH_PATTERN= Error: Unable to seek to necessary offset: Invalid argument;
+--source include/search_pattern_in_file.inc
+
+--echo [34]: check the invalid upper bound values for options, allow-mismatches, end-page, start-page and page.
+--echo # innochecksum will fail with error code: 1
+--error 1
+--exec $INNOCHECKSUM --allow-mismatches=18446744073709551616 $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+let SEARCH_PATTERN= Incorrect unsigned integer value: '18446744073709551616';
+--source include/search_pattern_in_file.inc
+
+--error 1
+--exec $INNOCHECKSUM -a 18446744073709551616 $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+let SEARCH_PATTERN= Incorrect unsigned integer value: '18446744073709551616';
+--source include/search_pattern_in_file.inc
+
+--error 1
+--exec $INNOCHECKSUM --end-page=18446744073709551616 $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+let SEARCH_PATTERN= Incorrect unsigned integer value: '18446744073709551616';
+--source include/search_pattern_in_file.inc
+
+--error 1
+--exec $INNOCHECKSUM -e 18446744073709551616 $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+let SEARCH_PATTERN= Incorrect unsigned integer value: '18446744073709551616';
+--source include/search_pattern_in_file.inc
+
+--error 1
+--exec $INNOCHECKSUM --page=18446744073709551616 $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+let SEARCH_PATTERN= Incorrect unsigned integer value: '18446744073709551616';
+--source include/search_pattern_in_file.inc
+
+--error 1
+--exec $INNOCHECKSUM -p 18446744073709551616 $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+let SEARCH_PATTERN= Incorrect unsigned integer value: '18446744073709551616';
+--source include/search_pattern_in_file.inc
+
+--error 1
+--exec $INNOCHECKSUM --start-page=18446744073709551616 $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+let SEARCH_PATTERN= Incorrect unsigned integer value: '18446744073709551616';
+--source include/search_pattern_in_file.inc
+
+--error 1
+--exec $INNOCHECKSUM -s 18446744073709551616 $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
+let SEARCH_PATTERN= Incorrect unsigned integer value: '18446744073709551616';
+--source include/search_pattern_in_file.inc
+--remove_file $SEARCH_FILE
+
+# Cleanup
+--source include/start_mysqld.inc
+
+DROP TABLE tab1,tab2;
diff --git a/storage/innobase/include/page0size.h b/storage/innobase/include/page0size.h
new file mode 100644
index 00000000000..b1e1254bfc5
--- /dev/null
+++ b/storage/innobase/include/page0size.h
@@ -0,0 +1,200 @@
+/*****************************************************************************
+
+Copyright (c) 2013, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2017, MariaDB Corporation.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
+
+*****************************************************************************/
+
+/**************************************************//**
+ at file include/page0size.h
+A class describing a page size.
+
+Created Nov 14, 2013 Vasil Dimov
+*******************************************************/
+
+#ifndef page0size_t
+#define page0size_t
+
+#include "univ.i"
+#include "fsp0types.h"
+
+#define FIELD_REF_SIZE 20
+
+/** A BLOB field reference full of zero, for use in assertions and
+tests.Initially, BLOB field references are set to zero, in
+dtuple_convert_big_rec(). */
+extern const byte field_ref_zero[FIELD_REF_SIZE];
+
+#define PAGE_SIZE_T_SIZE_BITS	17
+
+/** Page size descriptor. Contains the physical and logical page size, as well
+as whether the page is compressed or not. */
+class page_size_t {
+public:
+	/** Constructor from (physical, logical, is_compressed).
+	@param[in]	physical	physical (on-disk/zipped) page size
+	@param[in]	logical		logical (in-memory/unzipped) page size
+	@param[in]	is_compressed	whether the page is compressed */
+	page_size_t(ulint physical, ulint logical, bool is_compressed)
+	{
+		if (physical == 0) {
+			physical = UNIV_PAGE_SIZE_ORIG;
+		}
+		if (logical == 0) {
+			logical = UNIV_PAGE_SIZE_ORIG;
+		}
+
+		m_physical = static_cast<unsigned>(physical);
+		m_logical = static_cast<unsigned>(logical);
+		m_is_compressed = static_cast<unsigned>(is_compressed);
+
+		ut_ad(physical <= (1 << PAGE_SIZE_T_SIZE_BITS));
+		ut_ad(logical <= (1 << PAGE_SIZE_T_SIZE_BITS));
+
+		ut_ad(ut_is_2pow(physical));
+		ut_ad(ut_is_2pow(logical));
+
+		ut_ad(logical <= UNIV_PAGE_SIZE_MAX);
+		ut_ad(logical >= physical);
+		ut_ad(!is_compressed || physical <= UNIV_ZIP_SIZE_MAX);
+	}
+
+	/** Constructor from (fsp_flags).
+	@param[in]	fsp_flags	filespace flags */
+	explicit page_size_t(ulint fsp_flags)
+	{
+		ulint	ssize = FSP_FLAGS_GET_PAGE_SSIZE(fsp_flags);
+
+		/* If the logical page size is zero in fsp_flags, then use the
+		legacy 16k page size. */
+		ssize = (0 == ssize) ? UNIV_PAGE_SSIZE_ORIG : ssize;
+
+		/* Convert from a 'log2 minus 9' to a page size in bytes. */
+		const unsigned	size = ((UNIV_ZIP_SIZE_MIN >> 1) << ssize);
+
+		ut_ad(size <= UNIV_PAGE_SIZE_MAX);
+		ut_ad(size <= (1 << PAGE_SIZE_T_SIZE_BITS));
+
+		m_logical = size;
+
+		ssize = FSP_FLAGS_GET_ZIP_SSIZE(fsp_flags);
+
+		/* If the fsp_flags have zero in the zip_ssize field, then it means
+		that the tablespace does not have compressed pages and the physical
+		page size is the same as the logical page size. */
+		if (ssize == 0) {
+			m_is_compressed = false;
+			m_physical = m_logical;
+		} else {
+			m_is_compressed = true;
+
+			/* Convert from a 'log2 minus 9' to a page size
+			in bytes. */
+			const unsigned	phy
+				= ((UNIV_ZIP_SIZE_MIN >> 1) << ssize);
+
+			ut_ad(phy <= UNIV_ZIP_SIZE_MAX);
+			ut_ad(phy <= (1 << PAGE_SIZE_T_SIZE_BITS));
+
+			m_physical = phy;
+		}
+	}
+
+	/** Retrieve the physical page size (on-disk).
+	@return physical page size in bytes */
+	inline ulint physical() const
+	{
+		ut_ad(m_physical > 0);
+
+		return(m_physical);
+	}
+
+	/** Retrieve the logical page size (in-memory).
+	@return logical page size in bytes */
+	inline ulint logical() const
+	{
+		ut_ad(m_logical > 0);
+		return(m_logical);
+	}
+
+	/** Check whether the page is compressed on disk.
+	@return true if compressed */
+	inline bool is_compressed() const
+	{
+		return(m_is_compressed);
+	}
+
+	/** Copy the values from a given page_size_t object.
+	@param[in]	src	page size object whose values to fetch */
+	inline void copy_from(const page_size_t& src)
+	{
+		*this = src;
+	}
+
+	/** Check if a given page_size_t object is equal to the current one.
+	@param[in]	a	page_size_t object to compare
+	@return true if equal */
+	inline bool equals_to(const page_size_t& a) const
+	{
+		return(a.physical() == m_physical
+		       && a.logical() == m_logical
+		       && a.is_compressed() == m_is_compressed);
+	}
+
+private:
+
+	/* For non compressed tablespaces, physical page size is equal to
+	the logical page size and the data is stored in buf_page_t::frame
+	(and is also always equal to univ_page_size (--innodb-page-size=)).
+
+	For compressed tablespaces, physical page size is the compressed
+	page size as stored on disk and in buf_page_t::zip::data. The logical
+	page size is the uncompressed page size in memory - the size of
+	buf_page_t::frame (currently also always equal to univ_page_size
+	(--innodb-page-size=)). */
+
+	/** Physical page size. */
+	unsigned	m_physical:PAGE_SIZE_T_SIZE_BITS;
+
+	/** Logical page size. */
+	unsigned	m_logical:PAGE_SIZE_T_SIZE_BITS;
+
+	/** Flag designating whether the physical page is compressed, which is
+	true IFF the whole tablespace where the page belongs is compressed. */
+	unsigned	m_is_compressed:1;
+};
+
+#ifndef UNIV_INNOCHECKSUM
+/* Overloading the global output operator to conveniently print an object
+of type the page_size_t.
+ at param[in,out]	out	the output stream
+ at param[in]	obj	an object of type page_size_t to be printed
+ at retval	the output stream */
+inline
+std::ostream&
+operator<<(
+	std::ostream&		out,
+	const page_size_t&	obj)
+{
+	out << "[page size: physical=" << obj.physical()
+		<< ", logical=" << obj.logical()
+		<< ", compressed=" << obj.is_compressed() << "]";
+	return(out);
+}
+#endif
+
+extern page_size_t	univ_page_size;
+
+#endif /* page0size_t */
diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
index aafb84db6f1..2398010f75b 100644
--- a/storage/innobase/include/univ.i
+++ b/storage/innobase/include/univ.i
@@ -371,6 +371,8 @@ and 2 bits for flags. This limits the uncompressed page size to 16k.
 #define UNIV_PAGE_SIZE_SHIFT_DEF	14
 /** Original 16k InnoDB Page Size Shift, in case the default changes */
 #define UNIV_PAGE_SIZE_SHIFT_ORIG	14
+/** Original 16k InnoDB Page Size as an ssize (log2 - 9) */
+#define UNIV_PAGE_SSIZE_ORIG		(UNIV_PAGE_SIZE_SHIFT_ORIG - 9)
 
 /** Minimum page size InnoDB currently supports. */
 #define UNIV_PAGE_SIZE_MIN	(1 << UNIV_PAGE_SIZE_SHIFT_MIN)


More information about the commits mailing list