List:Commits« Previous MessageNext Message »
From:vasil.dimov Date:November 21 2011 8:40am
Subject:bzr push into mysql-trunk branch (vasil.dimov:3636 to 3637) Bug#13397030
View as plain text  
 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#13397030vasil.dimov21 Nov