summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--extra/innochecksum.cc598
-rw-r--r--mysql-test/suite/encryption/t/innochecksum.test1
-rw-r--r--mysql-test/suite/innodb/include/innodb-wl6045.inc22
-rw-r--r--mysql-test/suite/innodb/r/innodb_zip_innochecksum.result91
-rw-r--r--mysql-test/suite/innodb/r/innodb_zip_innochecksum2.result160
-rw-r--r--mysql-test/suite/innodb/r/innodb_zip_innochecksum3.result227
-rw-r--r--mysql-test/suite/innodb/t/innodb_zip_innochecksum.opt4
-rw-r--r--mysql-test/suite/innodb/t/innodb_zip_innochecksum.test239
-rw-r--r--mysql-test/suite/innodb/t/innodb_zip_innochecksum2.opt4
-rw-r--r--mysql-test/suite/innodb/t/innodb_zip_innochecksum2.test118
-rw-r--r--mysql-test/suite/innodb/t/innodb_zip_innochecksum3.opt2
-rw-r--r--mysql-test/suite/innodb/t/innodb_zip_innochecksum3.test406
-rw-r--r--storage/innobase/buf/buf0buf.cc54
-rw-r--r--storage/innobase/include/page0size.h200
-rw-r--r--storage/innobase/include/univ.i8
-rw-r--r--storage/innobase/page/page0zip.cc8
16 files changed, 1899 insertions, 243 deletions
diff --git a/extra/innochecksum.cc b/extra/innochecksum.cc
index e258a8c1d08..7ad71aa8159 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>
@@ -83,9 +84,9 @@ typedef void fil_space_t;
/* Global variables */
static bool verbose;
static bool just_count;
-static ulint start_page;
-static ulint end_page;
-static ulint do_page;
+static unsigned long long start_page;
+static unsigned long long end_page;
+static unsigned long long do_page;
static bool use_end_page;
static bool do_one_page;
static my_bool do_leaf;
@@ -95,8 +96,9 @@ 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;
+unsigned long long cur_page_num;
/* Skip the checksum verification. */
static bool no_check;
/* Enabled for strict checksum verification. */
@@ -104,7 +106,7 @@ bool strict_verify = 0;
/* Enabled for rewrite checksum. */
static bool do_write;
/* Mismatches count allowed (0 by default). */
-static ulint allow_mismatches;
+static unsigned long long allow_mismatches=0;
static bool page_type_summary;
static bool page_type_dump;
/* Store filename for page-type-dump option. */
@@ -228,7 +230,7 @@ void print_index_leaf_stats(
fprintf(fil_out, "page_no\tdata_size\tn_recs\n");
while (it_page != index.leaves.end()) {
const per_page_stats& stat = it_page->second;
- fprintf(fil_out, "%llu\t%lu\t%lu\n", it_page->first, stat.data_size, stat.n_recs);
+ fprintf(fil_out, "%llu\t" ULINTPF "\t" ULINTPF "\n", it_page->first, stat.data_size, stat.n_recs);
page_no = stat.right_page_no;
it_page = index.leaves.find(page_no);
}
@@ -264,14 +266,14 @@ void defrag_analysis(
}
if (index.leaf_pages) {
- fprintf(fil_out, "count = %lu free = %lu\n", index.count, index.free_pages);
+ fprintf(fil_out, "count = " ULINTPF " free = " ULINTPF "\n", index.count, index.free_pages);
}
if (!n_leaf_pages) {
n_leaf_pages = 1;
}
- fprintf(fil_out, "%llu\t\t%llu\t\t%lu\t\t%lu\t\t%lu\t\t%.2f\t%lu\n",
+ fprintf(fil_out, "%llu\t\t%llu\t\t" ULINTPF "\t\t" ULINTPF "\t\t" ULINTPF "\t\t%.2f\t" ULINTPF "\n",
id, index.leaf_pages, n_leaf_pages, n_merge, n_pages,
1.0 - (double)n_pages / (double)n_leaf_pages, index.max_data_size);
}
@@ -296,6 +298,31 @@ void print_leaf_stats(
}
}
+/** Get the page size of the filespace from the filespace header.
+@param[in] buf buffer used to read the page.
+@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
-@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)
{
@@ -448,7 +473,7 @@ is_page_corrupted(
ulint logseq;
ulint logseqfield;
ulint page_type = mach_read_from_2(buf+FIL_PAGE_TYPE);
- ulint key_version = mach_read_from_4(buf+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
+ uint key_version = mach_read_from_4(buf+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
ulint space_id = mach_read_from_4(
buf + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
@@ -462,23 +487,23 @@ 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,
- "space::%" PRIuMAX " page::%" PRIuMAX
+ "space::" ULINTPF " page::%llu"
"; log sequence number:first = " ULINTPF
"; second = " ULINTPF "\n",
space_id, cur_page_num, logseq, logseqfield);
if (logseq != logseqfield) {
fprintf(log_file,
- "Fail; space %" PRIuMAX " page %" PRIuMAX
+ "Fail; space::" ULINTPF " page::%llu"
" invalid (fails log "
"sequence number check)\n",
space_id, cur_page_num);
@@ -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);
@@ -592,7 +627,7 @@ update_checksum(
mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, checksum);
if (is_log_enabled) {
- fprintf(log_file, "page::%" PRIuMAX "; Updated checksum ="
+ fprintf(log_file, "page::%llu; Updated checksum ="
" %u\n", cur_page_num, checksum);
}
@@ -623,7 +658,7 @@ update_checksum(
mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, checksum);
if (is_log_enabled) {
- fprintf(log_file, "page::%" PRIuMAX "; Updated checksum field1"
+ fprintf(log_file, "page::%llu; Updated checksum field1"
" = %u\n", cur_page_num, checksum);
}
@@ -637,13 +672,13 @@ update_checksum(
FIL_PAGE_END_LSN_OLD_CHKSUM,checksum);
if (is_log_enabled) {
- fprintf(log_file, "page::%" PRIuMAX "; Updated checksum "
+ fprintf(log_file, "page::%llu; Updated checksum "
"field2 = %u\n", cur_page_num, 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. */
@@ -712,7 +747,7 @@ write_file(
if (page_size
!= fwrite(buf, 1, page_size, file == stdin ? stdout : file)) {
- fprintf(stderr, "Failed to write page %" PRIuMAX " to %s: %s\n",
+ fprintf(stderr, "Failed to write page::%llu to %s: %s\n",
cur_page_num, filename, strerror(errno));
return(false);
@@ -734,12 +769,16 @@ 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.
+@param [in] page_size page_size
+@param [in] is_encrypted tablespace is encrypted
*/
void
parse_page(
const byte* page,
byte* xdes,
- FILE* file)
+ FILE* file,
+ const page_size_t& page_size,
+ bool is_encrypted)
{
unsigned long long id;
ulint undo_page_type;
@@ -749,7 +788,7 @@ parse_page(
ulint left_page_no;
ulint right_page_no;
ulint data_bytes;
- int is_leaf;
+ bool is_leaf;
int size_range_id;
/* Check whether page is doublewrite buffer. */
@@ -761,83 +800,107 @@ parse_page(
switch (mach_read_from_2(page + FIL_PAGE_TYPE)) {
- case FIL_PAGE_INDEX:
+ case FIL_PAGE_INDEX: {
+ uint key_version = mach_read_from_4(page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
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);
- 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);
- 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) {
- fprintf(file, "#::%8" PRIuMAX "\t\t|\t\tIndex page\t\t\t|"
- "\tindex id=%llu,", cur_page_num, id);
-
- fprintf(file,
- " page level=" ULINTPF
- ", No. of records=" ULINTPF
- ", garbage=" ULINTPF ", %s\n",
- page_header_get_field(page, PAGE_LEVEL),
- page_header_get_field(page, PAGE_N_RECS),
- page_header_get_field(page, PAGE_GARBAGE), str);
- }
- break;
+ /* If page is encrypted we can't read index header */
+ if (!is_encrypted) {
+ id = mach_read_from_8(page + PAGE_HEADER + PAGE_INDEX_ID);
+ n_recs = mach_read_from_2(page + PAGE_HEADER + PAGE_N_RECS);
+ 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);
+ ulint is_comp = mach_read_from_2(page + PAGE_HEADER + PAGE_N_HEAP) & 0x8000;
+ ulint level = mach_read_from_2(page + PAGE_HEADER + PAGE_LEVEL);
+ ulint garbage = mach_read_from_2(page + PAGE_HEADER + PAGE_GARBAGE);
+
+
+ data_bytes = (ulint)(mach_read_from_2(page + PAGE_HEADER + PAGE_HEAP_TOP)
+ - (is_comp
+ ? PAGE_NEW_SUPREMUM_END
+ : PAGE_OLD_SUPREMUM_END)
+ - garbage);
+
+ is_leaf = (!*(const uint16*) (page + (PAGE_HEADER + PAGE_LEVEL)));
+
+ if (page_type_dump) {
+ fprintf(file, "#::%llu\t\t|\t\tIndex page\t\t\t|"
+ "\tindex id=%llu,", cur_page_num, id);
+
+ fprintf(file,
+ " page level=" ULINTPF
+ ", No. of records=" ULINTPF
+ ", garbage=" ULINTPF ", %s\n",
+ level, n_recs, garbage, str);
+ }
+
+ size_range_id = (data_bytes * SIZE_RANGES_FOR_PAGE
+ + 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 id=%llu page " ULINTPF " leaf %d n_recs " ULINTPF " data_bytes " ULINTPF
+ "\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] ++;
+ }
+ } else {
+ fprintf(file, "#::%llu\t\t|\t\tEncrypted Index page\t\t\t|"
+ "\tkey_version %u,%s\n", cur_page_num, key_version, str);
+ }
+
+ break;
+ }
case FIL_PAGE_UNDO_LOG:
page_type.n_fil_page_undo_log++;
undo_page_type = mach_read_from_2(page +
TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE);
if (page_type_dump) {
- fprintf(file, "#::%8" PRIuMAX "\t\t|\t\tUndo log page\t\t\t|",
+ fprintf(file, "#::%llu\t\t|\t\tUndo log page\t\t\t|",
cur_page_num);
}
if (undo_page_type == TRX_UNDO_INSERT) {
@@ -911,7 +974,7 @@ parse_page(
case FIL_PAGE_INODE:
page_type.n_fil_page_inode++;
if (page_type_dump) {
- fprintf(file, "#::%8" PRIuMAX "\t\t|\t\tInode page\t\t\t|"
+ fprintf(file, "#::%llu\t\t|\t\tInode page\t\t\t|"
"\t%s\n",cur_page_num, str);
}
break;
@@ -919,7 +982,7 @@ parse_page(
case FIL_PAGE_IBUF_FREE_LIST:
page_type.n_fil_page_ibuf_free_list++;
if (page_type_dump) {
- fprintf(file, "#::%8" PRIuMAX "\t\t|\t\tInsert buffer free list"
+ fprintf(file, "#::%llu\t\t|\t\tInsert buffer free list"
" page\t|\t%s\n", cur_page_num, str);
}
break;
@@ -927,7 +990,7 @@ parse_page(
case FIL_PAGE_TYPE_ALLOCATED:
page_type.n_fil_page_type_allocated++;
if (page_type_dump) {
- fprintf(file, "#::%8" PRIuMAX "\t\t|\t\tFreshly allocated "
+ fprintf(file, "#::%llu\t\t|\t\tFreshly allocated "
"page\t\t|\t%s\n", cur_page_num, str);
}
break;
@@ -935,7 +998,7 @@ parse_page(
case FIL_PAGE_IBUF_BITMAP:
page_type.n_fil_page_ibuf_bitmap++;
if (page_type_dump) {
- fprintf(file, "#::%8" PRIuMAX "\t\t|\t\tInsert Buffer "
+ fprintf(file, "#::%llu\t\t|\t\tInsert Buffer "
"Bitmap\t\t|\t%s\n", cur_page_num, str);
}
break;
@@ -943,7 +1006,7 @@ parse_page(
case FIL_PAGE_TYPE_SYS:
page_type.n_fil_page_type_sys++;
if (page_type_dump) {
- fprintf(file, "#::%8" PRIuMAX "\t\t|\t\tSystem page\t\t\t|"
+ fprintf(file, "#::%llu\t\t|\t\tSystem page\t\t\t|"
"\t%s\n",cur_page_num, str);
}
break;
@@ -951,25 +1014,25 @@ parse_page(
case FIL_PAGE_TYPE_TRX_SYS:
page_type.n_fil_page_type_trx_sys++;
if (page_type_dump) {
- fprintf(file, "#::%8" PRIuMAX "\t\t|\t\tTransaction system "
+ fprintf(file, "#::%llu\t\t|\t\tTransaction system "
"page\t\t|\t%s\n", cur_page_num, str);
}
break;
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 "
+ fprintf(file, "#::%llu\t\t|\t\tFile Space "
"Header\t\t|\t%s\n", cur_page_num, str);
}
break;
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 "
+ fprintf(file, "#::%llu\t\t|\t\tExtent descriptor "
"page\t\t|\t%s\n", cur_page_num, str);
}
break;
@@ -977,7 +1040,7 @@ parse_page(
case FIL_PAGE_TYPE_BLOB:
page_type.n_fil_page_type_blob++;
if (page_type_dump) {
- fprintf(file, "#::%8" PRIuMAX "\t\t|\t\tBLOB page\t\t\t|\t%s\n",
+ fprintf(file, "#::%llu\t\t|\t\tBLOB page\t\t\t|\t%s\n",
cur_page_num, str);
}
break;
@@ -985,7 +1048,7 @@ parse_page(
case FIL_PAGE_TYPE_ZBLOB:
page_type.n_fil_page_type_zblob++;
if (page_type_dump) {
- fprintf(file, "#::%8" PRIuMAX "\t\t|\t\tCompressed BLOB "
+ fprintf(file, "#::%llu\t\t|\t\tCompressed BLOB "
"page\t\t|\t%s\n", cur_page_num, str);
}
break;
@@ -993,7 +1056,7 @@ parse_page(
case FIL_PAGE_TYPE_ZBLOB2:
page_type.n_fil_page_type_zblob2++;
if (page_type_dump) {
- fprintf(file, "#::%8" PRIuMAX "\t\t|\t\tSubsequent Compressed "
+ fprintf(file, "#::%llu\t\t|\t\tSubsequent Compressed "
"BLOB page\t|\t%s\n", cur_page_num, str);
}
break;
@@ -1001,7 +1064,7 @@ parse_page(
case FIL_PAGE_PAGE_COMPRESSED:
page_type.n_fil_page_type_page_compressed++;
if (page_type_dump) {
- fprintf(file, "#::%8" PRIuMAX "\t\t|\t\tPage compressed "
+ fprintf(file, "#::%llu\t\t|\t\tPage compressed "
"page\t|\t%s\n", cur_page_num, str);
}
break;
@@ -1009,7 +1072,7 @@ parse_page(
case FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED:
page_type.n_fil_page_type_page_compressed_encrypted++;
if (page_type_dump) {
- fprintf(file, "#::%8" PRIuMAX "\t\t|\t\tPage compressed encrypted "
+ fprintf(file, "#::%llu\t\t|\t\tPage compressed encrypted "
"page\t|\t%s\n", cur_page_num, str);
}
break;
@@ -1096,12 +1159,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 +1319,7 @@ innochecksum_get_one_option(
break;
case 'V':
print_version();
+ my_end(0);
exit(EXIT_SUCCESS);
break;
case 'C':
@@ -1316,27 +1380,35 @@ get_options(
char ***argv)
{
if (handle_options(argc, argv, innochecksum_options,
- innochecksum_get_one_option))
+ innochecksum_get_one_option)) {
+ my_end(0);
exit(true);
+ }
/* The next arg must be the filename */
if (!*argc) {
usage();
+ my_end(0);
return (true);
}
return (false);
}
-/** Check from page 0 if table is encrypted. */
+/** Check from page 0 if table is encrypted.
+@param[in] filename Filename
+@param[in] page_size page size
+@param[in] page Page 0
+@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 +1433,95 @@ 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.
+@param[in] buf page to verify
+@param[in] page_size page size
+@param[in] is_encrypted true if tablespace is encrypted
+@param[in] is_compressed true if tablespace is page compressed
+@param[in,out] mismatch_count Number of pages failed in checksum verify
+@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,
+ unsigned long long* 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::%llu invalid\n",
+ cur_page_num);
+
+ (*mismatch_count)++;
+
+ if (*mismatch_count > allow_mismatches) {
+ fprintf(stderr,
+ "Exceeded the "
+ "maximum allowed "
+ "checksum mismatch "
+ "count::%llu current::%llu\n",
+ *mismatch_count,
+ allow_mismatches);
+
+ exit_status = 1;
+ }
+ }
+
+ return (exit_status);
+}
+
+/** Rewrite page checksum if needed.
+@param[in] filename File name
+@param[in] fil_in File pointer
+@param[in] buf page
+@param[in] page_size page size
+@param[in] pos File position
+@param[in] is_encrypted true if tablespace is encrypted
+@param[in] is_compressed true if tablespace is page compressed
+@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 +1531,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 */
@@ -1404,9 +1557,7 @@ 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;
+ unsigned long long mismatch_count = 0;
bool partial_page_read = false;
/* Enabled when read from stdin is done. */
@@ -1465,16 +1616,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;
@@ -1526,7 +1677,7 @@ int main(
if (bytes != UNIV_ZIP_SIZE_MIN) {
fprintf(stderr, "Error: Was not able to read the "
"minimum page size ");
- fprintf(stderr, "of %d bytes. Bytes read was %lu\n",
+ fprintf(stderr, "of %d bytes. Bytes read was " ULINTPF "\n",
UNIV_ZIP_SIZE_MIN, bytes);
exit_status = 1;
@@ -1542,23 +1693,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);
+ fprintf(stderr, "of " ULINTPF " bytes. Bytes read was " ULINTPF "\n",
+ page_size.physical() - UNIV_ZIP_SIZE_MIN, bytes);
exit_status = 1;
goto my_exit;
@@ -1567,9 +1718,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) {
+ unsigned long long tmp_allow_mismatches = allow_mismatches;
+ allow_mismatches = 0;
- pages = (ulint) (size / page_size);
+ 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 %llu ", cur_page_num);
+ }
+
+ if (page_type_summary || page_type_dump) {
+ parse_page(buf, xdes, fil_page_type, page_size, is_encrypted);
+ }
+
+ pages = (ulint) (size / page_size.physical());
if (just_count) {
if (read_from_stdin) {
@@ -1584,14 +1778,14 @@ int main(
"(" ULINTPF " pages)\n", filename, size, pages);
if (do_one_page) {
fprintf(log_file, "Innochecksum: "
- "checking page %" PRIuMAX "\n",
+ "checking page::%llu;\n",
do_page);
}
}
} else {
if (is_log_enabled) {
fprintf(log_file, "Innochecksum: checking "
- "pages in range %" PRIuMAX " to %" PRIuMAX "\n",
+ "pages in range::%llu to %llu\n",
start_page, use_end_page ?
end_page : (pages - 1));
}
@@ -1606,7 +1800,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 +1838,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 +1856,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 +1872,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) {
- fprintf(stderr, "Error: bytes read (%lu) "
+ if (bytes != page_size.physical()) {
+ fprintf(stderr, "Error: bytes read (" ULINTPF ") "
"doesn't match page size (" ULINTPF ")\n",
- bytes, page_size);
+ bytes, page_size.physical());
exit_status = 1;
goto my_exit;
}
@@ -1714,46 +1894,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;
}
@@ -1763,15 +1923,16 @@ int main(
}
if (per_page_details) {
- printf("page %ld ", cur_page_num);
+ printf("page %llu ", cur_page_num);
}
if (page_type_summary || page_type_dump) {
- parse_page(buf, xdes, fil_page_type);
+ parse_page(buf, xdes, fil_page_type, page_size, is_encrypted);
}
/* do counter increase and progress printing */
cur_page_num++;
+
if (verbose && !read_from_stdin) {
if ((cur_page_num % 64) == 0) {
now = time(0);
@@ -1780,7 +1941,7 @@ int main(
}
if (now - lastt >= 1
&& is_log_enabled) {
- fprintf(log_file, "page %" PRIuMAX " "
+ fprintf(log_file, "page::%llu "
"okay: %.3f%% done\n",
(cur_page_num - 1),
(float) cur_page_num / pages * 100);
@@ -1811,10 +1972,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/encryption/t/innochecksum.test b/mysql-test/suite/encryption/t/innochecksum.test
index 74fe7bcf7a0..f1c1b65d418 100644
--- a/mysql-test/suite/encryption/t/innochecksum.test
+++ b/mysql-test/suite/encryption/t/innochecksum.test
@@ -7,6 +7,7 @@
# Require InnoDB
-- source include/have_innodb.inc
-- source include/have_file_key_management_plugin.inc
+-- source include/innodb_page_size_small.inc
if (!$INNOCHECKSUM) {
--echo Need innochecksum binary
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..03e8b5df75f
--- /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,@col_2,@col_3,@col_4,@cl_5,@col_6,5);
+INSERT INTO tab2(col_1,col_2,col_3,col_4,col_5,col_6,col_7)
+VALUES (@col_1,@col_2,@col_3,@col_4,@cl_5,@col_6,4);
+INSERT INTO tab2(col_1,col_2,col_3,col_4,col_5,col_6,col_7)
+VALUES (@col_1,@col_2,@col_3,@col_4,@cl_5,@col_6,3);
+INSERT INTO tab2(col_1,col_2,col_3,col_4,col_5,col_6,col_7)
+VALUES (@col_1,@col_2,@col_3,@col_4,@cl_5,@col_6,2);
+INSERT INTO tab2(col_1,col_2,col_3,col_4,col_5,col_6,col_7)
+VALUES (@col_1,@col_2,@col_3,@col_4,@cl_5,@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,@col_2,@col_3,@col_4,@cl_5,@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,@col_2,@col_3,@col_4,@cl_5,@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,@col_2,@col_3,@col_4,@cl_5,@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,@col_2,@col_3,@col_4,@cl_5,@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,@col_2,@col_3,@col_4,@cl_5,@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,@col_2,@col_3,@col_4,@cl_5,@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,@col_2,@col_3,@col_4,@cl_5,@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/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index 50d067b3f85..85d7485678e 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -571,10 +571,10 @@ buf_page_is_checksum_valid_crc32(
#ifdef UNIV_INNOCHECKSUM
if (log_file
&& srv_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_STRICT_CRC32) {
- fprintf(log_file, "page::%lu;"
+ fprintf(log_file, "page::%llu;"
" crc32 calculated = %u;"
- " recorded checksum field1 = %lu recorded"
- " checksum field2 =%lu\n", cur_page_num,
+ " recorded checksum field1 = " ULINTPF " recorded"
+ " checksum field2 =" ULINTPF "\n", cur_page_num,
crc32, checksum_field1, checksum_field2);
}
#endif /* UNIV_INNOCHECKSUM */
@@ -619,28 +619,28 @@ buf_page_is_checksum_valid_innodb(
#ifdef UNIV_INNOCHECKSUM
if (log_file
&& srv_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_INNODB) {
- fprintf(log_file, "page::%lu;"
+ fprintf(log_file, "page::%llu;"
" old style: calculated ="
- " %lu; recorded = %lu\n",
+ " " ULINTPF "; recorded = " ULINTPF "\n",
cur_page_num, old_checksum,
checksum_field2);
- fprintf(log_file, "page::%lu;"
+ fprintf(log_file, "page::%llu;"
" new style: calculated ="
- " %lu; crc32 = %u; recorded = %lu\n",
+ " " ULINTPF "; crc32 = %u; recorded = " ULINTPF "\n",
cur_page_num, new_checksum,
buf_calc_page_crc32(read_buf), checksum_field1);
}
if (log_file
&& srv_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_STRICT_INNODB) {
- fprintf(log_file, "page::%lu;"
+ fprintf(log_file, "page::%llu;"
" old style: calculated ="
- " %lu; recorded checksum = %lu\n",
+ " " ULINTPF "; recorded checksum = " ULINTPF "\n",
cur_page_num, old_checksum,
checksum_field2);
- fprintf(log_file, "page::%lu;"
+ fprintf(log_file, "page::%llu;"
" new style: calculated ="
- " %lu; recorded checksum = %lu\n",
+ " " ULINTPF "; recorded checksum = " ULINTPF "\n",
cur_page_num, new_checksum,
checksum_field1);
}
@@ -701,9 +701,9 @@ buf_page_is_checksum_valid_none(
if (log_file
&& srv_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_STRICT_NONE) {
fprintf(log_file,
- "page::%lu; none checksum: calculated"
- " = %lu; recorded checksum_field1 = %lu"
- " recorded checksum_field2 = %lu\n",
+ "page::%llu; none checksum: calculated"
+ " = " ULINTPF "; recorded checksum_field1 = " ULINTPF
+ " recorded checksum_field2 = " ULINTPF "\n",
cur_page_num, BUF_NO_CHECKSUM_MAGIC,
checksum_field1, checksum_field2);
}
@@ -765,7 +765,7 @@ buf_page_is_corrupted(
of page do not match */
#ifndef UNIV_INNOCHECKSUM
ib_logf(IB_LOG_LEVEL_INFO,
- "Log sequence number at the start %lu and the end %lu do not match.",
+ "Log sequence number at the start " ULINTPF " and the end " ULINTPF " do not match.",
mach_read_from_4(read_buf + FIL_PAGE_LSN + 4),
mach_read_from_4(read_buf + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM + 4));
#endif /* UNIV_INNOCHECKSUM */
@@ -786,7 +786,7 @@ buf_page_is_corrupted(
ut_print_timestamp(stderr);
fprintf(stderr,
- " InnoDB: Error: page %lu log sequence number"
+ " InnoDB: Error: page " ULINTPF " log sequence number"
" " LSN_PF "\n"
"InnoDB: is in the future! Current system "
"log sequence number " LSN_PF ".\n"
@@ -876,13 +876,13 @@ buf_page_is_corrupted(
#ifdef UNIV_INNOCHECKSUM
if (log_file) {
- fprintf(log_file, "page::" ULINTPF ";"
+ fprintf(log_file, "page::%llu;"
" old style: calculated = " ULINTPF ";"
" recorded = " ULINTPF "\n",
cur_page_num,
buf_calc_page_old_checksum(read_buf),
checksum_field2);
- fprintf(log_file, "page::" ULINTPF ";"
+ fprintf(log_file, "page::%llu;"
" new style: calculated = " ULINTPF ";"
" crc32 = %u; recorded = " ULINTPF "\n",
cur_page_num,
@@ -912,7 +912,7 @@ buf_page_is_corrupted(
#ifdef UNIV_INNOCHECKSUM
if (log_file) {
- fprintf(log_file, "Fail; page " ULINTPF
+ fprintf(log_file, "Fail; page::%llu;"
" invalid (fails crc32 checksum)\n",
cur_page_num);
}
@@ -940,12 +940,12 @@ buf_page_is_corrupted(
}
#ifdef UNIV_INNOCHECKSUM
if (log_file) {
- fprintf(log_file, "page::" ULINTPF ";"
+ fprintf(log_file, "page::%llu;"
" old style: calculated = " ULINTPF ";"
" recorded = " ULINTPF "\n", cur_page_num,
buf_calc_page_old_checksum(read_buf),
checksum_field2);
- fprintf(log_file, "page::" ULINTPF ";"
+ fprintf(log_file, "page::%llu;"
" new style: calculated = " ULINTPF ";"
" crc32 = %u; recorded = " ULINTPF "\n",
cur_page_num,
@@ -975,7 +975,7 @@ buf_page_is_corrupted(
#ifdef UNIV_INNOCHECKSUM
if (log_file) {
- fprintf(log_file, "Fail; page " ULINTPF
+ fprintf(log_file, "Fail; page::%llu;"
" invalid (fails innodb checksum)\n",
cur_page_num);
}
@@ -1014,7 +1014,7 @@ buf_page_is_corrupted(
#ifdef UNIV_INNOCHECKSUM
if (log_file) {
- fprintf(log_file, "Fail; page " ULINTPF
+ fprintf(log_file, "Fail; page::%llu;"
" invalid (fails none checksum)\n",
cur_page_num);
}
@@ -1060,7 +1060,7 @@ buf_page_print(
if (!(flags & BUF_PAGE_PRINT_NO_FULL)) {
ut_print_timestamp(stderr);
fprintf(stderr,
- " InnoDB: Page dump in ascii and hex (%lu bytes):\n",
+ " InnoDB: Page dump in ascii and hex (" ULINTPF " bytes):\n",
size);
ut_print_buf(stderr, read_buf, size);
fputs("\nInnoDB: End of page dump\n", stderr);
@@ -1116,7 +1116,7 @@ buf_page_print(
"low 4 bytes of LSN at page end " ULINTPF ", "
"page number (if stored to page already) " ULINTPF ", "
"space id (if created with >= MySQL-4.1.1 "
- "and stored already) %lu\n",
+ "and stored already) " ULINTPF "\n",
mach_read_from_4(read_buf + FIL_PAGE_SPACE_OR_CHKSUM),
buf_checksum_algorithm_name(SRV_CHECKSUM_ALGORITHM_CRC32),
buf_calc_page_crc32(read_buf),
@@ -2853,8 +2853,8 @@ buf_block_align_instance(
if (block->page.space != space ||
block->page.offset != offset) {
ib_logf(IB_LOG_LEVEL_ERROR,
- "Corruption: Block space_id %lu != page space_id %lu or "
- "Block offset %lu != page offset %lu",
+ "Corruption: Block space_id " ULINTPF " != page space_id " ULINTPF " or "
+ "Block offset " ULINTPF " != page offset " ULINTPF " ",
(ulint)block->page.space, space,
(ulint)block->page.offset, offset);
}
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
+
+*****************************************************************************/
+
+/**************************************************//**
+@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.
+@param[in,out] out the output stream
+@param[in] obj an object of type page_size_t to be printed
+@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..755b10ba65a 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)
@@ -483,9 +485,9 @@ typedef unsigned long long int ullint;
#endif /* UNIV_HOTBACKUP */
#ifdef UNIV_INNOCHECKSUM
-extern bool strict_verify;
-extern FILE* log_file;
-extern ulint cur_page_num;
+extern bool strict_verify;
+extern FILE* log_file;
+extern unsigned long long cur_page_num;
#endif /* UNIV_INNOCHECKSUM */
#ifndef __WIN__
diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc
index 6e26f830fe6..b580ba6d098 100644
--- a/storage/innobase/page/page0zip.cc
+++ b/storage/innobase/page/page0zip.cc
@@ -4950,7 +4950,7 @@ page_zip_verify_checksum(
}
#ifdef UNIV_INNOCHECKSUM
if (log_file) {
- fprintf(log_file, "Page::%lu is empty and"
+ fprintf(log_file, "Page::%llu is empty and"
" uncorrupted\n", cur_page_num);
}
#endif /* UNIV_INNOCHECKSUM */
@@ -4970,7 +4970,7 @@ page_zip_verify_checksum(
#ifdef UNIV_INNOCHECKSUM
if (log_file) {
- fprintf(log_file, "page::%lu;"
+ fprintf(log_file, "page::%llu;"
" %s checksum: calculated = %u;"
" recorded = %u\n", cur_page_num,
buf_checksum_algorithm_name(
@@ -4985,10 +4985,10 @@ page_zip_verify_checksum(
data, size, SRV_CHECKSUM_ALGORITHM_CRC32);
if (log_file) {
- fprintf(log_file, "page::%lu: crc32 checksum:"
+ fprintf(log_file, "page::%llu: crc32 checksum:"
" calculated = %u; recorded = %u\n",
cur_page_num, crc32, stored);
- fprintf(log_file, "page::%lu: none checksum:"
+ fprintf(log_file, "page::%llu: none checksum:"
" calculated = %lu; recorded = %u\n",
cur_page_num, BUF_NO_CHECKSUM_MAGIC, stored);
}