mirror of
https://github.com/MariaDB/server.git
synced 2026-01-06 05:22:24 +03:00
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.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2013, 2015, MariaDB Corporation. All Rights Reserved.
|
||||
Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
@@ -37,6 +37,7 @@ Created 2011/12/19
|
||||
#include "page0zip.h"
|
||||
#include "trx0sys.h"
|
||||
#include "fil0crypt.h"
|
||||
#include "fil0pagecompress.h"
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
|
||||
@@ -500,6 +501,7 @@ buf_dblwr_process()
|
||||
|
||||
for (std::list<byte*>::iterator i = recv_dblwr.pages.begin();
|
||||
i != recv_dblwr.pages.end(); ++i, ++page_no_dblwr ) {
|
||||
bool is_compressed = false;
|
||||
|
||||
page = *i;
|
||||
page_no = mach_read_from_4(page + FIL_PAGE_OFFSET);
|
||||
@@ -533,6 +535,16 @@ buf_dblwr_process()
|
||||
NULL,
|
||||
0);
|
||||
|
||||
/* Is page compressed ? */
|
||||
is_compressed = fil_page_is_compressed_encrypted(read_buf) |
|
||||
fil_page_is_compressed(read_buf);
|
||||
|
||||
/* If page was compressed, decompress it before we
|
||||
check checksum. */
|
||||
if (is_compressed) {
|
||||
fil_decompress_page(NULL, read_buf, UNIV_PAGE_SIZE, NULL, true);
|
||||
}
|
||||
|
||||
if (fil_space_verify_crypt_checksum(read_buf, zip_size)) {
|
||||
/* page is encrypted and checksum is OK */
|
||||
} else if (buf_page_is_corrupted(true, read_buf, zip_size)) {
|
||||
@@ -546,6 +558,16 @@ buf_dblwr_process()
|
||||
" the doublewrite buffer.\n",
|
||||
(ulong) space_id, (ulong) page_no);
|
||||
|
||||
/* Is page compressed ? */
|
||||
is_compressed = fil_page_is_compressed_encrypted(page) |
|
||||
fil_page_is_compressed(page);
|
||||
|
||||
/* If page was compressed, decompress it before we
|
||||
check checksum. */
|
||||
if (is_compressed) {
|
||||
fil_decompress_page(NULL, page, UNIV_PAGE_SIZE, NULL, true);
|
||||
}
|
||||
|
||||
if (fil_space_verify_crypt_checksum(page, zip_size)) {
|
||||
/* the doublewrite buffer page is encrypted and OK */
|
||||
} else if (buf_page_is_corrupted(true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (C) 2013, 2015, MariaDB Corporation. All Rights Reserved.
|
||||
Copyright (C) 2013, 2016, MariaDB Corporation. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
@@ -447,8 +447,11 @@ fil_decompress_page(
|
||||
byte* buf, /*!< out: buffer from which to read; in aio
|
||||
this must be appropriately aligned */
|
||||
ulong len, /*!< in: length of output buffer.*/
|
||||
ulint* write_size) /*!< in/out: Actual payload size of
|
||||
ulint* write_size, /*!< in/out: Actual payload size of
|
||||
the compressed data. */
|
||||
bool return_error) /*!< in: true if only an error should
|
||||
be produced when decompression fails.
|
||||
By default this parameter is false. */
|
||||
{
|
||||
int err = 0;
|
||||
ulint actual_size = 0;
|
||||
@@ -493,6 +496,9 @@ fil_decompress_page(
|
||||
mach_read_from_2(buf+FIL_PAGE_TYPE), len);
|
||||
|
||||
fflush(stderr);
|
||||
if (return_error) {
|
||||
goto error_return;
|
||||
}
|
||||
ut_error;
|
||||
}
|
||||
|
||||
@@ -512,6 +518,9 @@ fil_decompress_page(
|
||||
" actual size %lu compression %s.",
|
||||
actual_size, fil_get_compression_alg_name(compression_alg));
|
||||
fflush(stderr);
|
||||
if (return_error) {
|
||||
goto error_return;
|
||||
}
|
||||
ut_error;
|
||||
}
|
||||
|
||||
@@ -543,6 +552,9 @@ fil_decompress_page(
|
||||
|
||||
fflush(stderr);
|
||||
|
||||
if (return_error) {
|
||||
goto error_return;
|
||||
}
|
||||
ut_error;
|
||||
}
|
||||
break;
|
||||
@@ -559,6 +571,9 @@ fil_decompress_page(
|
||||
err, actual_size, len);
|
||||
fflush(stderr);
|
||||
|
||||
if (return_error) {
|
||||
goto error_return;
|
||||
}
|
||||
ut_error;
|
||||
}
|
||||
break;
|
||||
@@ -577,6 +592,9 @@ fil_decompress_page(
|
||||
olen, actual_size, len);
|
||||
fflush(stderr);
|
||||
|
||||
if (return_error) {
|
||||
goto error_return;
|
||||
}
|
||||
ut_error;
|
||||
}
|
||||
break;
|
||||
@@ -610,6 +628,9 @@ fil_decompress_page(
|
||||
dst_pos, actual_size, len);
|
||||
fflush(stderr);
|
||||
|
||||
if (return_error) {
|
||||
goto error_return;
|
||||
}
|
||||
ut_error;
|
||||
}
|
||||
|
||||
@@ -636,6 +657,9 @@ fil_decompress_page(
|
||||
dst_pos, actual_size, len, err);
|
||||
fflush(stderr);
|
||||
|
||||
if (return_error) {
|
||||
goto error_return;
|
||||
}
|
||||
ut_error;
|
||||
}
|
||||
break;
|
||||
@@ -661,6 +685,9 @@ fil_decompress_page(
|
||||
olen, actual_size, len, (int)cstatus);
|
||||
fflush(stderr);
|
||||
|
||||
if (return_error) {
|
||||
goto error_return;
|
||||
}
|
||||
ut_error;
|
||||
}
|
||||
break;
|
||||
@@ -674,6 +701,9 @@ fil_decompress_page(
|
||||
,fil_get_compression_alg_name(compression_alg));
|
||||
|
||||
fflush(stderr);
|
||||
if (return_error) {
|
||||
goto error_return;
|
||||
}
|
||||
ut_error;
|
||||
break;
|
||||
}
|
||||
@@ -684,6 +714,7 @@ fil_decompress_page(
|
||||
really any other options. */
|
||||
memcpy(buf, in_buf, len);
|
||||
|
||||
error_return:
|
||||
// Need to free temporal buffer if no buffer was given
|
||||
if (page_buf == NULL) {
|
||||
ut_free(in_buf);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (C) 2013, 2015 MariaDB Corporation. All Rights Reserved.
|
||||
Copyright (C) 2013, 2016 MariaDB Corporation. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
@@ -117,8 +117,12 @@ fil_decompress_page(
|
||||
byte* buf, /*!< out: buffer from which to read; in aio
|
||||
this must be appropriately aligned */
|
||||
ulong len, /*!< in: length of output buffer.*/
|
||||
ulint* write_size); /*!< in/out: Actual payload size of
|
||||
ulint* write_size, /*!< in/out: Actual payload size of
|
||||
the compressed data. */
|
||||
bool return_error=false);
|
||||
/*!< in: true if only an error should
|
||||
be produced when decompression fails.
|
||||
By default this parameter is false. */
|
||||
|
||||
/****************************************************************//**
|
||||
Get space id from fil node
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2013, 2015, MariaDB Corporation. All Rights Reserved.
|
||||
Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
@@ -37,6 +37,7 @@ Created 2011/12/19
|
||||
#include "page0zip.h"
|
||||
#include "trx0sys.h"
|
||||
#include "fil0crypt.h"
|
||||
#include "fil0pagecompress.h"
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
|
||||
@@ -500,6 +501,7 @@ buf_dblwr_process()
|
||||
|
||||
for (std::list<byte*>::iterator i = recv_dblwr.pages.begin();
|
||||
i != recv_dblwr.pages.end(); ++i, ++page_no_dblwr ) {
|
||||
bool is_compressed = false;
|
||||
|
||||
page = *i;
|
||||
page_no = mach_read_from_4(page + FIL_PAGE_OFFSET);
|
||||
@@ -533,6 +535,16 @@ buf_dblwr_process()
|
||||
NULL,
|
||||
0);
|
||||
|
||||
/* Is page compressed ? */
|
||||
is_compressed = fil_page_is_compressed_encrypted(read_buf) |
|
||||
fil_page_is_compressed(read_buf);
|
||||
|
||||
/* If page was compressed, decompress it before we
|
||||
check checksum. */
|
||||
if (is_compressed) {
|
||||
fil_decompress_page(NULL, read_buf, UNIV_PAGE_SIZE, NULL, true);
|
||||
}
|
||||
|
||||
if (fil_space_verify_crypt_checksum(read_buf, zip_size)) {
|
||||
/* page is encrypted and checksum is OK */
|
||||
} else if (buf_page_is_corrupted(true, read_buf, zip_size)) {
|
||||
@@ -546,6 +558,16 @@ buf_dblwr_process()
|
||||
" the doublewrite buffer.\n",
|
||||
(ulong) space_id, (ulong) page_no);
|
||||
|
||||
/* Is page compressed ? */
|
||||
is_compressed = fil_page_is_compressed_encrypted(page) |
|
||||
fil_page_is_compressed(page);
|
||||
|
||||
/* If page was compressed, decompress it before we
|
||||
check checksum. */
|
||||
if (is_compressed) {
|
||||
fil_decompress_page(NULL, page, UNIV_PAGE_SIZE, NULL, true);
|
||||
}
|
||||
|
||||
if (fil_space_verify_crypt_checksum(page, zip_size)) {
|
||||
/* the doublewrite buffer page is encrypted and OK */
|
||||
} else if (buf_page_is_corrupted(true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (C) 2013, 2015, MariaDB Corporation. All Rights Reserved.
|
||||
Copyright (C) 2013, 2016, MariaDB Corporation. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
@@ -446,8 +446,11 @@ fil_decompress_page(
|
||||
byte* buf, /*!< out: buffer from which to read; in aio
|
||||
this must be appropriately aligned */
|
||||
ulong len, /*!< in: length of output buffer.*/
|
||||
ulint* write_size) /*!< in/out: Actual payload size of
|
||||
ulint* write_size, /*!< in/out: Actual payload size of
|
||||
the compressed data. */
|
||||
bool return_error) /*!< in: true if only an error should
|
||||
be produced when decompression fails.
|
||||
By default this parameter is false. */
|
||||
{
|
||||
int err = 0;
|
||||
ulint actual_size = 0;
|
||||
@@ -492,6 +495,9 @@ fil_decompress_page(
|
||||
mach_read_from_2(buf+FIL_PAGE_TYPE), len);
|
||||
|
||||
fflush(stderr);
|
||||
if (return_error) {
|
||||
goto error_return;
|
||||
}
|
||||
ut_error;
|
||||
}
|
||||
|
||||
@@ -511,6 +517,9 @@ fil_decompress_page(
|
||||
" actual size %lu compression %s.",
|
||||
actual_size, fil_get_compression_alg_name(compression_alg));
|
||||
fflush(stderr);
|
||||
if (return_error) {
|
||||
goto error_return;
|
||||
}
|
||||
ut_error;
|
||||
}
|
||||
|
||||
@@ -542,6 +551,9 @@ fil_decompress_page(
|
||||
|
||||
fflush(stderr);
|
||||
|
||||
if (return_error) {
|
||||
goto error_return;
|
||||
}
|
||||
ut_error;
|
||||
}
|
||||
break;
|
||||
@@ -558,6 +570,9 @@ fil_decompress_page(
|
||||
err, actual_size, len);
|
||||
fflush(stderr);
|
||||
|
||||
if (return_error) {
|
||||
goto error_return;
|
||||
}
|
||||
ut_error;
|
||||
}
|
||||
break;
|
||||
@@ -576,6 +591,9 @@ fil_decompress_page(
|
||||
olen, actual_size, len);
|
||||
fflush(stderr);
|
||||
|
||||
if (return_error) {
|
||||
goto error_return;
|
||||
}
|
||||
ut_error;
|
||||
}
|
||||
break;
|
||||
@@ -609,6 +627,9 @@ fil_decompress_page(
|
||||
dst_pos, actual_size, len);
|
||||
fflush(stderr);
|
||||
|
||||
if (return_error) {
|
||||
goto error_return;
|
||||
}
|
||||
ut_error;
|
||||
}
|
||||
|
||||
@@ -635,6 +656,9 @@ fil_decompress_page(
|
||||
dst_pos, actual_size, len, err);
|
||||
fflush(stderr);
|
||||
|
||||
if (return_error) {
|
||||
goto error_return;
|
||||
}
|
||||
ut_error;
|
||||
}
|
||||
break;
|
||||
@@ -660,6 +684,9 @@ fil_decompress_page(
|
||||
olen, actual_size, len, (int)cstatus);
|
||||
fflush(stderr);
|
||||
|
||||
if (return_error) {
|
||||
goto error_return;
|
||||
}
|
||||
ut_error;
|
||||
}
|
||||
break;
|
||||
@@ -673,6 +700,9 @@ fil_decompress_page(
|
||||
,fil_get_compression_alg_name(compression_alg));
|
||||
|
||||
fflush(stderr);
|
||||
if (return_error) {
|
||||
goto error_return;
|
||||
}
|
||||
ut_error;
|
||||
break;
|
||||
}
|
||||
@@ -683,6 +713,7 @@ fil_decompress_page(
|
||||
really any other options. */
|
||||
memcpy(buf, in_buf, len);
|
||||
|
||||
error_return:
|
||||
// Need to free temporal buffer if no buffer was given
|
||||
if (page_buf == NULL) {
|
||||
ut_free(in_buf);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (C) 2013, 2015 MariaDB Corporation. All Rights Reserved.
|
||||
Copyright (C) 2013, 2016 MariaDB Corporation. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
@@ -117,8 +117,12 @@ fil_decompress_page(
|
||||
byte* buf, /*!< out: buffer from which to read; in aio
|
||||
this must be appropriately aligned */
|
||||
ulong len, /*!< in: length of output buffer.*/
|
||||
ulint* write_size); /*!< in/out: Actual payload size of
|
||||
ulint* write_size, /*!< in/out: Actual payload size of
|
||||
the compressed data. */
|
||||
bool return_error=false);
|
||||
/*!< in: true if only an error should
|
||||
be produced when decompression fails.
|
||||
By default this parameter is false. */
|
||||
|
||||
/****************************************************************//**
|
||||
Get space id from fil node
|
||||
|
||||
Reference in New Issue
Block a user