summaryrefslogtreecommitdiff
path: root/extra
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2019-07-02 17:46:22 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2019-07-02 17:46:22 +0300
commite82fe21e3ac3141c92b7c4fb2d1fc3c083d834e8 (patch)
tree3ecf4329b6a623165aa6cb392ae71998de50c89e /extra
parent709f0510e32981c59d7353e55a564073939db770 (diff)
parent7f1e1309bbd54a7923cf33a37938a29171ca0993 (diff)
downloadmariadb-git-e82fe21e3ac3141c92b7c4fb2d1fc3c083d834e8.tar.gz
Merge 10.2 into 10.3
Diffstat (limited to 'extra')
-rw-r--r--extra/innochecksum.cc101
-rw-r--r--extra/mariabackup/xtrabackup.cc2
2 files changed, 89 insertions, 14 deletions
diff --git a/extra/innochecksum.cc b/extra/innochecksum.cc
index 7354dfcb656..b6f478b943b 100644
--- a/extra/innochecksum.cc
+++ b/extra/innochecksum.cc
@@ -101,6 +101,8 @@ ulong srv_page_size_shift;
page_size_t univ_page_size(0, 0, false);
/* Current page number (0 based). */
unsigned long long cur_page_num;
+/* Current space. */
+unsigned long long cur_space;
/* Skip the checksum verification. */
static bool no_check;
/* Enabled for strict checksum verification. */
@@ -452,6 +454,27 @@ ulint read_file(
return bytes;
}
+/** Check whether the page contains all zeroes.
+@param[in] buf page
+@param[in] size physical size of the page
+@return true if the page is all zeroes; else false */
+static bool is_page_all_zeroes(
+ byte* buf,
+ ulint size)
+{
+ /* On pages that are not all zero, the page number
+ must match. */
+ const ulint* p = reinterpret_cast<const ulint*>(buf);
+ const ulint* const end = reinterpret_cast<const ulint*>(buf + size);
+ do {
+ if (*p++) {
+ return false;
+ }
+ } while (p != end);
+
+ return true;
+}
+
/** Check if page is corrupted or not.
@param[in] buf page frame
@param[in] page_size page size
@@ -463,10 +486,10 @@ ulint read_file(
static
bool
is_page_corrupted(
- byte* buf,
+ byte* buf,
const page_size_t& page_size,
- bool is_encrypted,
- bool is_compressed)
+ bool is_encrypted,
+ bool is_compressed)
{
/* enable if page is corrupted. */
@@ -479,6 +502,24 @@ is_page_corrupted(
ulint space_id = mach_read_from_4(
buf + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
+ if (mach_read_from_4(buf + FIL_PAGE_OFFSET) != cur_page_num
+ || space_id != cur_space) {
+ /* On pages that are not all zero, the page number
+ must match. */
+ if (is_page_all_zeroes(buf, page_size.physical())) {
+ return false;
+ }
+
+ if (is_log_enabled) {
+ fprintf(log_file,
+ "page id mismatch space::" ULINTPF
+ " page::%llu \n",
+ space_id, cur_page_num);
+ }
+
+ return true;
+ }
+
/* We can't trust only a page type, thus we take account
also fsp_flags or crypt_data on page 0 */
if ((page_type == FIL_PAGE_PAGE_COMPRESSED && is_compressed) ||
@@ -1577,9 +1618,6 @@ int main(
FILE* fil_page_type = NULL;
fpos_t pos;
- /* Use to check the space id of given file. If space_id is zero,
- then check whether page is doublewrite buffer.*/
- ulint space_id = 0UL;
/* enable when space_id of given file is zero. */
bool is_system_tablespace = false;
@@ -1701,9 +1739,8 @@ int main(
/* enable variable is_system_tablespace when space_id of given
file is zero. Use to skip the checksum verification and rewrite
for doublewrite pages. */
- is_system_tablespace = (!memcmp(&space_id, buf +
- FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, 4))
- ? true : false;
+ cur_space = mach_read_from_4(buf + FIL_PAGE_SPACE_ID);
+ cur_page_num = mach_read_from_4(buf + FIL_PAGE_OFFSET);
/* Determine page size, zip_size and page compression
from fsp_flags and encryption metadata from page 0 */
@@ -1715,7 +1752,9 @@ int main(
physical_page_size = page_size.physical();
bool is_compressed = FSP_FLAGS_HAS_PAGE_COMPRESSION(flags);
- if (page_size.physical() > UNIV_ZIP_SIZE_MIN) {
+ if (physical_page_size == UNIV_ZIP_SIZE_MIN) {
+ partial_page_read = false;
+ } else {
/* Read rest of the page 0 to determine crypt_data */
bytes = read_file(buf, partial_page_read, page_size.physical(), fil_in);
if (bytes != page_size.physical()) {
@@ -1730,6 +1769,7 @@ int main(
partial_page_read = false;
}
+
/* Now that we have full page 0 in buffer, check encryption */
bool is_encrypted = check_encryption(filename, page_size, buf);
@@ -1740,7 +1780,9 @@ int main(
unsigned long long tmp_allow_mismatches = allow_mismatches;
allow_mismatches = 0;
- exit_status = verify_checksum(buf, page_size, is_encrypted, is_compressed, &mismatch_count);
+ exit_status = verify_checksum(
+ buf, page_size, is_encrypted,
+ is_compressed, &mismatch_count);
if (exit_status) {
fprintf(stderr, "Error: Page 0 checksum mismatch, can't continue. \n");
@@ -1804,6 +1846,36 @@ int main(
}
}
+ off_t cur_offset = 0;
+ /* Find the first non all-zero page and fetch the
+ space id from there. */
+ while (is_page_all_zeroes(buf, physical_page_size)) {
+ bytes = ulong(read_file(
+ buf, false, physical_page_size,
+ fil_in));
+
+ if (feof(fil_in)) {
+ fprintf(stderr, "All are "
+ "zero-filled pages.");
+ goto my_exit;
+ }
+
+ cur_offset++;
+ }
+
+ cur_space = mach_read_from_4(buf + FIL_PAGE_SPACE_ID);
+ is_system_tablespace = (cur_space == 0);
+
+ if (cur_offset > 0) {
+ /* Re-read the non-zero page to check the
+ checksum. So move the file pointer to
+ previous position and reset the page number too. */
+ cur_page_num = mach_read_from_4(buf + FIL_PAGE_OFFSET);
+ if (!start_page) {
+ goto first_non_zero;
+ }
+ }
+
/* seek to the necessary position */
if (start_page) {
if (!read_from_stdin) {
@@ -1901,6 +1973,7 @@ int main(
goto my_exit;
}
+first_non_zero:
if (is_system_tablespace) {
/* enable when page is double write buffer.*/
skip_page = is_page_doublewritebuffer(buf);
@@ -1921,8 +1994,10 @@ int main(
checksum verification.*/
if (!no_check
&& !skip_page
- && (exit_status = verify_checksum(buf, page_size,
- is_encrypted, is_compressed, &mismatch_count))) {
+ && (exit_status = verify_checksum(
+ buf, page_size,
+ is_encrypted, is_compressed,
+ &mismatch_count))) {
goto my_exit;
}
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc
index c06d677786c..8775584bff0 100644
--- a/extra/mariabackup/xtrabackup.cc
+++ b/extra/mariabackup/xtrabackup.cc
@@ -3794,7 +3794,7 @@ open_or_create_log_file(
fil_space_t* space,
ulint i) /*!< in: log file number in group */
{
- char name[10000];
+ char name[FN_REFLEN];
ulint dirnamelen;
os_normalize_path(srv_log_group_home_dir);