summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Kosov <claprix@yandex.ru>2021-06-21 14:54:26 +0300
committerEugene Kosov <claprix@yandex.ru>2021-07-20 19:32:33 +0300
commit1918bdf32cdbd1f190cc4479f4076ee4a467f25d (patch)
treec594b1756284fa0033f224393fd70d01d804790e
parent5f8651ac238d8d6cd3e4a7e3090b4b529f990331 (diff)
downloadmariadb-git-1918bdf32cdbd1f190cc4479f4076ee4a467f25d.tar.gz
MDEV-25361 innochecksum must not report errors for freed pages
Store and maintain xdes pages always. And doesn't verify checksums for freed pages. innochecksum can work only with the first space file of multiple ones. Tell about it and abort in case of not the first file.
-rw-r--r--extra/innochecksum.cc25
1 files changed, 18 insertions, 7 deletions
diff --git a/extra/innochecksum.cc b/extra/innochecksum.cc
index 4dca6572434..beda56032b8 100644
--- a/extra/innochecksum.cc
+++ b/extra/innochecksum.cc
@@ -817,6 +817,16 @@ write_file(
return(true);
}
+// checks using current xdes page whether the page is free
+static bool page_is_free(const byte *xdes, page_size_t page_size,
+ size_t page_no)
+{
+ const byte *des=
+ xdes + XDES_ARR_OFFSET +
+ XDES_SIZE * ((page_no & (page_size.physical() - 1)) / FSP_EXTENT_SIZE);
+ return xdes_get_bit(des, XDES_FREE_BIT, page_no % FSP_EXTENT_SIZE);
+}
+
/*
Parse the page and collect/dump the information about page type
@param [in] page buffer page
@@ -908,11 +918,7 @@ parse_page(
std::map<unsigned long long, per_index_stats>::iterator it;
it = index_ids.find(id);
per_index_stats &index = (it->second);
- const byte* des = xdes + XDES_ARR_OFFSET
- + XDES_SIZE * ((page_no & (page_size.physical() - 1))
- / FSP_EXTENT_SIZE);
- if (xdes_get_bit(des, XDES_FREE_BIT,
- page_no % FSP_EXTENT_SIZE)) {
+ if (page_is_free(xdes, page_size, page_no)) {
index.free_pages++;
return;
}
@@ -1072,7 +1078,6 @@ parse_page(
case FIL_PAGE_TYPE_FSP_HDR:
page_type.n_fil_page_type_fsp_hdr++;
- memcpy(xdes, page, page_size.physical());
if (page_type_dump) {
fprintf(file, "#::%llu\t\t|\t\tFile Space "
"Header\t\t|\t%s\n", cur_page_num, str);
@@ -1081,7 +1086,6 @@ parse_page(
case FIL_PAGE_TYPE_XDES:
page_type.n_fil_page_type_xdes++;
- memcpy(xdes, page, page_size.physical());
if (page_type_dump) {
fprintf(file, "#::%llu\t\t|\t\tExtent descriptor "
"page\t\t|\t%s\n", cur_page_num, str);
@@ -1814,6 +1818,8 @@ int main(
printf("page %llu ", cur_page_num);
}
+ memcpy(xdes, buf, physical_page_size);
+
if (page_type_summary || page_type_dump) {
parse_page(buf, xdes, fil_page_type, page_size, is_encrypted);
}
@@ -1992,6 +1998,7 @@ first_non_zero:
/* If no-check is enabled, skip the
checksum verification.*/
if (!no_check
+ && !page_is_free(xdes, page_size, cur_page_num)
&& !skip_page
&& (exit_status = verify_checksum(
buf, page_size,
@@ -2014,6 +2021,10 @@ first_non_zero:
printf("page %llu ", cur_page_num);
}
+ if (page_get_page_no(buf) % physical_page_size == 0) {
+ memcpy(xdes, buf, physical_page_size);
+ }
+
if (page_type_summary || page_type_dump) {
parse_page(buf, xdes, fil_page_type, page_size, is_encrypted);
}