summaryrefslogtreecommitdiff
path: root/storage/innobase/log/log0recv.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/log/log0recv.cc')
-rw-r--r--storage/innobase/log/log0recv.cc435
1 files changed, 183 insertions, 252 deletions
diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc
index c2eb1fe7659..bb83c38704f 100644
--- a/storage/innobase/log/log0recv.cc
+++ b/storage/innobase/log/log0recv.cc
@@ -59,7 +59,7 @@ Created 9/20/1997 Heikki Tuuri
#include "row0merge.h"
/** Log records are stored in the hash table in chunks at most of this size;
-this must be less than UNIV_PAGE_SIZE as it is stored in the buffer pool */
+this must be less than srv_page_size as it is stored in the buffer pool */
#define RECV_DATA_BLOCK_SIZE (MEM_MAX_ALLOC_IN_BUF - sizeof(recv_data_t) - REDZONE_SIZE)
/** Read-ahead area in applying log records to file pages */
@@ -76,7 +76,7 @@ volatile bool recv_recovery_on;
bool recv_needed_recovery;
#ifdef UNIV_DEBUG
/** TRUE if writing to the redo log (mtr_commit) is forbidden.
-Protected by log_sys->mutex. */
+Protected by log_sys.mutex. */
bool recv_no_log_write = false;
#endif /* UNIV_DEBUG */
@@ -724,7 +724,9 @@ recv_sys_close()
os_event_destroy(recv_sys->flush_end);
}
- ut_free(recv_sys->buf);
+ if (recv_sys->buf != NULL) {
+ ut_free_dodump(recv_sys->buf, recv_sys->buf_size);
+ }
ut_ad(!recv_writer_thread_active);
mutex_free(&recv_sys->writer_mutex);
@@ -783,7 +785,7 @@ DECLARE_THREAD(recv_writer_thread)(
/* Wait till we get a signal to clean the LRU list.
Bounded by max wait time of 100ms. */
- ib_uint64_t sig_count = os_event_reset(buf_flush_event);
+ int64_t sig_count = os_event_reset(buf_flush_event);
os_event_wait_time_low(buf_flush_event, 100000, sig_count);
mutex_enter(&recv_sys->writer_mutex);
@@ -832,7 +834,8 @@ recv_sys_init()
}
recv_sys->buf = static_cast<byte*>(
- ut_malloc_nokey(RECV_PARSING_BUF_SIZE));
+ ut_malloc_dontdump(RECV_PARSING_BUF_SIZE));
+ recv_sys->buf_size = RECV_PARSING_BUF_SIZE;
recv_sys->addr_hash = hash_create(buf_pool_get_curr_size() / 512);
recv_sys->progress_time = time(NULL);
@@ -866,8 +869,9 @@ recv_sys_debug_free(void)
hash_table_free(recv_sys->addr_hash);
mem_heap_free(recv_sys->heap);
- ut_free(recv_sys->buf);
+ ut_free_dodump(recv_sys->buf, recv_sys->buf_size);
+ recv_sys->buf_size = 0;
recv_sys->buf = NULL;
recv_sys->heap = NULL;
recv_sys->addr_hash = NULL;
@@ -883,57 +887,46 @@ recv_sys_debug_free(void)
mutex_exit(&(recv_sys->mutex));
}
-/** Read a log segment to a buffer.
-@param[out] buf buffer
-@param[in] group redo log files
-@param[in, out] start_lsn in : read area start, out: the last read valid lsn
+/** Read a log segment to log_sys.buf.
+@param[in,out] start_lsn in: read area start,
+out: the last read valid lsn
@param[in] end_lsn read area end
-@param[out] invalid_block - invalid, (maybe incompletely written) block encountered
-@return false, if invalid block encountered (e.g checksum mismatch), true otherwise */
-bool
-log_group_read_log_seg(
- byte* buf,
- const log_group_t* group,
- lsn_t *start_lsn,
- lsn_t end_lsn)
+@return whether no invalid blocks (e.g checksum mismatch) were found */
+bool log_t::files::read_log_seg(lsn_t* start_lsn, lsn_t end_lsn)
{
ulint len;
- lsn_t source_offset;
bool success = true;
- ut_ad(log_mutex_own());
+ ut_ad(log_sys.mutex.is_owned());
ut_ad(!(*start_lsn % OS_FILE_LOG_BLOCK_SIZE));
ut_ad(!(end_lsn % OS_FILE_LOG_BLOCK_SIZE));
-
+ byte* buf = log_sys.buf;
loop:
- source_offset = log_group_calc_lsn_offset(*start_lsn, group);
+ lsn_t source_offset = calc_lsn_offset(*start_lsn);
ut_a(end_lsn - *start_lsn <= ULINT_MAX);
len = (ulint) (end_lsn - *start_lsn);
ut_ad(len != 0);
- const bool at_eof = (source_offset % group->file_size) + len
- > group->file_size;
+ const bool at_eof = (source_offset % file_size) + len > file_size;
if (at_eof) {
/* If the above condition is true then len (which is ulint)
is > the expression below, so the typecast is ok */
- len = (ulint) (group->file_size -
- (source_offset % group->file_size));
+ len = ulint(file_size - (source_offset % file_size));
}
- log_sys->n_log_ios++;
+ log_sys.n_log_ios++;
MONITOR_INC(MONITOR_LOG_IO);
- ut_a(source_offset / UNIV_PAGE_SIZE <= ULINT_MAX);
+ ut_a((source_offset >> srv_page_size_shift) <= ULINT_MAX);
- const ulint page_no
- = (ulint) (source_offset / univ_page_size.physical());
+ const ulint page_no = ulint(source_offset >> srv_page_size_shift);
fil_io(IORequestLogRead, true,
page_id_t(SRV_LOG_SPACE_FIRST_ID, page_no),
univ_page_size,
- (ulint) (source_offset % univ_page_size.physical()),
+ ulint(source_offset & (srv_page_size - 1)),
len, buf, NULL);
for (ulint l = 0; l < len; l += OS_FILE_LOG_BLOCK_SIZE,
@@ -953,7 +946,7 @@ fail:
break;
}
- if (innodb_log_checksums || group->is_encrypted()) {
+ if (innodb_log_checksums || is_encrypted()) {
ulint crc = log_block_calc_checksum_crc32(buf);
ulint cksum = log_block_get_checksum(buf);
@@ -974,7 +967,7 @@ fail:
goto fail;
}
- if (group->is_encrypted()) {
+ if (is_encrypted()) {
log_crypt(buf, *start_lsn,
OS_FILE_LOG_BLOCK_SIZE, true);
}
@@ -1020,14 +1013,10 @@ recv_synchronize_groups()
the block is always incomplete */
lsn_t start_lsn = ut_uint64_align_down(recovered_lsn,
- OS_FILE_LOG_BLOCK_SIZE);
- log_group_read_log_seg(log_sys->buf, &log_sys->log,
- &start_lsn, start_lsn + OS_FILE_LOG_BLOCK_SIZE);
-
- /* Update the fields in the group struct to correspond to
- recovered_lsn */
-
- log_group_set_fields(&log_sys->log, recovered_lsn);
+ OS_FILE_LOG_BLOCK_SIZE);
+ log_sys.log.read_log_seg(&start_lsn,
+ start_lsn + OS_FILE_LOG_BLOCK_SIZE);
+ log_sys.log.set_fields(recovered_lsn);
/* Copy the checkpoint info to the log; remember that we have
incremented checkpoint_no by one, and the info will not be written
@@ -1053,19 +1042,17 @@ recv_check_log_header_checksum(
}
/** Find the latest checkpoint in the format-0 log header.
-@param[out] max_group log group, or NULL
@param[out] max_field LOG_CHECKPOINT_1 or LOG_CHECKPOINT_2
@return error code or DB_SUCCESS */
static MY_ATTRIBUTE((warn_unused_result))
dberr_t
-recv_find_max_checkpoint_0(log_group_t** max_group, ulint* max_field)
+recv_find_max_checkpoint_0(ulint* max_field)
{
- log_group_t* group = &log_sys->log;
ib_uint64_t max_no = 0;
ib_uint64_t checkpoint_no;
- byte* buf = log_sys->checkpoint_buf;
+ byte* buf = log_sys.checkpoint_buf;
- ut_ad(group->format == 0);
+ ut_ad(log_sys.log.format == 0);
/** Offset of the first checkpoint checksum */
static const uint CHECKSUM_1 = 288;
@@ -1076,11 +1063,11 @@ recv_find_max_checkpoint_0(log_group_t** max_group, ulint* max_field)
/** Least significant bits of the checkpoint offset */
static const uint OFFSET_LOW32 = 16;
- *max_group = NULL;
+ bool found = false;
for (ulint field = LOG_CHECKPOINT_1; field <= LOG_CHECKPOINT_2;
field += LOG_CHECKPOINT_2 - LOG_CHECKPOINT_1) {
- log_group_header_read(group, field);
+ log_header_read(field);
if (static_cast<uint32_t>(ut_fold_binary(buf, CHECKSUM_1))
!= mach_read_from_4(buf + CHECKSUM_1)
@@ -1107,21 +1094,20 @@ recv_find_max_checkpoint_0(log_group_t** max_group, ulint* max_field)
mach_read_from_8(buf + LOG_CHECKPOINT_LSN)));
if (checkpoint_no >= max_no) {
- *max_group = group;
+ found = true;
*max_field = field;
max_no = checkpoint_no;
- group->state = LOG_GROUP_OK;
-
- group->lsn = mach_read_from_8(
- buf + LOG_CHECKPOINT_LSN);
- group->lsn_offset = static_cast<ib_uint64_t>(
- mach_read_from_4(buf + OFFSET_HIGH32)) << 32
- | mach_read_from_4(buf + OFFSET_LOW32);
+ log_sys.log.set_lsn(mach_read_from_8(
+ buf + LOG_CHECKPOINT_LSN));
+ log_sys.log.set_lsn_offset(
+ lsn_t(mach_read_from_4(buf + OFFSET_HIGH32))
+ << 32
+ | mach_read_from_4(buf + OFFSET_LOW32));
}
}
- if (*max_group != NULL) {
+ if (found) {
return(DB_SUCCESS);
}
@@ -1142,34 +1128,27 @@ recv_find_max_checkpoint_0(log_group_t** max_group, ulint* max_field)
static dberr_t recv_log_format_0_recover(lsn_t lsn, bool crypt)
{
log_mutex_enter();
- log_group_t* group = &log_sys->log;
- const lsn_t source_offset
- = log_group_calc_lsn_offset(lsn, group);
+ const lsn_t source_offset = log_sys.log.calc_lsn_offset(lsn);
log_mutex_exit();
- const ulint page_no
- = (ulint) (source_offset / univ_page_size.physical());
- byte* buf = log_sys->buf;
+ const ulint page_no = ulint(source_offset >> srv_page_size_shift);
+ byte* buf = log_sys.buf;
static const char* NO_UPGRADE_RECOVERY_MSG =
"Upgrade after a crash is not supported."
" This redo log was created before MariaDB 10.2.2";
- static const char* NO_UPGRADE_RTFM_MSG =
- ". Please follow the instructions at "
- "https://mariadb.com/kb/en/library/upgrading/";
fil_io(IORequestLogRead, true,
page_id_t(SRV_LOG_SPACE_FIRST_ID, page_no),
univ_page_size,
- (ulint) ((source_offset & ~(OS_FILE_LOG_BLOCK_SIZE - 1))
- % univ_page_size.physical()),
- OS_FILE_LOG_BLOCK_SIZE, buf, NULL);
+ ulint((source_offset & ~(OS_FILE_LOG_BLOCK_SIZE - 1))
+ & (srv_page_size - 1)),
+ OS_FILE_LOG_BLOCK_SIZE, buf, NULL);
if (log_block_calc_checksum_format_0(buf)
!= log_block_get_checksum(buf)
&& !log_crypt_101_read_block(buf)) {
ib::error() << NO_UPGRADE_RECOVERY_MSG
- << ", and it appears corrupted"
- << NO_UPGRADE_RTFM_MSG;
+ << ", and it appears corrupted.";
return(DB_CORRUPTION);
}
@@ -1177,12 +1156,11 @@ static dberr_t recv_log_format_0_recover(lsn_t lsn, bool crypt)
== (source_offset & (OS_FILE_LOG_BLOCK_SIZE - 1))) {
} else if (crypt) {
ib::error() << "Cannot decrypt log for upgrading."
- " The encrypted log was created before MariaDB 10.2.2"
- << NO_UPGRADE_RTFM_MSG;
+ " The encrypted log was created"
+ " before MariaDB 10.2.2.";
return DB_ERROR;
} else {
- ib::error() << NO_UPGRADE_RECOVERY_MSG
- << NO_UPGRADE_RTFM_MSG;
+ ib::error() << NO_UPGRADE_RECOVERY_MSG << ".";
return(DB_ERROR);
}
@@ -1191,29 +1169,27 @@ static dberr_t recv_log_format_0_recover(lsn_t lsn, bool crypt)
recv_sys->parse_start_lsn = recv_sys->recovered_lsn
= recv_sys->scanned_lsn
= recv_sys->mlog_checkpoint_lsn = lsn;
- log_sys->last_checkpoint_lsn = log_sys->next_checkpoint_lsn
- = log_sys->lsn = log_sys->write_lsn
- = log_sys->current_flush_lsn = log_sys->flushed_to_disk_lsn
+ log_sys.last_checkpoint_lsn = log_sys.next_checkpoint_lsn
+ = log_sys.lsn = log_sys.write_lsn
+ = log_sys.current_flush_lsn = log_sys.flushed_to_disk_lsn
= lsn;
- log_sys->next_checkpoint_no = 0;
+ log_sys.next_checkpoint_no = 0;
return(DB_SUCCESS);
}
-/** Determine if a redo log from MariaDB 10.3 is clean.
+/** Determine if a redo log from MariaDB 10.4 is clean.
@return error code
@retval DB_SUCCESS if the redo log is clean
@retval DB_CORRUPTION if the redo log is corrupted
@retval DB_ERROR if the redo log is not empty */
-static
-dberr_t
-recv_log_recover_10_3()
+static dberr_t recv_log_recover_10_4()
{
- log_group_t* group = &log_sys->log;
- const lsn_t lsn = group->lsn;
- const lsn_t source_offset = log_group_calc_lsn_offset(lsn, group);
+ ut_ad(!log_sys.is_encrypted());
+ const lsn_t lsn = log_sys.log.get_lsn();
+ const lsn_t source_offset = log_sys.log.calc_lsn_offset(lsn);
const ulint page_no
= (ulint) (source_offset / univ_page_size.physical());
- byte* buf = log_sys->buf;
+ byte* buf = log_sys.buf;
fil_io(IORequestLogRead, true,
page_id_t(SRV_LOG_SPACE_FIRST_ID, page_no),
@@ -1223,11 +1199,7 @@ recv_log_recover_10_3()
OS_FILE_LOG_BLOCK_SIZE, buf, NULL);
if (log_block_calc_checksum(buf) != log_block_get_checksum(buf)) {
- return(DB_CORRUPTION);
- }
-
- if (group->is_encrypted()) {
- log_crypt(buf, lsn, OS_FILE_LOG_BLOCK_SIZE, true);
+ return DB_CORRUPTION;
}
/* On a clean shutdown, the redo log will be logically empty
@@ -1235,7 +1207,7 @@ recv_log_recover_10_3()
if (log_block_get_data_len(buf)
!= (source_offset & (OS_FILE_LOG_BLOCK_SIZE - 1))) {
- return(DB_ERROR);
+ return DB_ERROR;
}
/* Mark the redo log for downgrading. */
@@ -1243,12 +1215,12 @@ recv_log_recover_10_3()
recv_sys->parse_start_lsn = recv_sys->recovered_lsn
= recv_sys->scanned_lsn
= recv_sys->mlog_checkpoint_lsn = lsn;
- log_sys->last_checkpoint_lsn = log_sys->next_checkpoint_lsn
- = log_sys->lsn = log_sys->write_lsn
- = log_sys->current_flush_lsn = log_sys->flushed_to_disk_lsn
+ log_sys.last_checkpoint_lsn = log_sys.next_checkpoint_lsn
+ = log_sys.lsn = log_sys.write_lsn
+ = log_sys.current_flush_lsn = log_sys.flushed_to_disk_lsn
= lsn;
- log_sys->next_checkpoint_no = 0;
- return(DB_SUCCESS);
+ log_sys.next_checkpoint_no = 0;
+ return DB_SUCCESS;
}
/** Find the latest checkpoint in the log header.
@@ -1257,29 +1229,24 @@ recv_log_recover_10_3()
dberr_t
recv_find_max_checkpoint(ulint* max_field)
{
- log_group_t* group;
ib_uint64_t max_no;
ib_uint64_t checkpoint_no;
ulint field;
byte* buf;
- group = &log_sys->log;
-
max_no = 0;
*max_field = 0;
- buf = log_sys->checkpoint_buf;
+ buf = log_sys.checkpoint_buf;
- group->state = LOG_GROUP_CORRUPTED;
-
- log_group_header_read(group, 0);
+ log_header_read(0);
/* Check the header page checksum. There was no
checksum in the first redo log format (version 0). */
- group->format = mach_read_from_4(buf + LOG_HEADER_FORMAT);
- group->subformat = group->format
+ log_sys.log.format = mach_read_from_4(buf + LOG_HEADER_FORMAT);
+ log_sys.log.subformat = log_sys.log.format != LOG_HEADER_FORMAT_3_23
? mach_read_from_4(buf + LOG_HEADER_SUBFORMAT)
: 0;
- if (group->format != 0
+ if (log_sys.log.format != LOG_HEADER_FORMAT_3_23
&& !recv_check_log_header_checksum(buf)) {
ib::error() << "Invalid redo log header checksum.";
return(DB_CORRUPTION);
@@ -1291,35 +1258,27 @@ recv_find_max_checkpoint(ulint* max_field)
/* Ensure that the string is NUL-terminated. */
creator[LOG_HEADER_CREATOR_END - LOG_HEADER_CREATOR] = 0;
- switch (group->format) {
- case 0:
- return(recv_find_max_checkpoint_0(&group, max_field));
+ switch (log_sys.log.format) {
+ case LOG_HEADER_FORMAT_3_23:
+ return(recv_find_max_checkpoint_0(max_field));
case LOG_HEADER_FORMAT_10_2:
case LOG_HEADER_FORMAT_10_2 | LOG_HEADER_FORMAT_ENCRYPTED:
- case LOG_HEADER_FORMAT_10_3:
- case LOG_HEADER_FORMAT_10_3 | LOG_HEADER_FORMAT_ENCRYPTED:
+ case LOG_HEADER_FORMAT_CURRENT:
+ case LOG_HEADER_FORMAT_CURRENT | LOG_HEADER_FORMAT_ENCRYPTED:
case LOG_HEADER_FORMAT_10_4:
/* We can only parse the unencrypted LOG_HEADER_FORMAT_10_4.
The encrypted format uses a larger redo log block trailer. */
break;
default:
ib::error() << "Unsupported redo log format."
- " The redo log was created"
- " with " << creator <<
- ". Please follow the instructions at "
- "https://mariadb.com/kb/en/library/upgrading/";
- /* Do not issue a message about a possibility
- to cleanly shut down the newer server version
- and to remove the redo logs, because the
- format of the system data structures may
- radically change after MySQL 5.7. */
+ " The redo log was created with " << creator << ".";
return(DB_ERROR);
}
for (field = LOG_CHECKPOINT_1; field <= LOG_CHECKPOINT_2;
field += LOG_CHECKPOINT_2 - LOG_CHECKPOINT_1) {
- log_group_header_read(group, field);
+ log_header_read(field);
const ulint crc32 = log_block_calc_checksum_crc32(buf);
const ulint cksum = log_block_get_checksum(buf);
@@ -1334,7 +1293,7 @@ recv_find_max_checkpoint(ulint* max_field)
continue;
}
- if (group->is_encrypted()
+ if (log_sys.is_encrypted()
&& !log_crypt_read_checkpoint_buf(buf)) {
ib::error() << "Reading checkpoint"
" encryption info failed.";
@@ -1352,12 +1311,11 @@ recv_find_max_checkpoint(ulint* max_field)
if (checkpoint_no >= max_no) {
*max_field = field;
max_no = checkpoint_no;
- group->state = LOG_GROUP_OK;
- group->lsn = mach_read_from_8(
- buf + LOG_CHECKPOINT_LSN);
- group->lsn_offset = mach_read_from_8(
- buf + LOG_CHECKPOINT_OFFSET);
- log_sys->next_checkpoint_no = checkpoint_no;
+ log_sys.log.set_lsn(mach_read_from_8(
+ buf + LOG_CHECKPOINT_LSN));
+ log_sys.log.set_lsn_offset(mach_read_from_8(
+ buf + LOG_CHECKPOINT_OFFSET));
+ log_sys.next_checkpoint_no = checkpoint_no;
}
}
@@ -1374,22 +1332,8 @@ recv_find_max_checkpoint(ulint* max_field)
return(DB_ERROR);
}
- switch (group->format) {
- case LOG_HEADER_FORMAT_10_3:
- case LOG_HEADER_FORMAT_10_3 | LOG_HEADER_FORMAT_ENCRYPTED:
- if (group->subformat == 1) {
- /* 10.2 with new crash-safe TRUNCATE */
- break;
- }
- /* fall through */
- case LOG_HEADER_FORMAT_10_4:
- if (srv_operation == SRV_OPERATION_BACKUP) {
- ib::error()
- << "Incompatible redo log format."
- " The redo log was created with " << creator;
- return DB_ERROR;
- }
- dberr_t err = recv_log_recover_10_3();
+ if (log_sys.log.format == LOG_HEADER_FORMAT_10_4) {
+ dberr_t err = recv_log_recover_10_4();
if (err != DB_SUCCESS) {
ib::error()
<< "Downgrade after a crash is not supported."
@@ -1397,10 +1341,10 @@ recv_find_max_checkpoint(ulint* max_field)
<< (err == DB_ERROR
? "." : ", and it appears corrupted.");
}
- return(err);
+ return err;
}
- return(DB_SUCCESS);
+ return DB_SUCCESS;
}
/** Try to parse a single log record body and also applies it if
@@ -1732,18 +1676,22 @@ parse_log:
ptr = trx_undo_parse_add_undo_rec(ptr, end_ptr, page);
break;
case MLOG_UNDO_ERASE_END:
- ut_ad(!page || page_type == FIL_PAGE_UNDO_LOG);
- ptr = trx_undo_parse_erase_page_end(ptr, end_ptr, page, mtr);
+ if (page) {
+ ut_ad(page_type == FIL_PAGE_UNDO_LOG);
+ trx_undo_erase_page_end(page);
+ }
break;
case MLOG_UNDO_INIT:
/* Allow anything in page_type when creating a page. */
- ptr = trx_undo_parse_page_init(ptr, end_ptr, page, mtr);
+ ptr = trx_undo_parse_page_init(ptr, end_ptr, page);
break;
- case MLOG_UNDO_HDR_CREATE:
case MLOG_UNDO_HDR_REUSE:
ut_ad(!page || page_type == FIL_PAGE_UNDO_LOG);
- ptr = trx_undo_parse_page_header(type, ptr, end_ptr,
- page, mtr);
+ ptr = trx_undo_parse_page_header_reuse(ptr, end_ptr, page);
+ break;
+ case MLOG_UNDO_HDR_CREATE:
+ ut_ad(!page || page_type == FIL_PAGE_UNDO_LOG);
+ ptr = trx_undo_parse_page_header(ptr, end_ptr, page, mtr);
break;
case MLOG_REC_MIN_MARK: case MLOG_COMP_REC_MIN_MARK:
ut_ad(!page || fil_page_type_is_index(page_type));
@@ -1810,9 +1758,15 @@ parse_log:
ptr, end_ptr, page, page_zip, index);
}
break;
+ case MLOG_ZIP_WRITE_TRX_ID:
+ /* This must be a clustered index leaf page. */
+ ut_ad(!page || page_type == FIL_PAGE_INDEX);
+ ptr = page_zip_parse_write_trx_id(ptr, end_ptr,
+ page, page_zip);
+ break;
case MLOG_FILE_WRITE_CRYPT_DATA:
dberr_t err;
- ptr = const_cast<byte*>(fil_parse_write_crypt_data(ptr, end_ptr, block, &err));
+ ptr = const_cast<byte*>(fil_parse_write_crypt_data(ptr, end_ptr, &err));
if (err != DB_SUCCESS) {
recv_sys->found_corrupt_log = TRUE;
@@ -1924,13 +1878,13 @@ recv_add_to_hash_table(
ut_ad(type != MLOG_INDEX_LOAD);
ut_ad(type != MLOG_TRUNCATE);
- len = rec_end - body;
+ len = ulint(rec_end - body);
recv = static_cast<recv_t*>(
mem_heap_alloc(recv_sys->heap, sizeof(recv_t)));
recv->type = type;
- recv->len = rec_end - body;
+ recv->len = ulint(rec_end - body);
recv->start_lsn = start_lsn;
recv->end_lsn = end_lsn;
@@ -1967,13 +1921,13 @@ recv_add_to_hash_table(
prev_field = &(recv->data);
- /* Store the log record body in chunks of less than UNIV_PAGE_SIZE:
+ /* Store the log record body in chunks of less than srv_page_size:
recv_sys->heap grows into the buffer pool, and bigger chunks could not
be allocated */
while (rec_end > body) {
- len = rec_end - body;
+ len = ulint(rec_end - body);
if (len > RECV_DATA_BLOCK_SIZE) {
len = RECV_DATA_BLOCK_SIZE;
@@ -2066,6 +2020,7 @@ static void recv_recover_page(buf_block_t* block, mtr_t& mtr,
}
lsn_t start_lsn = 0, end_lsn = 0;
+ fil_space_t* space;
if (srv_is_tablespace_truncated(recv_addr->space)) {
/* The table will be truncated after applying
@@ -2073,11 +2028,16 @@ static void recv_recover_page(buf_block_t* block, mtr_t& mtr,
goto skip_log;
}
+ space = fil_space_acquire(recv_addr->space);
+ if (!space) {
+ goto skip_log;
+ }
+
for (recv_t* recv = UT_LIST_GET_FIRST(recv_addr->rec_list);
recv; recv = UT_LIST_GET_NEXT(rec_list, recv)) {
ut_ad(recv->start_lsn);
end_lsn = recv->end_lsn;
- ut_ad(end_lsn <= log_sys->log.scanned_lsn);
+ ut_ad(end_lsn <= log_sys.log.scanned_lsn);
if (recv->start_lsn < page_lsn) {
/* Ignore this record, because there are later changes
@@ -2091,8 +2051,7 @@ static void recv_recover_page(buf_block_t* block, mtr_t& mtr,
<< get_mlog_string(recv->type)
<< " LSN " << recv->start_lsn << " < "
<< init_lsn);
- } else if (srv_was_tablespace_truncated(
- fil_space_get(recv_addr->space))
+ } else if (srv_was_tablespace_truncated(space)
&& recv->start_lsn
< truncate_t::get_truncated_tablespace_init_lsn(
recv_addr->space)) {
@@ -2154,6 +2113,8 @@ static void recv_recover_page(buf_block_t* block, mtr_t& mtr,
}
}
+ space->release();
+
skip_log:
#ifdef UNIV_ZIP_DEBUG
ut_ad(!fil_page_index_page_check(page)
@@ -2300,35 +2261,35 @@ to create a page which has buffered page intialization redo log records.
static buf_block_t* recv_recovery_create_page_low(const page_id_t page_id,
recv_addr_t* recv_addr)
{
- mtr_t mtr;
- mlog_init_t::init& i = mlog_init.last(page_id);
- const lsn_t end_lsn = UT_LIST_GET_LAST(recv_addr->rec_list)->end_lsn;
+ mtr_t mtr;
+ mlog_init_t::init &i= mlog_init.last(page_id);
+ const lsn_t end_lsn= UT_LIST_GET_LAST(recv_addr->rec_list)->end_lsn;
if (end_lsn < i.lsn)
{
DBUG_LOG("ib_log", "skip log for page "
- << page_id
- << " LSN " << end_lsn
- << " < " << i.lsn);
- recv_addr->state = RECV_PROCESSED;
+ << page_id
+ << " LSN " << end_lsn
+ << " < " << i.lsn);
+ recv_addr->state= RECV_PROCESSED;
ignore:
ut_a(recv_sys->n_addrs);
recv_sys->n_addrs--;
return NULL;
}
- fil_space_t* space = fil_space_acquire(recv_addr->space);
+ fil_space_t *space= fil_space_acquire(recv_addr->space);
if (!space)
{
- recv_addr->state = RECV_PROCESSED;
+ recv_addr->state= RECV_PROCESSED;
goto ignore;
}
if (space->enable_lsn)
{
init_fail:
- fil_space_release(space);
- recv_addr->state = RECV_NOT_PROCESSED;
+ space->release();
+ recv_addr->state= RECV_NOT_PROCESSED;
return NULL;
}
@@ -2347,7 +2308,7 @@ init_fail:
mtr.start();
mtr.set_log_mode(MTR_LOG_NONE);
- buf_block_t* block = buf_page_create(page_id, page_size_t(space->flags),
+ buf_block_t *block= buf_page_create(page_id, page_size_t(space->flags),
&mtr);
if (recv_addr->state == RECV_PROCESSED)
/* The page happened to exist in the buffer pool, or it was
@@ -2356,14 +2317,14 @@ init_fail:
mtr.commit();
else
{
- i.created = true;
+ i.created= true;
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
mtr.x_latch_at_savepoint(0, block);
recv_recover_page(block, mtr, recv_addr, i.lsn);
ut_ad(mtr.has_committed());
}
- fil_space_release(space);
+ space->release();
return block;
}
@@ -2663,7 +2624,7 @@ recv_parse_log_rec(
fil_space_set_recv_size(*space, size);
}
- return(new_ptr - ptr);
+ return ulint(new_ptr - ptr);
}
/*******************************************************//**
@@ -2891,9 +2852,7 @@ loop:
/* Do nothing */
break;
case MLOG_CHECKPOINT:
-#if SIZE_OF_MLOG_CHECKPOINT != 1 + 8
-# error SIZE_OF_MLOG_CHECKPOINT != 1 + 8
-#endif
+ compile_time_assert(SIZE_OF_MLOG_CHECKPOINT == 1 + 8);
lsn = mach_read_from_8(ptr + 1);
if (UNIV_UNLIKELY(srv_print_verbose_log == 2)) {
@@ -3431,7 +3390,6 @@ func_exit:
/** Scans log from a buffer and stores new log data to the parsing buffer.
Parses and hashes the log records if new data found.
-@param[in,out] group log group
@param[in] checkpoint_lsn latest checkpoint log sequence number
@param[in,out] contiguous_lsn log sequence number
until which all redo log has been scanned
@@ -3441,7 +3399,6 @@ can be applied to the tablespaces
static
bool
recv_group_scan_log_recs(
- log_group_t* group,
lsn_t checkpoint_lsn,
lsn_t* contiguous_lsn,
bool last_phase)
@@ -3471,10 +3428,10 @@ recv_group_scan_log_recs(
store_t store_to_hash = recv_sys->mlog_checkpoint_lsn == 0
? STORE_NO : (last_phase ? STORE_IF_EXISTS : STORE_YES);
ulint available_mem = (buf_pool_get_n_pages() * 2 / 3)
- << srv_page_size_shift;
+ << srv_page_size_shift;
- group->scanned_lsn = end_lsn = *contiguous_lsn = ut_uint64_align_down(
- *contiguous_lsn, OS_FILE_LOG_BLOCK_SIZE);
+ log_sys.log.scanned_lsn = end_lsn = *contiguous_lsn =
+ ut_uint64_align_down(*contiguous_lsn, OS_FILE_LOG_BLOCK_SIZE);
do {
if (last_phase && store_to_hash == STORE_NO) {
@@ -3491,14 +3448,13 @@ recv_group_scan_log_recs(
start_lsn = ut_uint64_align_down(end_lsn,
OS_FILE_LOG_BLOCK_SIZE);
end_lsn = start_lsn;
- log_group_read_log_seg(
- log_sys->buf, group, &end_lsn,
- start_lsn + RECV_SCAN_SIZE);
+ log_sys.log.read_log_seg(&end_lsn, start_lsn + RECV_SCAN_SIZE);
} while (end_lsn != start_lsn
&& !recv_scan_log_recs(
- available_mem, &store_to_hash, log_sys->buf,
- checkpoint_lsn, start_lsn, end_lsn,
- contiguous_lsn, &group->scanned_lsn));
+ available_mem, &store_to_hash, log_sys.buf,
+ checkpoint_lsn,
+ start_lsn, end_lsn,
+ contiguous_lsn, &log_sys.log.scanned_lsn));
if (recv_sys->found_corrupt_log || recv_sys->found_corrupt_fs) {
DBUG_RETURN(false);
@@ -3506,7 +3462,7 @@ recv_group_scan_log_recs(
DBUG_PRINT("ib_log", ("%s " LSN_PF " completed",
last_phase ? "rescan" : "scan",
- group->scanned_lsn));
+ log_sys.log.scanned_lsn));
DBUG_RETURN(store_to_hash == STORE_NO);
}
@@ -3713,55 +3669,35 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn)
log_mutex_enter();
- /* Look for the latest checkpoint from any of the log groups */
-
err = recv_find_max_checkpoint(&max_cp_field);
if (err != DB_SUCCESS) {
-skip_apply:
+
+ srv_start_lsn = recv_sys->recovered_lsn = log_sys.lsn;
log_mutex_exit();
return(err);
}
- switch (log_sys->log.format) {
- case 0:
- break;
- case LOG_HEADER_FORMAT_10_2:
- case LOG_HEADER_FORMAT_10_2 | LOG_HEADER_FORMAT_ENCRYPTED:
- break;
- case LOG_HEADER_FORMAT_10_3:
- case LOG_HEADER_FORMAT_10_3 | LOG_HEADER_FORMAT_ENCRYPTED:
- if (log_sys->log.subformat == 1) {
- /* 10.2 with new crash-safe TRUNCATE */
- break;
- }
- /* fall through */
- default:
- /* This must be a clean log from a newer version. */
- goto skip_apply;
- }
-
- log_group_header_read(&log_sys->log, max_cp_field);
+ log_header_read(max_cp_field);
- buf = log_sys->checkpoint_buf;
+ buf = log_sys.checkpoint_buf;
checkpoint_lsn = mach_read_from_8(buf + LOG_CHECKPOINT_LSN);
checkpoint_no = mach_read_from_8(buf + LOG_CHECKPOINT_NO);
- /* Start reading the log groups from the checkpoint lsn up. The
- variable contiguous_lsn contains an lsn up to which the log is
- known to be contiguously written to all log groups. */
-
+ /* Start reading the log from the checkpoint lsn. The variable
+ contiguous_lsn contains an lsn up to which the log is known to
+ be contiguously written. */
recv_sys->mlog_checkpoint_lsn = 0;
- ut_ad(RECV_SCAN_SIZE <= log_sys->buf_size);
+ ut_ad(RECV_SCAN_SIZE <= srv_log_buffer_size);
const lsn_t end_lsn = mach_read_from_8(
buf + LOG_CHECKPOINT_END_LSN);
ut_ad(recv_sys->n_addrs == 0);
contiguous_lsn = checkpoint_lsn;
- switch (log_sys->log.format) {
+ switch (log_sys.log.format) {
case 0:
log_mutex_exit();
return recv_log_format_0_recover(checkpoint_lsn,
@@ -3780,9 +3716,7 @@ skip_apply:
}
/* Look for MLOG_CHECKPOINT. */
- log_group_t* group = &log_sys->log;
- recv_group_scan_log_recs(group, checkpoint_lsn, &contiguous_lsn,
- false);
+ recv_group_scan_log_recs(checkpoint_lsn, &contiguous_lsn, false);
/* The first scan should not have stored or applied any records. */
ut_ad(recv_sys->n_addrs == 0);
ut_ad(!recv_sys->found_corrupt_fs);
@@ -3799,7 +3733,7 @@ skip_apply:
}
if (recv_sys->mlog_checkpoint_lsn == 0) {
- lsn_t scan_lsn = group->scanned_lsn;
+ lsn_t scan_lsn = log_sys.log.scanned_lsn;
if (!srv_read_only_mode && scan_lsn != checkpoint_lsn) {
log_mutex_exit();
ib::error err;
@@ -3812,12 +3746,12 @@ skip_apply:
return(DB_ERROR);
}
- group->scanned_lsn = checkpoint_lsn;
+ log_sys.log.scanned_lsn = checkpoint_lsn;
rescan = false;
} else {
contiguous_lsn = checkpoint_lsn;
rescan = recv_group_scan_log_recs(
- group, checkpoint_lsn, &contiguous_lsn, false);
+ checkpoint_lsn, &contiguous_lsn, false);
if ((recv_sys->found_corrupt_log && !srv_force_recovery)
|| recv_sys->found_corrupt_fs) {
@@ -3863,7 +3797,7 @@ skip_apply:
}
}
- log_sys->lsn = recv_sys->recovered_lsn;
+ log_sys.lsn = recv_sys->recovered_lsn;
if (recv_needed_recovery) {
bool missing_tablespace = false;
@@ -3890,8 +3824,7 @@ skip_apply:
lsn_t recent_stored_lsn = recv_sys->last_stored_lsn;
rescan = recv_group_scan_log_recs(
- group, checkpoint_lsn,
- &recent_stored_lsn, false);
+ checkpoint_lsn, &recent_stored_lsn, false);
ut_ad(!recv_sys->found_corrupt_fs);
@@ -3924,8 +3857,8 @@ skip_apply:
if (rescan) {
contiguous_lsn = checkpoint_lsn;
- recv_group_scan_log_recs(group, checkpoint_lsn,
- &contiguous_lsn, true);
+ recv_group_scan_log_recs(
+ checkpoint_lsn, &contiguous_lsn, true);
if ((recv_sys->found_corrupt_log
&& !srv_force_recovery)
@@ -3938,12 +3871,11 @@ skip_apply:
ut_ad(!rescan || recv_sys->n_addrs == 0);
}
- /* We currently have only one log group */
-
- if (group->scanned_lsn < checkpoint_lsn
- || group->scanned_lsn < recv_max_page_lsn) {
+ if (log_sys.log.scanned_lsn < checkpoint_lsn
+ || log_sys.log.scanned_lsn < recv_max_page_lsn) {
- ib::error() << "We scanned the log up to " << group->scanned_lsn
+ ib::error() << "We scanned the log up to "
+ << log_sys.log.scanned_lsn
<< ". A checkpoint was at " << checkpoint_lsn << " and"
" the maximum LSN on a database page was "
<< recv_max_page_lsn << ". It is possible that the"
@@ -3959,11 +3891,8 @@ skip_apply:
return(DB_ERROR);
}
- /* Synchronize the uncorrupted log groups to the most up-to-date log
- group; we also copy checkpoint info to groups */
-
- log_sys->next_checkpoint_lsn = checkpoint_lsn;
- log_sys->next_checkpoint_no = checkpoint_no + 1;
+ log_sys.next_checkpoint_lsn = checkpoint_lsn;
+ log_sys.next_checkpoint_no = checkpoint_no + 1;
recv_synchronize_groups();
@@ -3973,24 +3902,24 @@ skip_apply:
srv_start_lsn = recv_sys->recovered_lsn;
}
- log_sys->buf_free = (ulint) log_sys->lsn % OS_FILE_LOG_BLOCK_SIZE;
- log_sys->buf_next_to_write = log_sys->buf_free;
- log_sys->write_lsn = log_sys->lsn;
+ log_sys.buf_free = ulong(log_sys.lsn % OS_FILE_LOG_BLOCK_SIZE);
+ log_sys.buf_next_to_write = log_sys.buf_free;
+ log_sys.write_lsn = log_sys.lsn;
- log_sys->last_checkpoint_lsn = checkpoint_lsn;
+ log_sys.last_checkpoint_lsn = checkpoint_lsn;
if (!srv_read_only_mode && srv_operation == SRV_OPERATION_NORMAL) {
/* Write a MLOG_CHECKPOINT marker as the first thing,
before generating any other redo log. This ensures
that subsequent crash recovery will be possible even
if the server were killed soon after this. */
- fil_names_clear(log_sys->last_checkpoint_lsn, true);
+ fil_names_clear(log_sys.last_checkpoint_lsn, true);
}
MONITOR_SET(MONITOR_LSN_CHECKPOINT_AGE,
- log_sys->lsn - log_sys->last_checkpoint_lsn);
+ log_sys.lsn - log_sys.last_checkpoint_lsn);
- log_sys->next_checkpoint_no = ++checkpoint_no;
+ log_sys.next_checkpoint_no = ++checkpoint_no;
mutex_enter(&recv_sys->mutex);
@@ -4067,7 +3996,6 @@ recv_recovery_rollback_active(void)
/* Drop partially created indexes. */
row_merge_drop_temp_indexes();
/* Drop garbage tables. */
- if (srv_safe_truncate)
row_mysql_drop_garbage_tables();
/* Drop any auxiliary tables that were not dropped when the
@@ -4079,8 +4007,8 @@ recv_recovery_rollback_active(void)
/* Rollback the uncommitted transactions which have no user
session */
- trx_rollback_or_clean_is_active = true;
- os_thread_create(trx_rollback_or_clean_all_recovered, 0, 0);
+ trx_rollback_is_active = true;
+ os_thread_create(trx_rollback_all_recovered, 0, 0);
}
}
@@ -4252,6 +4180,9 @@ static const char* get_mlog_string(mlog_id_t type)
case MLOG_ZIP_PAGE_REORGANIZE:
return("MLOG_ZIP_PAGE_REORGANIZE");
+ case MLOG_ZIP_WRITE_TRX_ID:
+ return("MLOG_ZIP_WRITE_TRX_ID");
+
case MLOG_FILE_RENAME2:
return("MLOG_FILE_RENAME2");