Skip to content

Commit

Permalink
Merge branch 'merge-xtradb-5.6' into 10.0
Browse files Browse the repository at this point in the history
XtraDB 5.6.25-73.1
  • Loading branch information
vuvova committed Aug 3, 2015
2 parents 772c3f3 + 0b3eb45 commit 4f479fb
Show file tree
Hide file tree
Showing 22 changed files with 445 additions and 176 deletions.
15 changes: 15 additions & 0 deletions storage/xtradb/api/api0api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,21 @@ ib_trx_begin(
return(static_cast<ib_trx_t>(trx));
}


/*****************************************************************//**
Check if transaction is read_only
@return transaction read_only status */
UNIV_INTERN
ib_u32_t
ib_trx_read_only(
/*=============*/
ib_trx_t ib_trx) /*!< in: trx handle */
{
trx_t* trx = (trx_t*) ib_trx;

return(trx->read_only);
}

/*****************************************************************//**
Get the transaction's state.
@return transaction state */
Expand Down
277 changes: 162 additions & 115 deletions storage/xtradb/buf/buf0buf.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
Expand Down Expand Up @@ -555,6 +555,79 @@ buf_page_is_zeroes(
return(true);
}

/** Checks if the page is in crc32 checksum format.
@param[in] read_buf database page
@param[in] checksum_field1 new checksum field
@param[in] checksum_field2 old checksum field
@return true if the page is in crc32 checksum format */
UNIV_INLINE
bool
buf_page_is_checksum_valid_crc32(
const byte* read_buf,
ulint checksum_field1,
ulint checksum_field2)
{
ib_uint32_t crc32 = buf_calc_page_crc32(read_buf);

return(checksum_field1 == crc32 && checksum_field2 == crc32);
}

/** Checks if the page is in innodb checksum format.
@param[in] read_buf database page
@param[in] checksum_field1 new checksum field
@param[in] checksum_field2 old checksum field
@return true if the page is in innodb checksum format */
UNIV_INLINE
bool
buf_page_is_checksum_valid_innodb(
const byte* read_buf,
ulint checksum_field1,
ulint checksum_field2)
{
/* There are 2 valid formulas for
checksum_field2 (old checksum field) which algo=innodb could have
written to the page:
1. Very old versions of InnoDB only stored 8 byte lsn to the
start and the end of the page.
2. Newer InnoDB versions store the old formula checksum
(buf_calc_page_old_checksum()). */

if (checksum_field2 != mach_read_from_4(read_buf + FIL_PAGE_LSN)
&& checksum_field2 != buf_calc_page_old_checksum(read_buf)) {
return(false);
}

/* old field is fine, check the new field */

/* InnoDB versions < 4.0.14 and < 4.1.1 stored the space id
(always equal to 0), to FIL_PAGE_SPACE_OR_CHKSUM */

if (checksum_field1 != 0
&& checksum_field1 != buf_calc_page_new_checksum(read_buf)) {
return(false);
}

return(true);
}

/** Checks if the page is in none checksum format.
@param[in] read_buf database page
@param[in] checksum_field1 new checksum field
@param[in] checksum_field2 old checksum field
@return true if the page is in none checksum format */
UNIV_INLINE
bool
buf_page_is_checksum_valid_none(
const byte* read_buf,
ulint checksum_field1,
ulint checksum_field2)
{
return(checksum_field1 == checksum_field2
&& checksum_field1 == BUF_NO_CHECKSUM_MAGIC);
}

/********************************************************************//**
Checks if a page is corrupt.
@return TRUE if corrupted */
Expand All @@ -570,8 +643,6 @@ buf_page_is_corrupted(
{
ulint checksum_field1;
ulint checksum_field2;
ibool crc32_inited = FALSE;
ib_uint32_t crc32 = ULINT32_UNDEFINED;

if (!zip_size
&& memcmp(read_buf + FIL_PAGE_LSN + 4,
Expand Down Expand Up @@ -651,148 +722,121 @@ buf_page_is_corrupted(
return(FALSE);
}

switch ((srv_checksum_algorithm_t) srv_checksum_algorithm) {
case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:

crc32 = buf_calc_page_crc32(read_buf);

return(checksum_field1 != crc32 || checksum_field2 != crc32);

case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB:

return(checksum_field1
!= buf_calc_page_new_checksum(read_buf)
|| checksum_field2
!= buf_calc_page_old_checksum(read_buf));

case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:
DBUG_EXECUTE_IF("buf_page_is_corrupt_failure", return(TRUE); );

return(checksum_field1 != BUF_NO_CHECKSUM_MAGIC
|| checksum_field2 != BUF_NO_CHECKSUM_MAGIC);
ulint page_no = mach_read_from_4(read_buf + FIL_PAGE_OFFSET);
ulint space_id = mach_read_from_4(read_buf + FIL_PAGE_SPACE_ID);
const srv_checksum_algorithm_t curr_algo =
static_cast<srv_checksum_algorithm_t>(srv_checksum_algorithm);

switch (curr_algo) {
case SRV_CHECKSUM_ALGORITHM_CRC32:
case SRV_CHECKSUM_ALGORITHM_INNODB:
/* There are 3 valid formulas for
checksum_field2 (old checksum field):
1. Very old versions of InnoDB only stored 8 byte lsn to the
start and the end of the page.
2. InnoDB versions before MySQL 5.6.3 store the old formula
checksum (buf_calc_page_old_checksum()).
3. InnoDB versions 5.6.3 and newer with
innodb_checksum_algorithm=strict_crc32|crc32 store CRC32. */

/* since innodb_checksum_algorithm is not strict_* allow
any of the algos to match for the old field */

if (checksum_field2
!= mach_read_from_4(read_buf + FIL_PAGE_LSN)
&& checksum_field2 != BUF_NO_CHECKSUM_MAGIC) {

/* The checksum does not match any of the
fast to check. First check the selected algorithm
for writing checksums because we assume that the
chance of it matching is higher. */

if (srv_checksum_algorithm
== SRV_CHECKSUM_ALGORITHM_CRC32) {

crc32 = buf_calc_page_crc32(read_buf);
crc32_inited = TRUE;

if (checksum_field2 != crc32
&& checksum_field2
!= buf_calc_page_old_checksum(read_buf)) {
case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:

return(TRUE);
}
} else {
ut_ad(srv_checksum_algorithm
== SRV_CHECKSUM_ALGORITHM_INNODB);
if (buf_page_is_checksum_valid_crc32(read_buf,
checksum_field1, checksum_field2)) {
return(FALSE);
}

if (checksum_field2
!= buf_calc_page_old_checksum(read_buf)) {
if (buf_page_is_checksum_valid_none(read_buf,
checksum_field1, checksum_field2)) {
if (curr_algo
== SRV_CHECKSUM_ALGORITHM_STRICT_CRC32) {
page_warn_strict_checksum(
curr_algo,
SRV_CHECKSUM_ALGORITHM_NONE,
space_id, page_no);
}

crc32 = buf_calc_page_crc32(read_buf);
crc32_inited = TRUE;
return(FALSE);
}

if (checksum_field2 != crc32) {
return(TRUE);
}
}
if (buf_page_is_checksum_valid_innodb(read_buf,
checksum_field1, checksum_field2)) {
if (curr_algo
== SRV_CHECKSUM_ALGORITHM_STRICT_CRC32) {
page_warn_strict_checksum(
curr_algo,
SRV_CHECKSUM_ALGORITHM_INNODB,
space_id, page_no);
}
}

/* old field is fine, check the new field */
return(FALSE);
}

/* InnoDB versions < 4.0.14 and < 4.1.1 stored the space id
(always equal to 0), to FIL_PAGE_SPACE_OR_CHKSUM */
return(TRUE);

if (checksum_field1 != 0
&& checksum_field1 != BUF_NO_CHECKSUM_MAGIC) {
case SRV_CHECKSUM_ALGORITHM_INNODB:
case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB:

/* The checksum does not match any of the
fast to check. First check the selected algorithm
for writing checksums because we assume that the
chance of it matching is higher. */
if (buf_page_is_checksum_valid_innodb(read_buf,
checksum_field1, checksum_field2)) {
return(FALSE);
}

if (srv_checksum_algorithm
== SRV_CHECKSUM_ALGORITHM_CRC32) {
if (buf_page_is_checksum_valid_none(read_buf,
checksum_field1, checksum_field2)) {
if (curr_algo
== SRV_CHECKSUM_ALGORITHM_STRICT_INNODB) {
page_warn_strict_checksum(
curr_algo,
SRV_CHECKSUM_ALGORITHM_NONE,
space_id, page_no);
}

if (!crc32_inited) {
crc32 = buf_calc_page_crc32(read_buf);
crc32_inited = TRUE;
}
return(FALSE);
}

if (checksum_field1 != crc32
&& checksum_field1
!= buf_calc_page_new_checksum(read_buf)) {
if (buf_page_is_checksum_valid_crc32(read_buf,
checksum_field1, checksum_field2)) {
if (curr_algo
== SRV_CHECKSUM_ALGORITHM_STRICT_INNODB) {
page_warn_strict_checksum(
curr_algo,
SRV_CHECKSUM_ALGORITHM_CRC32,
space_id, page_no);
}

return(TRUE);
}
} else {
ut_ad(srv_checksum_algorithm
== SRV_CHECKSUM_ALGORITHM_INNODB);
return(FALSE);
}

if (checksum_field1
!= buf_calc_page_new_checksum(read_buf)) {
return(TRUE);

if (!crc32_inited) {
crc32 = buf_calc_page_crc32(
read_buf);
crc32_inited = TRUE;
}
case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:

if (checksum_field1 != crc32) {
return(TRUE);
}
}
}
if (buf_page_is_checksum_valid_none(read_buf,
checksum_field1, checksum_field2)) {
return(FALSE);
}

/* If CRC32 is stored in at least one of the fields, then the
other field must also be CRC32 */
if (crc32_inited
&& ((checksum_field1 == crc32
&& checksum_field2 != crc32)
|| (checksum_field1 != crc32
&& checksum_field2 == crc32))) {
if (buf_page_is_checksum_valid_crc32(read_buf,
checksum_field1, checksum_field2)) {
page_warn_strict_checksum(
curr_algo,
SRV_CHECKSUM_ALGORITHM_CRC32,
space_id, page_no);
return(FALSE);
}

return(TRUE);
if (buf_page_is_checksum_valid_innodb(read_buf,
checksum_field1, checksum_field2)) {
page_warn_strict_checksum(
curr_algo,
SRV_CHECKSUM_ALGORITHM_INNODB,
space_id, page_no);
return(FALSE);
}

break;
return(TRUE);

case SRV_CHECKSUM_ALGORITHM_NONE:
/* should have returned FALSE earlier */
ut_error;
break;
/* no default so the compiler will emit a warning if new enum
is added and not handled here */
}

DBUG_EXECUTE_IF("buf_page_is_corrupt_failure", return(TRUE); );

ut_error;
return(FALSE);
}

Expand Down Expand Up @@ -1762,6 +1806,9 @@ buf_pool_watch_set(
goto page_found;
}

/* The maximum number of purge threads should never exceed
BUF_POOL_WATCH_SIZE. So there is no way for purge thread
instance to hold a watch when setting another watch. */
for (i = 0; i < BUF_POOL_WATCH_SIZE; i++) {
bpage = &buf_pool->watch[i];

Expand Down
Loading

0 comments on commit 4f479fb

Please sign in to comment.