Skip to content

Commit 037b78e

Browse files
author
Jan Lindström
committed
MDEV-9242: Innodb reports Assertion failure in file buf0dblwr.cc line 579
Analysis: When pages in doublewrite buffer are analyzed compressed pages do not have correct checksum. Fix: Decompress page before checksum is compared. If decompression fails we still check checksum and corrupted pages are found. If decompression succeeds, page now contains the original checksum.
1 parent d5822a3 commit 037b78e

File tree

6 files changed

+124
-10
lines changed

6 files changed

+124
-10
lines changed

storage/innobase/buf/buf0dblwr.cc

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*****************************************************************************
22
33
Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved.
4-
Copyright (c) 2013, 2015, MariaDB Corporation. All Rights Reserved.
4+
Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved.
55
66
This program is free software; you can redistribute it and/or modify it under
77
the terms of the GNU General Public License as published by the Free Software
@@ -37,6 +37,7 @@ Created 2011/12/19
3737
#include "page0zip.h"
3838
#include "trx0sys.h"
3939
#include "fil0crypt.h"
40+
#include "fil0pagecompress.h"
4041

4142
#ifndef UNIV_HOTBACKUP
4243

@@ -500,6 +501,7 @@ buf_dblwr_process()
500501

501502
for (std::list<byte*>::iterator i = recv_dblwr.pages.begin();
502503
i != recv_dblwr.pages.end(); ++i, ++page_no_dblwr ) {
504+
bool is_compressed = false;
503505

504506
page = *i;
505507
page_no = mach_read_from_4(page + FIL_PAGE_OFFSET);
@@ -533,6 +535,16 @@ buf_dblwr_process()
533535
NULL,
534536
0);
535537

538+
/* Is page compressed ? */
539+
is_compressed = fil_page_is_compressed_encrypted(read_buf) |
540+
fil_page_is_compressed(read_buf);
541+
542+
/* If page was compressed, decompress it before we
543+
check checksum. */
544+
if (is_compressed) {
545+
fil_decompress_page(NULL, read_buf, UNIV_PAGE_SIZE, NULL, true);
546+
}
547+
536548
if (fil_space_verify_crypt_checksum(read_buf, zip_size)) {
537549
/* page is encrypted and checksum is OK */
538550
} else if (buf_page_is_corrupted(true, read_buf, zip_size)) {
@@ -546,6 +558,16 @@ buf_dblwr_process()
546558
" the doublewrite buffer.\n",
547559
(ulong) space_id, (ulong) page_no);
548560

561+
/* Is page compressed ? */
562+
is_compressed = fil_page_is_compressed_encrypted(page) |
563+
fil_page_is_compressed(page);
564+
565+
/* If page was compressed, decompress it before we
566+
check checksum. */
567+
if (is_compressed) {
568+
fil_decompress_page(NULL, page, UNIV_PAGE_SIZE, NULL, true);
569+
}
570+
549571
if (fil_space_verify_crypt_checksum(page, zip_size)) {
550572
/* the doublewrite buffer page is encrypted and OK */
551573
} else if (buf_page_is_corrupted(true,

storage/innobase/fil/fil0pagecompress.cc

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*****************************************************************************
22
3-
Copyright (C) 2013, 2015, MariaDB Corporation. All Rights Reserved.
3+
Copyright (C) 2013, 2016, MariaDB Corporation. All Rights Reserved.
44
55
This program is free software; you can redistribute it and/or modify it under
66
the terms of the GNU General Public License as published by the Free Software
@@ -447,8 +447,11 @@ fil_decompress_page(
447447
byte* buf, /*!< out: buffer from which to read; in aio
448448
this must be appropriately aligned */
449449
ulong len, /*!< in: length of output buffer.*/
450-
ulint* write_size) /*!< in/out: Actual payload size of
450+
ulint* write_size, /*!< in/out: Actual payload size of
451451
the compressed data. */
452+
bool return_error) /*!< in: true if only an error should
453+
be produced when decompression fails.
454+
By default this parameter is false. */
452455
{
453456
int err = 0;
454457
ulint actual_size = 0;
@@ -493,6 +496,9 @@ fil_decompress_page(
493496
mach_read_from_2(buf+FIL_PAGE_TYPE), len);
494497

495498
fflush(stderr);
499+
if (return_error) {
500+
goto error_return;
501+
}
496502
ut_error;
497503
}
498504

@@ -512,6 +518,9 @@ fil_decompress_page(
512518
" actual size %lu compression %s.",
513519
actual_size, fil_get_compression_alg_name(compression_alg));
514520
fflush(stderr);
521+
if (return_error) {
522+
goto error_return;
523+
}
515524
ut_error;
516525
}
517526

@@ -543,6 +552,9 @@ fil_decompress_page(
543552

544553
fflush(stderr);
545554

555+
if (return_error) {
556+
goto error_return;
557+
}
546558
ut_error;
547559
}
548560
break;
@@ -559,6 +571,9 @@ fil_decompress_page(
559571
err, actual_size, len);
560572
fflush(stderr);
561573

574+
if (return_error) {
575+
goto error_return;
576+
}
562577
ut_error;
563578
}
564579
break;
@@ -577,6 +592,9 @@ fil_decompress_page(
577592
olen, actual_size, len);
578593
fflush(stderr);
579594

595+
if (return_error) {
596+
goto error_return;
597+
}
580598
ut_error;
581599
}
582600
break;
@@ -610,6 +628,9 @@ fil_decompress_page(
610628
dst_pos, actual_size, len);
611629
fflush(stderr);
612630

631+
if (return_error) {
632+
goto error_return;
633+
}
613634
ut_error;
614635
}
615636

@@ -636,6 +657,9 @@ fil_decompress_page(
636657
dst_pos, actual_size, len, err);
637658
fflush(stderr);
638659

660+
if (return_error) {
661+
goto error_return;
662+
}
639663
ut_error;
640664
}
641665
break;
@@ -661,6 +685,9 @@ fil_decompress_page(
661685
olen, actual_size, len, (int)cstatus);
662686
fflush(stderr);
663687

688+
if (return_error) {
689+
goto error_return;
690+
}
664691
ut_error;
665692
}
666693
break;
@@ -674,6 +701,9 @@ fil_decompress_page(
674701
,fil_get_compression_alg_name(compression_alg));
675702

676703
fflush(stderr);
704+
if (return_error) {
705+
goto error_return;
706+
}
677707
ut_error;
678708
break;
679709
}
@@ -684,6 +714,7 @@ fil_decompress_page(
684714
really any other options. */
685715
memcpy(buf, in_buf, len);
686716

717+
error_return:
687718
// Need to free temporal buffer if no buffer was given
688719
if (page_buf == NULL) {
689720
ut_free(in_buf);

storage/innobase/include/fil0pagecompress.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*****************************************************************************
22
3-
Copyright (C) 2013, 2015 MariaDB Corporation. All Rights Reserved.
3+
Copyright (C) 2013, 2016 MariaDB Corporation. All Rights Reserved.
44
55
This program is free software; you can redistribute it and/or modify it under
66
the terms of the GNU General Public License as published by the Free Software
@@ -117,8 +117,12 @@ fil_decompress_page(
117117
byte* buf, /*!< out: buffer from which to read; in aio
118118
this must be appropriately aligned */
119119
ulong len, /*!< in: length of output buffer.*/
120-
ulint* write_size); /*!< in/out: Actual payload size of
120+
ulint* write_size, /*!< in/out: Actual payload size of
121121
the compressed data. */
122+
bool return_error=false);
123+
/*!< in: true if only an error should
124+
be produced when decompression fails.
125+
By default this parameter is false. */
122126

123127
/****************************************************************//**
124128
Get space id from fil node

storage/xtradb/buf/buf0dblwr.cc

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*****************************************************************************
22
33
Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved.
4-
Copyright (c) 2013, 2015, MariaDB Corporation. All Rights Reserved.
4+
Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved.
55
66
This program is free software; you can redistribute it and/or modify it under
77
the terms of the GNU General Public License as published by the Free Software
@@ -37,6 +37,7 @@ Created 2011/12/19
3737
#include "page0zip.h"
3838
#include "trx0sys.h"
3939
#include "fil0crypt.h"
40+
#include "fil0pagecompress.h"
4041

4142
#ifndef UNIV_HOTBACKUP
4243

@@ -500,6 +501,7 @@ buf_dblwr_process()
500501

501502
for (std::list<byte*>::iterator i = recv_dblwr.pages.begin();
502503
i != recv_dblwr.pages.end(); ++i, ++page_no_dblwr ) {
504+
bool is_compressed = false;
503505

504506
page = *i;
505507
page_no = mach_read_from_4(page + FIL_PAGE_OFFSET);
@@ -533,6 +535,16 @@ buf_dblwr_process()
533535
NULL,
534536
0);
535537

538+
/* Is page compressed ? */
539+
is_compressed = fil_page_is_compressed_encrypted(read_buf) |
540+
fil_page_is_compressed(read_buf);
541+
542+
/* If page was compressed, decompress it before we
543+
check checksum. */
544+
if (is_compressed) {
545+
fil_decompress_page(NULL, read_buf, UNIV_PAGE_SIZE, NULL, true);
546+
}
547+
536548
if (fil_space_verify_crypt_checksum(read_buf, zip_size)) {
537549
/* page is encrypted and checksum is OK */
538550
} else if (buf_page_is_corrupted(true, read_buf, zip_size)) {
@@ -546,6 +558,16 @@ buf_dblwr_process()
546558
" the doublewrite buffer.\n",
547559
(ulong) space_id, (ulong) page_no);
548560

561+
/* Is page compressed ? */
562+
is_compressed = fil_page_is_compressed_encrypted(page) |
563+
fil_page_is_compressed(page);
564+
565+
/* If page was compressed, decompress it before we
566+
check checksum. */
567+
if (is_compressed) {
568+
fil_decompress_page(NULL, page, UNIV_PAGE_SIZE, NULL, true);
569+
}
570+
549571
if (fil_space_verify_crypt_checksum(page, zip_size)) {
550572
/* the doublewrite buffer page is encrypted and OK */
551573
} else if (buf_page_is_corrupted(true,

storage/xtradb/fil/fil0pagecompress.cc

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*****************************************************************************
22
3-
Copyright (C) 2013, 2015, MariaDB Corporation. All Rights Reserved.
3+
Copyright (C) 2013, 2016, MariaDB Corporation. All Rights Reserved.
44
55
This program is free software; you can redistribute it and/or modify it under
66
the terms of the GNU General Public License as published by the Free Software
@@ -446,8 +446,11 @@ fil_decompress_page(
446446
byte* buf, /*!< out: buffer from which to read; in aio
447447
this must be appropriately aligned */
448448
ulong len, /*!< in: length of output buffer.*/
449-
ulint* write_size) /*!< in/out: Actual payload size of
449+
ulint* write_size, /*!< in/out: Actual payload size of
450450
the compressed data. */
451+
bool return_error) /*!< in: true if only an error should
452+
be produced when decompression fails.
453+
By default this parameter is false. */
451454
{
452455
int err = 0;
453456
ulint actual_size = 0;
@@ -492,6 +495,9 @@ fil_decompress_page(
492495
mach_read_from_2(buf+FIL_PAGE_TYPE), len);
493496

494497
fflush(stderr);
498+
if (return_error) {
499+
goto error_return;
500+
}
495501
ut_error;
496502
}
497503

@@ -511,6 +517,9 @@ fil_decompress_page(
511517
" actual size %lu compression %s.",
512518
actual_size, fil_get_compression_alg_name(compression_alg));
513519
fflush(stderr);
520+
if (return_error) {
521+
goto error_return;
522+
}
514523
ut_error;
515524
}
516525

@@ -542,6 +551,9 @@ fil_decompress_page(
542551

543552
fflush(stderr);
544553

554+
if (return_error) {
555+
goto error_return;
556+
}
545557
ut_error;
546558
}
547559
break;
@@ -558,6 +570,9 @@ fil_decompress_page(
558570
err, actual_size, len);
559571
fflush(stderr);
560572

573+
if (return_error) {
574+
goto error_return;
575+
}
561576
ut_error;
562577
}
563578
break;
@@ -576,6 +591,9 @@ fil_decompress_page(
576591
olen, actual_size, len);
577592
fflush(stderr);
578593

594+
if (return_error) {
595+
goto error_return;
596+
}
579597
ut_error;
580598
}
581599
break;
@@ -609,6 +627,9 @@ fil_decompress_page(
609627
dst_pos, actual_size, len);
610628
fflush(stderr);
611629

630+
if (return_error) {
631+
goto error_return;
632+
}
612633
ut_error;
613634
}
614635

@@ -635,6 +656,9 @@ fil_decompress_page(
635656
dst_pos, actual_size, len, err);
636657
fflush(stderr);
637658

659+
if (return_error) {
660+
goto error_return;
661+
}
638662
ut_error;
639663
}
640664
break;
@@ -660,6 +684,9 @@ fil_decompress_page(
660684
olen, actual_size, len, (int)cstatus);
661685
fflush(stderr);
662686

687+
if (return_error) {
688+
goto error_return;
689+
}
663690
ut_error;
664691
}
665692
break;
@@ -673,6 +700,9 @@ fil_decompress_page(
673700
,fil_get_compression_alg_name(compression_alg));
674701

675702
fflush(stderr);
703+
if (return_error) {
704+
goto error_return;
705+
}
676706
ut_error;
677707
break;
678708
}
@@ -683,6 +713,7 @@ fil_decompress_page(
683713
really any other options. */
684714
memcpy(buf, in_buf, len);
685715

716+
error_return:
686717
// Need to free temporal buffer if no buffer was given
687718
if (page_buf == NULL) {
688719
ut_free(in_buf);

storage/xtradb/include/fil0pagecompress.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*****************************************************************************
22
3-
Copyright (C) 2013, 2015 MariaDB Corporation. All Rights Reserved.
3+
Copyright (C) 2013, 2016 MariaDB Corporation. All Rights Reserved.
44
55
This program is free software; you can redistribute it and/or modify it under
66
the terms of the GNU General Public License as published by the Free Software
@@ -117,8 +117,12 @@ fil_decompress_page(
117117
byte* buf, /*!< out: buffer from which to read; in aio
118118
this must be appropriately aligned */
119119
ulong len, /*!< in: length of output buffer.*/
120-
ulint* write_size); /*!< in/out: Actual payload size of
120+
ulint* write_size, /*!< in/out: Actual payload size of
121121
the compressed data. */
122+
bool return_error=false);
123+
/*!< in: true if only an error should
124+
be produced when decompression fails.
125+
By default this parameter is false. */
122126

123127
/****************************************************************//**
124128
Get space id from fil node

0 commit comments

Comments
 (0)