1
0
mirror of https://github.com/MariaDB/server.git synced 2025-11-28 17:36:30 +03:00

MDEV-14192: mariabackup.incremental_backup failed in buildbot with Failing assertion: byte_offset % OS_FILE_LOG_BLOCK_SIZE == 0

In some cases it's possible that InnoDB redo log file header is re-written so,
that checkpoint lsn and checkpoint lsn offset are updated, but checkpoint
number stays the same. The fix is to re-read redo log header if at least one
of those three parametes is changed at backup start.

Repeat the logic of log_group_checkpoint() on choosing InnoDB checkpoint info
field on backup start. This does not influence backup correctness, but
simplifies bugs analysis.
This commit is contained in:
Vlad Lesin
2019-05-16 11:04:39 +03:00
parent c874040729
commit bff9b8026b

View File

@@ -4187,9 +4187,11 @@ reread_log_header:
log_group_header_read(&log_sys->log, max_cp_field); log_group_header_read(&log_sys->log, max_cp_field);
if (checkpoint_no_start != mach_read_from_8(buf + LOG_CHECKPOINT_NO)) { if (checkpoint_no_start != mach_read_from_8(buf + LOG_CHECKPOINT_NO)
|| checkpoint_lsn_start != mach_read_from_8(buf + LOG_CHECKPOINT_LSN)
|| log_sys->log.lsn_offset
!= mach_read_from_8(buf + LOG_CHECKPOINT_OFFSET))
goto reread_log_header; goto reread_log_header;
}
log_mutex_exit(); log_mutex_exit();
@@ -4209,43 +4211,39 @@ reread_log_header:
} }
/* label it */ /* label it */
byte MY_ALIGNED(OS_FILE_LOG_BLOCK_SIZE) log_hdr[OS_FILE_LOG_BLOCK_SIZE]; byte MY_ALIGNED(OS_FILE_LOG_BLOCK_SIZE) log_hdr_buf[LOG_FILE_HDR_SIZE];
memset(log_hdr, 0, sizeof log_hdr); memset(log_hdr_buf, 0, sizeof log_hdr_buf);
mach_write_to_4(LOG_HEADER_FORMAT + log_hdr, log_sys->log.format);
mach_write_to_4(LOG_HEADER_SUBFORMAT + log_hdr,
log_sys->log.subformat);
mach_write_to_8(LOG_HEADER_START_LSN + log_hdr, checkpoint_lsn_start);
strcpy(reinterpret_cast<char*>(LOG_HEADER_CREATOR + log_hdr),
"Backup " MYSQL_SERVER_VERSION);
log_block_set_checksum(log_hdr,
log_block_calc_checksum_crc32(log_hdr));
/* Write the log header. */ byte *log_hdr_field = log_hdr_buf;
if (ds_write(dst_log_file, log_hdr, sizeof log_hdr)) { mach_write_to_4(LOG_HEADER_FORMAT + log_hdr_field, log_sys->log.format);
log_write_fail: mach_write_to_4(LOG_HEADER_SUBFORMAT + log_hdr_field, log_sys->log.subformat);
msg("error: write to logfile failed"); mach_write_to_8(LOG_HEADER_START_LSN + log_hdr_field, checkpoint_lsn_start);
goto fail; strcpy(reinterpret_cast<char*>(LOG_HEADER_CREATOR + log_hdr_field),
} "Backup " MYSQL_SERVER_VERSION);
/* Adjust the checkpoint page. */ log_block_set_checksum(log_hdr_field,
memcpy(log_hdr, buf, OS_FILE_LOG_BLOCK_SIZE); log_block_calc_checksum_crc32(log_hdr_field));
mach_write_to_8(log_hdr + LOG_CHECKPOINT_OFFSET,
(checkpoint_lsn_start & (OS_FILE_LOG_BLOCK_SIZE - 1)) /* copied from log_group_checkpoint() */
| LOG_FILE_HDR_SIZE); log_hdr_field +=
(log_sys->next_checkpoint_no & 1) ? LOG_CHECKPOINT_2 : LOG_CHECKPOINT_1;
/* The least significant bits of LOG_CHECKPOINT_OFFSET must be /* The least significant bits of LOG_CHECKPOINT_OFFSET must be
stored correctly in the copy of the ib_logfile. The most significant stored correctly in the copy of the ib_logfile. The most significant
bits, which identify the start offset of the log block in the file, bits, which identify the start offset of the log block in the file,
we did choose freely, as LOG_FILE_HDR_SIZE. */ we did choose freely, as LOG_FILE_HDR_SIZE. */
ut_ad(!((log_sys->log.lsn ^ checkpoint_lsn_start) ut_ad(!((log_sys->log.lsn ^ checkpoint_lsn_start)
& (OS_FILE_LOG_BLOCK_SIZE - 1))); & (OS_FILE_LOG_BLOCK_SIZE - 1)));
log_block_set_checksum(log_hdr, /* Adjust the checkpoint page. */
log_block_calc_checksum_crc32(log_hdr)); memcpy(log_hdr_field, log_sys->checkpoint_buf, OS_FILE_LOG_BLOCK_SIZE);
/* Write checkpoint page 1 and two empty log pages before the mach_write_to_8(log_hdr_field + LOG_CHECKPOINT_OFFSET,
payload. */ (checkpoint_lsn_start & (OS_FILE_LOG_BLOCK_SIZE - 1))
if (ds_write(dst_log_file, log_hdr, OS_FILE_LOG_BLOCK_SIZE) | LOG_FILE_HDR_SIZE);
|| !memset(log_hdr, 0, sizeof log_hdr) log_block_set_checksum(log_hdr_field,
|| ds_write(dst_log_file, log_hdr, sizeof log_hdr) log_block_calc_checksum_crc32(log_hdr_field));
|| ds_write(dst_log_file, log_hdr, sizeof log_hdr)) {
goto log_write_fail; /* Write log header*/
if (ds_write(dst_log_file, log_hdr_buf, sizeof(log_hdr_buf))) {
msg("error: write to logfile failed");
goto fail;
} }
log_copying_running = true; log_copying_running = true;