Commit 2ef7a5a1 authored by Jan Lindström's avatar Jan Lindström

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

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

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

Added page 0 checksum checking and if that fails whole test fails.
parent 19f2b3d0
......@@ -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);
}
......@@ -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
......
--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;
# 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;
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
# 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;
--skip-innodb-doublewrite
--innodb-file-per-table
--innodb-file-format=Barracuda
#************************************************************
# 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;
--skip-innodb-doublewrite
--innodb-file-per-table
--innodb-file-format=Barracuda
--innodb-change-buffering=none
#************************************************************
# 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
--innodb-file-per-table
--innodb-file-format=Barracuda
#************************************************************
# 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;
......@@ -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);
}
......
/*****************************************************************************
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 */
......@@ -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__
......
......@@ -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);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment