1
1
/* ****************************************************************************
2
2
3
- Copyright (c) 1995, 2014 , Oracle and/or its affiliates. All Rights Reserved.
3
+ Copyright (c) 1995, 2015 , Oracle and/or its affiliates. All Rights Reserved.
4
4
Copyright (c) 2008, Google Inc.
5
5
6
6
Portions of this file contain modifications contributed and copyrighted by
@@ -486,6 +486,79 @@ buf_page_is_zeroes(
486
486
return (true );
487
487
}
488
488
489
+ /* * Checks if the page is in crc32 checksum format.
490
+ @param[in] read_buf database page
491
+ @param[in] checksum_field1 new checksum field
492
+ @param[in] checksum_field2 old checksum field
493
+ @return true if the page is in crc32 checksum format */
494
+ UNIV_INLINE
495
+ bool
496
+ buf_page_is_checksum_valid_crc32 (
497
+ const byte* read_buf,
498
+ ulint checksum_field1,
499
+ ulint checksum_field2)
500
+ {
501
+ ib_uint32_t crc32 = buf_calc_page_crc32 (read_buf);
502
+
503
+ return (checksum_field1 == crc32 && checksum_field2 == crc32);
504
+ }
505
+
506
+ /* * Checks if the page is in innodb checksum format.
507
+ @param[in] read_buf database page
508
+ @param[in] checksum_field1 new checksum field
509
+ @param[in] checksum_field2 old checksum field
510
+ @return true if the page is in innodb checksum format */
511
+ UNIV_INLINE
512
+ bool
513
+ buf_page_is_checksum_valid_innodb (
514
+ const byte* read_buf,
515
+ ulint checksum_field1,
516
+ ulint checksum_field2)
517
+ {
518
+ /* There are 2 valid formulas for
519
+ checksum_field2 (old checksum field) which algo=innodb could have
520
+ written to the page:
521
+
522
+ 1. Very old versions of InnoDB only stored 8 byte lsn to the
523
+ start and the end of the page.
524
+
525
+ 2. Newer InnoDB versions store the old formula checksum
526
+ (buf_calc_page_old_checksum()). */
527
+
528
+ if (checksum_field2 != mach_read_from_4 (read_buf + FIL_PAGE_LSN)
529
+ && checksum_field2 != buf_calc_page_old_checksum (read_buf)) {
530
+ return (false );
531
+ }
532
+
533
+ /* old field is fine, check the new field */
534
+
535
+ /* InnoDB versions < 4.0.14 and < 4.1.1 stored the space id
536
+ (always equal to 0), to FIL_PAGE_SPACE_OR_CHKSUM */
537
+
538
+ if (checksum_field1 != 0
539
+ && checksum_field1 != buf_calc_page_new_checksum (read_buf)) {
540
+ return (false );
541
+ }
542
+
543
+ return (true );
544
+ }
545
+
546
+ /* * Checks if the page is in none checksum format.
547
+ @param[in] read_buf database page
548
+ @param[in] checksum_field1 new checksum field
549
+ @param[in] checksum_field2 old checksum field
550
+ @return true if the page is in none checksum format */
551
+ UNIV_INLINE
552
+ bool
553
+ buf_page_is_checksum_valid_none (
554
+ const byte* read_buf,
555
+ ulint checksum_field1,
556
+ ulint checksum_field2)
557
+ {
558
+ return (checksum_field1 == checksum_field2
559
+ && checksum_field1 == BUF_NO_CHECKSUM_MAGIC);
560
+ }
561
+
489
562
/* *******************************************************************/ /* *
490
563
Checks if a page is corrupt.
491
564
@return TRUE if corrupted */
@@ -501,8 +574,6 @@ buf_page_is_corrupted(
501
574
{
502
575
ulint checksum_field1;
503
576
ulint checksum_field2;
504
- ibool crc32_inited = FALSE ;
505
- ib_uint32_t crc32 = ULINT32_UNDEFINED;
506
577
507
578
if (!zip_size
508
579
&& memcmp (read_buf + FIL_PAGE_LSN + 4 ,
@@ -582,148 +653,121 @@ buf_page_is_corrupted(
582
653
return (FALSE );
583
654
}
584
655
585
- switch ((srv_checksum_algorithm_t ) srv_checksum_algorithm) {
586
- case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:
587
-
588
- crc32 = buf_calc_page_crc32 (read_buf);
589
-
590
- return (checksum_field1 != crc32 || checksum_field2 != crc32);
591
-
592
- case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB:
593
-
594
- return (checksum_field1
595
- != buf_calc_page_new_checksum (read_buf)
596
- || checksum_field2
597
- != buf_calc_page_old_checksum (read_buf));
598
-
599
- case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:
656
+ DBUG_EXECUTE_IF (" buf_page_is_corrupt_failure" , return (TRUE ); );
600
657
601
- return (checksum_field1 != BUF_NO_CHECKSUM_MAGIC
602
- || checksum_field2 != BUF_NO_CHECKSUM_MAGIC);
658
+ ulint page_no = mach_read_from_4 (read_buf + FIL_PAGE_OFFSET);
659
+ ulint space_id = mach_read_from_4 (read_buf + FIL_PAGE_SPACE_ID);
660
+ const srv_checksum_algorithm_t curr_algo =
661
+ static_cast <srv_checksum_algorithm_t >(srv_checksum_algorithm);
603
662
663
+ switch (curr_algo) {
604
664
case SRV_CHECKSUM_ALGORITHM_CRC32:
605
- case SRV_CHECKSUM_ALGORITHM_INNODB:
606
- /* There are 3 valid formulas for
607
- checksum_field2 (old checksum field):
608
-
609
- 1. Very old versions of InnoDB only stored 8 byte lsn to the
610
- start and the end of the page.
611
-
612
- 2. InnoDB versions before MySQL 5.6.3 store the old formula
613
- checksum (buf_calc_page_old_checksum()).
614
-
615
- 3. InnoDB versions 5.6.3 and newer with
616
- innodb_checksum_algorithm=strict_crc32|crc32 store CRC32. */
617
-
618
- /* since innodb_checksum_algorithm is not strict_* allow
619
- any of the algos to match for the old field */
620
-
621
- if (checksum_field2
622
- != mach_read_from_4 (read_buf + FIL_PAGE_LSN)
623
- && checksum_field2 != BUF_NO_CHECKSUM_MAGIC) {
624
-
625
- /* The checksum does not match any of the
626
- fast to check. First check the selected algorithm
627
- for writing checksums because we assume that the
628
- chance of it matching is higher. */
629
-
630
- if (srv_checksum_algorithm
631
- == SRV_CHECKSUM_ALGORITHM_CRC32) {
632
-
633
- crc32 = buf_calc_page_crc32 (read_buf);
634
- crc32_inited = TRUE ;
635
-
636
- if (checksum_field2 != crc32
637
- && checksum_field2
638
- != buf_calc_page_old_checksum (read_buf)) {
665
+ case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:
639
666
640
- return (TRUE );
641
- }
642
- } else {
643
- ut_ad (srv_checksum_algorithm
644
- == SRV_CHECKSUM_ALGORITHM_INNODB);
667
+ if (buf_page_is_checksum_valid_crc32 (read_buf,
668
+ checksum_field1, checksum_field2)) {
669
+ return (FALSE );
670
+ }
645
671
646
- if (checksum_field2
647
- != buf_calc_page_old_checksum (read_buf)) {
672
+ if (buf_page_is_checksum_valid_none (read_buf,
673
+ checksum_field1, checksum_field2)) {
674
+ if (curr_algo
675
+ == SRV_CHECKSUM_ALGORITHM_STRICT_CRC32) {
676
+ page_warn_strict_checksum (
677
+ curr_algo,
678
+ SRV_CHECKSUM_ALGORITHM_NONE,
679
+ space_id, page_no);
680
+ }
648
681
649
- crc32 = buf_calc_page_crc32 (read_buf );
650
- crc32_inited = TRUE ;
682
+ return ( FALSE );
683
+ }
651
684
652
- if (checksum_field2 != crc32) {
653
- return (TRUE );
654
- }
655
- }
685
+ if (buf_page_is_checksum_valid_innodb (read_buf,
686
+ checksum_field1, checksum_field2)) {
687
+ if (curr_algo
688
+ == SRV_CHECKSUM_ALGORITHM_STRICT_CRC32) {
689
+ page_warn_strict_checksum (
690
+ curr_algo,
691
+ SRV_CHECKSUM_ALGORITHM_INNODB,
692
+ space_id, page_no);
656
693
}
657
- }
658
694
659
- /* old field is fine, check the new field */
695
+ return (FALSE );
696
+ }
660
697
661
- /* InnoDB versions < 4.0.14 and < 4.1.1 stored the space id
662
- (always equal to 0), to FIL_PAGE_SPACE_OR_CHKSUM */
698
+ return (TRUE );
663
699
664
- if (checksum_field1 != 0
665
- && checksum_field1 != BUF_NO_CHECKSUM_MAGIC) {
700
+ case SRV_CHECKSUM_ALGORITHM_INNODB:
701
+ case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB:
666
702
667
- /* The checksum does not match any of the
668
- fast to check. First check the selected algorithm
669
- for writing checksums because we assume that the
670
- chance of it matching is higher. */
703
+ if ( buf_page_is_checksum_valid_innodb (read_buf,
704
+ checksum_field1, checksum_field2)) {
705
+ return ( FALSE );
706
+ }
671
707
672
- if (srv_checksum_algorithm
673
- == SRV_CHECKSUM_ALGORITHM_CRC32) {
708
+ if (buf_page_is_checksum_valid_none (read_buf,
709
+ checksum_field1, checksum_field2)) {
710
+ if (curr_algo
711
+ == SRV_CHECKSUM_ALGORITHM_STRICT_INNODB) {
712
+ page_warn_strict_checksum (
713
+ curr_algo,
714
+ SRV_CHECKSUM_ALGORITHM_NONE,
715
+ space_id, page_no);
716
+ }
674
717
675
- if (!crc32_inited) {
676
- crc32 = buf_calc_page_crc32 (read_buf);
677
- crc32_inited = TRUE ;
678
- }
718
+ return (FALSE );
719
+ }
679
720
680
- if (checksum_field1 != crc32
681
- && checksum_field1
682
- != buf_calc_page_new_checksum (read_buf)) {
721
+ if (buf_page_is_checksum_valid_crc32 (read_buf,
722
+ checksum_field1, checksum_field2)) {
723
+ if (curr_algo
724
+ == SRV_CHECKSUM_ALGORITHM_STRICT_INNODB) {
725
+ page_warn_strict_checksum (
726
+ curr_algo,
727
+ SRV_CHECKSUM_ALGORITHM_CRC32,
728
+ space_id, page_no);
729
+ }
683
730
684
- return (TRUE );
685
- }
686
- } else {
687
- ut_ad (srv_checksum_algorithm
688
- == SRV_CHECKSUM_ALGORITHM_INNODB);
731
+ return (FALSE );
732
+ }
689
733
690
- if (checksum_field1
691
- != buf_calc_page_new_checksum (read_buf)) {
734
+ return (TRUE );
692
735
693
- if (!crc32_inited) {
694
- crc32 = buf_calc_page_crc32 (
695
- read_buf);
696
- crc32_inited = TRUE ;
697
- }
736
+ case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:
698
737
699
- if (checksum_field1 != crc32) {
700
- return (TRUE );
701
- }
702
- }
703
- }
738
+ if (buf_page_is_checksum_valid_none (read_buf,
739
+ checksum_field1, checksum_field2)) {
740
+ return (FALSE );
704
741
}
705
742
706
- /* If CRC32 is stored in at least one of the fields, then the
707
- other field must also be CRC32 */
708
- if (crc32_inited
709
- && ((checksum_field1 == crc32
710
- && checksum_field2 != crc32)
711
- || (checksum_field1 != crc32
712
- && checksum_field2 == crc32))) {
743
+ if (buf_page_is_checksum_valid_crc32 (read_buf,
744
+ checksum_field1, checksum_field2)) {
745
+ page_warn_strict_checksum (
746
+ curr_algo,
747
+ SRV_CHECKSUM_ALGORITHM_CRC32,
748
+ space_id, page_no);
749
+ return (FALSE );
750
+ }
713
751
714
- return (TRUE );
752
+ if (buf_page_is_checksum_valid_innodb (read_buf,
753
+ checksum_field1, checksum_field2)) {
754
+ page_warn_strict_checksum (
755
+ curr_algo,
756
+ SRV_CHECKSUM_ALGORITHM_INNODB,
757
+ space_id, page_no);
758
+ return (FALSE );
715
759
}
716
760
717
- break ;
761
+ return (TRUE );
762
+
718
763
case SRV_CHECKSUM_ALGORITHM_NONE:
719
764
/* should have returned FALSE earlier */
720
- ut_error ;
765
+ break ;
721
766
/* no default so the compiler will emit a warning if new enum
722
767
is added and not handled here */
723
768
}
724
769
725
- DBUG_EXECUTE_IF (" buf_page_is_corrupt_failure" , return (TRUE ); );
726
-
770
+ ut_error;
727
771
return (FALSE );
728
772
}
729
773
@@ -1673,6 +1717,9 @@ buf_pool_watch_set(
1673
1717
goto page_found;
1674
1718
}
1675
1719
1720
+ /* The maximum number of purge threads should never exceed
1721
+ BUF_POOL_WATCH_SIZE. So there is no way for purge thread
1722
+ instance to hold a watch when setting another watch. */
1676
1723
for (i = 0 ; i < BUF_POOL_WATCH_SIZE; i++) {
1677
1724
bpage = &buf_pool->watch [i];
1678
1725
0 commit comments