MDEV-12026: Implement innodb_checksum_algorithm=full_crc32

MariaDB data-at-rest encryption (innodb_encrypt_tables)
had repurposed the same unused data field that was repurposed
in MySQL 5.7 (and MariaDB 10.2) for the Split Sequence Number (SSN)
field of SPATIAL INDEX. Because of this, MariaDB was unable to
support encryption on SPATIAL INDEX pages.

Furthermore, InnoDB page checksums skipped some bytes, and there
are multiple variations and checksum algorithms. By default,
InnoDB accepts all variations of all algorithms that ever existed.
This unnecessarily weakens the page checksums.

We hereby introduce two more innodb_checksum_algorithm variants
(full_crc32, strict_full_crc32) that are special in a way:
When either setting is active, newly created data files will
carry a flag (fil_space_t::full_crc32()) that indicates that
all pages of the file will use a full CRC-32C checksum over the
entire page contents (excluding the bytes where the checksum
is stored, at the very end of the page). Such files will always
use that checksum, no matter what the parameter
innodb_checksum_algorithm is assigned to.

For old files, the old checksum algorithms will continue to be
used. The value strict_full_crc32 will be equivalent to strict_crc32
and the value full_crc32 will be equivalent to crc32.

ROW_FORMAT=COMPRESSED tables will only use the old format.
These tables do not support new features, such as larger
innodb_page_size or instant ADD/DROP COLUMN. They may be
deprecated in the future. We do not want an unnecessary
file format change for them.

The new full_crc32() format also cleans up the MariaDB tablespace
flags. We will reserve flags to store the page_compressed
compression algorithm, and to store the compressed payload length,
so that checksum can be computed over the compressed (and
possibly encrypted) stream and can be validated without
decrypting or decompressing the page.

In the full_crc32 format, there no longer are separate before-encryption
and after-encryption checksums for pages. The single checksum is
computed on the page contents that is written to the file.

We do not make the new algorithm the default for two reasons.
First, MariaDB 10.4.2 was a beta release, and the default values
of parameters should not change after beta. Second, we did not
yet implement the full_crc32 format for page_compressed pages.
This will be fixed in MDEV-18644.

This is joint work with Marko Mäkelä.
This commit is contained in:
Thirunarayanan Balathandayuthapani 2019-02-19 21:00:00 +02:00 committed by Marko Mäkelä
parent 93984ff6d6
commit c0f47a4a58
83 changed files with 2346 additions and 544 deletions

View file

@ -274,30 +274,27 @@ void print_leaf_stats(
}
}
/** Get the ROW_FORMAT=COMPRESSED size from the filespace header.
@param[in] buf buffer used to read the page.
@return ROW_FORMAT_COMPRESSED page size
@retval 0 if not ROW_FORMAT=COMPRESSED */
static ulint get_zip_size(const byte* buf)
/** Init the page size for the tablespace.
@param[in] buf buffer used to read the page */
static void init_page_size(const byte* buf)
{
const unsigned flags = mach_read_from_4(buf + FIL_PAGE_DATA
+ FSP_SPACE_FLAGS);
if (FSP_FLAGS_FCRC32_HAS_MARKER(flags)) {
srv_page_size = fil_space_t::logical_size(flags);
physical_page_size = srv_page_size;
return;
}
const ulong ssize = FSP_FLAGS_GET_PAGE_SSIZE(flags);
srv_page_size_shift = ssize
? UNIV_ZIP_SIZE_SHIFT_MIN - 1 + ssize
: UNIV_PAGE_SIZE_SHIFT_ORIG;
srv_page_size = 1U << srv_page_size_shift;
ulint zip_size = FSP_FLAGS_GET_ZIP_SSIZE(flags);
if (zip_size) {
zip_size = (UNIV_ZIP_SIZE_MIN >> 1) << zip_size;
physical_page_size = zip_size;
} else {
physical_page_size = srv_page_size;
}
return zip_size;
srv_page_size = fil_space_t::logical_size(flags);
physical_page_size = fil_space_t::physical_size(flags);
}
#ifdef _WIN32
@ -429,19 +426,16 @@ ulint read_file(
/** Check if page is corrupted or not.
@param[in] buf page frame
@param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0
@param[in] is_encrypted true if page0 contained cryp_data
with crypt_scheme encrypted
@param[in] is_compressed true if page0 fsp_flags contained
page compression flag
@param[in] flags tablespace flags
@retval true if page is corrupted otherwise false. */
static
bool
is_page_corrupted(
byte* buf,
ulint zip_size,
bool is_encrypted,
bool is_compressed)
ulint flags)
{
/* enable if page is corrupted. */
@ -450,9 +444,12 @@ is_page_corrupted(
ulint logseq;
ulint logseqfield;
ulint page_type = mach_read_from_2(buf+FIL_PAGE_TYPE);
uint key_version = mach_read_from_4(buf+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
uint key_version = buf_page_get_key_version(buf, flags);
ulint space_id = mach_read_from_4(
buf + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
ulint zip_size = fil_space_t::zip_size(flags);
ulint is_compressed = fil_space_t::is_compressed(flags);
const bool use_full_crc32 = fil_space_t::full_crc32(flags);
/* We can't trust only a page type, thus we take account
also fsp_flags or crypt_data on page 0 */
@ -468,9 +465,11 @@ is_page_corrupted(
/* 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 + srv_page_size -
FIL_PAGE_END_LSN_OLD_CHKSUM + 4);
logseqfield = use_full_crc32
? mach_read_from_4(buf + srv_page_size
- FIL_PAGE_FCRC32_END_LSN)
: mach_read_from_4(buf + srv_page_size
- FIL_PAGE_END_LSN_OLD_CHKSUM + 4);
if (is_log_enabled) {
fprintf(log_file,
@ -498,23 +497,22 @@ is_page_corrupted(
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);
is_corrupted = use_full_crc32
? buf_page_is_corrupted(true, buf, flags)
: !fil_space_verify_crypt_checksum(buf, zip_size);
if (is_corrupted && log_file) {
fprintf(log_file,
"Page " ULINTPF ":%llu may be corrupted;"
" key_version=%u\n",
space_id, cur_page_num,
mach_read_from_4(
FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION
+ buf));
space_id, cur_page_num, key_version);
}
} else {
is_corrupted = true;
}
if (is_corrupted) {
is_corrupted = buf_page_is_corrupted(
true, buf, zip_size, NULL);
is_corrupted = buf_page_is_corrupted(true, buf, flags);
}
return(is_corrupted);
@ -566,17 +564,13 @@ is_page_empty(
/********************************************************************//**
Rewrite the checksum for the page.
@param [in/out] page page buffer
@param [in] iscompressed Is compressed/Uncompressed Page.
@param [in] flags tablespace flags
@retval true : do rewrite
@retval false : skip the rewrite as checksum stored match with
calculated or page is doublwrite buffer.
*/
bool
update_checksum(
byte* page,
bool iscompressed)
static bool update_checksum(byte* page, ulint flags)
{
ib_uint32_t checksum = 0;
byte stored1[4]; /* get FIL_PAGE_SPACE_OR_CHKSUM field checksum */
@ -588,6 +582,9 @@ update_checksum(
return (false);
}
const bool use_full_crc32 = fil_space_t::full_crc32(flags);
const bool iscompressed = fil_space_t::zip_size(flags);
memcpy(stored1, page + FIL_PAGE_SPACE_OR_CHKSUM, 4);
memcpy(stored2, page + physical_page_size -
FIL_PAGE_END_LSN_OLD_CHKSUM, 4);
@ -615,12 +612,24 @@ update_checksum(
" %u\n", cur_page_num, checksum);
}
} else if (use_full_crc32) {
checksum = buf_calc_page_full_crc32(page);
byte* c = page + physical_page_size - FIL_PAGE_FCRC32_CHECKSUM;
if (mach_read_from_4(c) == checksum) return false;
mach_write_to_4(c, checksum);
if (is_log_enabled) {
fprintf(log_file, "page::%llu; Updated checksum"
" = %u\n", cur_page_num, checksum);
}
return true;
} else {
/* page is uncompressed. */
/* Store the new formula checksum */
switch ((srv_checksum_algorithm_t) write_check) {
case SRV_CHECKSUM_ALGORITHM_FULL_CRC32:
case SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32:
case SRV_CHECKSUM_ALGORITHM_CRC32:
case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:
checksum = buf_calc_page_crc32(page);
@ -636,6 +645,7 @@ update_checksum(
case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:
checksum = BUF_NO_CHECKSUM_MAGIC;
break;
/* no default so the compiler will emit a warning if new
enum is added and not handled here */
}
@ -689,8 +699,7 @@ func_exit:
@param[in,out] file file pointer where content
have to be written
@param[in] buf file buffer read
@param[in] compressed Enabled if tablespace is
compressed.
@param[in] flags tablespace flags
@param[in,out] pos current file position.
@retval true if successfully written
@ -702,12 +711,12 @@ write_file(
const char* filename,
FILE* file,
byte* buf,
bool compressed,
ulint flags,
fpos_t* pos)
{
bool do_update;
do_update = update_checksum(buf, compressed);
do_update = update_checksum(buf, flags);
if (file != stdin) {
if (do_update) {
@ -1322,6 +1331,13 @@ innochecksum_get_one_option(
srv_checksum_algorithm =
SRV_CHECKSUM_ALGORITHM_STRICT_NONE;
break;
case SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32:
case SRV_CHECKSUM_ALGORITHM_FULL_CRC32:
srv_checksum_algorithm =
SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32;
break;
default:
return(true);
}
@ -1415,30 +1431,21 @@ static bool check_encryption(const char* filename, const byte* page)
return (type == CRYPT_SCHEME_1);
}
/**
Verify page checksum.
/** Verify page checksum.
@param[in] buf page to verify
@param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0
@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,
ulint zip_size,
bool is_encrypted,
bool is_compressed,
unsigned long long* mismatch_count)
@param[in] flags tablespace flags
@retval 0 if page checksum matches or 1 if it does not match */
static int verify_checksum(
byte* buf,
bool is_encrypted,
unsigned long long* mismatch_count,
ulint flags)
{
int exit_status = 0;
bool is_corrupted = false;
is_corrupted = is_page_corrupted(
buf, zip_size, is_encrypted, is_compressed);
if (is_corrupted) {
if (is_page_corrupted(buf, is_encrypted, flags)) {
fprintf(stderr, "Fail: page::%llu invalid\n",
cur_page_num);
@ -1464,10 +1471,9 @@ int verify_checksum(
@param[in] filename File name
@param[in] fil_in File pointer
@param[in] buf page
@param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0
@param[in] pos File position
@param[in] is_encrypted true if tablespace is encrypted
@param[in] is_compressed true if tablespace is page compressed
@param[in] flags tablespace flags
@retval 0 if checksum rewrite was successful, 1 if error was detected */
static
int
@ -1475,24 +1481,16 @@ rewrite_checksum(
const char* filename,
FILE* fil_in,
byte* buf,
ulint zip_size,
fpos_t* pos,
bool is_encrypted,
bool is_compressed)
bool is_encrypted,
ulint flags)
{
int exit_status = 0;
bool is_compressed = fil_space_t::is_compressed(flags);
/* 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, pos)) {
exit_status = 1;
}
return (exit_status);
return do_write && !is_encrypted && !is_compressed
&& !write_file(filename, fil_in, buf, flags, pos);
}
int main(
@ -1668,10 +1666,9 @@ int main(
/* Determine page size, zip_size and page compression
from fsp_flags and encryption metadata from page 0 */
ulint zip_size = get_zip_size(buf);
init_page_size(buf);
ulint flags = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + buf);
bool is_compressed = FSP_FLAGS_HAS_PAGE_COMPRESSION(flags);
if (physical_page_size > UNIV_ZIP_SIZE_MIN) {
/* Read rest of the page 0 to determine crypt_data */
@ -1698,7 +1695,8 @@ int main(
unsigned long long tmp_allow_mismatches = allow_mismatches;
allow_mismatches = 0;
exit_status = verify_checksum(buf, zip_size, is_encrypted, is_compressed, &mismatch_count);
exit_status = verify_checksum(buf, is_encrypted,
&mismatch_count, flags);
if (exit_status) {
fprintf(stderr, "Error: Page 0 checksum mismatch, can't continue. \n");
@ -1707,8 +1705,9 @@ int main(
allow_mismatches = tmp_allow_mismatches;
}
if ((exit_status = rewrite_checksum(filename, fil_in, buf,
zip_size, &pos, is_encrypted, is_compressed))) {
if ((exit_status = rewrite_checksum(
filename, fil_in, buf,
&pos, is_encrypted, flags))) {
goto my_exit;
}
@ -1874,13 +1873,15 @@ int main(
checksum verification.*/
if (!no_check
&& !skip_page
&& (exit_status = verify_checksum(buf, zip_size,
is_encrypted, is_compressed, &mismatch_count))) {
&& (exit_status = verify_checksum(
buf, is_encrypted,
&mismatch_count, flags))) {
goto my_exit;
}
if ((exit_status = rewrite_checksum(filename, fil_in, buf,
zip_size, &pos, is_encrypted, is_compressed))) {
if ((exit_status = rewrite_checksum(
filename, fil_in, buf,
&pos, is_encrypted, flags))) {
goto my_exit;
}

View file

@ -312,6 +312,10 @@ static bool page_is_corrupted(const byte *page, ulint page_no,
return false;
}
if (space->full_crc32()) {
return buf_page_is_corrupted(true, page, space->flags);
}
/* Validate encrypted pages. The first page is never encrypted.
In the system tablespace, the first page would be written with
FIL_PAGE_FILE_FLUSH_LSN at shutdown, and if the LSN exceeds
@ -344,7 +348,8 @@ static bool page_is_corrupted(const byte *page, ulint page_no,
}
if (page_type != FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED) {
return buf_page_is_corrupted(true, tmp_page, 0, space);
return buf_page_is_corrupted(true, tmp_page,
space->flags);
}
}
@ -363,10 +368,10 @@ static bool page_is_corrupted(const byte *page, ulint page_no,
|| page_type == FIL_PAGE_PAGE_COMPRESSED
|| page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED
|| buf_page_is_corrupted(true, tmp_page,
space->zip_size(), space));
space->flags));
}
return buf_page_is_corrupted(true, page, space->zip_size(), space);
return buf_page_is_corrupted(true, page, space->flags);
}
/************************************************************************

View file

@ -1689,7 +1689,7 @@ xb_get_one_option(int optid,
case OPT_INNODB_CHECKSUM_ALGORITHM:
ut_a(srv_checksum_algorithm <= SRV_CHECKSUM_ALGORITHM_STRICT_NONE);
ut_a(srv_checksum_algorithm <= SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32);
ADD_PRINT_PARAM_OPT(innodb_checksum_algorithm_names[srv_checksum_algorithm]);
break;
@ -1864,7 +1864,15 @@ static bool innodb_init_param()
srv_sys_space.set_space_id(TRX_SYS_SPACE);
srv_sys_space.set_name("innodb_system");
srv_sys_space.set_path(srv_data_home);
srv_sys_space.set_flags(FSP_FLAGS_PAGE_SSIZE());
switch (srv_checksum_algorithm) {
case SRV_CHECKSUM_ALGORITHM_FULL_CRC32:
case SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32:
srv_sys_space.set_flags(FSP_FLAGS_FCRC32_MASK_MARKER
| FSP_FLAGS_FCRC32_PAGE_SSIZE());
break;
default:
srv_sys_space.set_flags(FSP_FLAGS_PAGE_SSIZE());
}
if (!srv_sys_space.parse_params(innobase_data_file_path, true)) {
goto error;
@ -3278,7 +3286,8 @@ static dberr_t xb_assign_undo_space_start()
bool ret;
dberr_t error = DB_SUCCESS;
ulint space, page_no __attribute__((unused));
int n_retries = 5;
int n_retries = 5;
ulint fsp_flags;
if (srv_undo_tablespaces == 0) {
return error;
@ -3295,6 +3304,15 @@ static dberr_t xb_assign_undo_space_start()
buf = static_cast<byte*>(ut_malloc_nokey(2U << srv_page_size_shift));
page = static_cast<byte*>(ut_align(buf, srv_page_size));
if (!os_file_read(IORequestRead, file, page,
0, srv_page_size)) {
msg("Reading first page failed.\n");
error = DB_ERROR;
goto func_exit;
}
fsp_flags = mach_read_from_4(
page + FSP_HEADER_OFFSET + FSP_SPACE_FLAGS);
retry:
if (!os_file_read(IORequestRead, file, page,
TRX_SYS_PAGE_NO << srv_page_size_shift,
@ -3305,7 +3323,7 @@ retry:
}
/* TRX_SYS page can't be compressed or encrypted. */
if (buf_page_is_corrupted(false, page, 0)) {
if (buf_page_is_corrupted(false, page, fsp_flags)) {
if (n_retries--) {
os_thread_sleep(1000);
goto retry;
@ -4586,7 +4604,9 @@ xb_space_create_file(
const ulint zip_size = fil_space_t::zip_size(flags);
if (!zip_size) {
buf_flush_init_for_writing(NULL, page, NULL, 0);
buf_flush_init_for_writing(
NULL, page, NULL, 0,
fil_space_t::full_crc32(flags));
ret = os_file_write(IORequestWrite, path, *file, page, 0,
srv_page_size);
@ -4602,7 +4622,7 @@ xb_space_create_file(
page_zip.m_end = page_zip.m_nonempty =
page_zip.n_blobs = 0;
buf_flush_init_for_writing(NULL, page, &page_zip, 0);
buf_flush_init_for_writing(NULL, page, &page_zip, 0, false);
ret = os_file_write(IORequestWrite, path, *file,
page_zip.data, 0, zip_size);

View file

@ -0,0 +1,11 @@
[crc32]
--innodb-checksum-algorithm=crc32
[strict_crc32]
--innodb-checksum-algorithm=strict_crc32
[full_crc32]
--innodb-checksum-algorithm=full_crc32
[strict_full_crc32]
--innodb-checksum-algorithm=strict_full_crc32

View file

@ -0,0 +1 @@
--source include/have_innodb.inc

View file

@ -20,13 +20,15 @@ CREATE TABLE t6 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ENGINE=InnoDB;
# Run innochecksum on t3
# no encryption corrupting the field should not have effect
# Run innochecksum on t6
# no encryption corrupting the field should not have effect
# In new checksum format, checksum calculated for whole page.
# So It should affected.
# Restore the original tables
# Corrupt FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION+4 (post encryption checksum)
# Run innochecksum on t2
# Run innochecksum on t3
# Run innochecksum on t6
# no encryption corrupting the field should not have effect
# In new checksum format, checksum calculated for whole page.
# So It should affected.
# Restore the original tables
# Corrupt FIL_DATA+10 (data)
# Run innochecksum on t2

View file

@ -1,5 +1,5 @@
call mtr.add_suppression("InnoDB: Table `test`\\.`t[13]` (has an unreadable root page|is corrupted)");
call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=\\d+, page number=[36]\\] in file .*test.t[123]\\.ibd looks corrupted; key_version=3221342974");
call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=\\d+, page number=[36]\\] in file .*test.t[123]\\.ibd looks corrupted; key_version=");
SET GLOBAL innodb_file_per_table = ON;
set global innodb_compression_algorithm = 1;
# Create and populate tables to be corrupted

View file

@ -0,0 +1,34 @@
--- innodb-spatial-index.result
+++ innodb-spatial-index.result
@@ -1,22 +1,25 @@
CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT,
c VARCHAR(256), coordinate POINT NOT NULL, SPATIAL index(coordinate)) ENGINE=INNODB
ENCRYPTED=YES;
-Got one of the listed errors
+INSERT INTO t1(c, coordinate) values('mysql', ST_GeomFromText('POINT(903994614 180726515)'));
+INSERT INTO t1(c, coordinate) values('mariadb', ST_GeomFromText('POINT(903994614 180726515)'));
+DROP TABLE t1;
CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT,
c VARCHAR(256), coordinate POINT NOT NULL, SPATIAL index(coordinate)) ENGINE=INNODB;
ALTER TABLE t1 ENCRYPTED=YES;
-Got one of the listed errors
DROP TABLE t1;
CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT,
c VARCHAR(256), coordinate POINT NOT NULL) ENCRYPTED=YES ENGINE=INNODB;
ALTER TABLE t1 ADD SPATIAL INDEX b1(coordinate), ALGORITHM=COPY;
-Got one of the listed errors
ALTER TABLE t1 ADD SPATIAL INDEX b2(coordinate), FORCE, ALGORITHM=INPLACE;
-Got one of the listed errors
+Warnings:
+Note 1831 Duplicate index `b2`. This is deprecated and will be disallowed in a future release
ALTER TABLE t1 ADD SPATIAL INDEX(coordinate);
-Got one of the listed errors
+Warnings:
+Note 1831 Duplicate index `coordinate`. This is deprecated and will be disallowed in a future release
CREATE SPATIAL INDEX b3 on t1(coordinate);
-Got one of the listed errors
+Warnings:
+Note 1831 Duplicate index `b3`. This is deprecated and will be disallowed in a future release
DROP TABLE t1;
CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT,
c VARCHAR(256), coordinate POINT NOT NULL) ENCRYPTED=DEFAULT ENGINE=INNODB;

View file

@ -0,0 +1,34 @@
--- innodb-spatial-index.result
+++ innodb-spatial-index.result
@@ -1,22 +1,25 @@
CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT,
c VARCHAR(256), coordinate POINT NOT NULL, SPATIAL index(coordinate)) ENGINE=INNODB
ENCRYPTED=YES;
-Got one of the listed errors
+INSERT INTO t1(c, coordinate) values('mysql', ST_GeomFromText('POINT(903994614 180726515)'));
+INSERT INTO t1(c, coordinate) values('mariadb', ST_GeomFromText('POINT(903994614 180726515)'));
+DROP TABLE t1;
CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT,
c VARCHAR(256), coordinate POINT NOT NULL, SPATIAL index(coordinate)) ENGINE=INNODB;
ALTER TABLE t1 ENCRYPTED=YES;
-Got one of the listed errors
DROP TABLE t1;
CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT,
c VARCHAR(256), coordinate POINT NOT NULL) ENCRYPTED=YES ENGINE=INNODB;
ALTER TABLE t1 ADD SPATIAL INDEX b1(coordinate), ALGORITHM=COPY;
-Got one of the listed errors
ALTER TABLE t1 ADD SPATIAL INDEX b2(coordinate), FORCE, ALGORITHM=INPLACE;
-Got one of the listed errors
+Warnings:
+Note 1831 Duplicate index `b2`. This is deprecated and will be disallowed in a future release
ALTER TABLE t1 ADD SPATIAL INDEX(coordinate);
-Got one of the listed errors
+Warnings:
+Note 1831 Duplicate index `coordinate`. This is deprecated and will be disallowed in a future release
CREATE SPATIAL INDEX b3 on t1(coordinate);
-Got one of the listed errors
+Warnings:
+Note 1831 Duplicate index `b3`. This is deprecated and will be disallowed in a future release
DROP TABLE t1;
CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT,
c VARCHAR(256), coordinate POINT NOT NULL) ENCRYPTED=DEFAULT ENGINE=INNODB;

View file

@ -1,22 +1,22 @@
CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT,
c VARCHAR(256), coordinate POINT NOT NULL, SPATIAL index(coordinate)) ENGINE=INNODB
ENCRYPTED=YES;
ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options")
Got one of the listed errors
CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT,
c VARCHAR(256), coordinate POINT NOT NULL, SPATIAL index(coordinate)) ENGINE=INNODB;
ALTER TABLE t1 ENCRYPTED=YES;
ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'ENCRYPTED'
Got one of the listed errors
DROP TABLE t1;
CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT,
c VARCHAR(256), coordinate POINT NOT NULL) ENCRYPTED=YES ENGINE=INNODB;
ALTER TABLE t1 ADD SPATIAL INDEX b(coordinate), ALGORITHM=COPY;
ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options")
ALTER TABLE t1 ADD SPATIAL INDEX b(coordinate), FORCE, ALGORITHM=INPLACE;
ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'ENCRYPTED'
ALTER TABLE t1 ADD SPATIAL INDEX b1(coordinate), ALGORITHM=COPY;
Got one of the listed errors
ALTER TABLE t1 ADD SPATIAL INDEX b2(coordinate), FORCE, ALGORITHM=INPLACE;
Got one of the listed errors
ALTER TABLE t1 ADD SPATIAL INDEX(coordinate);
ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'ENCRYPTED'
CREATE SPATIAL INDEX b on t1(coordinate);
ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'ENCRYPTED'
Got one of the listed errors
CREATE SPATIAL INDEX b3 on t1(coordinate);
Got one of the listed errors
DROP TABLE t1;
CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT,
c VARCHAR(256), coordinate POINT NOT NULL) ENCRYPTED=DEFAULT ENGINE=INNODB;

View file

@ -8,16 +8,19 @@
-- source include/have_innodb.inc
-- source include/have_file_key_management_plugin.inc
-- source include/innodb_page_size_small.inc
-- source include/innodb_checksum_algorithm.inc
if (!$INNOCHECKSUM) {
--echo Need innochecksum binary
--die Need innochecksum binary
}
let $checksum_algorithm = `SELECT @@innodb_checksum_algorithm`;
SET GLOBAL innodb_file_per_table = ON;
# zlib
set global innodb_compression_algorithm = 1;
--echo # Create and populate a tables
CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ENGINE=InnoDB ENCRYPTED=YES ENCRYPTION_KEY_ID=4;
CREATE TABLE t2 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED ENCRYPTED=YES ENCRYPTION_KEY_ID=4;
@ -136,7 +139,20 @@ EOF
--exec $INNOCHECKSUM $t3_IBD
--echo # Run innochecksum on t6
--echo # no encryption corrupting the field should not have effect
--echo # In new checksum format, checksum calculated for whole page.
--echo # So It should affected.
let $error_code = 0;
if ($checksum_algorithm == "full_crc32")
{
let $error_code = 1;
}
if ($checksum_algorithm == "strict_full_crc32")
{
let $error_code = 1;
}
--error $error_code
--exec $INNOCHECKSUM $t6_IBD
--enable_result_log
@ -193,7 +209,9 @@ EOF
--exec $INNOCHECKSUM $t3_IBD
--echo # Run innochecksum on t6
--echo # no encryption corrupting the field should not have effect
--echo # In new checksum format, checksum calculated for whole page.
--echo # So It should affected.
--error $error_code
--exec $INNOCHECKSUM $t6_IBD
--enable_result_log

View file

@ -8,7 +8,7 @@
-- source include/not_embedded.inc
call mtr.add_suppression("InnoDB: Table `test`\\.`t[13]` (has an unreadable root page|is corrupted)");
call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=\\d+, page number=[36]\\] in file .*test.t[123]\\.ibd looks corrupted; key_version=3221342974");
call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=\\d+, page number=[36]\\] in file .*test.t[123]\\.ibd looks corrupted; key_version=");
SET GLOBAL innodb_file_per_table = ON;
set global innodb_compression_algorithm = 1;

View file

@ -1,26 +1,44 @@
--source include/have_innodb.inc
--source include/have_file_key_management_plugin.inc
--source include/innodb_checksum_algorithm.inc
#
# MDEV-11974: MariaDB 10.2 encryption does not support spatial indexes
#
#
# (1) Do not allow creating table with ENCRYPTED=YES
#
#
let $checksum_algorithm = `SELECT @@innodb_checksum_algorithm`;
let $error_code = ER_CANT_CREATE_TABLE, ER_ILLEGAL_HA_CREATE_OPTION;
if ($checksum_algorithm == "full_crc32")
{
let $error_code = 0;
}
if ($checksum_algorithm == "strict_full_crc32")
{
let $error_code = 0;
}
--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
--error ER_CANT_CREATE_TABLE
--error $error_code
CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT,
c VARCHAR(256), coordinate POINT NOT NULL, SPATIAL index(coordinate)) ENGINE=INNODB
ENCRYPTED=YES;
if (!$error_code) {
INSERT INTO t1(c, coordinate) values('mysql', ST_GeomFromText('POINT(903994614 180726515)'));
--source include/restart_mysqld.inc
INSERT INTO t1(c, coordinate) values('mariadb', ST_GeomFromText('POINT(903994614 180726515)'));
DROP TABLE t1;
}
#
# (2) Alter table
#
CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT,
c VARCHAR(256), coordinate POINT NOT NULL, SPATIAL index(coordinate)) ENGINE=INNODB;
--error ER_ILLEGAL_HA_CREATE_OPTION
--error $error_code
ALTER TABLE t1 ENCRYPTED=YES;
DROP TABLE t1;
@ -32,14 +50,14 @@ c VARCHAR(256), coordinate POINT NOT NULL) ENCRYPTED=YES ENGINE=INNODB;
# FIXME: MDEV-13851 Encrypted table refuses some form of ALGORITHM=COPY,
# but allows rebuild by FORCE
--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
--error ER_CANT_CREATE_TABLE
ALTER TABLE t1 ADD SPATIAL INDEX b(coordinate), ALGORITHM=COPY;
--error ER_ILLEGAL_HA_CREATE_OPTION
ALTER TABLE t1 ADD SPATIAL INDEX b(coordinate), FORCE, ALGORITHM=INPLACE;
--error ER_ILLEGAL_HA_CREATE_OPTION
--error $error_code
ALTER TABLE t1 ADD SPATIAL INDEX b1(coordinate), ALGORITHM=COPY;
--error $error_code
ALTER TABLE t1 ADD SPATIAL INDEX b2(coordinate), FORCE, ALGORITHM=INPLACE;
--error $error_code
ALTER TABLE t1 ADD SPATIAL INDEX(coordinate);
--error ER_ILLEGAL_HA_CREATE_OPTION
CREATE SPATIAL INDEX b on t1(coordinate);
--error $error_code
CREATE SPATIAL INDEX b3 on t1(coordinate);
DROP TABLE t1;
CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT,

View file

@ -0,0 +1,133 @@
FLUSH TABLES;
# Treating compact format as dynamic format after import stmt
CREATE TABLE t1
(a int AUTO_INCREMENT PRIMARY KEY,
b blob,
c blob,
KEY (b(200))) ENGINE=InnoDB ROW_FORMAT=COMPACT;
INSERT INTO t1 (b, c) values (repeat("ab", 200), repeat("bc", 200));
INSERT INTO t1 (b, c) values (repeat("bc", 200), repeat("cd", 200));
INSERT INTO t1 (b, c) values (repeat("cd", 200), repeat("ef", 200));
INSERT INTO t1 (b, c) values (repeat("de", 200), repeat("fg", 200));
INSERT INTO t1 (b, c) values (repeat("ef", 200), repeat("gh", 200));
INSERT INTO t1 (b, c) values (repeat("fg", 200), repeat("hi", 200));
INSERT INTO t1 (b, c) values (repeat("gh", 200), repeat("ij", 200));
INSERT INTO t1 (b, c) values (repeat("hi", 200), repeat("jk", 200));
INSERT INTO t1 (b, c) values (repeat("ij", 200), repeat("kl", 200));
INSERT INTO t1 (b, c) values (repeat("jk", 200), repeat("lm", 200));
INSERT INTO t1 (b, c) SELECT b,c FROM t1 ORDER BY a;
INSERT INTO t1 (b, c) SELECT b,c FROM t1 ORDER BY a;
SELECT COUNT(*) FROM t1;
COUNT(*)
40
FLUSH TABLE t1 FOR EXPORT;
# List before copying files
db.opt
t1.cfg
t1.frm
t1.ibd
backup: t1
UNLOCK TABLES;
ALTER TABLE t1 ROW_FORMAT=DYNAMIC;
ALTER TABLE t1 DISCARD TABLESPACE;
db.opt
t1.frm
restore: t1 .ibd and .cfg files
ALTER TABLE t1 IMPORT TABLESPACE;
Warnings:
Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t1.cfg', will attempt to import without schema verification
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL AUTO_INCREMENT,
`b` blob DEFAULT NULL,
`c` blob DEFAULT NULL,
PRIMARY KEY (`a`),
KEY `b` (`b`(200))
) ENGINE=InnoDB AUTO_INCREMENT=46 DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
UPDATE t1 set b = repeat("de", 100) where b = repeat("cd", 200);
explain SELECT a FROM t1 where b = repeat("de", 100);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref b b 203 const # Using where
SELECT a FROM t1 where b = repeat("de", 100);
a
3
13
28
38
SELECT COUNT(*) FROM t1;
COUNT(*)
40
DELETE FROM t1;
InnoDB 0 transactions not purged
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
CREATE TABLE t1
(c1 int AUTO_INCREMENT PRIMARY KEY,
c2 POINT NOT NULL,
c3 LINESTRING NOT NULL,
SPATIAL INDEX idx1(c2)) ENGINE=InnoDB ROW_FORMAT=COMPACT;
INSERT INTO t1(c2,c3) VALUES(
ST_GeomFromText('POINT(10 10)'),
ST_GeomFromText('LINESTRING(5 5,20 20,30 30)'));
INSERT INTO t1(c2,c3) VALUES(
ST_GeomFromText('POINT(20 20)'),
ST_GeomFromText('LINESTRING(5 15,20 10,30 20)'));
INSERT INTO t1(c2,c3) VALUES(
ST_GeomFromText('POINT(30 30)'),
ST_GeomFromText('LINESTRING(10 5,20 24,30 32)'));
INSERT INTO t1(c2,c3) VALUES(
ST_GeomFromText('POINT(40 40)'),
ST_GeomFromText('LINESTRING(15 5,25 20,35 30)'));
INSERT INTO t1(c2,c3) VALUES(
ST_GeomFromText('POINT(50 10)'),
ST_GeomFromText('LINESTRING(15 15,24 10,31 20)'));
INSERT INTO t1(c2,c3) VALUES(
ST_GeomFromText('POINT(60 50)'),
ST_GeomFromText('LINESTRING(10 15,20 44,35 32)'));
INSERT INTO t1(c2, c3) SELECT c2, c3 FROM t1;
INSERT INTO t1(c2, c3) SELECT c2, c3 FROM t1;
INSERT INTO t1(c2, c3) SELECT c2, c3 FROM t1;
INSERT INTO t1(c2, c3) SELECT c2, c3 FROM t1;
INSERT INTO t1(c2, c3) SELECT c2, c3 FROM t1;
INSERT INTO t1(c2, c3) SELECT c2, c3 FROM t1;
INSERT INTO t1(c2, c3) SELECT c2, c3 FROM t1;
INSERT INTO t1(c2, c3) SELECT c2, c3 FROM t1;
INSERT INTO t1(c2, c3) SELECT c2, c3 FROM t1;
INSERT INTO t1(c2, c3) SELECT c2, c3 FROM t1;
INSERT INTO t1(c2, c3) SELECT c2, c3 FROM t1;
FLUSH TABLE t1 FOR EXPORT;
# List before copying files
db.opt
t1.cfg
t1.frm
t1.ibd
backup: t1
UNLOCK TABLES;
ALTER TABLE t1 ROW_FORMAT=DYNAMIC;
ALTER TABLE t1 DISCARD TABLESPACE;
restore: t1 .ibd and .cfg files
ALTER TABLE t1 IMPORT TABLESPACE;
Warnings:
Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t1.cfg', will attempt to import without schema verification
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` int(11) NOT NULL AUTO_INCREMENT,
`c2` point NOT NULL,
`c3` linestring NOT NULL,
PRIMARY KEY (`c1`),
SPATIAL KEY `idx1` (`c2`)
) ENGINE=InnoDB AUTO_INCREMENT=14325 DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
UPDATE t1 SET C2 = ST_GeomFromText('POINT(0 0)');
SELECT COUNT(*) FROM t1;
COUNT(*)
12288
DELETE FROM t1;
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
InnoDB 0 transactions not purged
DROP TABLE t1;

View file

@ -0,0 +1,5 @@
120,121c120
< Warnings:
< Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t2.cfg', will attempt to import without schema verification
---
> ERROR HY000: Schema mismatch (Expected FSP_SPACE_FLAGS=0x*, .ibd file contains 0x*.)

View file

@ -0,0 +1,5 @@
120,121c120
< Warnings:
< Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t2.cfg', will attempt to import without schema verification
---
> ERROR HY000: Schema mismatch (Expected FSP_SPACE_FLAGS=0x*, .ibd file contains 0x*.)

View file

@ -117,7 +117,8 @@ t2.frm
ALTER TABLE t2 IMPORT TABLESPACE;
ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x21 and the meta-data file has 0x1; .cfg file uses ROW_FORMAT=COMPACT)
ALTER TABLE t2 IMPORT TABLESPACE;
ERROR HY000: Schema mismatch (Expected FSP_SPACE_FLAGS=0x*, .ibd file contains 0x*.)
Warnings:
Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t2.cfg', will attempt to import without schema verification
DROP TABLE t2;
SET GLOBAL innodb_file_per_table = 1;
SELECT @@innodb_file_per_table;

View file

@ -3,9 +3,8 @@
#
# FIXME: Unlike MySQL, maybe MariaDB should not read the .ibd files
# of tables with .isl file or DATA DIRECTORY attribute.
call mtr.add_suppression("\\[ERROR\\] InnoDB: Invalid flags 0x7a207879 in .*td\\.ibd");
# FIXME: This is much more noisy than MariaDB 10.1!
call mtr.add_suppression("\\[ERROR\\] InnoDB: Cannot read first page in datafile: .*td\\.ibd, Space ID:2048948345, Flags: 2048948345");
call mtr.add_suppression("\\[ERROR\\] InnoDB: Tablespace flags are invalid in datafile: .*test.t[rcd]\\.ibd");
call mtr.add_suppression("\\[ERROR\\] InnoDB: Operating system error number .* in a file operation\\.");
call mtr.add_suppression("\\[ERROR\\] InnoDB: The error means the system cannot find the path specified\\.");
call mtr.add_suppression("\\[ERROR\\] InnoDB: If you are installing InnoDB, remember that you must create directories yourself, InnoDB does not create them\\.");

View file

@ -2,6 +2,7 @@
# The embedded server does not support restarting in mysql-test-run.
-- source include/not_embedded.inc
-- source include/no_valgrind_without_big.inc
-- source include/innodb_checksum_algorithm.inc
let MYSQLD_DATADIR=`select @@datadir`;
let PAGE_SIZE=`select @@innodb_page_size`;
@ -55,10 +56,19 @@ my $page;
die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps;
substr($page,4,4)=pack("N",0xc001cafe);
my $polynomial = 0x82f63b78; # CRC-32C
my $ck= pack("N",mycrc32(substr($page, 4, 22), 0, $polynomial) ^
my $full_crc32 = unpack("N",substr($page,54,4)) & 0x10; # FIL_SPACE_FLAGS
if ($full_crc32)
{
my $ck = mycrc32(substr($page, 0, $ps-4), 0, $polynomial);
substr($page, $ps-4, 4) = pack("N", $ck);
}
else
{
my $ck= pack("N",mycrc32(substr($page, 4, 22), 0, $polynomial) ^
mycrc32(substr($page, 38, $ps - 38 - 8), 0, $polynomial));
substr($page,0,4)=$ck;
substr($page,$ps-8,4)=$ck;
substr($page,0,4)=$ck;
substr($page,$ps-8,4)=$ck;
}
sysseek(FILE, 0, 0) || die "Unable to rewind $file\n";
syswrite(FILE, $page, $ps)==$ps || die "Unable to write $file\n";
close(FILE) || die "Unable to close $file";
@ -116,10 +126,19 @@ my $page;
die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps;
substr($page,4,4)=pack("N",0);
my $polynomial = 0x82f63b78; # CRC-32C
my $ck= pack("N",mycrc32(substr($page, 4, 22), 0, $polynomial) ^
my $full_crc32 = unpack("N",substr($page,54,4)) & 0x10; # FIL_SPACE_FLAGS
if ($full_crc32)
{
my $ck = mycrc32(substr($page, 0, $ps-4), 0, $polynomial);
substr($page, $ps-4, 4) = pack("N", $ck);
}
else
{
my $ck= pack("N",mycrc32(substr($page, 4, 22), 0, $polynomial) ^
mycrc32(substr($page, 38, $ps - 38 - 8), 0, $polynomial));
substr($page,0,4)=$ck;
substr($page,$ps-8,4)=$ck;
substr($page,0,4)=$ck;
substr($page,$ps-8,4)=$ck;
}
sysseek(FILE, 0, 0) || die "Unable to rewind $file\n";
syswrite(FILE, $page, $ps)==$ps || die "Unable to write $file\n";
close(FILE) || die "Unable to close $file";

View file

@ -0,0 +1,5 @@
[strict_crc32]
--innodb-checksum-algorithm=strict_crc32
[strict_full_crc32]
--innodb-checksum-algorithm=strict_full_crc32

View file

@ -19,11 +19,14 @@ call mtr.add_suppression("InnoDB: New log files created");
call mtr.add_suppression("InnoDB: Cannot create doublewrite buffer: the first file in innodb_data_file_path must be at least (3|6|12)M\\.");
call mtr.add_suppression("InnoDB: Database creation was aborted");
call mtr.add_suppression("Plugin 'InnoDB' (init function returned error|registration as a STORAGE ENGINE failed)");
call mtr.add_suppression("InnoDB: A bad Space ID was found in datafile.*");
call mtr.add_suppression("InnoDB: Checksum mismatch in datafile: .*");
--enable_query_log
--source include/restart_mysqld.inc
let INNODB_PAGE_SIZE=`select @@innodb_page_size`;
let MYSQLD_DATADIR=`select @@datadir`;
let ALGO=`select @@innodb_checksum_algorithm`;
let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
show variables like 'innodb_doublewrite';
@ -75,14 +78,22 @@ perl;
use IO::Handle;
do "$ENV{MTR_SUITE_DIR}/include/crc32.pl";
my $polynomial = 0x82f63b78; # CRC-32C
my $algo = $ENV{ALGO};
die "Unsupported innodb_checksum_algorithm=$algo\n" unless $algo =~ /crc32/;
my $fname= "$ENV{'MYSQLD_DATADIR'}test/t1.ibd";
my $page_size = $ENV{INNODB_PAGE_SIZE};
my $page;
do "$ENV{MTR_SUITE_DIR}/../innodb/include/crc32.pl";
open(FILE, "+<", $fname) or die;
sysread(FILE, $page, $page_size)==$page_size||die "Unable to read $name\n";
my $page1 = $page;
substr($page1, 34, 4) = pack("N", 0);
my $polynomial0 = 0x82f63b78; # CRC-32C
my $ck0 = mycrc32(substr($page1, 0, ($page_size-4)), 0, $polynomial0);
substr($page1, ($page_size - 4), 4) = pack("N", $ck0);
sysseek(FILE, 0, 0)||die "Unable to seek $fname\n";
die unless syswrite(FILE, chr(0) x $page_size, $page_size) == $page_size;
die unless syswrite(FILE, $page1, $page_size) == $page_size;
close FILE;
open(FILE, "+<", "$ENV{MYSQLD_DATADIR}ibdata1")||die "cannot open ibdata1\n";
@ -105,12 +116,21 @@ for (my $d = $d1; $d < $d2 + 64; $d++)
$badflags |= ($flags & 15 << 6) << 7; # PAGE_SSIZE
substr ($_, 54, 4) = pack("N", $badflags);
# Replace the innodb_checksum_algorithm=crc32 checksum
my $ck= pack("N",
mycrc32(substr($_, 4, 22), 0, $polynomial) ^
mycrc32(substr($_, 38, $page_size - 38 - 8), 0, $polynomial));
substr ($_, 0, 4) = $ck;
substr ($_, $page_size - 8, 4) = $ck;
if ($algo =~ /full_crc32/)
{
my $ck = mycrc32(substr($_, 0, $page_size - 4), 0, $polynomial);
substr($_, $page_size - 4, 4) = pack("N", $ck);
}
else
{
# Replace the innodb_checksum_algorithm=crc32 checksum
my $ck= pack("N",
mycrc32(substr($_, 4, 22), 0, $polynomial) ^
mycrc32(substr($_, 38, $page_size - 38 - 8), 0,
$polynomial));
substr ($_, 0, 4) = $ck;
substr ($_, $page_size - 8, 4) = $ck;
}
syswrite(FILE, $_, $page_size)==$page_size||die;
close(FILE);
exit 0;
@ -153,10 +173,12 @@ set global innodb_buf_flush_list_now = 1;
perl;
use IO::Handle;
my $fname= "$ENV{'MYSQLD_DATADIR'}test/t1.ibd";
my $page_size = $ENV{INNODB_PAGE_SIZE};
open(FILE, "+<", $fname) or die;
FILE->autoflush(1);
binmode FILE;
print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}/2);
sysread(FILE, $page, $page_size)==$page_size||die "Unable to read $name\n";
substr($page, 28, 4) = pack("N", 1000);
sysseek(FILE, 0, 0)||die "Unable to seek $fname\n";
die unless syswrite(FILE, $page, $page_size) == $page_size;
close FILE;
EOF

View file

@ -0,0 +1 @@
--innodb_checksum_algorithm=full_crc32

View file

@ -0,0 +1,133 @@
-- source include/have_innodb.inc
FLUSH TABLES;
let $MYSQLD_TMPDIR = `SELECT @@tmpdir`;
let $MYSQLD_DATADIR = `SELECT @@datadir`;
--echo # Treating compact format as dynamic format after import stmt
CREATE TABLE t1
(a int AUTO_INCREMENT PRIMARY KEY,
b blob,
c blob,
KEY (b(200))) ENGINE=InnoDB ROW_FORMAT=COMPACT;
INSERT INTO t1 (b, c) values (repeat("ab", 200), repeat("bc", 200));
INSERT INTO t1 (b, c) values (repeat("bc", 200), repeat("cd", 200));
INSERT INTO t1 (b, c) values (repeat("cd", 200), repeat("ef", 200));
INSERT INTO t1 (b, c) values (repeat("de", 200), repeat("fg", 200));
INSERT INTO t1 (b, c) values (repeat("ef", 200), repeat("gh", 200));
INSERT INTO t1 (b, c) values (repeat("fg", 200), repeat("hi", 200));
INSERT INTO t1 (b, c) values (repeat("gh", 200), repeat("ij", 200));
INSERT INTO t1 (b, c) values (repeat("hi", 200), repeat("jk", 200));
INSERT INTO t1 (b, c) values (repeat("ij", 200), repeat("kl", 200));
INSERT INTO t1 (b, c) values (repeat("jk", 200), repeat("lm", 200));
INSERT INTO t1 (b, c) SELECT b,c FROM t1 ORDER BY a;
INSERT INTO t1 (b, c) SELECT b,c FROM t1 ORDER BY a;
SELECT COUNT(*) FROM t1;
FLUSH TABLE t1 FOR EXPORT;
--echo # List before copying files
let MYSQLD_DATADIR =`SELECT @@datadir`;
--list_files $MYSQLD_DATADIR/test
perl;
do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
ib_backup_tablespaces("test", "t1");
EOF
UNLOCK TABLES;
ALTER TABLE t1 ROW_FORMAT=DYNAMIC;
ALTER TABLE t1 DISCARD TABLESPACE;
--list_files $MYSQLD_DATADIR/test
perl;
do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
ib_discard_tablespaces("test", "t1");
ib_restore_tablespaces("test", "t1");
EOF
--remove_file $MYSQLD_DATADIR/test/t1.cfg
ALTER TABLE t1 IMPORT TABLESPACE;
SHOW CREATE TABLE t1;
UPDATE t1 set b = repeat("de", 100) where b = repeat("cd", 200);
--replace_column 9 #
explain SELECT a FROM t1 where b = repeat("de", 100);
SELECT a FROM t1 where b = repeat("de", 100);
SELECT COUNT(*) FROM t1;
DELETE FROM t1;
--source include/wait_all_purged.inc
CHECK TABLE t1;
DROP TABLE t1;
CREATE TABLE t1
(c1 int AUTO_INCREMENT PRIMARY KEY,
c2 POINT NOT NULL,
c3 LINESTRING NOT NULL,
SPATIAL INDEX idx1(c2)) ENGINE=InnoDB ROW_FORMAT=COMPACT;
INSERT INTO t1(c2,c3) VALUES(
ST_GeomFromText('POINT(10 10)'),
ST_GeomFromText('LINESTRING(5 5,20 20,30 30)'));
INSERT INTO t1(c2,c3) VALUES(
ST_GeomFromText('POINT(20 20)'),
ST_GeomFromText('LINESTRING(5 15,20 10,30 20)'));
INSERT INTO t1(c2,c3) VALUES(
ST_GeomFromText('POINT(30 30)'),
ST_GeomFromText('LINESTRING(10 5,20 24,30 32)'));
INSERT INTO t1(c2,c3) VALUES(
ST_GeomFromText('POINT(40 40)'),
ST_GeomFromText('LINESTRING(15 5,25 20,35 30)'));
INSERT INTO t1(c2,c3) VALUES(
ST_GeomFromText('POINT(50 10)'),
ST_GeomFromText('LINESTRING(15 15,24 10,31 20)'));
INSERT INTO t1(c2,c3) VALUES(
ST_GeomFromText('POINT(60 50)'),
ST_GeomFromText('LINESTRING(10 15,20 44,35 32)'));
INSERT INTO t1(c2, c3) SELECT c2, c3 FROM t1;
INSERT INTO t1(c2, c3) SELECT c2, c3 FROM t1;
INSERT INTO t1(c2, c3) SELECT c2, c3 FROM t1;
INSERT INTO t1(c2, c3) SELECT c2, c3 FROM t1;
INSERT INTO t1(c2, c3) SELECT c2, c3 FROM t1;
INSERT INTO t1(c2, c3) SELECT c2, c3 FROM t1;
INSERT INTO t1(c2, c3) SELECT c2, c3 FROM t1;
INSERT INTO t1(c2, c3) SELECT c2, c3 FROM t1;
INSERT INTO t1(c2, c3) SELECT c2, c3 FROM t1;
INSERT INTO t1(c2, c3) SELECT c2, c3 FROM t1;
INSERT INTO t1(c2, c3) SELECT c2, c3 FROM t1;
FLUSH TABLE t1 FOR EXPORT;
--echo # List before copying files
let MYSQLD_DATADIR =`SELECT @@datadir`;
--list_files $MYSQLD_DATADIR/test
perl;
do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
ib_backup_tablespaces("test", "t1");
EOF
UNLOCK TABLES;
ALTER TABLE t1 ROW_FORMAT=DYNAMIC;
ALTER TABLE t1 DISCARD TABLESPACE;
perl;
do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
ib_discard_tablespaces("test", "t1");
ib_restore_tablespaces("test", "t1");
EOF
--remove_file $MYSQLD_DATADIR/test/t1.cfg
ALTER TABLE t1 IMPORT TABLESPACE;
SHOW CREATE TABLE t1;
UPDATE t1 SET C2 = ST_GeomFromText('POINT(0 0)');
SELECT COUNT(*) FROM t1;
DELETE FROM t1;
CHECK TABLE t1;
--source include/wait_all_purged.inc
DROP TABLE t1;

View file

@ -2,6 +2,7 @@
--source include/not_embedded.inc
-- source include/have_innodb.inc
-- source include/innodb_checksum_algorithm.inc
call mtr.add_suppression("InnoDB: Unable to import tablespace .* because it already exists. Please DISCARD the tablespace before IMPORT.");
call mtr.add_suppression("Index for table 't2' is corrupt; try to repair it");
@ -9,6 +10,7 @@ FLUSH TABLES;
let $MYSQLD_TMPDIR = `SELECT @@tmpdir`;
let $MYSQLD_DATADIR = `SELECT @@datadir`;
let $checksum_algorithm = `SELECT @@innodb_checksum_algorithm`;
CREATE TABLE t1
(a INT AUTO_INCREMENT PRIMARY KEY,
@ -80,8 +82,19 @@ ALTER TABLE t2 DISCARD TABLESPACE;
--error ER_TABLE_SCHEMA_MISMATCH
ALTER TABLE t2 IMPORT TABLESPACE;
--remove_file $MYSQLD_DATADIR/test/t2.cfg
let $error_code = ER_TABLE_SCHEMA_MISMATCH;
if ($checksum_algorithm == "full_crc32") {
let $error_code = 0;
}
if ($checksum_algorithm == "strict_full_crc32") {
let $error_code = 0;
}
--replace_regex /(FSP_SPACE_FLAGS=0x)[0-9a-f]+(,.*0x)[0-9a-f]+(.*)/\1*\2*\3/
--error ER_TABLE_SCHEMA_MISMATCH
--error $error_code
ALTER TABLE t2 IMPORT TABLESPACE;
DROP TABLE t2;

View file

@ -14,9 +14,8 @@ let page_size= `select @@innodb_page_size`;
--echo # FIXME: Unlike MySQL, maybe MariaDB should not read the .ibd files
--echo # of tables with .isl file or DATA DIRECTORY attribute.
call mtr.add_suppression("\\[ERROR\\] InnoDB: Invalid flags 0x7a207879 in .*td\\.ibd");
--echo # FIXME: This is much more noisy than MariaDB 10.1!
call mtr.add_suppression("\\[ERROR\\] InnoDB: Cannot read first page in datafile: .*td\\.ibd, Space ID:2048948345, Flags: 2048948345");
call mtr.add_suppression("\\[ERROR\\] InnoDB: Tablespace flags are invalid in datafile: .*test.t[rcd]\\.ibd");
call mtr.add_suppression("\\[ERROR\\] InnoDB: Operating system error number .* in a file operation\\.");
call mtr.add_suppression("\\[ERROR\\] InnoDB: The error means the system cannot find the path specified\\.");
call mtr.add_suppression("\\[ERROR\\] InnoDB: If you are installing InnoDB, remember that you must create directories yourself, InnoDB does not create them\\.");

View file

@ -96,6 +96,9 @@ do "$ENV{MTR_SUITE_DIR}/include/crc32.pl";
my $ps= $ENV{INNODB_PAGE_SIZE};
my $file= "$ENV{bugdir}/ibdata1";
open(FILE, "+<", $file) || die "Unable to open $file\n";
die "Unable to read $file" unless sysread(FILE, $_, $ps) == $ps;
my $full_crc32 = unpack("N",substr($_,54,4)) & 0x10; # FIL_SPACE_FLAGS;
sysseek(FILE, 0, 0) || die "Unable to seek $file";
# Read DICT_HDR_TABLES, the root page number of CLUST_IND (SYS_TABLES.NAME).
sysseek(FILE, 7*$ps+38+32, 0) || die "Unable to seek $file";
die "Unable to read $file" unless sysread(FILE, $_, 4) == 4;
@ -122,10 +125,16 @@ for (my $offset= 0x65; $offset;
}
}
my $polynomial = 0x82f63b78; # CRC-32C
my $ck= pack("N",mycrc32(substr($page, 4, 22), 0, $polynomial) ^
if ($full_crc32) {
my $ck = mycrc32(substr($page, 0, $ps-4), 0, $polynomial);
substr($page, $ps-4, 4) = pack("N", $ck);
} else {
my $ck= pack("N",mycrc32(substr($page, 4, 22), 0, $polynomial) ^
mycrc32(substr($page, 38, $ps - 38 - 8), 0, $polynomial));
substr($page,0,4)=$ck;
substr($page,$ps-8,4)=$ck;
substr($page,0,4)=$ck;
substr($page,$ps-8,4)=$ck;
}
sysseek(FILE, $sys_tables_root*$ps, 0) || die "Unable to seek $file";
syswrite(FILE, $page, $ps)==$ps || die "Unable to write $file\n";
close(FILE) || die "Unable to close $file\n";

View file

@ -0,0 +1,5 @@
[strict_crc32]
--innodb-checksum-algorithm=strict_crc32
[strict_full_crc32]
--innodb-checksum-algorithm=strict_full_crc32

View file

@ -0,0 +1 @@
--innodb-checksum-algorithm=crc32

View file

@ -56,6 +56,8 @@ do "$ENV{MTR_SUITE_DIR}/include/crc32.pl";
my $ps= $ENV{INNODB_PAGE_SIZE};
my $file= "$ENV{bugdir}/ibdata1";
open(FILE, "+<", $file) || die "Unable to open $file\n";
die "Unable to read $file" unless sysread(FILE, $_, 58) == 58;
my $full_crc32 = unpack("N",substr($_,54,4)) & 0x10; # FIL_SPACE_FLAGS
# Read DICT_HDR_TABLES, the root page number of CLUST_IND (SYS_TABLES.NAME).
sysseek(FILE, 7*$ps+38+32, 0) || die "Unable to seek $file";
die "Unable to read $file" unless sysread(FILE, $_, 4) == 4;
@ -129,10 +131,18 @@ for (my $offset= 0x65; $offset;
print ")\n";
}
my $polynomial = 0x82f63b78; # CRC-32C
my $ck= pack("N",mycrc32(substr($page, 4, 22), 0, $polynomial) ^
if ($full_crc32)
{
my $ck = mycrc32(substr($page, 0, $ps-4), 0, $polynomial);
substr($page, $ps-4, 4) = pack("N", $ck);
}
else
{
my $ck= pack("N",mycrc32(substr($page, 4, 22), 0, $polynomial) ^
mycrc32(substr($page, 38, $ps - 38 - 8), 0, $polynomial));
substr($page,0,4)=$ck;
substr($page,$ps-8,4)=$ck;
substr($page,0,4)=$ck;
substr($page,$ps-8,4)=$ck;
}
sysseek(FILE, $sys_tables_root*$ps, 0) || die "Unable to seek $file";
syswrite(FILE, $page, $ps)==$ps || die "Unable to write $file\n";
close(FILE) || die "Unable to close $file\n";

View file

@ -0,0 +1,5 @@
[strict_crc32]
--innodb-checksum-algorithm=strict_crc32
[strict_full_crc32]
--innodb-checksum-algorithm=strict_full_crc32

View file

@ -32,6 +32,7 @@ while ($i) {
--enable_query_log
commit;
let $checksum_algorithm = `SELECT @@GLOBAL.innodb_checksum_algorithm`;
let SEARCH_PATTERN = ib_undo_trunc;
begin;
update t1 set c = 'MariaDB';
@ -41,6 +42,15 @@ commit;
SET GLOBAL innodb_fast_shutdown=0;
--source include/shutdown_mysqld.inc
--source include/search_pattern_in_file.inc
if ($checksum_algorithm == "strict_full_crc32")
{
let $restart_parameters= --innodb_checksum_algorithm=strict_crc32;
}
if ($checksum_algorithm == "strict_crc32")
{
let $restart_parameters= --innodb_checksum_algorithm=strict_full_crc32;
}
--source include/start_mysqld.inc
drop table t1;

View file

@ -0,0 +1,16 @@
--- 16k.result
+++ 16k.reject
@@ -41,10 +41,10 @@
test/t4 5 33 PRIMARY 3 3 1 50
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
Space_Name Space_Type Page_Size Zip_Size Formats_Permitted Path
-test/t1 Single DEFAULT DEFAULT Compact or Redundant MYSQLD_DATADIR/test/t1.ibd
-test/t2 Single DEFAULT DEFAULT Compact or Redundant MYSQLD_DATADIR/test/t2.ibd
+test/t1 Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t1.ibd
+test/t2 Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t2.ibd
test/t3 Single DEFAULT 8192 Compressed MYSQLD_DATADIR/test/t3.ibd
-test/t4 Single DEFAULT DEFAULT Dynamic MYSQLD_DATADIR/test/t4.ibd
+test/t4 Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t4.ibd
DROP TABLE t1, t2, t3, t4;
# Test 4) The maximum row size is dependent upon the page size.
# Redundant: 8123, Compact: 8126.

View file

@ -0,0 +1,16 @@
--- 16k.result
+++ 16k.reject
@@ -41,10 +41,10 @@
test/t4 5 33 PRIMARY 3 3 1 50
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
Space_Name Space_Type Page_Size Zip_Size Formats_Permitted Path
-test/t1 Single DEFAULT DEFAULT Compact or Redundant MYSQLD_DATADIR/test/t1.ibd
-test/t2 Single DEFAULT DEFAULT Compact or Redundant MYSQLD_DATADIR/test/t2.ibd
+test/t1 Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t1.ibd
+test/t2 Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t2.ibd
test/t3 Single DEFAULT 8192 Compressed MYSQLD_DATADIR/test/t3.ibd
-test/t4 Single DEFAULT DEFAULT Dynamic MYSQLD_DATADIR/test/t4.ibd
+test/t4 Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t4.ibd
DROP TABLE t1, t2, t3, t4;
# Test 4) The maximum row size is dependent upon the page size.
# Redundant: 8123, Compact: 8126.

View file

@ -379,7 +379,7 @@ Table Op Msg_type Msg_text
test.t1 check status OK
EXPLAIN SELECT * FROM t1 WHERE b LIKE 'adfd%';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range b b 769 NULL 12 Using where
1 SIMPLE t1 range b b 769 NULL # Using where
DROP TABLE t1;
# Test 8) Test creating a table that could lead to undo log overflow.
CREATE TABLE t1(a blob,b blob,c blob,d blob,e blob,f blob,g blob,
@ -686,8 +686,8 @@ SELECT COUNT(*) FROM
(SELECT * FROM t1 FORCE INDEX (idx,PRIMARY)
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 1537
2 DERIVED t1 index_merge PRIMARY,idx idx,PRIMARY 5,4 NULL 1537 Using sort_union(idx,PRIMARY); Using where
1 PRIMARY <derived2> ALL NULL NULL NULL NULL #
2 DERIVED t1 index_merge PRIMARY,idx idx,PRIMARY 5,4 NULL # Using sort_union(idx,PRIMARY); Using where
SELECT COUNT(*) FROM
(SELECT * FROM t1 FORCE INDEX (idx,PRIMARY)
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;

View file

@ -0,0 +1,16 @@
--- 8k.result
+++ 8k.result
@@ -45,10 +45,10 @@
test/t4 5 33 PRIMARY 3 3 1 50
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
Space_Name Space_Type Page_Size Zip_Size Formats_Permitted Path
-test/t1 Single DEFAULT DEFAULT Compact or Redundant MYSQLD_DATADIR/test/t1.ibd
-test/t2 Single DEFAULT DEFAULT Compact or Redundant MYSQLD_DATADIR/test/t2.ibd
+test/t1 Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t1.ibd
+test/t2 Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t2.ibd
test/t3 Single DEFAULT 4096 Compressed MYSQLD_DATADIR/test/t3.ibd
-test/t4 Single DEFAULT DEFAULT Dynamic MYSQLD_DATADIR/test/t4.ibd
+test/t4 Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t4.ibd
DROP TABLE t1, t2, t3, t4;
# Test 4) The maximum row size is dependent upon the page size.
# Redundant: 4027, Compact: 4030.

View file

@ -0,0 +1,16 @@
--- 8k.result
+++ 8k.result
@@ -45,10 +45,10 @@
test/t4 5 33 PRIMARY 3 3 1 50
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
Space_Name Space_Type Page_Size Zip_Size Formats_Permitted Path
-test/t1 Single DEFAULT DEFAULT Compact or Redundant MYSQLD_DATADIR/test/t1.ibd
-test/t2 Single DEFAULT DEFAULT Compact or Redundant MYSQLD_DATADIR/test/t2.ibd
+test/t1 Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t1.ibd
+test/t2 Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t2.ibd
test/t3 Single DEFAULT 4096 Compressed MYSQLD_DATADIR/test/t3.ibd
-test/t4 Single DEFAULT DEFAULT Dynamic MYSQLD_DATADIR/test/t4.ibd
+test/t4 Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t4.ibd
DROP TABLE t1, t2, t3, t4;
# Test 4) The maximum row size is dependent upon the page size.
# Redundant: 4027, Compact: 4030.

View file

@ -0,0 +1,188 @@
--- restart.result
+++ restart.reject
@@ -211,18 +211,18 @@
test/t7_restart#p#p1#sp#s3 test/t7_restart#p#p1#sp#s3 97 8 Dynamic 0 Single
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
Space_Name Space_Type Page_Size Zip_Size Formats_Permitted Path
-test/t1_restart Single DEFAULT DEFAULT Compact or Redundant MYSQLD_DATADIR/test/t1_restart.ibd
-test/t2_restart Single DEFAULT DEFAULT Compact or Redundant MYSQLD_DATADIR/test/t2_restart.ibd
+test/t1_restart Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t1_restart.ibd
+test/t2_restart Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t2_restart.ibd
test/t3_restart Single DEFAULT 2048 Compressed MYSQLD_DATADIR/test/t3_restart.ibd
-test/t4_restart Single DEFAULT DEFAULT Dynamic MYSQLD_DATADIR/test/t4_restart.ibd
-test/t5_restart Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t5_restart.ibd
+test/t4_restart Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t4_restart.ibd
+test/t5_restart Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t5_restart.ibd
test/t6_restart#p#p0 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p0.ibd
test/t6_restart#p#p1 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p1.ibd
test/t6_restart#p#p2 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p2.ibd
-test/t7_restart#p#p0#sp#s0 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s0.ibd
-test/t7_restart#p#p0#sp#s1 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s1.ibd
-test/t7_restart#p#p1#sp#s2 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s2.ibd
-test/t7_restart#p#p1#sp#s3 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s3.ibd
+test/t7_restart#p#p0#sp#s0 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s0.ibd
+test/t7_restart#p#p0#sp#s1 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s1.ibd
+test/t7_restart#p#p1#sp#s2 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s2.ibd
+test/t7_restart#p#p1#sp#s3 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s3.ibd
#
# Shutdown the server and list the tablespace OS files
#
@@ -395,18 +395,18 @@
test/t7_restart#p#p1#sp#s3 test/t7_restart#p#p1#sp#s3 97 8 Dynamic 0 Single
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
Space_Name Space_Type Page_Size Zip_Size Formats_Permitted Path
-test/t1_restart Single DEFAULT DEFAULT Compact or Redundant MYSQLD_DATADIR/test/t1_restart.ibd
-test/t2_restart Single DEFAULT DEFAULT Compact or Redundant MYSQLD_DATADIR/test/t2_restart.ibd
+test/t1_restart Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t1_restart.ibd
+test/t2_restart Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t2_restart.ibd
test/t3_restart Single DEFAULT 2048 Compressed MYSQLD_DATADIR/test/t3_restart.ibd
-test/t4_restart Single DEFAULT DEFAULT Dynamic MYSQLD_DATADIR/test/t4_restart.ibd
-test/t5_restart Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t5_restart.ibd
+test/t4_restart Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t4_restart.ibd
+test/t5_restart Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t5_restart.ibd
test/t6_restart#p#p0 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p0.ibd
test/t6_restart#p#p1 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p1.ibd
test/t6_restart#p#p2 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p2.ibd
-test/t7_restart#p#p0#sp#s0 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s0.ibd
-test/t7_restart#p#p0#sp#s1 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s1.ibd
-test/t7_restart#p#p1#sp#s2 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s2.ibd
-test/t7_restart#p#p1#sp#s3 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s3.ibd
+test/t7_restart#p#p0#sp#s0 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s0.ibd
+test/t7_restart#p#p0#sp#s1 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s1.ibd
+test/t7_restart#p#p1#sp#s2 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s2.ibd
+test/t7_restart#p#p1#sp#s3 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s3.ibd
DROP TABLE t1_restart;
DROP TABLE t2_restart;
DROP TABLE t3_restart;
@@ -418,15 +418,15 @@
ALTER TABLE t7_restart TRUNCATE PARTITION p1;
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
Space_Name Space_Type Page_Size Zip_Size Formats_Permitted Path
-test/t4_restart Single DEFAULT DEFAULT Dynamic MYSQLD_DATADIR/test/t4_restart.ibd
+test/t4_restart Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t4_restart.ibd
test/t6_restart#p#p0 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p0.ibd
test/t6_restart#p#p1 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p1.ibd
-test/t7_restart#p#p0#sp#s0 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s0.ibd
-test/t7_restart#p#p0#sp#s1 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s1.ibd
-test/t5_restart Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t5_restart.ibd
+test/t7_restart#p#p0#sp#s0 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s0.ibd
+test/t7_restart#p#p0#sp#s1 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s1.ibd
+test/t5_restart Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t5_restart.ibd
test/t6_restart#p#p2 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p2.ibd
-test/t7_restart#p#p1#sp#s2 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s2.ibd
-test/t7_restart#p#p1#sp#s3 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s3.ibd
+test/t7_restart#p#p1#sp#s2 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s2.ibd
+test/t7_restart#p#p1#sp#s3 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s3.ibd
INSERT INTO t5_restart VALUES (1000000000, 'MySQL', 'InnoDB', '2011-11-11', 'Read this after reboot');
INSERT INTO t5_restart (SELECT 0, c2, c3, c4, c5 FROM t5_restart);
INSERT INTO t5_restart (SELECT 0, c2, c3, c4, c5 FROM t5_restart);
@@ -522,15 +522,15 @@
innodb_file_per_table ON
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
Space_Name Space_Type Page_Size Zip_Size Formats_Permitted Path
-test/t4_restart Single DEFAULT DEFAULT Dynamic MYSQLD_DATADIR/test/t4_restart.ibd
+test/t4_restart Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t4_restart.ibd
test/t6_restart#p#p0 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p0.ibd
test/t6_restart#p#p1 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p1.ibd
-test/t7_restart#p#p0#sp#s0 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s0.ibd
-test/t7_restart#p#p0#sp#s1 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s1.ibd
-test/t5_restart Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t5_restart.ibd
+test/t7_restart#p#p0#sp#s0 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s0.ibd
+test/t7_restart#p#p0#sp#s1 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s1.ibd
+test/t5_restart Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t5_restart.ibd
test/t6_restart#p#p2 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p2.ibd
-test/t7_restart#p#p1#sp#s2 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s2.ibd
-test/t7_restart#p#p1#sp#s3 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s3.ibd
+test/t7_restart#p#p1#sp#s2 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s2.ibd
+test/t7_restart#p#p1#sp#s3 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s3.ibd
SELECT count(*) FROM t5_restart;
count(*)
8
@@ -623,15 +623,15 @@
RENAME TABLE t7_restart TO t77_restart;
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
Space_Name Space_Type Page_Size Zip_Size Formats_Permitted Path
-test/t4_restart Single DEFAULT DEFAULT Dynamic MYSQLD_DATADIR/test/t4_restart.ibd
+test/t4_restart Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t4_restart.ibd
test/t66_restart#p#p0 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t66_restart#p#p0.ibd
test/t66_restart#p#p1 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t66_restart#p#p1.ibd
-test/t77_restart#p#p0#sp#s0 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p0#sp#s0.ibd
-test/t77_restart#p#p0#sp#s1 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p0#sp#s1.ibd
-test/t55_restart Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t55_restart.ibd
+test/t77_restart#p#p0#sp#s0 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p0#sp#s0.ibd
+test/t77_restart#p#p0#sp#s1 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p0#sp#s1.ibd
+test/t55_restart Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t55_restart.ibd
test/t66_restart#p#p2 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t66_restart#p#p2.ibd
-test/t77_restart#p#p1#sp#s2 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p1#sp#s2.ibd
-test/t77_restart#p#p1#sp#s3 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p1#sp#s3.ibd
+test/t77_restart#p#p1#sp#s2 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p1#sp#s2.ibd
+test/t77_restart#p#p1#sp#s3 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p1#sp#s3.ibd
INSERT INTO t55_restart (SELECT 0, c2, c3, c4, c5 FROM t55_restart);
SELECT count(*) FROM t55_restart;
count(*)
@@ -720,15 +720,15 @@
innodb_file_per_table ON
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
Space_Name Space_Type Page_Size Zip_Size Formats_Permitted Path
-test/t4_restart Single DEFAULT DEFAULT Dynamic MYSQLD_DATADIR/test/t4_restart.ibd
+test/t4_restart Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t4_restart.ibd
test/t66_restart#p#p0 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t66_restart#p#p0.ibd
test/t66_restart#p#p1 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t66_restart#p#p1.ibd
-test/t77_restart#p#p0#sp#s0 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p0#sp#s0.ibd
-test/t77_restart#p#p0#sp#s1 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p0#sp#s1.ibd
-test/t55_restart Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t55_restart.ibd
+test/t77_restart#p#p0#sp#s0 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p0#sp#s0.ibd
+test/t77_restart#p#p0#sp#s1 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p0#sp#s1.ibd
+test/t55_restart Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t55_restart.ibd
test/t66_restart#p#p2 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t66_restart#p#p2.ibd
-test/t77_restart#p#p1#sp#s2 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p1#sp#s2.ibd
-test/t77_restart#p#p1#sp#s3 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p1#sp#s3.ibd
+test/t77_restart#p#p1#sp#s2 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p1#sp#s2.ibd
+test/t77_restart#p#p1#sp#s3 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p1#sp#s3.ibd
INSERT INTO t55_restart (SELECT 0, c2, c3, c4, c5 FROM t55_restart);
SELECT count(*) FROM t55_restart;
count(*)
@@ -853,15 +853,15 @@
#
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
Space_Name Space_Type Page_Size Zip_Size Formats_Permitted Path
-test/t4_restart Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/new_dir/test/t4_restart.ibd
+test/t4_restart Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/new_dir/test/t4_restart.ibd
test/t66_restart#p#p0 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/new_dir/test/t66_restart#p#p0.ibd
test/t66_restart#p#p1 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/new_dir/test/t66_restart#p#p1.ibd
-test/t77_restart#p#p0#sp#s0 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/new_dir/test/t77_restart#p#p0#sp#s0.ibd
-test/t77_restart#p#p0#sp#s1 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/new_dir/test/t77_restart#p#p0#sp#s1.ibd
-test/t55_restart Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/new_dir/test/t55_restart.ibd
+test/t77_restart#p#p0#sp#s0 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/new_dir/test/t77_restart#p#p0#sp#s0.ibd
+test/t77_restart#p#p0#sp#s1 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/new_dir/test/t77_restart#p#p0#sp#s1.ibd
+test/t55_restart Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/new_dir/test/t55_restart.ibd
test/t66_restart#p#p2 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/new_dir/test/t66_restart#p#p2.ibd
-test/t77_restart#p#p1#sp#s2 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/new_dir/test/t77_restart#p#p1#sp#s2.ibd
-test/t77_restart#p#p1#sp#s3 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/new_dir/test/t77_restart#p#p1#sp#s3.ibd
+test/t77_restart#p#p1#sp#s2 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/new_dir/test/t77_restart#p#p1#sp#s2.ibd
+test/t77_restart#p#p1#sp#s3 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/new_dir/test/t77_restart#p#p1#sp#s3.ibd
INSERT INTO t4_restart (SELECT 0, c2, c3, c4, c5 FROM t4_restart);
SELECT count(*) FROM t4_restart;
count(*)
@@ -990,15 +990,15 @@
#
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
Space_Name Space_Type Page_Size Zip_Size Formats_Permitted Path
-test/t4_restart Single DEFAULT DEFAULT Dynamic MYSQLD_DATADIR/test/t4_restart.ibd
+test/t4_restart Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t4_restart.ibd
test/t66_restart#p#p0 Single DEFAULT DEFAULT Compressed MYSQLD_DATADIR/test/t66_restart#p#p0.ibd
test/t66_restart#p#p1 Single DEFAULT DEFAULT Compressed MYSQLD_DATADIR/test/t66_restart#p#p1.ibd
-test/t77_restart#p#p0#sp#s0 Single DEFAULT DEFAULT Dynamic MYSQLD_DATADIR/test/t77_restart#p#p0#sp#s0.ibd
-test/t77_restart#p#p0#sp#s1 Single DEFAULT DEFAULT Dynamic MYSQLD_DATADIR/test/t77_restart#p#p0#sp#s1.ibd
-test/t55_restart Single DEFAULT DEFAULT Dynamic MYSQLD_DATADIR/test/t55_restart.ibd
+test/t77_restart#p#p0#sp#s0 Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t77_restart#p#p0#sp#s0.ibd
+test/t77_restart#p#p0#sp#s1 Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t77_restart#p#p0#sp#s1.ibd
+test/t55_restart Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t55_restart.ibd
test/t66_restart#p#p2 Single DEFAULT DEFAULT Compressed MYSQLD_DATADIR/test/t66_restart#p#p2.ibd
-test/t77_restart#p#p1#sp#s2 Single DEFAULT DEFAULT Dynamic MYSQLD_DATADIR/test/t77_restart#p#p1#sp#s2.ibd
-test/t77_restart#p#p1#sp#s3 Single DEFAULT DEFAULT Dynamic MYSQLD_DATADIR/test/t77_restart#p#p1#sp#s3.ibd
+test/t77_restart#p#p1#sp#s2 Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t77_restart#p#p1#sp#s2.ibd
+test/t77_restart#p#p1#sp#s3 Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t77_restart#p#p1#sp#s3.ibd
INSERT INTO t4_restart (SELECT 0, c2, c3, c4, c5 FROM t4_restart);
SELECT count(*) FROM t4_restart;
count(*)

View file

@ -0,0 +1,188 @@
--- restart.result
+++ restart.reject
@@ -211,18 +211,18 @@
test/t7_restart#p#p1#sp#s3 test/t7_restart#p#p1#sp#s3 97 8 Dynamic 0 Single
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
Space_Name Space_Type Page_Size Zip_Size Formats_Permitted Path
-test/t1_restart Single DEFAULT DEFAULT Compact or Redundant MYSQLD_DATADIR/test/t1_restart.ibd
-test/t2_restart Single DEFAULT DEFAULT Compact or Redundant MYSQLD_DATADIR/test/t2_restart.ibd
+test/t1_restart Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t1_restart.ibd
+test/t2_restart Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t2_restart.ibd
test/t3_restart Single DEFAULT 2048 Compressed MYSQLD_DATADIR/test/t3_restart.ibd
-test/t4_restart Single DEFAULT DEFAULT Dynamic MYSQLD_DATADIR/test/t4_restart.ibd
-test/t5_restart Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t5_restart.ibd
+test/t4_restart Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t4_restart.ibd
+test/t5_restart Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t5_restart.ibd
test/t6_restart#p#p0 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p0.ibd
test/t6_restart#p#p1 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p1.ibd
test/t6_restart#p#p2 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p2.ibd
-test/t7_restart#p#p0#sp#s0 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s0.ibd
-test/t7_restart#p#p0#sp#s1 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s1.ibd
-test/t7_restart#p#p1#sp#s2 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s2.ibd
-test/t7_restart#p#p1#sp#s3 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s3.ibd
+test/t7_restart#p#p0#sp#s0 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s0.ibd
+test/t7_restart#p#p0#sp#s1 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s1.ibd
+test/t7_restart#p#p1#sp#s2 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s2.ibd
+test/t7_restart#p#p1#sp#s3 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s3.ibd
#
# Shutdown the server and list the tablespace OS files
#
@@ -395,18 +395,18 @@
test/t7_restart#p#p1#sp#s3 test/t7_restart#p#p1#sp#s3 97 8 Dynamic 0 Single
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
Space_Name Space_Type Page_Size Zip_Size Formats_Permitted Path
-test/t1_restart Single DEFAULT DEFAULT Compact or Redundant MYSQLD_DATADIR/test/t1_restart.ibd
-test/t2_restart Single DEFAULT DEFAULT Compact or Redundant MYSQLD_DATADIR/test/t2_restart.ibd
+test/t1_restart Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t1_restart.ibd
+test/t2_restart Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t2_restart.ibd
test/t3_restart Single DEFAULT 2048 Compressed MYSQLD_DATADIR/test/t3_restart.ibd
-test/t4_restart Single DEFAULT DEFAULT Dynamic MYSQLD_DATADIR/test/t4_restart.ibd
-test/t5_restart Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t5_restart.ibd
+test/t4_restart Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t4_restart.ibd
+test/t5_restart Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t5_restart.ibd
test/t6_restart#p#p0 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p0.ibd
test/t6_restart#p#p1 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p1.ibd
test/t6_restart#p#p2 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p2.ibd
-test/t7_restart#p#p0#sp#s0 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s0.ibd
-test/t7_restart#p#p0#sp#s1 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s1.ibd
-test/t7_restart#p#p1#sp#s2 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s2.ibd
-test/t7_restart#p#p1#sp#s3 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s3.ibd
+test/t7_restart#p#p0#sp#s0 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s0.ibd
+test/t7_restart#p#p0#sp#s1 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s1.ibd
+test/t7_restart#p#p1#sp#s2 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s2.ibd
+test/t7_restart#p#p1#sp#s3 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s3.ibd
DROP TABLE t1_restart;
DROP TABLE t2_restart;
DROP TABLE t3_restart;
@@ -418,15 +418,15 @@
ALTER TABLE t7_restart TRUNCATE PARTITION p1;
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
Space_Name Space_Type Page_Size Zip_Size Formats_Permitted Path
-test/t4_restart Single DEFAULT DEFAULT Dynamic MYSQLD_DATADIR/test/t4_restart.ibd
+test/t4_restart Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t4_restart.ibd
test/t6_restart#p#p0 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p0.ibd
test/t6_restart#p#p1 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p1.ibd
-test/t7_restart#p#p0#sp#s0 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s0.ibd
-test/t7_restart#p#p0#sp#s1 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s1.ibd
-test/t5_restart Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t5_restart.ibd
+test/t7_restart#p#p0#sp#s0 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s0.ibd
+test/t7_restart#p#p0#sp#s1 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s1.ibd
+test/t5_restart Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t5_restart.ibd
test/t6_restart#p#p2 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p2.ibd
-test/t7_restart#p#p1#sp#s2 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s2.ibd
-test/t7_restart#p#p1#sp#s3 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s3.ibd
+test/t7_restart#p#p1#sp#s2 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s2.ibd
+test/t7_restart#p#p1#sp#s3 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s3.ibd
INSERT INTO t5_restart VALUES (1000000000, 'MySQL', 'InnoDB', '2011-11-11', 'Read this after reboot');
INSERT INTO t5_restart (SELECT 0, c2, c3, c4, c5 FROM t5_restart);
INSERT INTO t5_restart (SELECT 0, c2, c3, c4, c5 FROM t5_restart);
@@ -522,15 +522,15 @@
innodb_file_per_table ON
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
Space_Name Space_Type Page_Size Zip_Size Formats_Permitted Path
-test/t4_restart Single DEFAULT DEFAULT Dynamic MYSQLD_DATADIR/test/t4_restart.ibd
+test/t4_restart Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t4_restart.ibd
test/t6_restart#p#p0 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p0.ibd
test/t6_restart#p#p1 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p1.ibd
-test/t7_restart#p#p0#sp#s0 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s0.ibd
-test/t7_restart#p#p0#sp#s1 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s1.ibd
-test/t5_restart Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t5_restart.ibd
+test/t7_restart#p#p0#sp#s0 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s0.ibd
+test/t7_restart#p#p0#sp#s1 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s1.ibd
+test/t5_restart Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t5_restart.ibd
test/t6_restart#p#p2 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p2.ibd
-test/t7_restart#p#p1#sp#s2 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s2.ibd
-test/t7_restart#p#p1#sp#s3 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s3.ibd
+test/t7_restart#p#p1#sp#s2 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s2.ibd
+test/t7_restart#p#p1#sp#s3 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s3.ibd
SELECT count(*) FROM t5_restart;
count(*)
8
@@ -623,15 +623,15 @@
RENAME TABLE t7_restart TO t77_restart;
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
Space_Name Space_Type Page_Size Zip_Size Formats_Permitted Path
-test/t4_restart Single DEFAULT DEFAULT Dynamic MYSQLD_DATADIR/test/t4_restart.ibd
+test/t4_restart Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t4_restart.ibd
test/t66_restart#p#p0 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t66_restart#p#p0.ibd
test/t66_restart#p#p1 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t66_restart#p#p1.ibd
-test/t77_restart#p#p0#sp#s0 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p0#sp#s0.ibd
-test/t77_restart#p#p0#sp#s1 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p0#sp#s1.ibd
-test/t55_restart Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t55_restart.ibd
+test/t77_restart#p#p0#sp#s0 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p0#sp#s0.ibd
+test/t77_restart#p#p0#sp#s1 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p0#sp#s1.ibd
+test/t55_restart Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t55_restart.ibd
test/t66_restart#p#p2 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t66_restart#p#p2.ibd
-test/t77_restart#p#p1#sp#s2 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p1#sp#s2.ibd
-test/t77_restart#p#p1#sp#s3 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p1#sp#s3.ibd
+test/t77_restart#p#p1#sp#s2 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p1#sp#s2.ibd
+test/t77_restart#p#p1#sp#s3 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p1#sp#s3.ibd
INSERT INTO t55_restart (SELECT 0, c2, c3, c4, c5 FROM t55_restart);
SELECT count(*) FROM t55_restart;
count(*)
@@ -720,15 +720,15 @@
innodb_file_per_table ON
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
Space_Name Space_Type Page_Size Zip_Size Formats_Permitted Path
-test/t4_restart Single DEFAULT DEFAULT Dynamic MYSQLD_DATADIR/test/t4_restart.ibd
+test/t4_restart Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t4_restart.ibd
test/t66_restart#p#p0 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t66_restart#p#p0.ibd
test/t66_restart#p#p1 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t66_restart#p#p1.ibd
-test/t77_restart#p#p0#sp#s0 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p0#sp#s0.ibd
-test/t77_restart#p#p0#sp#s1 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p0#sp#s1.ibd
-test/t55_restart Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t55_restart.ibd
+test/t77_restart#p#p0#sp#s0 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p0#sp#s0.ibd
+test/t77_restart#p#p0#sp#s1 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p0#sp#s1.ibd
+test/t55_restart Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t55_restart.ibd
test/t66_restart#p#p2 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/alt_dir/test/t66_restart#p#p2.ibd
-test/t77_restart#p#p1#sp#s2 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p1#sp#s2.ibd
-test/t77_restart#p#p1#sp#s3 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p1#sp#s3.ibd
+test/t77_restart#p#p1#sp#s2 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p1#sp#s2.ibd
+test/t77_restart#p#p1#sp#s3 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p1#sp#s3.ibd
INSERT INTO t55_restart (SELECT 0, c2, c3, c4, c5 FROM t55_restart);
SELECT count(*) FROM t55_restart;
count(*)
@@ -853,15 +853,15 @@
#
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
Space_Name Space_Type Page_Size Zip_Size Formats_Permitted Path
-test/t4_restart Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/new_dir/test/t4_restart.ibd
+test/t4_restart Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/new_dir/test/t4_restart.ibd
test/t66_restart#p#p0 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/new_dir/test/t66_restart#p#p0.ibd
test/t66_restart#p#p1 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/new_dir/test/t66_restart#p#p1.ibd
-test/t77_restart#p#p0#sp#s0 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/new_dir/test/t77_restart#p#p0#sp#s0.ibd
-test/t77_restart#p#p0#sp#s1 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/new_dir/test/t77_restart#p#p0#sp#s1.ibd
-test/t55_restart Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/new_dir/test/t55_restart.ibd
+test/t77_restart#p#p0#sp#s0 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/new_dir/test/t77_restart#p#p0#sp#s0.ibd
+test/t77_restart#p#p0#sp#s1 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/new_dir/test/t77_restart#p#p0#sp#s1.ibd
+test/t55_restart Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/new_dir/test/t55_restart.ibd
test/t66_restart#p#p2 Single DEFAULT DEFAULT Compressed MYSQL_TMP_DIR/new_dir/test/t66_restart#p#p2.ibd
-test/t77_restart#p#p1#sp#s2 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/new_dir/test/t77_restart#p#p1#sp#s2.ibd
-test/t77_restart#p#p1#sp#s3 Single DEFAULT DEFAULT Dynamic MYSQL_TMP_DIR/new_dir/test/t77_restart#p#p1#sp#s3.ibd
+test/t77_restart#p#p1#sp#s2 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/new_dir/test/t77_restart#p#p1#sp#s2.ibd
+test/t77_restart#p#p1#sp#s3 Single DEFAULT DEFAULT NULL MYSQL_TMP_DIR/new_dir/test/t77_restart#p#p1#sp#s3.ibd
INSERT INTO t4_restart (SELECT 0, c2, c3, c4, c5 FROM t4_restart);
SELECT count(*) FROM t4_restart;
count(*)
@@ -990,15 +990,15 @@
#
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
Space_Name Space_Type Page_Size Zip_Size Formats_Permitted Path
-test/t4_restart Single DEFAULT DEFAULT Dynamic MYSQLD_DATADIR/test/t4_restart.ibd
+test/t4_restart Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t4_restart.ibd
test/t66_restart#p#p0 Single DEFAULT DEFAULT Compressed MYSQLD_DATADIR/test/t66_restart#p#p0.ibd
test/t66_restart#p#p1 Single DEFAULT DEFAULT Compressed MYSQLD_DATADIR/test/t66_restart#p#p1.ibd
-test/t77_restart#p#p0#sp#s0 Single DEFAULT DEFAULT Dynamic MYSQLD_DATADIR/test/t77_restart#p#p0#sp#s0.ibd
-test/t77_restart#p#p0#sp#s1 Single DEFAULT DEFAULT Dynamic MYSQLD_DATADIR/test/t77_restart#p#p0#sp#s1.ibd
-test/t55_restart Single DEFAULT DEFAULT Dynamic MYSQLD_DATADIR/test/t55_restart.ibd
+test/t77_restart#p#p0#sp#s0 Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t77_restart#p#p0#sp#s0.ibd
+test/t77_restart#p#p0#sp#s1 Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t77_restart#p#p0#sp#s1.ibd
+test/t55_restart Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t55_restart.ibd
test/t66_restart#p#p2 Single DEFAULT DEFAULT Compressed MYSQLD_DATADIR/test/t66_restart#p#p2.ibd
-test/t77_restart#p#p1#sp#s2 Single DEFAULT DEFAULT Dynamic MYSQLD_DATADIR/test/t77_restart#p#p1#sp#s2.ibd
-test/t77_restart#p#p1#sp#s3 Single DEFAULT DEFAULT Dynamic MYSQLD_DATADIR/test/t77_restart#p#p1#sp#s3.ibd
+test/t77_restart#p#p1#sp#s2 Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t77_restart#p#p1#sp#s2.ibd
+test/t77_restart#p#p1#sp#s3 Single DEFAULT DEFAULT NULL MYSQLD_DATADIR/test/t77_restart#p#p1#sp#s3.ibd
INSERT INTO t4_restart (SELECT 0, c2, c3, c4, c5 FROM t4_restart);
SELECT count(*) FROM t4_restart;
count(*)

View file

@ -2,6 +2,8 @@
--source include/big_test.inc
--source include/have_innodb.inc
--source include/have_innodb_16k.inc
--source include/innodb_checksum_algorithm.inc
SET default_storage_engine=InnoDB;
--disable_query_log
@ -339,6 +341,7 @@ SELECT a,
LENGTH(b), b=LEFT(REPEAT(d,100*a), 65535),LENGTH(c), c=REPEAT(d,20*a), d FROM t1;
SHOW CREATE TABLE t1;
CHECK TABLE t1;
--replace_column 9 #
EXPLAIN SELECT * FROM t1 WHERE b LIKE 'adfd%';
# The following tests are disabled because of the introduced timeouts for
@ -689,6 +692,7 @@ set @optimizer_switch_saved=@@optimizer_switch;
SET SESSION optimizer_switch='derived_merge=off';
SET SESSION sort_buffer_size = 1024*36;
--replace_column 9 #
EXPLAIN
SELECT COUNT(*) FROM
(SELECT * FROM t1 FORCE INDEX (idx,PRIMARY)

View file

@ -2,6 +2,8 @@
--source include/have_innodb.inc
--source include/have_innodb_8k.inc
--source include/innodb_checksum_algorithm.inc
SET default_storage_engine=InnoDB;
--disable_query_log

View file

@ -0,0 +1,5 @@
[crc32]
--innodb-checksum-algorithm=crc32
[full_crc32]
--innodb-checksum-algorithm=full_crc32

View file

@ -13,6 +13,8 @@
let MYSQLD_BASEDIR= `SELECT @@basedir`;
let MYSQLD_DATADIR= `SELECT @@datadir`;
let SEARCH_FILE= $MYSQLTEST_VARDIR/log/my_restart.err;
let $checksum_algorithm = `SELECT @@innodb_checksum_algorithm`;
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");
@ -79,22 +81,34 @@ let SEARCH_PATTERN= Error: --strict-check option cannot be used together with --
--echo [9]: check the innochecksum with full form --strict-check=innodb
# Server Default checksum = crc32
--error 1
let $error_code = 0;
if ($checksum_algorithm == "crc32")
{
let $error_code = 1;
}
if ($checksum_algorithm == "strict_crc32")
{
let $error_code = 1;
}
--error $error_code
--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
--error 1
--error $error_code
--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
--error 1
--error $error_code
--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
--error 1
--error $error_code
--exec $INNOCHECKSUM -C none $MYSQLD_DATADIR/test/tab1.ibd 2> $SEARCH_FILE
--echo [13]: check strict-check with invalid values

View file

@ -0,0 +1,5 @@
[crc32]
--innodb-checksum-algorithm=crc32
[full_crc32]
--innodb-checksum-algorithm=full_crc32

View file

@ -0,0 +1 @@
--innodb_checksum_algorithm=crc32

View file

@ -4,6 +4,8 @@
--source include/innodb_page_size_small.inc
--source include/have_partition.inc
--source include/not_embedded.inc
--source include/innodb_checksum_algorithm.inc
SET default_storage_engine=InnoDB;
LET $MYSQLD_DATADIR = `select @@datadir`;
LET $INNODB_PAGE_SIZE = `select @@innodb_page_size`;

View file

@ -4,3 +4,4 @@
--loose-file-key-management-filekey=FILE:$MTR_SUITE_DIR/filekeys-data.key
--loose-file-key-management-filename=$MTR_SUITE_DIR/filekeys-data.enc
--loose-file-key-management-encryption-algorithm=aes_cbc
--innodb-checksum-algorithm=crc32

View file

@ -0,0 +1,5 @@
[strict_crc32]
--innodb-checksum-algorithm=strict_crc32
[strict_full_crc32]
--innodb-checksum-algorithm=strict_full_crc32

View file

@ -20,10 +20,12 @@ my $page;
die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps;
substr($page,26,8) = pack("NN", 4096, ~1024);
my $polynomial = 0x82f63b78; # CRC-32C
my $ck= pack("N",mycrc32(substr($page, 4, 22), 0, $polynomial) ^
mycrc32(substr($page, 38, $ps - 38 - 8), 0, $polynomial));
substr($page,0,4)=$ck;
substr($page,$ps-8,4)=$ck;
my $full_crc32 = unpack("N",substr($page,54,4)) & 0x10; # FIL_SPACE_FLAGS
if ($full_crc32)
{
my $ck = mycrc32(substr($page, 0, $ps-4), 0, $polynomial);
substr($page, $ps-4, 4) = pack("N", $ck);
}
sysseek(FILE, 0, 0) || die "Unable to rewind $file\n";
syswrite(FILE, $page, $ps)==$ps || die "Unable to write $file\n";
close(FILE) || die "Unable to close $file\n";

View file

@ -34,7 +34,6 @@ exec $XTRABACKUP --prepare --verbose --apply-log-only --target-dir=$basedir --in
echo # Restore and check results;
let $targetdir=$basedir;
#-- source include/restart_and_restore.inc
let $_datadir= `SELECT @@datadir`;
let $innodb_data_file_path=`SELECT @@innodb_data_file_path`;

View file

@ -26,21 +26,29 @@ SET GLOBAL innodb_checksum_algorithm = 'strict_none';
SELECT @@global.innodb_checksum_algorithm;
@@global.innodb_checksum_algorithm
strict_none
SET GLOBAL innodb_checksum_algorithm = 'full_crc32';
SELECT @@global.innodb_checksum_algorithm;
@@global.innodb_checksum_algorithm
full_crc32
SET GLOBAL innodb_checksum_algorithm = 'strict_full_crc32';
SELECT @@global.innodb_checksum_algorithm;
@@global.innodb_checksum_algorithm
strict_full_crc32
SET GLOBAL innodb_checksum_algorithm = '';
ERROR 42000: Variable 'innodb_checksum_algorithm' can't be set to the value of ''
SELECT @@global.innodb_checksum_algorithm;
@@global.innodb_checksum_algorithm
strict_none
strict_full_crc32
SET GLOBAL innodb_checksum_algorithm = 'foobar';
ERROR 42000: Variable 'innodb_checksum_algorithm' can't be set to the value of 'foobar'
SELECT @@global.innodb_checksum_algorithm;
@@global.innodb_checksum_algorithm
strict_none
strict_full_crc32
SET GLOBAL innodb_checksum_algorithm = 123;
ERROR 42000: Variable 'innodb_checksum_algorithm' can't be set to the value of '123'
SELECT @@global.innodb_checksum_algorithm;
@@global.innodb_checksum_algorithm
strict_none
strict_full_crc32
SET GLOBAL innodb_checksum_algorithm = @orig;
SELECT @@global.innodb_checksum_algorithm;
@@global.innodb_checksum_algorithm

View file

@ -421,11 +421,11 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE crc32
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE ENUM
VARIABLE_COMMENT The algorithm InnoDB uses for page checksumming. Possible values are CRC32 (hardware accelerated if the CPU supports it) write crc32, allow any of the other checksums to match when reading; STRICT_CRC32 write crc32, do not allow other algorithms to match when reading; INNODB write a software calculated checksum, allow any other checksums to match when reading; STRICT_INNODB write a software calculated checksum, do not allow other algorithms to match when reading; NONE write a constant magic number, do not do any checksum verification when reading (same as innodb_checksums=OFF); STRICT_NONE write a constant magic number, do not allow values other than that magic number when reading; Files updated when this option is set to crc32 or strict_crc32 will not be readable by MariaDB versions older than 10.0.4
VARIABLE_COMMENT The algorithm InnoDB uses for page checksumming. Possible values are FULL_CRC32 for new files, always use CRC-32C; for old, see CRC32 below; STRICT_FULL_CRC32 for new files, always use CRC-32C; for old, see STRICT_CRC32 below; CRC32 write crc32, allow any of the other checksums to match when reading; STRICT_CRC32 write crc32, do not allow other algorithms to match when reading; INNODB write a software calculated checksum, allow any other checksums to match when reading; STRICT_INNODB write a software calculated checksum, do not allow other algorithms to match when reading; NONE write a constant magic number, do not do any checksum verification when reading (same as innodb_checksums=OFF); STRICT_NONE write a constant magic number, do not allow values other than that magic number when reading; Files updated when this option is set to crc32 or strict_crc32 will not be readable by MariaDB versions older than 10.0.4; new files created with full_crc32 are readable by MariaDB 10.4.3+
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST crc32,strict_crc32,innodb,strict_innodb,none,strict_none
ENUM_VALUE_LIST crc32,strict_crc32,innodb,strict_innodb,none,strict_none,full_crc32,strict_full_crc32
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME INNODB_CMP_PER_INDEX_ENABLED

View file

@ -22,6 +22,12 @@ SELECT @@global.innodb_checksum_algorithm;
SET GLOBAL innodb_checksum_algorithm = 'strict_none';
SELECT @@global.innodb_checksum_algorithm;
SET GLOBAL innodb_checksum_algorithm = 'full_crc32';
SELECT @@global.innodb_checksum_algorithm;
SET GLOBAL innodb_checksum_algorithm = 'strict_full_crc32';
SELECT @@global.innodb_checksum_algorithm;
-- error ER_WRONG_VALUE_FOR_VAR
SET GLOBAL innodb_checksum_algorithm = '';
SELECT @@global.innodb_checksum_algorithm;

View file

@ -491,6 +491,7 @@ static bool buf_page_decrypt_after_read(buf_page_t* bpage, fil_space_t* space)
also for pages first compressed and then encrypted. */
buf_tmp_buffer_t* slot;
uint key_version = buf_page_get_key_version(dst_frame, space->flags);
if (page_compressed) {
/* the page we read is unencrypted */
@ -500,31 +501,26 @@ decompress:
/* For decompression, use crypt_buf. */
buf_tmp_reserve_crypt_buf(slot);
decompress_with_slot:
ut_d(fil_page_type_validate(dst_frame));
ut_d(fil_page_type_validate(space, dst_frame));
bpage->write_size = fil_page_decompress(slot->crypt_buf,
dst_frame);
slot->release();
ut_ad(!bpage->write_size || fil_page_type_validate(dst_frame));
ut_ad(!bpage->write_size || fil_page_type_validate(space, dst_frame));
ut_ad(space->pending_io());
return bpage->write_size != 0;
}
if (space->crypt_data
&& mach_read_from_4(FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION
+ dst_frame)) {
if (key_version && space->crypt_data) {
/* Verify encryption checksum before we even try to
decrypt. */
if (!fil_space_verify_crypt_checksum(
dst_frame, space->zip_size())) {
if (!buf_page_verify_crypt_checksum(dst_frame, space->flags)) {
decrypt_failed:
ib::error() << "Encrypted page " << bpage->id
<< " in file " << space->chain.start->name
<< " looks corrupted; key_version="
<< mach_read_from_4(
FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION
+ dst_frame);
<< key_version;
/* Mark page encrypted in case it should be. */
if (space->crypt_data->type
!= CRYPT_SCHEME_UNENCRYPTED) {
@ -538,7 +534,7 @@ decrypt_failed:
slot = buf_pool_reserve_tmp_slot(buf_pool);
buf_tmp_reserve_crypt_buf(slot);
ut_d(fil_page_type_validate(dst_frame));
ut_d(fil_page_type_validate(space, dst_frame));
/* decrypt using crypt_buf to dst_frame */
if (!fil_space_decrypt(space, slot->crypt_buf,
@ -547,7 +543,7 @@ decrypt_failed:
goto decrypt_failed;
}
ut_d(fil_page_type_validate(dst_frame));
ut_d(fil_page_type_validate(space, dst_frame));
if (fil_page_is_compressed_encrypted(dst_frame)) {
goto decompress_with_slot;
@ -886,62 +882,25 @@ buf_page_is_checksum_valid_none(
&& checksum_field1 == BUF_NO_CHECKSUM_MAGIC);
}
/** Check if a page is corrupt.
@param[in] check_lsn whether the LSN should be checked
/** Checks if the page is in full crc32 checksum format.
@param[in] read_buf database page
@param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0
@param[in] space tablespace
@return whether the page is corrupted */
bool
buf_page_is_corrupted(
bool check_lsn,
const byte* read_buf,
ulint zip_size,
#ifndef UNIV_INNOCHECKSUM
const fil_space_t* space)
#else
const void* space)
#endif
@param[in] checksum_field checksum field
@return true if the page is in full crc32 checksum format. */
bool buf_page_is_checksum_valid_full_crc32(
const byte* read_buf,
size_t checksum_field)
{
#ifndef UNIV_INNOCHECKSUM
DBUG_EXECUTE_IF("buf_page_import_corrupt_failure", return(true); );
#endif
size_t checksum_field1 = 0;
size_t checksum_field2 = 0;
uint32_t crc32 = 0;
bool crc32_inited = false;
const uint32_t full_crc32 = buf_calc_page_full_crc32(read_buf);
ulint page_type = mach_read_from_2(read_buf + FIL_PAGE_TYPE);
/* We can trust page type if page compression is set on tablespace
flags because page compression flag means file must have been
created with 10.1 (later than 5.5 code base). In 10.1 page
compressed tables do not contain post compression checksum and
FIL_PAGE_END_LSN_OLD_CHKSUM field stored. Note that space can
be null if we are in fil_check_first_page() and first page
is not compressed or encrypted. Page checksum is verified
after decompression (i.e. normally pages are already
decompressed at this stage). */
if ((page_type == FIL_PAGE_PAGE_COMPRESSED ||
page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED)
#ifndef UNIV_INNOCHECKSUM
&& space && FSP_FLAGS_HAS_PAGE_COMPRESSION(space->flags)
#endif
) {
return(false);
}
if (!zip_size
&& memcmp(read_buf + FIL_PAGE_LSN + 4,
read_buf + srv_page_size
- FIL_PAGE_END_LSN_OLD_CHKSUM + 4, 4)) {
/* Stored log sequence numbers at the start and the end
of page do not match */
return(true);
}
return checksum_field == full_crc32;
}
/** Checks whether the lsn present in the page is lesser than the
peek current lsn.
@param[in] check_lsn lsn to check
@param[in] read_buf page. */
static void buf_page_check_lsn(bool check_lsn, const byte* read_buf)
{
#ifndef UNIV_INNOCHECKSUM
if (check_lsn && recv_lsn_checks_on) {
lsn_t current_lsn;
@ -973,10 +932,106 @@ buf_page_is_corrupted(
}
}
#endif /* !UNIV_INNOCHECKSUM */
}
/** Check if a page is corrupt.
@param[in] check_lsn whether the LSN should be checked
@param[in] read_buf database page
@param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0
@param[in] space tablespace
@return whether the page is corrupted */
bool
buf_page_is_corrupted(
bool check_lsn,
const byte* read_buf,
ulint fsp_flags)
{
#ifndef UNIV_INNOCHECKSUM
DBUG_EXECUTE_IF("buf_page_import_corrupt_failure", return(true); );
#endif
if (FSP_FLAGS_FCRC32_HAS_MARKER(fsp_flags)) {
const byte* end = read_buf + srv_page_size;
uint crc32 = mach_read_from_4(end - FIL_PAGE_FCRC32_CHECKSUM);
if (!crc32) {
const byte* b = read_buf;
while (b != end) if (*b++) goto nonzero;
/* An all-zero page is not corrupted. */
return false;
}
DBUG_EXECUTE_IF(
"page_intermittent_checksum_mismatch", {
static int page_counter;
if (page_counter++ == 2) {
crc32++;
}
});
nonzero:
if (!buf_page_is_checksum_valid_full_crc32(read_buf, crc32)) {
return true;
}
if (!mach_read_from_4(read_buf + FIL_PAGE_FCRC32_KEY_VERSION)
&& memcmp(read_buf + (FIL_PAGE_LSN + 4),
end - FIL_PAGE_FCRC32_END_LSN, 4)) {
return true;
}
buf_page_check_lsn(check_lsn, read_buf);
return false;
}
size_t checksum_field1 = 0;
size_t checksum_field2 = 0;
uint32_t crc32 = 0;
bool crc32_inited = false;
ulint zip_size = 0;
bool crc32_chksum = false;
zip_size = FSP_FLAGS_GET_ZIP_SSIZE(fsp_flags);
if (zip_size) {
zip_size = (UNIV_ZIP_SIZE_MIN >> 1) << zip_size;
}
ulint page_type = mach_read_from_2(read_buf + FIL_PAGE_TYPE);
/* We can trust page type if page compression is set on tablespace
flags because page compression flag means file must have been
created with 10.1 (later than 5.5 code base). In 10.1 page
compressed tables do not contain post compression checksum and
FIL_PAGE_END_LSN_OLD_CHKSUM field stored. Note that space can
be null if we are in fil_check_first_page() and first page
is not compressed or encrypted. Page checksum is verified
after decompression (i.e. normally pages are already
decompressed at this stage). */
if ((page_type == FIL_PAGE_PAGE_COMPRESSED ||
page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED)
#ifndef UNIV_INNOCHECKSUM
&& FSP_FLAGS_HAS_PAGE_COMPRESSION(fsp_flags)
#endif
) {
return(false);
}
if (!zip_size && memcmp(read_buf + FIL_PAGE_LSN + 4,
read_buf + srv_page_size
- FIL_PAGE_END_LSN_OLD_CHKSUM + 4, 4)) {
/* Stored log sequence numbers at the start and the end
of page do not match */
return(true);
}
buf_page_check_lsn(check_lsn, read_buf);
/* Check whether the checksum fields have correct values */
if (srv_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_NONE) {
const srv_checksum_algorithm_t curr_algo =
static_cast<srv_checksum_algorithm_t>(srv_checksum_algorithm);
if (curr_algo == SRV_CHECKSUM_ALGORITHM_NONE) {
return(false);
}
@ -1014,10 +1069,8 @@ buf_page_is_corrupted(
return(false);
}
const srv_checksum_algorithm_t curr_algo =
static_cast<srv_checksum_algorithm_t>(srv_checksum_algorithm);
switch (curr_algo) {
case SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32:
case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:
return !buf_page_is_checksum_valid_crc32(
read_buf, checksum_field1, checksum_field2);
@ -1027,6 +1080,7 @@ buf_page_is_corrupted(
case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:
return !buf_page_is_checksum_valid_none(
read_buf, checksum_field1, checksum_field2);
case SRV_CHECKSUM_ALGORITHM_FULL_CRC32:
case SRV_CHECKSUM_ALGORITHM_CRC32:
case SRV_CHECKSUM_ALGORITHM_INNODB:
if (buf_page_is_checksum_valid_none(read_buf,
@ -1051,6 +1105,9 @@ buf_page_is_corrupted(
return false;
}
crc32_chksum = curr_algo == SRV_CHECKSUM_ALGORITHM_CRC32
|| curr_algo == SRV_CHECKSUM_ALGORITHM_FULL_CRC32;
/* Very old versions of InnoDB only stored 8 byte lsn to the
start and the end of the page. */
@ -1061,17 +1118,17 @@ buf_page_is_corrupted(
!= mach_read_from_4(read_buf + FIL_PAGE_LSN)
&& checksum_field2 != BUF_NO_CHECKSUM_MAGIC) {
if (srv_checksum_algorithm
== SRV_CHECKSUM_ALGORITHM_CRC32) {
if (crc32_chksum) {
crc32 = buf_calc_page_crc32(read_buf);
crc32_inited = true;
DBUG_EXECUTE_IF(
"page_intermittent_checksum_mismatch", {
static int page_counter;
if (page_counter++ == 2) {
checksum_field2++;
crc32++;
}
});
crc32 = buf_calc_page_crc32(read_buf);
crc32_inited = true;
if (checksum_field2 != crc32
&& checksum_field2
@ -1079,7 +1136,7 @@ buf_page_is_corrupted(
return true;
}
} else {
ut_ad(srv_checksum_algorithm
ut_ad(curr_algo
== SRV_CHECKSUM_ALGORITHM_INNODB);
if (checksum_field2
@ -1096,8 +1153,7 @@ buf_page_is_corrupted(
if (checksum_field1 == 0
|| checksum_field1 == BUF_NO_CHECKSUM_MAGIC) {
} else if (srv_checksum_algorithm
== SRV_CHECKSUM_ALGORITHM_CRC32) {
} else if (crc32_chksum) {
if (!crc32_inited) {
crc32 = buf_calc_page_crc32(read_buf);
@ -1110,8 +1166,7 @@ buf_page_is_corrupted(
return true;
}
} else {
ut_ad(srv_checksum_algorithm
== SRV_CHECKSUM_ALGORITHM_INNODB);
ut_ad(curr_algo == SRV_CHECKSUM_ALGORITHM_INNODB);
if (checksum_field1
!= buf_calc_page_new_checksum(read_buf)) {
@ -5808,6 +5863,26 @@ buf_mark_space_corrupt(buf_page_t* bpage, const fil_space_t* space)
buf_pool_mutex_exit(buf_pool);
}
/** Check if the encrypted page is corrupted for the full crc32 format.
@param[in] space_id page belongs to space id
@param[in] dst_frame page
@return true if page is corrupted or false if it isn't */
static bool buf_encrypted_full_crc32_page_is_corrupted(
ulint space_id,
const byte* dst_frame)
{
if (memcmp(dst_frame + FIL_PAGE_LSN + 4,
dst_frame + srv_page_size - FIL_PAGE_FCRC32_END_LSN, 4)) {
return true;
}
if (space_id != mach_read_from_4(dst_frame + FIL_PAGE_SPACE_ID)) {
return true;
}
return false;
}
/** Check if page is maybe compressed, encrypted or both when we encounter
corrupted page. Note that we can't be 100% sure if page is corrupted
or decrypt/decompress just failed.
@ -5827,6 +5902,7 @@ static dberr_t buf_page_check_corrupt(buf_page_t* bpage, fil_space_t* space)
((buf_block_t*) bpage)->frame;
dberr_t err = DB_SUCCESS;
bool corrupted = false;
uint key_version = buf_page_get_key_version(dst_frame, space->flags);
/* In buf_decrypt_after_read we have either decrypted the page if
page post encryption checksum matches and used key_id is found
@ -5834,8 +5910,7 @@ static dberr_t buf_page_check_corrupt(buf_page_t* bpage, fil_space_t* space)
not decrypted and it could be either encrypted and corrupted
or corrupted or good page. If we decrypted, there page could
still be corrupted if used key does not match. */
const bool still_encrypted = mach_read_from_4(
dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION)
const bool still_encrypted = key_version
&& space->crypt_data
&& space->crypt_data->type != CRYPT_SCHEME_UNENCRYPTED
&& !bpage->encrypted
@ -5845,8 +5920,13 @@ static dberr_t buf_page_check_corrupt(buf_page_t* bpage, fil_space_t* space)
if (!still_encrypted) {
/* If traditional checksums match, we assume that page is
not anymore encrypted. */
corrupted = buf_page_is_corrupted(
true, dst_frame, bpage->zip_size(), space);
if (key_version && space->full_crc32()) {
corrupted = buf_encrypted_full_crc32_page_is_corrupted(
space->id, dst_frame);
} else {
corrupted = buf_page_is_corrupted(
true, dst_frame, space->flags);
}
if (!corrupted) {
bpage->encrypted = false;
@ -5871,8 +5951,7 @@ static dberr_t buf_page_check_corrupt(buf_page_t* bpage, fil_space_t* space)
ib::info()
<< "However key management plugin or used key_version "
<< mach_read_from_4(dst_frame
+ FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION)
<< key_version
<< " is not found or"
" used encryption algorithm or method does not match.";
@ -5963,8 +6042,7 @@ buf_page_io_complete(buf_page_t* bpage, bool dblwr, bool evict)
read_page_no = mach_read_from_4(frame + FIL_PAGE_OFFSET);
read_space_id = mach_read_from_4(
frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
key_version = mach_read_from_4(
frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
key_version = buf_page_get_key_version(frame, space->flags);
if (bpage->id.space() == TRX_SYS_SPACE
&& buf_dblwr_page_inside(bpage->id.page_no())) {
@ -7190,6 +7268,21 @@ buf_all_freed(void)
return(TRUE);
}
/** Verify that post encryption checksum match with the calculated checksum.
This function should be called only if tablespace contains crypt data metadata.
@param[in] page page frame
@param[in] fsp_flags tablespace flags
@return true if true if page is encrypted and OK, false otherwise */
bool buf_page_verify_crypt_checksum(const byte* page, ulint fsp_flags)
{
if (!fil_space_t::full_crc32(fsp_flags)) {
return fil_space_verify_crypt_checksum(
page, fil_space_t::zip_size(fsp_flags));
}
return !buf_page_is_corrupted(true, page, fsp_flags);
}
/*********************************************************************//**
Checks that there currently are no pending i/o-operations for the buffer
pool.
@ -7271,7 +7364,7 @@ a page is written to disk.
(may be src_frame or an encrypted/compressed copy of it) */
UNIV_INTERN
byte*
buf_page_encrypt_before_write(
buf_page_encrypt(
fil_space_t* space,
buf_page_t* bpage,
byte* src_frame)
@ -7279,7 +7372,7 @@ buf_page_encrypt_before_write(
ut_ad(space->id == bpage->id.space());
bpage->real_size = srv_page_size;
fil_page_type_validate(src_frame);
ut_d(fil_page_type_validate(space, src_frame));
switch (bpage->id.page_no()) {
case 0:
@ -7306,7 +7399,13 @@ buf_page_encrypt_before_write(
if (!encrypted && !page_compressed) {
/* No need to encrypt or page compress the page.
Clear key-version & crypt-checksum. */
memset(src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 0, 8);
if (space->full_crc32()) {
memset(src_frame + FIL_PAGE_FCRC32_KEY_VERSION, 0, 4);
} else {
memset(src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,
0, 8);
}
return src_frame;
}
@ -7332,16 +7431,16 @@ not_compressed:
bpage->real_size = srv_page_size;
slot->out_buf = dst_frame = tmp;
ut_d(fil_page_type_validate(tmp));
ut_d(fil_page_type_validate(space, tmp));
} else {
/* First we compress the page content */
buf_tmp_reserve_compression_buf(slot);
byte* tmp = slot->comp_buf;
ulint out_len = fil_page_compress(
src_frame, tmp,
fsp_flags_get_page_compression_level(space->flags),
src_frame, tmp, space->flags,
fil_space_get_block_size(space, bpage->id.page_no()),
encrypted);
if (!out_len) {
goto not_compressed;
}
@ -7350,7 +7449,7 @@ not_compressed:
/* Workaround for MDEV-15527. */
memset(tmp + out_len, 0 , srv_page_size - out_len);
ut_d(fil_page_type_validate(tmp));
ut_d(fil_page_type_validate(space, tmp));
if (encrypted) {
/* And then we encrypt the page content */
@ -7364,7 +7463,7 @@ not_compressed:
slot->out_buf = dst_frame = tmp;
}
ut_d(fil_page_type_validate(dst_frame));
ut_d(fil_page_type_validate(space, dst_frame));
// return dst_frame which will be written
return dst_frame;

View file

@ -102,6 +102,14 @@ buf_calc_page_old_checksum(const byte* page)
(ut_fold_binary(page, FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION)));
}
/** Calculate the CRC32 checksum for the whole page.
@param[in] page buffer page (srv_page_size bytes)
@return CRC32 value */
uint32_t buf_calc_page_full_crc32(const byte* page)
{
return ut_crc32(page, srv_page_size - FIL_PAGE_FCRC32_CHECKSUM);
}
/** Return a printable string describing the checksum algorithm.
@param[in] algo algorithm
@return algorithm name */
@ -121,6 +129,10 @@ buf_checksum_algorithm_name(srv_checksum_algorithm_t algo)
return("none");
case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:
return("strict_none");
case SRV_CHECKSUM_ALGORITHM_FULL_CRC32:
return("full_crc32");
case SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32:
return("strict_full_crc32");
}
ut_error;

View file

@ -477,6 +477,7 @@ buf_dblwr_init_or_load_pages(
page = buf;
for (ulint i = 0; i < TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * 2; i++) {
if (reset_space_ids) {
ulint source_page_no;
@ -609,6 +610,7 @@ buf_dblwr_process()
read_buf, physical_size);
const bool expect_encrypted = space->crypt_data
&& space->crypt_data->type != CRYPT_SCHEME_UNENCRYPTED;
bool is_corrupted = false;
if (is_all_zero) {
/* We will check if the copy in the
@ -623,13 +625,16 @@ buf_dblwr_process()
goto bad;
}
if (expect_encrypted && mach_read_from_4(
read_buf
+ FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION)
? fil_space_verify_crypt_checksum(read_buf,
zip_size)
: !buf_page_is_corrupted(true, read_buf,
zip_size, space)) {
if (expect_encrypted
&& buf_page_get_key_version(read_buf, space->flags)) {
is_corrupted = !buf_page_verify_crypt_checksum(
read_buf, space->flags);
} else {
is_corrupted = buf_page_is_corrupted(
true, read_buf, space->flags);
}
if (!is_corrupted) {
/* The page is good; there is no need
to consult the doublewrite buffer. */
continue;
@ -648,10 +653,16 @@ bad:
goto bad_doublewrite;
}
if (expect_encrypted && mach_read_from_4(
page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION)
? !fil_space_verify_crypt_checksum(page, zip_size)
: buf_page_is_corrupted(true, page, zip_size, space)) {
if (expect_encrypted
&& buf_page_get_key_version(read_buf, space->flags)) {
is_corrupted = !buf_page_verify_crypt_checksum(
page, space->flags);
} else {
is_corrupted = buf_page_is_corrupted(
true, page, space->flags);
}
if (is_corrupted) {
if (!is_all_zero) {
bad_doublewrite:
ib::warn() << "A doublewrite copy of page "
@ -668,7 +679,7 @@ bad_doublewrite:
if (page_no == 0) {
/* Check the FSP_SPACE_FLAGS. */
ulint flags = fsp_header_get_flags(page);
if (!fsp_flags_is_valid(flags, space_id)
if (!fil_space_t::is_valid_flags(flags, space_id)
&& fsp_flags_convert_from_101(flags)
== ULINT_UNDEFINED) {
ib::warn() << "Ignoring a doublewrite copy"
@ -806,11 +817,23 @@ buf_dblwr_check_page_lsn(
return;
}
bool lsn_mismatch = false;
// MDEV-12026 FIXME: invoke fil_space_t::full_crc32()
if (memcmp(page + (FIL_PAGE_LSN + 4),
page + (srv_page_size
- FIL_PAGE_END_LSN_OLD_CHKSUM + 4),
4)) {
if (memcmp(page + (FIL_PAGE_LSN + 4),
page + (srv_page_size
- FIL_PAGE_FCRC32_END_LSN),
4)) {
lsn_mismatch = true;
}
}
if (lsn_mismatch) {
// MDEV-12026 FIXME: lsn2 depends on fil_space_t::full_crc32()!
const ulint lsn1 = mach_read_from_4(
page + FIL_PAGE_LSN + 4);
const ulint lsn2 = mach_read_from_4(

View file

@ -747,18 +747,40 @@ buf_flush_update_zip_checksum(
mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, checksum);
}
/** Assign the full crc32 checksum for non-compressed page.
@param[in,out] page page to be updated */
void buf_flush_assign_full_crc32_checksum(byte* page)
{
uint32_t checksum = buf_calc_page_full_crc32(page);
mach_write_to_4(page + srv_page_size - FIL_PAGE_FCRC32_CHECKSUM,
checksum);
}
/** Initialize a page for writing to the tablespace.
@param[in] block buffer block; NULL if bypassing the buffer pool
@param[in,out] page page frame
@param[in,out] page_zip_ compressed page, or NULL if uncompressed
@param[in] newest_lsn newest modification LSN to the page */
@param[in] block buffer block; NULL if bypassing
the buffer pool
@param[in,out] page page frame
@param[in,out] page_zip_ compressed page, or NULL if
uncompressed
@param[in] newest_lsn newest modification LSN to the page
@param[in] use_full_checksum whether tablespace uses full checksum */
void
buf_flush_init_for_writing(
const buf_block_t* block,
byte* page,
void* page_zip_,
lsn_t newest_lsn)
lsn_t newest_lsn,
bool use_full_checksum)
{
if (block != NULL && block->frame != page) {
/* If page is encrypted in full crc32 format then
checksum stored already as a part of fil_encrypt_buf() */
ut_ad(use_full_checksum);
ut_ad(mach_read_from_4(
page + FIL_PAGE_FCRC32_KEY_VERSION));
return;
}
ut_ad(block == NULL || block->frame == page);
ut_ad(block == NULL || page_zip_ == NULL
|| &block->page.zip == page_zip_);
@ -807,8 +829,13 @@ buf_flush_init_for_writing(
/* Write the newest modification lsn to the page header and trailer */
mach_write_to_8(page + FIL_PAGE_LSN, newest_lsn);
mach_write_to_8(page + srv_page_size - FIL_PAGE_END_LSN_OLD_CHKSUM,
newest_lsn);
if (use_full_checksum) {
mach_write_to_4(page + srv_page_size - FIL_PAGE_FCRC32_END_LSN,
(ulint) newest_lsn);
} else {
mach_write_to_8(page + srv_page_size - FIL_PAGE_END_LSN_OLD_CHKSUM,
newest_lsn);
}
if (block && srv_page_size == 16384) {
/* The page type could be garbage in old files
@ -874,6 +901,10 @@ buf_flush_init_for_writing(
uint32_t checksum = BUF_NO_CHECKSUM_MAGIC;
if (use_full_checksum) {
return buf_flush_assign_full_crc32_checksum(page);
}
switch (srv_checksum_algorithm_t(srv_checksum_algorithm)) {
case SRV_CHECKSUM_ALGORITHM_INNODB:
case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB:
@ -886,6 +917,8 @@ buf_flush_init_for_writing(
be calculated after storing the new formula checksum. */
checksum = buf_calc_page_old_checksum(page);
break;
case SRV_CHECKSUM_ALGORITHM_FULL_CRC32:
case SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32:
case SRV_CHECKSUM_ALGORITHM_CRC32:
case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:
/* In other cases we write the same checksum to both fields. */
@ -928,7 +961,10 @@ buf_flush_write_block_low(
|| space->purpose == FIL_TYPE_TABLESPACE);
ut_ad((space->purpose == FIL_TYPE_TEMPORARY)
== (space == fil_system.temp_space));
page_t* frame = NULL;
const bool full_crc32 = space->full_crc32();
#ifdef UNIV_DEBUG
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
ut_ad(!buf_pool_mutex_own(buf_pool));
@ -985,15 +1021,23 @@ buf_flush_write_block_low(
frame = ((buf_block_t*) bpage)->frame;
}
byte* page = reinterpret_cast<const buf_block_t*>(bpage)->frame;
if (full_crc32) {
page = buf_page_encrypt(space, bpage, page);
frame = page;
}
buf_flush_init_for_writing(
reinterpret_cast<const buf_block_t*>(bpage),
reinterpret_cast<const buf_block_t*>(bpage)->frame,
reinterpret_cast<const buf_block_t*>(bpage), page,
bpage->zip.data ? &bpage->zip : NULL,
bpage->newest_modification);
bpage->newest_modification, full_crc32);
break;
}
frame = buf_page_encrypt_before_write(space, bpage, frame);
if (!full_crc32) {
frame = buf_page_encrypt(space, bpage, frame);
}
ut_ad(space->purpose == FIL_TYPE_TABLESPACE
|| space->atomic_write_supported);

View file

@ -537,18 +537,17 @@ fil_parse_write_crypt_data(
return ptr;
}
/** Encrypt a buffer.
@param[in,out] crypt_data Crypt data
@param[in] space space_id
@param[in] offset Page offset
@param[in] lsn Log sequence number
@param[in] src_frame Page to encrypt
@param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0
@param[in,out] dst_frame Output buffer
/** Encrypt a buffer for non full checksum.
@param[in,out] crypt_data Crypt data
@param[in] space space_id
@param[in] offset Page offset
@param[in] lsn Log sequence number
@param[in] src_frame Page to encrypt
@param[in] zip_size ROW_FORMAT=COMPRESSED
page size, or 0
@param[in,out] dst_frame Output buffer
@return encrypted buffer or NULL */
UNIV_INTERN
byte*
fil_encrypt_buf(
static byte* fil_encrypt_buf_for_non_full_checksum(
fil_space_crypt_t* crypt_data,
ulint space,
ulint offset,
@ -559,7 +558,6 @@ fil_encrypt_buf(
{
uint size = uint(zip_size ? zip_size : srv_page_size);
uint key_version = fil_crypt_get_latest_key_version(crypt_data);
ut_a(key_version != ENCRYPTION_KEY_VERSION_INVALID);
ulint orig_page_type = mach_read_from_2(src_frame+FIL_PAGE_TYPE);
@ -572,16 +570,16 @@ fil_encrypt_buf(
/* FIL page header is not encrypted */
memcpy(dst_frame, src_frame, header_len);
/* Store key version */
mach_write_to_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, key_version);
mach_write_to_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,
key_version);
/* Calculate the start offset in a page */
uint unencrypted_bytes = header_len + FIL_PAGE_DATA_END;
uint srclen = size - unencrypted_bytes;
const byte* src = src_frame + header_len;
byte* dst = dst_frame + header_len;
uint32 dstlen = 0;
uint unencrypted_bytes = header_len + FIL_PAGE_DATA_END;
uint srclen = size - unencrypted_bytes;
const byte* src = src_frame + header_len;
byte* dst = dst_frame + header_len;
uint32 dstlen = 0;
ib_uint32_t checksum = 0;
if (page_compressed) {
srclen = mach_read_from_2(src_frame + FIL_PAGE_DATA);
@ -608,13 +606,11 @@ fil_encrypt_buf(
size - (header_len + srclen));
}
/* handle post encryption checksum */
ib_uint32_t checksum = 0;
checksum = fil_crypt_calculate_checksum(zip_size, dst_frame);
// store the post-encryption checksum after the key-version
mach_write_to_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4, checksum);
/* store the post-encryption checksum after the key-version */
mach_write_to_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4,
checksum);
ut_ad(fil_space_verify_crypt_checksum(dst_frame, zip_size));
@ -623,6 +619,105 @@ fil_encrypt_buf(
return dst_frame;
}
/** Encrypt a buffer for full checksum format.
@param[in,out] crypt_data Crypt data
@param[in] space space_id
@param[in] offset Page offset
@param[in] lsn Log sequence number
@param[in] src_frame Page to encrypt
@param[in,out] dst_frame Output buffer
@return encrypted buffer or NULL */
static byte* fil_encrypt_buf_for_full_checksum(
fil_space_crypt_t* crypt_data,
ulint space,
ulint offset,
lsn_t lsn,
const byte* src_frame,
byte* dst_frame)
{
const uint size = uint(srv_page_size);
uint key_version = fil_crypt_get_latest_key_version(crypt_data);
uint srclen = size - (FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION
+ FIL_PAGE_FCRC32_CHECKSUM);
const byte* src = src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION;
byte* dst = dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION;
uint dstlen = 0;
ut_a(key_version != ENCRYPTION_KEY_VERSION_INVALID);
/* Till FIL_PAGE_LSN, page is not encrypted */
memcpy(dst_frame, src_frame, FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
/* Write key version to the page. */
mach_write_to_4(dst_frame + FIL_PAGE_FCRC32_KEY_VERSION, key_version);
int rc = encryption_scheme_encrypt(src, srclen, dst, &dstlen,
crypt_data, key_version,
uint(space), uint(offset), lsn);
ut_a(rc == MY_AES_OK);
ut_a(dstlen == srclen);
ib_uint32_t checksum = buf_calc_page_full_crc32(dst_frame);
mach_write_to_4(dst_frame + size - FIL_PAGE_FCRC32_CHECKSUM, checksum);
srv_stats.pages_encrypted.inc();
return dst_frame;
}
/** Encrypt a buffer.
@param[in,out] crypt_data Crypt data
@param[in] space space_id
@param[in] offset Page offset
@param[in] lsn Log sequence number
@param[in] src_frame Page to encrypt
@param[in] zip_size ROW_FORMAT=COMPRESSED
page size, or 0
@param[in,out] dst_frame Output buffer
@param[in] use_full_checksum full crc32 algo is used
@return encrypted buffer or NULL */
UNIV_INTERN
byte*
fil_encrypt_buf(
fil_space_crypt_t* crypt_data,
ulint space,
ulint offset,
lsn_t lsn,
const byte* src_frame,
ulint zip_size,
byte* dst_frame,
bool use_full_checksum)
{
if (use_full_checksum) {
return fil_encrypt_buf_for_full_checksum(
crypt_data, space, offset,
lsn, src_frame, dst_frame);
}
return fil_encrypt_buf_for_non_full_checksum(
crypt_data, space, offset, lsn,
src_frame, zip_size, dst_frame);
}
/** Check whether these page types are allowed to encrypt.
@param[in] space tablespace object
@param[in] src_frame source page
@return true if it is valid page type */
static bool fil_space_encrypt_valid_page_type(
const fil_space_t* space,
byte* src_frame)
{
switch (mach_read_from_2(src_frame+FIL_PAGE_TYPE)) {
case FIL_PAGE_RTREE:
return space->full_crc32();
case FIL_PAGE_TYPE_FSP_HDR:
case FIL_PAGE_TYPE_XDES:
return false;
}
return true;
}
/******************************************************************
Encrypt a page
@ -641,12 +736,7 @@ fil_space_encrypt(
byte* src_frame,
byte* dst_frame)
{
switch (mach_read_from_2(src_frame+FIL_PAGE_TYPE)) {
case FIL_PAGE_TYPE_FSP_HDR:
case FIL_PAGE_TYPE_XDES:
case FIL_PAGE_RTREE:
/* File space header, extent descriptor or spatial index
are not encrypted. */
if (!fil_space_encrypt_valid_page_type(space, src_frame)) {
return src_frame;
}
@ -657,8 +747,21 @@ fil_space_encrypt(
fil_space_crypt_t* crypt_data = space->crypt_data;
const ulint zip_size = space->zip_size();
ut_ad(space->pending_io());
const bool full_crc32 = space->full_crc32();
if (full_crc32) {
/* Write LSN for the full crc32 checksum before
encryption. Because lsn is one of the input for encryption. */
mach_write_to_8(src_frame + FIL_PAGE_LSN, lsn);
mach_write_to_4(
src_frame + srv_page_size - FIL_PAGE_FCRC32_END_LSN,
(ulint) lsn);
}
byte* tmp = fil_encrypt_buf(crypt_data, space->id, offset, lsn,
src_frame, zip_size, dst_frame);
src_frame, zip_size, dst_frame,
full_crc32);
#ifdef UNIV_DEBUG
if (tmp) {
@ -679,10 +782,12 @@ fil_space_encrypt(
}
}
ut_ad(!buf_page_is_corrupted(true, src, zip_size, space));
ut_ad(fil_space_decrypt(crypt_data, tmp_mem,
space->physical_size(), tmp,
&err));
ut_ad(full_crc32
|| !buf_page_is_corrupted(true, src, space->flags));
ut_ad(fil_space_decrypt(space->id, crypt_data, tmp_mem,
space->physical_size(), space->flags,
tmp, &err));
ut_ad(err == DB_SUCCESS);
/* Need to decompress the page if it was also compressed */
@ -693,25 +798,93 @@ fil_space_encrypt(
ut_ad(unzipped2);
}
memcpy(tmp_mem + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,
src + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 8);
ut_ad(!memcmp(src, tmp_mem, space->physical_size()));
if (full_crc32) {
memcpy(tmp_mem, src, FIL_PAGE_OFFSET);
ut_ad(!memcmp(src, tmp_mem,
(space->physical_size()
- FIL_PAGE_FCRC32_CHECKSUM)));
} else {
memcpy(tmp_mem + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,
src + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 8);
ut_ad(!memcmp(src, tmp_mem, space->physical_size()));
}
}
#endif /* UNIV_DEBUG */
return tmp;
}
/** Decrypt a page.
/** Decrypt a page for full checksum format.
@param[in] space space id
@param[in] crypt_data crypt_data
@param[in] tmp_frame Temporary buffer
@param[in,out] src_frame Page to decrypt
@param[out] err DB_SUCCESS or DB_DECRYPTION_FAILED
@return true if page decrypted, false if not.*/
static bool fil_space_decrypt_for_full_checksum(
ulint space,
fil_space_crypt_t* crypt_data,
byte* tmp_frame,
byte* src_frame,
dberr_t* err)
{
uint key_version = mach_read_from_4(
src_frame + FIL_PAGE_FCRC32_KEY_VERSION);
lsn_t lsn = mach_read_from_8(src_frame + FIL_PAGE_LSN);
uint offset = mach_read_from_4(src_frame + FIL_PAGE_OFFSET);
*err = DB_SUCCESS;
if (key_version == ENCRYPTION_KEY_NOT_ENCRYPTED) {
return false;
}
ut_a(crypt_data != NULL && crypt_data->is_encrypted());
memcpy(tmp_frame, src_frame, FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
/* Calculate the offset where decryption starts */
const byte* src = src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION;
byte* dst = tmp_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION;
uint dstlen = 0;
uint srclen = uint(srv_page_size)
- (FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION
+ FIL_PAGE_FCRC32_CHECKSUM);
int rc = encryption_scheme_decrypt(src, srclen, dst, &dstlen,
crypt_data, key_version,
(uint) space, offset, lsn);
if (rc != MY_AES_OK || dstlen != srclen) {
if (rc == -1) {
*err = DB_DECRYPTION_FAILED;
return false;
}
ib::fatal() << "Unable to decrypt data-block "
<< " src: " << src << "srclen: "
<< srclen << " buf: " << dst << "buflen: "
<< dstlen << " return-code: " << rc
<< " Can't continue!";
}
/* Copy only checksum part in the trailer */
memcpy(tmp_frame + srv_page_size - FIL_PAGE_FCRC32_CHECKSUM,
src_frame + srv_page_size - FIL_PAGE_FCRC32_CHECKSUM,
FIL_PAGE_FCRC32_CHECKSUM);
srv_stats.pages_decrypted.inc();
return true; /* page was decrypted */
}
/** Decrypt a page for non full checksum format.
@param[in] crypt_data crypt_data
@param[in] tmp_frame Temporary buffer
@param[in] physical_size page size
@param[in,out] src_frame Page to decrypt
@param[out] err DB_SUCCESS or DB_DECRYPTION_FAILED
@return true if page decrypted, false if not.*/
UNIV_INTERN
bool
fil_space_decrypt(
static bool fil_space_decrypt_for_non_full_checksum(
fil_space_crypt_t* crypt_data,
byte* tmp_frame,
ulint physical_size,
@ -719,10 +892,13 @@ fil_space_decrypt(
dberr_t* err)
{
ulint page_type = mach_read_from_2(src_frame+FIL_PAGE_TYPE);
uint key_version = mach_read_from_4(src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
bool page_compressed = (page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED);
uint key_version = mach_read_from_4(
src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
bool page_compressed = (page_type
== FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED);
uint offset = mach_read_from_4(src_frame + FIL_PAGE_OFFSET);
uint space = mach_read_from_4(src_frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
uint space = mach_read_from_4(
src_frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
ib_uint64_t lsn = mach_read_from_8(src_frame + FIL_PAGE_LSN);
*err = DB_SUCCESS;
@ -737,7 +913,8 @@ fil_space_decrypt(
uint header_len = FIL_PAGE_DATA;
if (page_compressed) {
header_len += (FIL_PAGE_COMPRESSED_SIZE + FIL_PAGE_COMPRESSION_METHOD_SIZE);
header_len += (FIL_PAGE_COMPRESSED_SIZE
+ FIL_PAGE_COMPRESSION_METHOD_SIZE);
}
/* Copy FIL page header, it is not encrypted */
@ -787,6 +964,36 @@ fil_space_decrypt(
return true; /* page was decrypted */
}
/** Decrypt a page.
@param[in] space_id tablespace id
@param[in] crypt_data crypt_data
@param[in] tmp_frame Temporary buffer
@param[in] physical_size page size
@param[in] fsp_flags Tablespace flags
@param[in,out] src_frame Page to decrypt
@param[out] err DB_SUCCESS or DB_DECRYPTION_FAILED
@return true if page decrypted, false if not.*/
UNIV_INTERN
bool
fil_space_decrypt(
ulint space_id,
fil_space_crypt_t* crypt_data,
byte* tmp_frame,
ulint physical_size,
ulint fsp_flags,
byte* src_frame,
dberr_t* err)
{
if (fil_space_t::full_crc32(fsp_flags)) {
return fil_space_decrypt_for_full_checksum(
space_id, crypt_data, tmp_frame, src_frame, err);
}
return fil_space_decrypt_for_non_full_checksum(crypt_data, tmp_frame,
physical_size, src_frame,
err);
}
/**
Decrypt a page.
@param[in] space Tablespace
@ -811,8 +1018,10 @@ fil_space_decrypt(
ut_ad(space->crypt_data != NULL && space->crypt_data->is_encrypted());
ut_ad(space->pending_io());
bool encrypted = fil_space_decrypt(space->crypt_data, tmp_frame,
physical_size, src_frame, &err);
bool encrypted = fil_space_decrypt(space->id, space->crypt_data,
tmp_frame, physical_size,
space->flags,
src_frame, &err);
if (err == DB_SUCCESS) {
if (encrypted) {
@ -1782,7 +1991,7 @@ fil_crypt_rotate_page(
int needs_scrubbing = BTR_SCRUB_SKIP_PAGE;
lsn_t block_lsn = block->page.newest_modification;
byte* frame = buf_block_get_frame(block);
uint kv = mach_read_from_4(frame+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
uint kv = buf_page_get_key_version(frame, space->flags);
if (space->is_stopping()) {
/* The tablespace is closing (in DROP TABLE or
@ -2544,6 +2753,7 @@ bool fil_space_verify_crypt_checksum(const byte* page, ulint zip_size)
page is not corrupted. */
switch (srv_checksum_algorithm_t(srv_checksum_algorithm)) {
case SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32:
case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:
if (zip_size) {
return checksum == page_zip_calc_checksum(
@ -2565,6 +2775,7 @@ bool fil_space_verify_crypt_checksum(const byte* page, ulint zip_size)
Due to this, we must treat "strict_innodb" as "innodb". */
case SRV_CHECKSUM_ALGORITHM_INNODB:
case SRV_CHECKSUM_ALGORITHM_CRC32:
case SRV_CHECKSUM_ALGORITHM_FULL_CRC32:
if (checksum == BUF_NO_CHECKSUM_MAGIC) {
return true;
}

View file

@ -505,7 +505,7 @@ bool fil_node_t::read_page0(bool first)
const ulint free_limit = fsp_header_get_field(page, FSP_FREE_LIMIT);
const ulint free_len = flst_get_len(FSP_HEADER_OFFSET + FSP_FREE
+ page);
if (!fsp_flags_is_valid(flags, space->id)) {
if (!fil_space_t::is_valid_flags(flags, space->id)) {
ulint cflags = fsp_flags_convert_from_101(flags);
if (cflags == ULINT_UNDEFINED
|| (cflags ^ space->flags) & ~FSP_FLAGS_MEM_MASK) {
@ -552,6 +552,11 @@ bool fil_node_t::read_page0(bool first)
size_bytes &= ~os_offset_t(mask);
}
if (space->flags != flags
&& fil_space_t::is_flags_equal(flags, space->flags)) {
space->flags = flags;
}
this->size = ulint(size_bytes / psize);
space->size += this->size;
}
@ -1298,7 +1303,7 @@ fil_space_create(
fil_space_t* space;
ut_ad(fil_system.is_initialised());
ut_ad(fsp_flags_is_valid(flags & ~FSP_FLAGS_MEM_MASK, id));
ut_ad(fil_space_t::is_valid_flags(flags & ~FSP_FLAGS_MEM_MASK, id));
ut_ad(purpose == FIL_TYPE_LOG
|| srv_page_size == UNIV_PAGE_SIZE_ORIG || flags != 0);
@ -1874,6 +1879,14 @@ fil_write_flushed_lsn(
if (err == DB_SUCCESS) {
mach_write_to_8(buf + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, lsn);
ulint fsp_flags = mach_read_from_4(
buf + FSP_HEADER_OFFSET + FSP_SPACE_FLAGS);
if (fil_space_t::full_crc32(fsp_flags)) {
buf_flush_assign_full_crc32_checksum(buf);
}
err = fil_write(page_id, 0, 0, srv_page_size, buf);
fil_flush_file_spaces(FIL_TYPE_TABLESPACE);
}
@ -1991,7 +2004,7 @@ fil_op_write_log(
ulint len;
ut_ad(first_page_no == 0 || type == MLOG_FILE_CREATE2);
ut_ad(fsp_flags_is_valid(flags, space_id));
ut_ad(fil_space_t::is_valid_flags(flags, space_id));
/* fil_name_parse() requires that there be at least one path
separator and that the file path end with ".ibd". */
@ -2942,7 +2955,7 @@ fil_ibd_create(
ut_ad(!srv_read_only_mode);
ut_a(space_id < SRV_LOG_SPACE_FIRST_ID);
ut_a(size >= FIL_IBD_FILE_INITIAL_SIZE);
ut_a(fsp_flags_is_valid(flags & ~FSP_FLAGS_MEM_MASK, space_id));
ut_a(fil_space_t::is_valid_flags(flags & ~FSP_FLAGS_MEM_MASK, space_id));
/* Create the subdirectories in the path, if they are
not there already. */
@ -3018,7 +3031,12 @@ err_exit:
memset(page, '\0', srv_page_size);
flags |= FSP_FLAGS_PAGE_SSIZE();
if (fil_space_t::full_crc32(flags)) {
flags |= FSP_FLAGS_FCRC32_PAGE_SSIZE();
} else {
flags |= FSP_FLAGS_PAGE_SSIZE();
}
fsp_header_init_fields(page, space_id, flags);
mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, space_id);
@ -3032,12 +3050,13 @@ err_exit:
page_zip.m_end = page_zip.m_nonempty =
page_zip.n_blobs = 0;
buf_flush_init_for_writing(NULL, page, &page_zip, 0);
buf_flush_init_for_writing(NULL, page, &page_zip, 0, false);
*err = os_file_write(
IORequestWrite, path, file, page_zip.data, 0, zip_size);
} else {
buf_flush_init_for_writing(NULL, page, NULL, 0);
buf_flush_init_for_writing(NULL, page, NULL, 0,
fil_space_t::full_crc32(flags));
*err = os_file_write(
IORequestWrite, path, file, page, 0, srv_page_size);
@ -3200,7 +3219,7 @@ corrupted:
return NULL;
}
ut_ad(fsp_flags_is_valid(flags & ~FSP_FLAGS_MEM_MASK, id));
ut_ad(fil_space_t::is_valid_flags(flags & ~FSP_FLAGS_MEM_MASK, id));
df_default.init(tablename.m_name, flags);
df_dict.init(tablename.m_name, flags);
df_remote.init(tablename.m_name, flags);
@ -3867,7 +3886,10 @@ fil_file_readdir_next_file(
void fsp_flags_try_adjust(fil_space_t* space, ulint flags)
{
ut_ad(!srv_read_only_mode);
ut_ad(fsp_flags_is_valid(flags, space->id));
ut_ad(fil_space_t::is_valid_flags(flags, space->id));
if (space->full_crc32()) {
return;
}
if (!space->size && (space->purpose != FIL_TYPE_TABLESPACE
|| !fil_space_get_size(space->id))) {
return;
@ -3881,6 +3903,12 @@ void fsp_flags_try_adjust(fil_space_t* space, ulint flags)
page_id_t(space->id, 0), space->zip_size(),
RW_X_LATCH, &mtr)) {
ulint f = fsp_header_get_flags(b->frame);
if (fil_space_t::full_crc32(f)) {
goto func_exit;
}
if (fil_space_t::is_flags_equal(f, flags)) {
goto func_exit;
}
/* Suppress the message if only the DATA_DIR flag to differs. */
if ((f ^ flags) & ~(1U << FSP_FLAGS_POS_RESERVED)) {
ib::warn()
@ -3889,13 +3917,11 @@ void fsp_flags_try_adjust(fil_space_t* space, ulint flags)
<< "' from " << ib::hex(f)
<< " to " << ib::hex(flags);
}
if (f != flags) {
mtr.set_named_space(space);
mlog_write_ulint(FSP_HEADER_OFFSET
+ FSP_SPACE_FLAGS + b->frame,
flags, MLOG_4BYTES, &mtr);
}
mtr.set_named_space(space);
mlog_write_ulint(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS
+ b->frame, flags, MLOG_4BYTES, &mtr);
}
func_exit:
mtr.commit();
}

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (C) 2013, 2018, MariaDB Corporation.
Copyright (C) 2013, 2019, 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
@ -76,15 +76,19 @@ Updated 14/02/2015
/** Compress a page_compressed page before writing to a data file.
@param[in] buf page to be compressed
@param[out] out_buf compressed page
@param[in] level compression level
@param[in] flags tablespace flags
@param[in] block_size file system block size
@param[in] encrypted whether the page will be subsequently encrypted
@return actual length of compressed page
@retval 0 if the page was not compressed */
ulint fil_page_compress(const byte* buf, byte* out_buf, ulint level,
ulint block_size, bool encrypted)
ulint fil_page_compress(
const byte* buf,
byte* out_buf,
ulint flags,
ulint block_size,
bool encrypted)
{
int comp_level = int(level);
int comp_level = int(fsp_flags_get_page_compression_level(flags));
ulint header_len = FIL_PAGE_DATA + FIL_PAGE_COMPRESSED_SIZE;
/* Cache to avoid change during function execution */
ulint comp_method = innodb_compression_algorithm;
@ -250,7 +254,17 @@ success:
page_t page[UNIV_PAGE_SIZE_MAX];
memcpy(page, out_buf, srv_page_size);
ut_ad(fil_page_decompress(tmp_buf, page));
ut_ad(!buf_page_is_corrupted(false, page, 0, NULL));
ulint fsp_flags = 0;
if (fil_space_t::full_crc32(flags)) {
/* Need to construct flag for new crc32 checksum */
fsp_flags = 1U << FSP_FLAGS_FCRC32_POS_MARKER;
fsp_flags |= FSP_FLAGS_FCRC32_PAGE_SSIZE();
ut_ad(!buf_page_is_corrupted(false, page, fsp_flags));
} else {
fsp_flags = flags;
ut_ad(!buf_page_is_corrupted(false, page, fsp_flags));
}
}
#endif /* UNIV_DEBUG */

View file

@ -343,7 +343,7 @@ Datafile::read_first_page(bool read_only_mode)
if (m_order == 0) {
m_space_id = fsp_header_get_space_id(m_first_page);
m_flags = fsp_header_get_flags(m_first_page);
if (!fsp_flags_is_valid(m_flags, m_space_id)) {
if (!fil_space_t::is_valid_flags(m_flags, m_space_id)) {
ulint cflags = fsp_flags_convert_from_101(m_flags);
if (cflags == ULINT_UNDEFINED) {
ib::error()
@ -356,12 +356,7 @@ Datafile::read_first_page(bool read_only_mode)
}
}
ulint ssize = FSP_FLAGS_GET_PAGE_SSIZE(m_flags);
if (!ssize) ssize = UNIV_PAGE_SSIZE_ORIG;
const ulint zip_ssize = FSP_FLAGS_GET_ZIP_SSIZE(m_flags);
const size_t logical_size = ((UNIV_ZIP_SIZE_MIN >> 1) << ssize);
const size_t physical_size = zip_ssize
? (UNIV_ZIP_SIZE_MIN >> 1) << zip_ssize : logical_size;
const size_t physical_size = fil_space_t::physical_size(m_flags);
if (physical_size > page_size) {
ib::error() << "File " << m_filepath
@ -413,7 +408,8 @@ Datafile::validate_to_dd(ulint space_id, ulint flags)
/* Make sure the datafile we found matched the space ID.
If the datafile is a file-per-table tablespace then also match
the row format and zip page size. */
if (m_space_id == space_id && m_flags == flags) {
if (m_space_id == space_id
&& fil_space_t::is_flags_equal(m_flags, flags)) {
/* Datafile matches the tablespace expected. */
return(DB_SUCCESS);
}
@ -543,7 +539,7 @@ err_exit:
}
}
if (!fsp_flags_is_valid(m_flags, m_space_id)) {
if (!fil_space_t::is_valid_flags(m_flags, m_space_id)) {
/* Tablespace flags must be valid. */
error_txt = "Tablespace flags are invalid";
goto err_exit;
@ -574,8 +570,7 @@ err_exit:
goto err_exit;
}
if (buf_page_is_corrupted(false, m_first_page,
fil_space_t::zip_size(m_flags))) {
if (buf_page_is_corrupted(false, m_first_page, m_flags)) {
/* Look for checksum and other corruptions. */
error_txt = "Checksum mismatch";
goto err_exit;
@ -664,6 +659,8 @@ Datafile::find_space_id()
byte* page = static_cast<byte*>(
ut_align(buf, UNIV_SECTOR_SIZE));
ulint fsp_flags;
for (ulint j = 0; j < page_count; ++j) {
dberr_t err;
@ -681,13 +678,18 @@ Datafile::find_space_id()
continue;
}
if (j == 0) {
fsp_flags = mach_read_from_4(
page + FSP_HEADER_OFFSET + FSP_SPACE_FLAGS);
}
bool noncompressed_ok = false;
/* For noncompressed pages, the page size must be
equal to srv_page_size. */
if (page_size == srv_page_size) {
noncompressed_ok = !buf_page_is_corrupted(
false, page, 0, NULL);
false, page, fsp_flags);
}
bool compressed_ok = false;
@ -695,8 +697,7 @@ Datafile::find_space_id()
if (srv_page_size <= UNIV_PAGE_SIZE_DEF
&& page_size <= srv_page_size) {
compressed_ok = !buf_page_is_corrupted(
false, page,
page_size, NULL);
false, page, fsp_flags);
}
if (noncompressed_ok || compressed_ok) {
@ -783,7 +784,7 @@ Datafile::restore_from_doublewrite()
ulint flags = mach_read_from_4(
FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page);
if (!fsp_flags_is_valid(flags, m_space_id)) {
if (!fil_space_t::is_valid_flags(flags, m_space_id)) {
ulint cflags = fsp_flags_convert_from_101(flags);
if (cflags == ULINT_UNDEFINED) {
ib::warn()

View file

@ -671,7 +671,7 @@ fsp_header_init_fields(
ulint flags) /*!< in: tablespace flags (FSP_SPACE_FLAGS) */
{
flags &= ~FSP_FLAGS_MEM_MASK;
ut_a(fsp_flags_is_valid(flags, space_id));
ut_a(fil_space_t::is_valid_flags(flags, space_id));
mach_write_to_4(FSP_HEADER_OFFSET + FSP_SPACE_ID + page,
space_id);

View file

@ -118,8 +118,20 @@ Tablespace::open_or_create(bool is_temp)
/* Create the tablespace entry for the multi-file
tablespace in the tablespace manager. */
ulint fsp_flags = 0;
switch (srv_checksum_algorithm) {
case SRV_CHECKSUM_ALGORITHM_FULL_CRC32:
case SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32:
fsp_flags = (FSP_FLAGS_FCRC32_MASK_MARKER
| FSP_FLAGS_FCRC32_PAGE_SSIZE());
break;
default:
fsp_flags = FSP_FLAGS_PAGE_SSIZE();
}
space = fil_space_create(
m_name, m_space_id, FSP_FLAGS_PAGE_SSIZE(),
m_name, m_space_id, fsp_flags,
is_temp
? FIL_TYPE_TEMPORARY : FIL_TYPE_TABLESPACE,
NULL);

View file

@ -914,7 +914,7 @@ SysTablespace::open_or_create(
ut_ad(!fil_system.sys_space);
ut_ad(space_id() == TRX_SYS_SPACE);
space = fil_system.sys_space = fil_space_create(
name(), TRX_SYS_SPACE, flags(),
name(), TRX_SYS_SPACE, it->flags(),
FIL_TYPE_TABLESPACE, NULL);
if (!space) {
return DB_ERROR;

View file

@ -365,6 +365,8 @@ const char* innodb_checksum_algorithm_names[] = {
"strict_innodb",
"none",
"strict_none",
"full_crc32",
"strict_full_crc32",
NullS
};
@ -3847,7 +3849,17 @@ static int innodb_init_params()
}
srv_sys_space.set_space_id(TRX_SYS_SPACE);
srv_sys_space.set_flags(FSP_FLAGS_PAGE_SSIZE());
switch (srv_checksum_algorithm) {
case SRV_CHECKSUM_ALGORITHM_FULL_CRC32:
case SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32:
srv_sys_space.set_flags(FSP_FLAGS_FCRC32_MASK_MARKER
| FSP_FLAGS_FCRC32_PAGE_SSIZE());
break;
default:
srv_sys_space.set_flags(FSP_FLAGS_PAGE_SSIZE());
}
srv_sys_space.set_name("innodb_system");
srv_sys_space.set_path(srv_data_home);
@ -3860,7 +3872,16 @@ static int innodb_init_params()
srv_tmp_space.set_name("innodb_temporary");
srv_tmp_space.set_path(srv_data_home);
srv_tmp_space.set_flags(FSP_FLAGS_PAGE_SSIZE());
switch (srv_checksum_algorithm) {
case SRV_CHECKSUM_ALGORITHM_FULL_CRC32:
case SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32:
srv_tmp_space.set_flags(FSP_FLAGS_FCRC32_MASK_MARKER
| FSP_FLAGS_FCRC32_PAGE_SSIZE());
break;
default:
srv_tmp_space.set_flags(FSP_FLAGS_PAGE_SSIZE());
}
if (!srv_tmp_space.parse_params(innobase_temp_data_file_path, false)) {
ib::error() << "Unable to parse innodb_temp_data_file_path="
@ -11547,7 +11568,10 @@ create_table_info_t::check_table_options()
encryption */
for(ulint i = 0; i < m_form->s->keys; i++) {
const KEY* key = m_form->key_info + i;
if (key->flags & HA_SPATIAL && should_encrypt) {
if (key->flags & HA_SPATIAL && should_encrypt
&& (options->page_compressed
|| srv_checksum_algorithm
< SRV_CHECKSUM_ALGORITHM_FULL_CRC32)) {
push_warning_printf(m_thd, Sql_condition::WARN_LEVEL_WARN,
HA_ERR_UNSUPPORTED,
"InnoDB: ENCRYPTED=ON not supported for table because "
@ -18732,7 +18756,11 @@ innobase_wsrep_get_checkpoint(
static MYSQL_SYSVAR_ENUM(checksum_algorithm, srv_checksum_algorithm,
PLUGIN_VAR_RQCMDARG,
"The algorithm InnoDB uses for page checksumming. Possible values are"
" CRC32 (hardware accelerated if the CPU supports it)"
" FULL_CRC32"
" for new files, always use CRC-32C; for old, see CRC32 below;"
" STRICT_FULL_CRC32"
" for new files, always use CRC-32C; for old, see STRICT_CRC32 below;"
" CRC32"
" write crc32, allow any of the other checksums to match when reading;"
" STRICT_CRC32"
" write crc32, do not allow other algorithms to match when reading;"
@ -18749,7 +18777,8 @@ static MYSQL_SYSVAR_ENUM(checksum_algorithm, srv_checksum_algorithm,
" write a constant magic number, do not allow values other than that"
" magic number when reading;"
" Files updated when this option is set to crc32 or strict_crc32 will"
" not be readable by MariaDB versions older than 10.0.4",
" not be readable by MariaDB versions older than 10.0.4;"
" new files created with full_crc32 are readable by MariaDB 10.4.3+",
NULL, NULL, SRV_CHECKSUM_ALGORITHM_CRC32,
&innodb_checksum_algorithm_typelib);

View file

@ -1784,6 +1784,16 @@ ha_innobase::check_if_supported_inplace_alter(
update_thd();
/* MDEV-12026 FIXME: Implement and allow
innodb_checksum_algorithm=full_crc32 for page_compressed! */
if (m_prebuilt->table->space
&& m_prebuilt->table->space->full_crc32()
&& altered_table->s->option_struct
&& altered_table->s->option_struct->page_compressed) {
ut_ad(!table->s->option_struct->page_compressed);
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
}
if (ha_alter_info->handler_flags
& ~(INNOBASE_INPLACE_IGNORE
| INNOBASE_ALTER_INSTANT

View file

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2014, 2018, MariaDB Corporation.
Copyright (c) 2014, 2019, 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
@ -7964,7 +7964,9 @@ i_s_dict_fill_sys_tablespaces(
DBUG_ENTER("i_s_dict_fill_sys_tablespaces");
if (is_system_tablespace(space)) {
if (fil_space_t::full_crc32(flags)) {
row_format = NULL;
} else if (is_system_tablespace(space)) {
row_format = "Compact, Redundant or Dynamic";
} else if (FSP_FLAGS_GET_ZIP_SSIZE(flags)) {
row_format = "Compressed";
@ -7988,7 +7990,7 @@ i_s_dict_fill_sys_tablespaces(
is_system_tablespace(space)
? "System" : "Single"));
ulint cflags = fsp_flags_is_valid(flags, space)
ulint cflags = fil_space_t::is_valid_flags(flags, space)
? flags : fsp_flags_convert_from_101(flags);
if (cflags == ULINT_UNDEFINED) {
fields[SYS_TABLESPACES_PAGE_SIZE]->set_null();

View file

@ -714,24 +714,40 @@ buf_page_is_checksum_valid_none(
ulint checksum_field2)
MY_ATTRIBUTE((nonnull(1), warn_unused_result));
/** Checks if the page is in full crc32 checksum format.
@param[in] read_buf database page
@param[in] checksum_field checksum field
@return true if the page is in full crc32 checksum format */
bool buf_page_is_checksum_valid_full_crc32(
const byte* read_buf,
size_t checksum_field);
/** Check if a page is corrupt.
@param[in] check_lsn whether the LSN should be checked
@param[in] read_buf database page
@param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0
@param[in] space tablespace
@param[in] fsp_flags tablespace flags
@return whether the page is corrupted */
bool
buf_page_is_corrupted(
bool check_lsn,
const byte* read_buf,
ulint zip_size,
#ifndef UNIV_INNOCHECKSUM
const fil_space_t* space = NULL)
#else
const void* space = NULL)
#endif
ulint fsp_flags)
MY_ATTRIBUTE((warn_unused_result));
/** Read the key version from the page. In full crc32 format,
key version is stored at {0-3th} bytes. In other format, it is
stored in 26th position.
@param[in] read_buf database page
@param[in] fsp_flags tablespace flags
@return key version of the page. */
inline uint32_t buf_page_get_key_version(const byte* read_buf, ulint fsp_flags)
{
return FSP_FLAGS_FCRC32_HAS_MARKER(fsp_flags)
? mach_read_from_4(read_buf + FIL_PAGE_FCRC32_KEY_VERSION)
: mach_read_from_4(read_buf
+ FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
}
#ifndef UNIV_INNOCHECKSUM
/**********************************************************************//**
Gets the space id, page offset, and byte offset within page of a
@ -1374,6 +1390,15 @@ ulint
buf_pool_size_align(
ulint size);
/** Verify that post encryption checksum match with the calculated checksum.
This function should be called only if tablespace contains crypt data metadata.
@param[in] page page frame
@param[in] fsp_flags tablespace flags
@return true if page is encrypted and OK, false otherwise */
bool buf_page_verify_crypt_checksum(
const byte* page,
ulint fsp_flags);
/** Calculate the checksum of a page from compressed table and update the
page.
@param[in,out] page page to update
@ -1394,7 +1419,7 @@ a page is written to disk.
(may be src_frame or an encrypted/compressed copy of it) */
UNIV_INTERN
byte*
buf_page_encrypt_before_write(
buf_page_encrypt(
fil_space_t* space,
buf_page_t* bpage,
byte* src_frame);

View file

@ -56,6 +56,11 @@ because this takes that field as an input!
uint32_t
buf_calc_page_old_checksum(const byte* page);
/** Calculate the CRC32 checksum for the whole page.
@param[in] page buffer page (srv_page_size bytes)
@return CRC32 value */
uint32_t buf_calc_page_full_crc32(const byte* page);
/** Return a printable string describing the checksum algorithm.
@param[in] algo algorithm
@return algorithm name */

View file

@ -73,17 +73,24 @@ buf_flush_relocate_on_flush_list(
@param[in,out] bpage flushed page
@param[in] dblwr whether the doublewrite buffer was used */
void buf_flush_write_complete(buf_page_t* bpage, bool dblwr);
/** Assign the full crc32 checksum for non-compressed page.
@param[in,out] page page to be updated */
void buf_flush_assign_full_crc32_checksum(byte* page);
/** Initialize a page for writing to the tablespace.
@param[in] block buffer block; NULL if bypassing the buffer pool
@param[in,out] page page frame
@param[in,out] page_zip_ compressed page, or NULL if uncompressed
@param[in] newest_lsn newest modification LSN to the page */
@param[in] block buffer block; NULL if bypassing the buffer pool
@param[in,out] page page frame
@param[in,out] page_zip_ compressed page, or NULL if uncompressed
@param[in] newest_lsn newest modification LSN to the page
@param[in] use_full_checksum whether tablespace uses full checksum */
void
buf_flush_init_for_writing(
const buf_block_t* block,
byte* page,
void* page_zip_,
lsn_t newest_lsn);
lsn_t newest_lsn,
bool use_full_checksum);
# if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
/********************************************************************//**

View file

@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2019, 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
@ -82,8 +83,16 @@ enum srv_checksum_algorithm_t {
innodb when reading */
SRV_CHECKSUM_ALGORITHM_NONE, /*!< Write none, allow crc32,
innodb or none when reading */
SRV_CHECKSUM_ALGORITHM_STRICT_NONE /*!< Write none, allow none
SRV_CHECKSUM_ALGORITHM_STRICT_NONE, /*!< Write none, allow none
when reading */
/** For new files, always compute CRC-32C for the whole page.
For old files, allow crc32, innodb or none when reading. */
SRV_CHECKSUM_ALGORITHM_FULL_CRC32,
/** For new files, always compute CRC-32C for the whole page.
For old files, allow crc32 when reading. */
SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32
};
inline

View file

@ -652,20 +652,30 @@ dict_tf_to_fsp_flags(ulint table_flags)
DBUG_EXECUTE_IF("dict_tf_to_fsp_flags_failure",
return(ULINT_UNDEFINED););
/* Adjust bit zero. */
fsp_flags = DICT_TF_HAS_ATOMIC_BLOBS(table_flags) ? 1 : 0;
/* Don't allow compressed row format for full crc32 algorithm */
if ((srv_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32
|| srv_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_FULL_CRC32)
&& !(table_flags & DICT_TF_MASK_ZIP_SSIZE)
&& !page_compression_level) {
/* ZIP_SSIZE and ATOMIC_BLOBS are at the same position. */
fsp_flags |= table_flags
& (DICT_TF_MASK_ZIP_SSIZE | DICT_TF_MASK_ATOMIC_BLOBS);
fsp_flags = 1U << FSP_FLAGS_FCRC32_POS_MARKER;
fsp_flags |= FSP_FLAGS_FCRC32_PAGE_SSIZE();
} else {
/* Adjust bit zero. */
fsp_flags = DICT_TF_HAS_ATOMIC_BLOBS(table_flags) ? 1 : 0;
fsp_flags |= FSP_FLAGS_PAGE_SSIZE();
/* ZIP_SSIZE and ATOMIC_BLOBS are at the same position. */
fsp_flags |= table_flags
& (DICT_TF_MASK_ZIP_SSIZE | DICT_TF_MASK_ATOMIC_BLOBS);
if (page_compression_level) {
fsp_flags |= FSP_FLAGS_MASK_PAGE_COMPRESSION;
fsp_flags |= FSP_FLAGS_PAGE_SSIZE();
if (page_compression_level) {
fsp_flags |= FSP_FLAGS_MASK_PAGE_COMPRESSION;
}
}
ut_a(fsp_flags_is_valid(fsp_flags, false));
ut_a(fil_space_t::is_valid_flags(fsp_flags, false));
if (DICT_TF_HAS_DATA_DIR(table_flags)) {
fsp_flags |= 1U << FSP_FLAGS_MEM_DATA_DIR;

View file

@ -303,13 +303,14 @@ fil_parse_write_crypt_data(
MY_ATTRIBUTE((warn_unused_result));
/** Encrypt a buffer.
@param[in,out] crypt_data Crypt data
@param[in] space space_id
@param[in] offset Page offset
@param[in] lsn Log sequence number
@param[in] src_frame Page to encrypt
@param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0
@param[in,out] dst_frame Output buffer
@param[in,out] crypt_data Crypt data
@param[in] space space_id
@param[in] offset Page offset
@param[in] lsn Log sequence number
@param[in] src_frame Page to encrypt
@param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0
@param[in,out] dst_frame Output buffer
@param[in] use_full_checksum full crc32 algo is used
@return encrypted buffer or NULL */
UNIV_INTERN
byte*
@ -320,7 +321,8 @@ fil_encrypt_buf(
lsn_t lsn,
const byte* src_frame,
ulint zip_size,
byte* dst_frame)
byte* dst_frame,
bool use_full_checksum)
MY_ATTRIBUTE((warn_unused_result));
/**
@ -344,18 +346,22 @@ fil_space_encrypt(
/** Decrypt a page.
@param]in] space_id space id
@param[in] crypt_data crypt_data
@param[in] tmp_frame Temporary buffer
@param[in] physical_size page size
@param[in] fsp_flags Tablespace flags
@param[in,out] src_frame Page to decrypt
@param[out] err DB_SUCCESS or DB_DECRYPTION_FAILED
@return true if page decrypted, false if not.*/
UNIV_INTERN
bool
fil_space_decrypt(
ulint space_id,
fil_space_crypt_t* crypt_data,
byte* tmp_frame,
ulint physical_size,
ulint fsp_flags,
byte* src_frame,
dberr_t* err);

View file

@ -71,8 +71,11 @@ fil_type_is_data(
struct fil_node_t;
#endif
/** Tablespace or log data space */
struct fil_space_t {
#ifndef UNIV_INNOCHECKSUM
ulint id; /*!< space id */
hash_node_t hash; /*!< hash chain node */
char* name; /*!< Tablespace name */
@ -118,9 +121,6 @@ struct fil_space_t {
/*!< recovered tablespace size in pages;
0 if no size change was read from the redo log,
or if the size change was implemented */
ulint flags; /*!< FSP_SPACE_FLAGS and FSP_FLAGS_MEM_ flags;
see fsp0types.h,
fsp_flags_is_valid() */
ulint n_reserved_extents;
/*!< number of reserved free extents for
ongoing operations like B-tree page split */
@ -255,16 +255,40 @@ struct fil_space_t {
void release_for_io() { ut_ad(pending_io()); n_pending_ios--; }
/** @return whether I/O is pending */
bool pending_io() const { return n_pending_ios; }
#endif
/** FSP_SPACE_FLAGS and FSP_FLAGS_MEM_ flags;
check fsp0types.h to more info about flags. */
ulint flags;
/** Determine if full_crc32 is used for a data file
@param[in] flags tablespace flags (FSP_FLAGS)
@return whether the full_crc32 algorithm is active */
static bool full_crc32(ulint flags) {
return flags & FSP_FLAGS_FCRC32_MASK_MARKER;
}
/** @return whether innodb_checksum_algorithm=full_crc32 is active */
bool full_crc32() const { return full_crc32(flags); }
/** Determine the logical page size.
@param flags tablespace flags (FSP_FLAGS)
@return the logical page size
@retval 0 if the flags are invalid */
static ulint logical_size(ulint flags) {
switch (FSP_FLAGS_GET_PAGE_SSIZE(flags)) {
ulint page_ssize = 0;
if (full_crc32(flags)) {
page_ssize = FSP_FLAGS_FCRC32_GET_PAGE_SSIZE(flags);
} else {
page_ssize = FSP_FLAGS_GET_PAGE_SSIZE(flags);
}
switch (page_ssize) {
case 3: return 4096;
case 4: return 8192;
case 0: return 16384;
case 5:
{ ut_ad(full_crc32(flags)); return 16384; }
case 0:
{ ut_ad(!full_crc32(flags)); return 16384; }
case 6: return 32768;
case 7: return 65536;
default: return 0;
@ -275,6 +299,11 @@ struct fil_space_t {
@return the ROW_FORMAT=COMPRESSED page size
@retval 0 if ROW_FORMAT=COMPRESSED is not used */
static ulint zip_size(ulint flags) {
if (full_crc32(flags)) {
return 0;
}
ulint zip_ssize = FSP_FLAGS_GET_ZIP_SSIZE(flags);
return zip_ssize
? (UNIV_ZIP_SIZE_MIN >> 1) << zip_ssize : 0;
@ -283,6 +312,11 @@ struct fil_space_t {
@param flags tablespace flags (FSP_FLAGS)
@return the physical page size */
static ulint physical_size(ulint flags) {
if (full_crc32(flags)) {
return logical_size(flags);
}
ulint zip_ssize = FSP_FLAGS_GET_ZIP_SSIZE(flags);
return zip_ssize
? (UNIV_ZIP_SIZE_MIN >> 1) << zip_ssize
@ -293,8 +327,170 @@ struct fil_space_t {
ulint zip_size() const { return zip_size(flags); }
/** @return the physical page size */
ulint physical_size() const { return physical_size(flags); }
/** Check whether the compression enabled in tablespace.
@param[in] flags tablespace flags */
static bool is_compressed(ulint flags) {
if (full_crc32(flags)) {
ulint algo = FSP_FLAGS_FCRC32_GET_COMPRESSED_ALGO(
flags);
ut_ad(algo < 6);
return (algo > 0);
}
return FSP_FLAGS_HAS_PAGE_COMPRESSION(flags);
}
/** @return whether the compression enabled for the tablespace. */
bool is_compressed() { return is_compressed(flags); }
/** Whether the full checksum matches with non full checksum flags.
@param[in] flags flags present
@param[in] expected expected flags
@return true if it is equivalent */
static bool is_flags_full_crc32_equal(ulint flags, ulint expected)
{
ut_ad(full_crc32(flags));
if (full_crc32(expected)) {
return false;
}
ulint page_ssize = FSP_FLAGS_FCRC32_GET_PAGE_SSIZE(flags);
ulint space_page_ssize = FSP_FLAGS_GET_PAGE_SSIZE(expected);
if ((page_ssize == 5 && space_page_ssize != 0)
|| (page_ssize != 5 && (space_page_ssize != page_ssize))) {
return false;
}
if (FSP_FLAGS_HAS_PAGE_COMPRESSION(expected)) {
return false;
}
return true;
}
/** Whether old tablespace flags match full_crc32 flags.
@param[in] flags flags present
@param[in] expected expected flags
@return true if it is equivalent */
static bool is_flags_non_full_crc32_equal(ulint flags, ulint expected)
{
ut_ad(!full_crc32(flags));
if (!full_crc32(expected)
|| FSP_FLAGS_HAS_PAGE_COMPRESSION(expected)) {
return false;
}
ulint page_ssize = FSP_FLAGS_GET_PAGE_SSIZE(flags);
ulint space_page_ssize = FSP_FLAGS_FCRC32_GET_PAGE_SSIZE(
expected);
if ((page_ssize == 0 && space_page_ssize != 5)
|| (page_ssize != 0 && (space_page_ssize != page_ssize))) {
return false;
}
return true;
}
/** Whether both fsp flags are equivalent */
static bool is_flags_equal(ulint flags, ulint expected)
{
if (!((flags ^ expected) & ~(1U << FSP_FLAGS_POS_RESERVED))) {
return true;
}
return full_crc32(flags)
? is_flags_full_crc32_equal(flags, expected)
: is_flags_non_full_crc32_equal(flags, expected);
}
/** Validate the tablespace flags for full crc32 format.
@param[in] flags the content of FSP_SPACE_FLAGS
@return whether the flags are correct in full crc32 format */
static bool is_fcrc32_valid_flags(ulint flags)
{
ut_ad(flags & FSP_FLAGS_FCRC32_MASK_MARKER);
const ulint page_ssize = physical_size(flags);
if (page_ssize < 3 || page_ssize & 8) {
return false;
}
flags >>= FSP_FLAGS_FCRC32_POS_COMPRESSED_ALGO;
return flags <= PAGE_ALGORITHM_LAST;
}
/** Validate the tablespace flags.
@param[in] flags content of FSP_SPACE_FLAGS
@param[in] is_ibd whether this is an .ibd file
(not system tablespace)
@return whether the flags are correct. */
static bool is_valid_flags(ulint flags, bool is_ibd)
{
DBUG_EXECUTE_IF("fsp_flags_is_valid_failure",
return false;);
if (full_crc32(flags)) {
return is_fcrc32_valid_flags(flags);
}
if (flags == 0) {
return true;
}
if (flags & ~FSP_FLAGS_MASK) {
return false;
}
if ((flags & (FSP_FLAGS_MASK_POST_ANTELOPE
| FSP_FLAGS_MASK_ATOMIC_BLOBS))
== FSP_FLAGS_MASK_ATOMIC_BLOBS) {
/* If the "atomic blobs" flag (indicating
ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED) flag
is set, then the "post Antelope"
(ROW_FORMAT!=REDUNDANT) flag must also be set. */
return false;
}
/* Bits 10..14 should be 0b0000d where d is the DATA_DIR flag
of MySQL 5.6 and MariaDB 10.0, which we ignore.
In the buggy FSP_SPACE_FLAGS written by MariaDB 10.1.0 to 10.1.20,
bits 10..14 would be nonzero 0bsssaa where sss is
nonzero PAGE_SSIZE (3, 4, 6, or 7)
and aa is ATOMIC_WRITES (not 0b11). */
if (FSP_FLAGS_GET_RESERVED(flags) & ~1U) {
return false;
}
const ulint ssize = FSP_FLAGS_GET_PAGE_SSIZE(flags);
if (ssize == 1 || ssize == 2 || ssize == 5 || ssize & 8) {
/* the page_size is not between 4k and 64k;
16k should be encoded as 0, not 5 */
return false;
}
const ulint zssize = FSP_FLAGS_GET_ZIP_SSIZE(flags);
if (zssize == 0) {
/* not ROW_FORMAT=COMPRESSED */
} else if (zssize > (ssize ? ssize : 5)) {
/* Invalid KEY_BLOCK_SIZE */
return false;
} else if (~flags & (FSP_FLAGS_MASK_POST_ANTELOPE
| FSP_FLAGS_MASK_ATOMIC_BLOBS)) {
/* both these flags should be set for
ROW_FORMAT=COMPRESSED */
return false;
}
/* The flags do look valid. But, avoid misinterpreting
buggy MariaDB 10.1 format flags for
PAGE_COMPRESSED=1 PAGE_COMPRESSION_LEVEL={0,2,3}
as valid-looking PAGE_SSIZE if this is known to be
an .ibd file and we are using the default innodb_page_size=16k. */
return(ssize == 0 || !is_ibd
|| srv_page_size != UNIV_PAGE_SIZE_ORIG);
}
};
#ifndef UNIV_INNOCHECKSUM
/** Value of fil_space_t::magic_n */
#define FIL_SPACE_MAGIC_N 89472
@ -441,15 +637,12 @@ struct fil_addr_t {
MySQL/InnoDB 5.1.7 or later, the
contents of this field is valid
for all uncompressed pages. */
#define FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION 26U /*!< for the first page
in a system tablespace data file
(ibdata*, not *.ibd): the file has
been flushed to disk at least up
to this lsn
for other pages: a 32-bit key version
used to encrypt the page + 32-bit checksum
or 64 bits of zero if no encryption
*/
/** For the first page in a system tablespace data file(ibdata*, not *.ibd):
the file has been flushed to disk at least up to this lsn
For other pages: 32-bit key version used to encrypt the page + 32-bit checksum
or 64 bites of zero if no encryption */
#define FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION 26U
/** This overloads FIL_PAGE_FILE_FLUSH_LSN for RTREE Split Sequence Number */
#define FIL_RTREE_SPLIT_SEQ_NUM FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION
@ -461,6 +654,10 @@ struct fil_addr_t {
#define FIL_PAGE_DATA 38U /*!< start of the data on the page */
/** 32-bit key version used to encrypt the page in full crc32 format.
For non-encrypted page, it contains 0. */
#define FIL_PAGE_FCRC32_KEY_VERSION 0
/* Following are used when page compression is used */
#define FIL_PAGE_COMPRESSED_SIZE 2 /*!< Number of bytes used to store
actual payload data size on
@ -475,6 +672,12 @@ struct fil_addr_t {
last 4 bytes should be identical
to the last 4 bytes of FIL_PAGE_LSN */
#define FIL_PAGE_DATA_END 8 /*!< size of the page trailer */
/** Store the last 4 bytes of FIL_PAGE_LSN */
#define FIL_PAGE_FCRC32_END_LSN 8
/** Store crc32 checksum at the end of the page */
#define FIL_PAGE_FCRC32_CHECKSUM 4
/* @} */
/** File page types (values of FIL_PAGE_TYPE) @{ */

View file

@ -75,15 +75,17 @@ fil_get_page_type_name(
}
}
/****************************************************************//**
Validate page type.
#ifdef UNIV_DEBUG
/** Validate page type.
@param[in] space Tablespace object
@param[in] page page to validate
@return true if valid, false if not */
UNIV_INLINE
bool
fil_page_type_validate(
const byte* page) /*!< in: page */
fil_space_t* space,
const byte* page)
{
#ifdef UNIV_DEBUG
ulint page_type = mach_read_from_2(page + FIL_PAGE_TYPE);
/* Validate page type */
@ -106,25 +108,31 @@ fil_page_type_validate(
page_type == FIL_PAGE_TYPE_ZBLOB2 ||
page_type == FIL_PAGE_TYPE_UNKNOWN))) {
ulint space = mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
ulint space_id = mach_read_from_4(
page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
ulint offset = mach_read_from_4(page + FIL_PAGE_OFFSET);
fil_system_enter();
fil_space_t* rspace = fil_space_get_by_id(space);
fil_system_exit();
ulint key_version = mach_read_from_4(
page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
if (space && space->full_crc32()) {
key_version = mach_read_from_4(
page + FIL_PAGE_FCRC32_KEY_VERSION);
}
/* Dump out the page info */
ib::fatal() << "Page " << space << ":" << offset
<< " name " << (rspace ? rspace->name : "???")
ib::fatal() << "Page " << space_id << ":" << offset
<< " name " << (space ? space->name : "???")
<< " page_type " << page_type
<< " key_version "
<< mach_read_from_4(page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION)
<< " key_version " << key_version
<< " lsn " << mach_read_from_8(page + FIL_PAGE_LSN)
<< " compressed_len " << mach_read_from_2(page + FIL_PAGE_DATA);
return false;
}
#endif /* UNIV_DEBUG */
return true;
}
#endif /* UNIV_DEBUG */
#endif /* fil0fil_ic */

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (C) 2013, 2018 MariaDB Corporation.
Copyright (C) 2013, 2019 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
@ -33,13 +33,17 @@ Created 11/12/2013 Jan Lindström jan.lindstrom@skysql.com
/** Compress a page_compressed page before writing to a data file.
@param[in] buf page to be compressed
@param[out] out_buf compressed page
@param[in] level compression level
@param[in] flags tablespace flags
@param[in] block_size file system block size
@param[in] encrypted whether the page will be subsequently encrypted
@return actual length of compressed page
@retval 0 if the page was not compressed */
ulint fil_page_compress(const byte* buf, byte* out_buf, ulint level,
ulint block_size, bool encrypted)
ulint fil_page_compress(
const byte* buf,
byte* out_buf,
ulint flags,
ulint block_size,
bool encrypted)
MY_ATTRIBUTE((nonnull, warn_unused_result));
/** Decompress a page that may be subject to page_compressed compression.

View file

@ -45,6 +45,12 @@ Created 12/18/1995 Heikki Tuuri
0U : (srv_page_size_shift - UNIV_ZIP_SIZE_SHIFT_MIN + 1) \
<< FSP_FLAGS_POS_PAGE_SSIZE)
/** @return the PAGE_SSIZE flags for the current innodb_page_size in
full checksum format */
#define FSP_FLAGS_FCRC32_PAGE_SSIZE() \
((srv_page_size_shift - UNIV_ZIP_SIZE_SHIFT_MIN + 1) \
<< FSP_FLAGS_FCRC32_POS_PAGE_SSIZE)
/* @defgroup Compatibility macros for MariaDB 10.1.0 through 10.1.20;
see the table in fsp0types.h @{ */
/** Zero relative shift position of the PAGE_COMPRESSION field */
@ -626,7 +632,7 @@ fsp_flags_convert_from_101(ulint flags)
{
DBUG_EXECUTE_IF("fsp_flags_is_valid_failure",
return(ULINT_UNDEFINED););
if (flags == 0) {
if (flags == 0 || fil_space_t::full_crc32(flags)) {
return(flags);
}
@ -721,7 +727,7 @@ fsp_flags_convert_from_101(ulint flags)
flags = ((flags & 0x3f) | ssize << FSP_FLAGS_POS_PAGE_SSIZE
| FSP_FLAGS_GET_PAGE_COMPRESSION_MARIADB101(flags)
<< FSP_FLAGS_POS_PAGE_COMPRESSION);
ut_ad(fsp_flags_is_valid(flags, false));
ut_ad(fil_space_t::is_valid_flags(flags, false));
return(flags);
}
@ -735,7 +741,7 @@ bool
fsp_flags_match(ulint expected, ulint actual)
{
expected &= ~FSP_FLAGS_MEM_MASK;
ut_ad(fsp_flags_is_valid(expected, false));
ut_ad(fil_space_t::is_valid_flags(expected, false));
if (actual == expected) {
return(true);

View file

@ -27,17 +27,6 @@ Created 11/12/2013 Jan Lindström jan.lindstrom@skysql.com
#ifndef fsp0pagecompress_h
#define fsp0pagecompress_h
/* Supported page compression methods */
#define PAGE_UNCOMPRESSED 0
#define PAGE_ZLIB_ALGORITHM 1
#define PAGE_LZ4_ALGORITHM 2
#define PAGE_LZO_ALGORITHM 3
#define PAGE_LZMA_ALGORITHM 4
#define PAGE_BZIP2_ALGORITHM 5
#define PAGE_SNAPPY_ALGORITHM 6
#define PAGE_ALGORITHM_LAST PAGE_SNAPPY_ALGORITHM
/**********************************************************************//**
Reads the page compression level from the first page of a tablespace.
@return page compression level, or 0 if uncompressed */

View file

@ -127,7 +127,7 @@ public:
@param[in] fsp_flags tablespace flags */
void set_flags(ulint fsp_flags)
{
ut_ad(fsp_flags_is_valid(fsp_flags, false));
ut_ad(fil_space_t::is_valid_flags(fsp_flags, false));
m_flags = fsp_flags;
}

View file

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2014, 2018, MariaDB Corporation.
Copyright (c) 2014, 2019, 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
@ -35,6 +35,16 @@ have a smaller fil_space_t::id. */
#include "ut0byte.h"
/* Possible values of innodb_compression_algorithm */
#define PAGE_UNCOMPRESSED 0
#define PAGE_ZLIB_ALGORITHM 1
#define PAGE_LZ4_ALGORITHM 2
#define PAGE_LZO_ALGORITHM 3
#define PAGE_LZMA_ALGORITHM 4
#define PAGE_BZIP2_ALGORITHM 5
#define PAGE_SNAPPY_ALGORITHM 6
#define PAGE_ALGORITHM_LAST PAGE_SNAPPY_ALGORITHM
/** @name Flags for inserting records in order
If records are inserted in order, there are the following
flags to tell this (their type is made byte for the compiler
@ -219,6 +229,15 @@ to ROW_FORMAT=REDUNDANT and ROW_FORMAT=COMPACT. */
/** A mask of all the known/used bits in FSP_SPACE_FLAGS */
#define FSP_FLAGS_MASK (~(~0U << FSP_FLAGS_WIDTH))
/** Number of flag bits used to indicate the tablespace page size */
#define FSP_FLAGS_FCRC32_WIDTH_PAGE_SSIZE 4
/** Marker to indicate whether tablespace is in full checksum format. */
#define FSP_FLAGS_FCRC32_WIDTH_MARKER 1
/** Stores the compressed algo for full checksum format. */
#define FSP_FLAGS_FCRC32_WIDTH_COMPRESSED_ALGO 3
/* FSP_SPACE_FLAGS position and name in MySQL 5.6/MariaDB 10.0 or older
and MariaDB 10.1.20 or older MariaDB 10.1 and in MariaDB 10.1.21
or newer.
@ -282,6 +301,19 @@ these are only used in MySQL 5.7 and used for compatibility. */
#define FSP_FLAGS_POS_PAGE_COMPRESSION (FSP_FLAGS_POS_RESERVED \
+ FSP_FLAGS_WIDTH_RESERVED)
/** Zero relative shift position of the PAGE_SIZE field
in full crc32 format */
#define FSP_FLAGS_FCRC32_POS_PAGE_SSIZE 0
/** Zero relative shift position of the MARKER field in full crc32 format. */
#define FSP_FLAGS_FCRC32_POS_MARKER (FSP_FLAGS_FCRC32_POS_PAGE_SSIZE \
+ FSP_FLAGS_FCRC32_WIDTH_PAGE_SSIZE)
/** Zero relative shift position of the compressed algorithm stored
in full crc32 format. */
#define FSP_FLAGS_FCRC32_POS_COMPRESSED_ALGO (FSP_FLAGS_FCRC32_POS_MARKER \
+ FSP_FLAGS_FCRC32_WIDTH_MARKER)
/** Bit mask of the POST_ANTELOPE field */
#define FSP_FLAGS_MASK_POST_ANTELOPE \
((~(~0U << FSP_FLAGS_WIDTH_POST_ANTELOPE)) \
@ -311,6 +343,21 @@ these are only used in MySQL 5.7 and used for compatibility. */
#define FSP_FLAGS_MASK_MEM_COMPRESSION_LEVEL \
(15U << FSP_FLAGS_MEM_COMPRESSION_LEVEL)
/** Bit mask of the PAGE_SIZE field in full crc32 format */
#define FSP_FLAGS_FCRC32_MASK_PAGE_SSIZE \
((~(~0U << FSP_FLAGS_FCRC32_WIDTH_PAGE_SSIZE)) \
<< FSP_FLAGS_FCRC32_POS_PAGE_SSIZE)
/** Bit mask of the MARKER field in full crc32 format */
#define FSP_FLAGS_FCRC32_MASK_MARKER \
((~(~0U << FSP_FLAGS_FCRC32_WIDTH_MARKER)) \
<< FSP_FLAGS_FCRC32_POS_MARKER)
/** Bit mask of the COMPRESSED ALGO field in full crc32 format */
#define FSP_FLAGS_FCRC32_MASK_COMPRESSED_ALGO \
((~(~0U << FSP_FLAGS_FCRC32_WIDTH_COMPRESSED_ALGO)) \
<< FSP_FLAGS_FCRC32_POS_COMPRESSED_ALGO)
/** Return the value of the POST_ANTELOPE field */
#define FSP_FLAGS_GET_POST_ANTELOPE(flags) \
((flags & FSP_FLAGS_MASK_POST_ANTELOPE) \
@ -335,10 +382,18 @@ these are only used in MySQL 5.7 and used for compatibility. */
#define FSP_FLAGS_HAS_PAGE_COMPRESSION(flags) \
((flags & FSP_FLAGS_MASK_PAGE_COMPRESSION) \
>> FSP_FLAGS_POS_PAGE_COMPRESSION)
/** Return the contents of the UNUSED bits */
#define FSP_FLAGS_GET_UNUSED(flags) \
(flags >> FSP_FLAGS_POS_UNUSED)
/** @return the PAGE_SSIZE flags in full crc32 format */
#define FSP_FLAGS_FCRC32_GET_PAGE_SSIZE(flags) \
((flags & FSP_FLAGS_FCRC32_MASK_PAGE_SSIZE) \
>> FSP_FLAGS_FCRC32_POS_PAGE_SSIZE)
/** @return the MARKER flag in full crc32 format */
#define FSP_FLAGS_FCRC32_HAS_MARKER(flags) \
((flags & FSP_FLAGS_FCRC32_MASK_MARKER) \
>> FSP_FLAGS_FCRC32_POS_MARKER)
/** @return the COMPRESSED_ALGO flags in full crc32 format */
#define FSP_FLAGS_FCRC32_GET_COMPRESSED_ALGO(flags) \
((flags & FSP_FLAGS_FCRC32_MASK_COMPRESSED_ALGO) \
>> FSP_FLAGS_FCRC32_POS_COMPRESSED_ALGO)
/** @return the value of the DATA_DIR field */
#define FSP_FLAGS_HAS_DATA_DIR(flags) \
@ -350,67 +405,4 @@ these are only used in MySQL 5.7 and used for compatibility. */
/* @} */
/** Validate the tablespace flags, which are stored in the
tablespace header at offset FSP_SPACE_FLAGS.
@param[in] flags the contents of FSP_SPACE_FLAGS
@param[in] is_ibd whether this is an .ibd file (not system tablespace)
@return whether the flags are correct (not in the buggy 10.1) format */
MY_ATTRIBUTE((warn_unused_result, const))
UNIV_INLINE
bool
fsp_flags_is_valid(ulint flags, bool is_ibd)
{
DBUG_EXECUTE_IF("fsp_flags_is_valid_failure",
return(false););
if (flags == 0) {
return(true);
}
if (flags & ~FSP_FLAGS_MASK) {
return(false);
}
if ((flags & (FSP_FLAGS_MASK_POST_ANTELOPE | FSP_FLAGS_MASK_ATOMIC_BLOBS))
== FSP_FLAGS_MASK_ATOMIC_BLOBS) {
/* If the "atomic blobs" flag (indicating
ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED) flag
is set, then the "post Antelope" (ROW_FORMAT!=REDUNDANT) flag
must also be set. */
return(false);
}
/* Bits 10..14 should be 0b0000d where d is the DATA_DIR flag
of MySQL 5.6 and MariaDB 10.0, which we ignore.
In the buggy FSP_SPACE_FLAGS written by MariaDB 10.1.0 to 10.1.20,
bits 10..14 would be nonzero 0bsssaa where sss is
nonzero PAGE_SSIZE (3, 4, 6, or 7)
and aa is ATOMIC_WRITES (not 0b11). */
if (FSP_FLAGS_GET_RESERVED(flags) & ~1U) {
return(false);
}
const ulint ssize = FSP_FLAGS_GET_PAGE_SSIZE(flags);
if (ssize == 1 || ssize == 2 || ssize == 5 || ssize & 8) {
/* the page_size is not between 4k and 64k;
16k should be encoded as 0, not 5 */
return(false);
}
const ulint zssize = FSP_FLAGS_GET_ZIP_SSIZE(flags);
if (zssize == 0) {
/* not ROW_FORMAT=COMPRESSED */
} else if (zssize > (ssize ? ssize : 5)) {
/* invalid KEY_BLOCK_SIZE */
return(false);
} else if (~flags & (FSP_FLAGS_MASK_POST_ANTELOPE
| FSP_FLAGS_MASK_ATOMIC_BLOBS)) {
/* both these flags should be set for
ROW_FORMAT=COMPRESSED */
return(false);
}
/* The flags do look valid. But, avoid misinterpreting
buggy MariaDB 10.1 format flags for
PAGE_COMPRESSED=1 PAGE_COMPRESSION_LEVEL={0,2,3}
as valid-looking PAGE_SSIZE if this is known to be
an .ibd file and we are using the default innodb_page_size=16k. */
return(ssize == 0 || !is_ibd || srv_page_size != UNIV_PAGE_SIZE_ORIG);
}
#endif /* fsp0types_h */

View file

@ -795,7 +795,9 @@ loop:
happen when InnoDB was killed while it was
writing redo log. We simply treat this as an
abrupt end of the redo log. */
fail:
end_lsn = *start_lsn;
success = false;
break;
}
@ -817,10 +819,7 @@ loop:
<< log_block_get_checkpoint_no(buf)
<< " expected: " << crc
<< " found: " << cksum;
fail:
end_lsn = *start_lsn;
success = false;
break;
goto fail;
}
if (is_encrypted()
@ -836,8 +835,7 @@ fail:
|| (dl != OS_FILE_LOG_BLOCK_SIZE
&& dl > log_sys.trailer_offset())) {
recv_sys->found_corrupt_log = true;
end_lsn = *start_lsn;
break;
goto fail;
}
}

View file

@ -4938,6 +4938,8 @@ page_zip_calc_checksum(
and FIL_PAGE_FILE_FLUSH_LSN from the checksum. */
switch (algo) {
case SRV_CHECKSUM_ALGORITHM_FULL_CRC32:
case SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32:
case SRV_CHECKSUM_ALGORITHM_CRC32:
case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:
ut_ad(size > FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
@ -5057,10 +5059,12 @@ page_zip_verify_checksum(
}
switch (curr_algo) {
case SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32:
case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:
case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB:
case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:
return FALSE;
case SRV_CHECKSUM_ALGORITHM_FULL_CRC32:
case SRV_CHECKSUM_ALGORITHM_CRC32:
if (stored == BUF_NO_CHECKSUM_MAGIC) {
return(TRUE);

View file

@ -563,7 +563,7 @@ AbstractCallback::init(
const page_t* page = block->frame;
m_space_flags = fsp_header_get_flags(page);
if (!fsp_flags_is_valid(m_space_flags, true)) {
if (!fil_space_t::is_valid_flags(m_space_flags, true)) {
ulint cflags = fsp_flags_convert_from_101(m_space_flags);
if (cflags == ULINT_UNDEFINED) {
ib::error() << "Invalid FSP_SPACE_FLAGS="
@ -823,6 +823,7 @@ public:
@param block block to convert, it is not from the buffer pool.
@retval DB_SUCCESS or error code. */
dberr_t operator()(buf_block_t* block) UNIV_NOTHROW;
private:
/** Update the page, set the space id, max trx id and index id.
@param block block read from file
@ -2024,13 +2025,25 @@ dberr_t PageConverter::operator()(buf_block_t* block) UNIV_NOTHROW
dberr_t err = update_page(block, page_type);
if (err != DB_SUCCESS) return err;
const bool full_crc32 = fil_space_t::full_crc32(get_space_flags());
if (!block->page.zip.data) {
if (full_crc32
&& block->page.encrypted && block->page.id.page_no() > 0) {
byte* page = block->frame;
mach_write_to_8(page + FIL_PAGE_LSN, m_current_lsn);
mach_write_to_4(
page + srv_page_size - FIL_PAGE_FCRC32_END_LSN,
(ulint) m_current_lsn);
return err;
}
buf_flush_init_for_writing(
NULL, block->frame, NULL, m_current_lsn);
NULL, block->frame, NULL, m_current_lsn, full_crc32);
} else if (fil_page_type_is_index(page_type)) {
buf_flush_init_for_writing(
NULL, block->page.zip.data, &block->page.zip,
m_current_lsn);
m_current_lsn, full_crc32);
} else {
/* Calculate and update the checksum of non-index
pages for ROW_FORMAT=COMPRESSED tables. */
@ -3314,6 +3327,9 @@ fil_iterate(
return DB_OUT_OF_MEMORY;
}
const bool full_crc32 = fil_space_t::full_crc32(
callback.get_space_flags());
/* TODO: For ROW_FORMAT=COMPRESSED tables we do a lot of useless
copying for non-index pages. Unfortunately, it is
required by buf_zip_decompress() */
@ -3406,11 +3422,11 @@ page_corrupted:
bool decrypted = false;
byte* dst = io_buffer + i * size;
bool frame_changed = false;
uint key_version = buf_page_get_key_version(
src, callback.get_space_flags());
if (!encrypted) {
} else if (!mach_read_from_4(
FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION
+ src)) {
} else if (!key_version) {
not_encrypted:
if (!page_compressed
&& !block->page.zip.data) {
@ -3421,14 +3437,17 @@ not_encrypted:
memcpy(dst, src, size);
}
} else {
if (!fil_space_verify_crypt_checksum(
src, callback.get_zip_size())) {
if (!buf_page_verify_crypt_checksum(
src, callback.get_space_flags())) {
goto page_corrupted;
}
decrypted = fil_space_decrypt(
block->page.id.space(),
iter.crypt_data, dst,
callback.physical_size(), src, &err);
callback.physical_size(),
callback.get_space_flags(),
src, &err);
if (err != DB_SUCCESS) {
goto func_exit;
@ -3441,6 +3460,10 @@ not_encrypted:
updated = true;
}
/* For full_crc32 format, skip checksum check
after decryption. */
bool skip_checksum_check = full_crc32 && encrypted;
/* If the original page is page_compressed, we need
to decompress it before adjusting further. */
if (page_compressed) {
@ -3451,14 +3474,19 @@ not_encrypted:
goto page_corrupted;
}
updated = true;
} else if (buf_page_is_corrupted(
} else if (!skip_checksum_check
&& buf_page_is_corrupted(
false,
encrypted && !frame_changed
? dst : src,
callback.get_zip_size(), NULL)) {
callback.get_space_flags())) {
goto page_corrupted;
}
if (encrypted) {
block->page.encrypted = true;
}
if ((err = callback(block)) != DB_SUCCESS) {
goto func_exit;
} else if (!updated) {
@ -3514,7 +3542,7 @@ not_encrypted:
if (ulint len = fil_page_compress(
src,
page_compress_buf,
0,/* FIXME: compression level */
callback.get_space_flags(),
512,/* FIXME: proper block size */
encrypted)) {
/* FIXME: remove memcpy() */
@ -3527,12 +3555,14 @@ not_encrypted:
/* Encrypt the page if encryption was used. */
if (encrypted && decrypted) {
byte *dest = writeptr + i * size;
byte* tmp = fil_encrypt_buf(
iter.crypt_data,
block->page.id.space(),
block->page.id.page_no(),
mach_read_from_8(src + FIL_PAGE_LSN),
src, block->zip_size(), dest);
src, block->zip_size(), dest,
full_crc32);
if (tmp == src) {
/* TODO: remove unnecessary memcpy's */

View file

@ -654,9 +654,19 @@ static bool srv_undo_tablespace_open(const char* name, ulint space_id,
fil_set_max_space_id_if_bigger(space_id);
fil_space_t* space = fil_space_create(
undo_name, space_id, FSP_FLAGS_PAGE_SSIZE(),
FIL_TYPE_TABLESPACE, NULL);
ulint fsp_flags;
switch (srv_checksum_algorithm) {
case SRV_CHECKSUM_ALGORITHM_FULL_CRC32:
case SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32:
fsp_flags = (FSP_FLAGS_FCRC32_MASK_MARKER
| FSP_FLAGS_FCRC32_PAGE_SSIZE());
break;
default:
fsp_flags = FSP_FLAGS_PAGE_SSIZE();
}
fil_space_t* space = fil_space_create(undo_name, space_id, fsp_flags,
FIL_TYPE_TABLESPACE, NULL);
ut_a(fil_validate());
ut_a(space);