/* Get the relative path for the destination tablespace name, i.e. the onethatcanbeappendedtothebackuprootdirectory.Non-system tablespacesmayhaveabsolutepathsforDATADIRECTORY.
We want to make "local" copies for the backup. */
strncpy(cursor->rel_path,
xb_get_relative_path(cursor->abs_path, cursor->is_system()),
(sizeof cursor->rel_path) - 1);
cursor->rel_path[(sizeof cursor->rel_path) - 1] = '\0';
/* In the backup mode we should already have a tablespace handle created byfil_ibd_load()unlessitisasystem
tablespace. Otherwise we open the file here. */ if (!node->is_open()) {
ut_ad(cursor->is_system()
|| srv_operation == SRV_OPERATION_RESTORE_DELTA
|| xb_close_files);
node->handle = os_file_create_simple_no_error_handling( 0, node->name,
OS_FILE_OPEN,
OS_FILE_READ_ALLOW_DELETE, true, &success); if (!success) { /* The following call prints an error message */
os_file_get_last_error(TRUE);
msg(thread_n, "mariabackup: error: cannot open " "tablespace %s", cursor->abs_path);
/* We ignore the doublewrite buffer pages.*/ if (cursor->space_id == TRX_SYS_SPACE
&& page_no >= FSP_EXTENT_SIZE
&& page_no < FSP_EXTENT_SIZE * 3) { returnfalse;
}
/* Validate page number. */ if (mach_read_from_4(page + FIL_PAGE_OFFSET) != page_no
&& cursor->space_id != TRX_SYS_SPACE) { /* On pages that are not all zero, the pagenumbermustmatch.
The first 38 and last 8 bytes are never encrypted. */ const ulint* p = reinterpret_cast<const ulint*>(page); const ulint* const end = reinterpret_cast<const ulint*>(
page + page_size); do { if (*p++) { returntrue;
}
} while (p != end);
/* Whole zero page is valid. */ returnfalse;
}
if (space->full_crc32()) { return buf_page_is_corrupted(false, page, space->flags);
}
/* Validate encrypted pages. The first page is never encrypted. Inthesystemtablespace,thefirstpagewouldbewrittenwith FIL_PAGE_FILE_FLUSH_LSNatshutdown,andiftheLSNexceeds 4,294,967,295,themach_read_from_4()belowwouldwrongly interpretthepageasencrypted.Wepreventthatbychecking
page_no first. */ if (page_no
&& mach_read_from_4(page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION)
&& (opt_encrypted_backup
|| (space->crypt_data
&& space->crypt_data->type != CRYPT_SCHEME_UNENCRYPTED))) {
if (!fil_space_verify_crypt_checksum(page, space->zip_size())) returntrue;
/* Compressed encrypted need to be decrypted
and decompressed for verification. */ if (page_type != FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED
&& !opt_extended_validation) returnfalse;
/** Reads and verifies the next block of pages from the source file.Positionsthecursorafterthelastreadnon-corruptedpage. @param[in,out]cursorsourcefilecursor @param[out]corrupted_pagesaddscorruptedpagesif opt_log_innodb_page_corruptionisset @returnXB_FIL_CUR_SUCCESSifsomehavebeenreadsuccessfully,XB_FIL_CUR_EOF
if there are no more pages to read and XB_FIL_CUR_ERROR on error. */
xb_fil_cur_result_t xb_fil_cur_read(xb_fil_cur_t* cursor,
CorruptedPages &corrupted_pages)
{
byte* page; unsigned i;
ulint npages;
ulint retry_count;
xb_fil_cur_result_t ret;
ib_int64_t offset;
ib_int64_t to_read; const ulint page_size = cursor->page_size; bool defer = false;
xb_ad(!cursor->is_system() || page_size == srv_page_size);
if (cursor->n_process_batch > 1) {
ret = XB_FIL_CUR_ERROR; goto func_exit;
}
space->release(); goto reinit_buf;
}
defer = UT_LIST_GET_FIRST(space->chain)->deferred; /* check pages for corruption and re-read if necessary. i.e. in case of
partially written pages */ for (page = cursor->buf, i = 0; i < npages;
page += page_size, i++) { unsigned page_no = cursor->buf_page_no + i;
if (!defer && page_is_corrupted(page, page_no, cursor, space)) {
retry_count--;
if (retry_count == 0) { constchar *ignore_corruption_warn = opt_log_innodb_page_corruption ? " WARNING!!! The corruption is ignored due to" " log-innodb-page-corruption option, the backup can contain" " corrupted data." : "";
msg(cursor->thread_n, "Error: failed to read page after " "10 retries. File %s seems to be " "corrupted.%s", cursor->abs_path, ignore_corruption_warn);
ut_print_buf(stderr, page, page_size); if (opt_log_innodb_page_corruption) {
corrupted_pages.add_page(cursor->node->name,
{cursor->node->space->id, page_no});
retry_count = 1;
} else {
ret = XB_FIL_CUR_ERROR; break;
}
} else {
msg(cursor->thread_n, "Database page corruption detected at page "
UINT32PF ", retrying...",
page_no);
std::this_thread::sleep_for(
std::chrono::milliseconds(100)); goto read_retry;
}
}
DBUG_EXECUTE_FOR_KEY("add_corrupted_page_for",
cursor->node->space->name(),
{ unsigned corrupted_page_no = static_cast<unsigned>(strtoul(dbug_val, NULL, 10)); if (page_no == corrupted_page_no)
corrupted_pages.add_page(cursor->node->name,
{cursor->node->space->id,
corrupted_page_no});
});
cursor->buf_read += page_size;
cursor->buf_npages++;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.