3637 Vasil Dimov 2011-11-21
Fix Bug#13397030 DO NOT CALC UNNECESSARY CHECKSUMS WHEN VALIDATING A PAGE
When checking if a checksum matches, before this patch, we always
calculated crc32 even if the selected algo is 'innodb'
(e.g. innodb_checksum_algotithm=innodb).
This is seen as unnecessary and crc32 should only be calculated if
the 'innodb' checksum does not match. Same applies for calculating the
'innodb' checksum if innodb_checksum_algotithm=crc32.
Approved by: Marko (http://bur03.no.oracle.com/rb/r/814/)
modified:
storage/innobase/buf/buf0buf.c
3636 Marko Mäkelä 2011-11-21
Add some assertions and comments for WL#6046.
modified:
storage/innobase/include/trx0trx.h
storage/innobase/include/trx0trx.ic
storage/innobase/lock/lock0lock.c
storage/innobase/read/read0read.c
storage/innobase/row/row0vers.c
storage/innobase/trx/trx0sys.c
storage/innobase/trx/trx0trx.c
=== modified file 'storage/innobase/buf/buf0buf.c'
--- a/storage/innobase/buf/buf0buf.c revid:marko.makela@stripped55-7swepqssvrj8lfca
+++ b/storage/innobase/buf/buf0buf.c revid:vasil.dimov@strippedy45
@@ -462,6 +462,7 @@ buf_page_is_corrupted(
ulint checksum_field1;
ulint checksum_field2;
ib_uint32_t crc32;
+ ibool crc32_inited = FALSE;
if (!zip_size
&& memcmp(read_buf + FIL_PAGE_LSN + 4,
@@ -550,35 +551,57 @@ buf_page_is_corrupted(
case SRV_CHECKSUM_ALGORITHM_CRC32:
case SRV_CHECKSUM_ALGORITHM_INNODB:
- /* There are 3 valid formulas for old_checksum_field:
+ /* 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.
+ checksum (buf_calc_page_old_checksum()).
3. InnoDB versions 5.6.3 and newer with
innodb_checksum_algorithm=strict_crc32|crc32 store CRC32. */
- crc32 = buf_calc_page_crc32(read_buf);
-
/* 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) {
- && checksum_field2
- != crc32
+ /* 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. */
- && checksum_field2
- != BUF_NO_CHECKSUM_MAGIC
+ if (srv_checksum_algorithm
+ == SRV_CHECKSUM_ALGORITHM_CRC32) {
- && checksum_field2
- != buf_calc_page_old_checksum(read_buf)) {
+ crc32 = buf_calc_page_crc32(read_buf);
+ crc32_inited = TRUE;
- return(TRUE);
+ if (checksum_field2 != crc32
+ && checksum_field2
+ != buf_calc_page_old_checksum(read_buf)) {
+
+ return(TRUE);
+ }
+ } else {
+ ut_ad(srv_checksum_algorithm
+ == SRV_CHECKSUM_ALGORITHM_INNODB);
+
+ if (checksum_field2
+ != buf_calc_page_old_checksum(read_buf)) {
+
+ crc32 = buf_calc_page_crc32(read_buf);
+ crc32_inited = TRUE;
+
+ if (checksum_field2 != crc32) {
+ return(TRUE);
+ }
+ }
+ }
}
/* old field is fine, check the new field */
@@ -586,25 +609,55 @@ buf_page_is_corrupted(
/* 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
+ if (checksum_field1 != 0
+ && checksum_field1 != 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) {
+
+ if (!crc32_inited) {
+ crc32 = buf_calc_page_crc32(read_buf);
+ crc32_inited = TRUE;
+ }
- && checksum_field1
- != BUF_NO_CHECKSUM_MAGIC
+ if (checksum_field1 != crc32
+ && checksum_field1
+ != buf_calc_page_new_checksum(read_buf)) {
- && checksum_field1
- != crc32
+ return(TRUE);
+ }
+ } else {
+ ut_ad(srv_checksum_algorithm
+ == SRV_CHECKSUM_ALGORITHM_INNODB);
- && checksum_field1
- != buf_calc_page_new_checksum(read_buf)) {
+ 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;
+ }
+
+ if (checksum_field1 != crc32) {
+ return(TRUE);
+ }
+ }
+ }
}
/* If CRC32 is stored in at least one of the fields, then the
other field must also be CRC32 */
- if ((checksum_field1 == crc32 && checksum_field2 != crc32)
- || (checksum_field1 != crc32 && checksum_field2 == crc32)) {
+ if (crc32_inited
+ && ((checksum_field1 == crc32
+ && checksum_field2 != crc32)
+ || (checksum_field1 != crc32
+ && checksum_field2 == crc32))) {
return(TRUE);
}
No bundle (reason: useless for push emails).| Thread |
|---|
| • bzr push into mysql-trunk branch (vasil.dimov:3636 to 3637) Bug#13397030 | vasil.dimov | 21 Nov |