237 lines
10 KiB
C++
237 lines
10 KiB
C++
/*****************************************************************************
|
|
|
|
Copyright (c) 1995, 2018, Oracle and/or its affiliates. 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, version 2.0, as published by the
|
|
Free Software Foundation.
|
|
|
|
This program is also distributed with certain software (including but not
|
|
limited to OpenSSL) that is licensed under separate terms, as designated in a
|
|
particular file or component or in included license documentation. The authors
|
|
of MySQL hereby grant you an additional permission to link the program and
|
|
your derivative works with the separately licensed software that they have
|
|
included with MySQL.
|
|
|
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
|
|
for more details.
|
|
|
|
You should have received a copy of the GNU General Public License along with
|
|
this program; if not, write to the Free Software Foundation, Inc.,
|
|
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*****************************************************************************/
|
|
|
|
/** @file include/buf0checksum.h
|
|
Buffer pool checksum functions, also linked from /extra/innochecksum.cc
|
|
|
|
Created Aug 11, 2011 Vasil Dimov
|
|
*******************************************************/
|
|
|
|
#ifndef buf0checksum_h
|
|
#define buf0checksum_h
|
|
|
|
#include "buf0types.h"
|
|
#include "page0size.h"
|
|
#include "univ.i"
|
|
|
|
/** Calculates the CRC32 checksum of a page. The value is stored to the page
|
|
when it is written to a file and also checked for a match when reading from
|
|
the file. When reading we allow both normal CRC32 and CRC-legacy-big-endian
|
|
variants. Note that we must be careful to calculate the same value on 32-bit
|
|
and 64-bit architectures.
|
|
@param[in] page buffer page (UNIV_PAGE_SIZE bytes)
|
|
@param[in] use_legacy_big_endian if true then use big endian
|
|
byteorder when converting byte strings to integers
|
|
@return checksum */
|
|
uint32_t buf_calc_page_crc32(const byte *page,
|
|
bool use_legacy_big_endian = false);
|
|
|
|
/** Calculates a page checksum which is stored to the page when it is written
|
|
to a file. Note that we must be careful to calculate the same value on
|
|
32-bit and 64-bit architectures.
|
|
@return checksum */
|
|
ulint buf_calc_page_new_checksum(const byte *page); /*!< in: buffer page */
|
|
|
|
/** In versions < 4.0.14 and < 4.1.1 there was a bug that the checksum only
|
|
looked at the first few bytes of the page. This calculates that old
|
|
checksum.
|
|
NOTE: we must first store the new formula checksum to
|
|
FIL_PAGE_SPACE_OR_CHKSUM before calculating and storing this old checksum
|
|
because this takes that field as an input!
|
|
@return checksum */
|
|
ulint buf_calc_page_old_checksum(const byte *page); /*!< in: buffer page */
|
|
|
|
/** Return a printable string describing the checksum algorithm.
|
|
@return algorithm name */
|
|
const char *buf_checksum_algorithm_name(
|
|
srv_checksum_algorithm_t algo); /*!< in: algorithm */
|
|
|
|
extern ulong srv_checksum_algorithm;
|
|
|
|
/** Class to print checksums to log file. */
|
|
class BlockReporter {
|
|
public:
|
|
/** Constructor
|
|
@param[in] check_lsn check lsn of the page with the
|
|
current lsn (only in recovery)
|
|
@param[in] read_buf buffer holding the page
|
|
@param[in] page_size page size
|
|
@param[in] skip_checksum skip checksum verification */
|
|
BlockReporter(bool check_lsn, const byte *read_buf,
|
|
const page_size_t &page_size, bool skip_checksum)
|
|
: m_check_lsn(check_lsn),
|
|
m_read_buf(read_buf),
|
|
m_page_size(page_size),
|
|
m_skip_checksum(skip_checksum) {}
|
|
|
|
virtual ~BlockReporter() {}
|
|
BlockReporter(const BlockReporter &) = default;
|
|
|
|
/** Checks if a page is corrupt.
|
|
@retval true if page is corrupt
|
|
@retval false if page is not corrupt */
|
|
bool MY_ATTRIBUTE((warn_unused_result)) is_corrupted() const;
|
|
|
|
/** Print message if page is empty.
|
|
@param[in] empty true if page is empty */
|
|
virtual inline void report_empty_page(bool empty) const {}
|
|
|
|
/** Print crc32 checksum and the checksum fields in page.
|
|
@param[in] checksum_field1 Checksum in page header
|
|
@param[in] checksum_field2 Checksum in page trailer
|
|
@param[in] crc32 Calculated crc32 checksum
|
|
@param[in] algo Current checksum algorithm */
|
|
virtual inline void print_strict_crc32(ulint checksum_field1,
|
|
ulint checksum_field2, uint32_t crc32,
|
|
srv_checksum_algorithm_t algo) const {}
|
|
|
|
/** Print innodb checksum and the checksum fields in page.
|
|
@param[in] checksum_field1 Checksum in page header
|
|
@param[in] checksum_field2 Checksum in page trailer */
|
|
virtual inline void print_strict_innodb(ulint checksum_field1,
|
|
ulint checksum_field2) const {}
|
|
|
|
/** Print none checksum and the checksum fields in page.
|
|
@param[in] checksum_field1 Checksum in page header
|
|
@param[in] checksum_field2 Checksum in page trailer
|
|
@param[in] algo Current checksum algorithm */
|
|
virtual inline void print_strict_none(ulint checksum_field1,
|
|
ulint checksum_field2,
|
|
srv_checksum_algorithm_t algo) const {}
|
|
|
|
/** Print innodb checksum value stored in page trailer.
|
|
@param[in] old_checksum checksum value according to old style
|
|
@param[in] new_checksum checksum value according to new style
|
|
@param[in] checksum_field1 Checksum in page header
|
|
@param[in] checksum_field2 Checksum in page trailer
|
|
@param[in] algo current checksum algorithm */
|
|
virtual inline void print_innodb_checksum(
|
|
ulint old_checksum, ulint new_checksum, ulint checksum_field1,
|
|
ulint checksum_field2, srv_checksum_algorithm_t algo) const {}
|
|
|
|
/** Print the message that checksum mismatch happened in
|
|
page header. */
|
|
virtual inline void print_innodb_fail() const {}
|
|
|
|
/** Print both new-style, old-style & crc32 checksum values.
|
|
@param[in] checksum_field1 Checksum in page header
|
|
@param[in] checksum_field2 Checksum in page trailer */
|
|
virtual inline void print_crc32_checksum(ulint checksum_field1,
|
|
ulint checksum_field2) const {}
|
|
|
|
/** Print a message that crc32 check failed. */
|
|
virtual inline void print_crc32_fail() const {}
|
|
|
|
/** Print a message that none check failed. */
|
|
virtual inline void print_none_fail() const {}
|
|
|
|
/** Print checksum values on a compressed page.
|
|
@param[in] calc the calculated checksum value
|
|
@param[in] stored the stored checksum in header. */
|
|
virtual inline void print_compressed_checksum(ib_uint32_t calc,
|
|
ib_uint32_t stored) const {}
|
|
|
|
/** Verify a compressed page's checksum.
|
|
@retval true if stored checksum is valid
|
|
according to the value of srv_checksum_algorithm
|
|
@retval false if stored schecksum is not valid
|
|
according to the value of srv_checksum_algorithm */
|
|
bool verify_zip_checksum() const;
|
|
|
|
/** Calculate the compressed page checksum. This variant
|
|
should be used when only the page_size_t is unknown and
|
|
only physical page_size of compressed page is available.
|
|
@param[in] read_buf buffer holding the page
|
|
@param[in] phys_page_size physical page size
|
|
@param[in] algo checksum algorithm to use
|
|
@param[in] use_legacy_big_endian only used if algo is
|
|
SRV_CHECKSUM_ALGORITHM_CRC32 or SRV_CHECKSUM_ALGORITHM_STRICT_CRC32 -
|
|
if true then use big endian byteorder when converting byte strings to
|
|
integers.
|
|
@return page checksum */
|
|
uint32_t calc_zip_checksum(const byte *read_buf, ulint phys_page_size,
|
|
srv_checksum_algorithm_t algo,
|
|
bool use_legacy_big_endian = false) const;
|
|
|
|
/** Calculate the compressed page checksum.
|
|
@param[in] algo checksum algorithm to use
|
|
@param[in] use_legacy_big_endian only used if algo is
|
|
SRV_CHECKSUM_ALGORITHM_CRC32 or SRV_CHECKSUM_ALGORITHM_STRICT_CRC32 -
|
|
if true then use big endian byteorder when converting byte strings to
|
|
integers.
|
|
@return page checksum */
|
|
uint32_t calc_zip_checksum(srv_checksum_algorithm_t algo,
|
|
bool use_legacy_big_endian = false) const;
|
|
|
|
private:
|
|
/** Checks if the page is in innodb checksum format.
|
|
@param[in] checksum_field1 new checksum field
|
|
@param[in] checksum_field2 old checksum field
|
|
@param[in] algo current checksum algorithm
|
|
@return true if the page is in innodb checksum format. */
|
|
bool is_checksum_valid_innodb(ulint checksum_field1, ulint checksum_field2,
|
|
const srv_checksum_algorithm_t algo) const;
|
|
|
|
/** Checks if the page is in none checksum format.
|
|
@param[in] checksum_field1 new checksum field
|
|
@param[in] checksum_field2 old checksum field
|
|
@param[in] algo current checksum algorithm
|
|
@return true if the page is in none checksum format. */
|
|
bool is_checksum_valid_none(ulint checksum_field1, ulint checksum_field2,
|
|
const srv_checksum_algorithm_t algo) const;
|
|
|
|
/** Checks if the page is in crc32 checksum format.
|
|
@param[in] checksum_field1 new checksum field
|
|
@param[in] checksum_field2 old checksum field
|
|
@param[in] algo current checksum algorithm
|
|
@param[in] use_legacy_big_endian big endian algorithm
|
|
@return true if the page is in crc32 checksum format. */
|
|
bool is_checksum_valid_crc32(ulint checksum_field1, ulint checksum_field2,
|
|
const srv_checksum_algorithm_t algo,
|
|
bool use_legacy_big_endian) const;
|
|
|
|
/** Issue a warning when the checksum that is stored in the page is
|
|
valid, but different than the global setting innodb_checksum_algorithm.
|
|
@param[in] curr_algo current checksum algorithm
|
|
@param[in] page_checksum page valid checksum
|
|
@param[in] page_id page identifier */
|
|
void page_warn_strict_checksum(srv_checksum_algorithm_t curr_algo,
|
|
srv_checksum_algorithm_t page_checksum,
|
|
const page_id_t &page_id) const;
|
|
|
|
protected:
|
|
/** If true, do a LSN check during innodb recovery. */
|
|
bool m_check_lsn;
|
|
/** Buffer holding the page. */
|
|
const byte *m_read_buf;
|
|
/** Page size. */
|
|
const page_size_t &m_page_size;
|
|
/** Skip checksum verification but compare only data. */
|
|
bool m_skip_checksum;
|
|
};
|
|
|
|
#endif /* buf0checksum_h */
|