Skip to content
Permalink
Browse files
MDEV-19346: Remove dummy InnoDB log checkpoints
log_checkpoint(), log_make_checkpoint_at(): Remove the parameter
write_always. It seems that the primary purpose of this parameter
was to ensure in the function recv_reset_logs() that both checkpoint
header pages will be overwritten, when the function is called from
the never-enabled function recv_recovery_from_archive_start().

create_log_files(): Merge recv_reset_logs() to its only caller.

Debug instrumentation: Prefer to flush the redo log, instead of
triggering a redo log checkpoint.

page_header_set_field(): Disable a debug assertion that will
always fail due to MDEV-19344, now that we no longer initiate
a redo log checkpoint before an injected crash.

In recv_reset_logs() there used to be two calls to
log_make_checkpoint_at(). The apparent purpose of this was
to ensure that both InnoDB redo log checkpoint header pages
will be initialized or overwritten.
The second call was removed (without any explanation) in MySQL 5.6.3:
mysql/mysql-server@4ca3796

In MySQL 5.6.8 WL#6494, starting with
mysql/mysql-server@00a0ba8
the function recv_reset_logs() was not only invoked during
InnoDB data file initialization, but also during a regular
startup when the redo log is being resized.

mysql/mysql-server@45e9167
in MySQL 5.7.2 removed the UNIV_LOG_ARCHIVE code, but still
did not remove the parameter write_always.
  • Loading branch information
dr-m committed May 3, 2019
1 parent bcc1359 commit 3db94d2
Show file tree
Hide file tree
Showing 15 changed files with 56 additions and 120 deletions.
@@ -328,7 +328,7 @@ buf_dblwr_create()
mtr_commit(&mtr);

/* Flush the modified pages to disk and make a checkpoint */
log_make_checkpoint_at(LSN_MAX, TRUE);
log_make_checkpoint_at(LSN_MAX);

/* Remove doublewrite pages from LRU */
buf_pool_invalidate();
@@ -19110,7 +19110,7 @@ checkpoint_now_set(
+ (log_sys->append_on_checkpoint != NULL
? log_sys->append_on_checkpoint->size() : 0)
< log_sys->lsn) {
log_make_checkpoint_at(LSN_MAX, TRUE);
log_make_checkpoint_at(LSN_MAX);
fil_flush_file_spaces(FIL_TYPE_LOG);
}

@@ -8474,7 +8474,6 @@ ha_innobase::commit_inplace_alter_table(
and the .frm files must be swapped manually by
the administrator. No loss of data. */
DBUG_EXECUTE_IF("innodb_alter_commit_crash_after_commit",
log_make_checkpoint_at(LSN_MAX, TRUE);
log_buffer_flush_to_disk();
DBUG_SUICIDE(););
}
@@ -2,7 +2,7 @@
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2009, Google Inc.
Copyright (c) 2017, 2018, MariaDB Corporation.
Copyright (c) 2017, 2019, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -208,23 +208,13 @@ blocks from the buffer pool: it only checks what is lsn of the oldest
modification in the pool, and writes information about the lsn in
log files. Use log_make_checkpoint_at() to flush also the pool.
@param[in] sync whether to wait for the write to complete
@param[in] write_always force a write even if no log
has been generated since the latest checkpoint
@return true if success, false if a checkpoint write was already running */
bool
log_checkpoint(
bool sync,
bool write_always);
bool log_checkpoint(bool sync);

/** Make a checkpoint at or after a specified LSN.
@param[in] lsn the log sequence number, or LSN_MAX
for the latest LSN
@param[in] write_always force a write even if no log
has been generated since the latest checkpoint */
void
log_make_checkpoint_at(
lsn_t lsn,
bool write_always);
for the latest LSN */
void log_make_checkpoint_at(lsn_t lsn);

/****************************************************************//**
Makes a checkpoint at the latest lsn and writes it to first page of each
@@ -69,16 +69,6 @@ Initiates the rollback of active transactions. */
void
recv_recovery_rollback_active(void);
/*===============================*/
/******************************************************//**
Resets the logs. The contents of log files will be lost! */
void
recv_reset_logs(
/*============*/
lsn_t lsn); /*!< in: reset to this lsn
rounded up to be divisible by
OS_FILE_LOG_BLOCK_SIZE, after
which we add
LOG_BLOCK_HDR_SIZE */
/** Clean up after recv_sys_init() */
void
recv_sys_close();
@@ -173,7 +173,9 @@ page_header_set_field(
{
ut_ad(page);
ut_ad(field <= PAGE_N_RECS);
#if 0 /* FIXME: MDEV-19344 hits this */
ut_ad(field != PAGE_N_RECS || val);
#endif
ut_ad(field == PAGE_N_HEAP || val < srv_page_size);
ut_ad(field != PAGE_N_HEAP || (val & 0x7fff) < srv_page_size);

@@ -337,7 +337,7 @@ log_margin_checkpoint_age(
if (!flushed_enough) {
os_thread_sleep(100000);
}
log_checkpoint(true, false);
log_checkpoint(true);

log_mutex_enter();
}
@@ -1610,13 +1610,8 @@ blocks from the buffer pool: it only checks what is lsn of the oldest
modification in the pool, and writes information about the lsn in
log files. Use log_make_checkpoint_at() to flush also the pool.
@param[in] sync whether to wait for the write to complete
@param[in] write_always force a write even if no log
has been generated since the latest checkpoint
@return true if success, false if a checkpoint write was already running */
bool
log_checkpoint(
bool sync,
bool write_always)
bool log_checkpoint(bool sync)
{
lsn_t oldest_lsn;

@@ -1657,9 +1652,15 @@ log_checkpoint(
flushed up to oldest_lsn. */

ut_ad(oldest_lsn >= log_sys->last_checkpoint_lsn);
if (!write_always
&& oldest_lsn
<= log_sys->last_checkpoint_lsn + SIZE_OF_MLOG_CHECKPOINT) {
if (oldest_lsn
> log_sys->last_checkpoint_lsn + SIZE_OF_MLOG_CHECKPOINT) {
/* Some log has been written since the previous checkpoint. */
} else if (srv_shutdown_state != SRV_SHUTDOWN_NONE) {
/* MariaDB 10.3 startup expects the redo log file to be
logically empty (not even containing a MLOG_CHECKPOINT record)
after a clean shutdown. Perform an extra checkpoint at
shutdown. */
} else {
/* Do nothing, because nothing was logged (other than
a MLOG_CHECKPOINT marker) since the previous checkpoint. */
log_mutex_exit();
@@ -1691,20 +1692,6 @@ log_checkpoint(

log_write_up_to(flush_lsn, true);

DBUG_EXECUTE_IF(
"using_wa_checkpoint_middle",
if (write_always) {
DEBUG_SYNC_C("wa_checkpoint_middle");

const my_bool b = TRUE;
buf_flush_page_cleaner_disabled_debug_update(
NULL, NULL, NULL, &b);
dict_stats_disabled_debug_update(
NULL, NULL, NULL, &b);
srv_master_thread_disabled_debug_update(
NULL, NULL, NULL, &b);
});

log_mutex_enter();

ut_ad(log_sys->flushed_to_disk_lsn >= flush_lsn);
@@ -1737,21 +1724,16 @@ log_checkpoint(

/** Make a checkpoint at or after a specified LSN.
@param[in] lsn the log sequence number, or LSN_MAX
for the latest LSN
@param[in] write_always force a write even if no log
has been generated since the latest checkpoint */
void
log_make_checkpoint_at(
lsn_t lsn,
bool write_always)
for the latest LSN */
void log_make_checkpoint_at(lsn_t lsn)
{
/* Preflush pages synchronously */

while (!log_preflush_pool_modified_pages(lsn)) {
/* Flush as much as we can */
}

while (!log_checkpoint(true, write_always)) {
while (!log_checkpoint(true)) {
/* Force a checkpoint */
}
}
@@ -1834,7 +1816,7 @@ log_checkpoint_margin(void)
}

if (do_checkpoint) {
log_checkpoint(checkpoint_sync, FALSE);
log_checkpoint(checkpoint_sync);

if (checkpoint_sync) {

@@ -2083,7 +2065,7 @@ logs_empty_and_mark_files_at_shutdown(void)
if (!srv_read_only_mode) {
service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL,
"ensuring dirty buffer pool are written to log");
log_make_checkpoint_at(LSN_MAX, TRUE);
log_make_checkpoint_at(LSN_MAX);

log_mutex_enter();

@@ -2849,11 +2849,6 @@ bool recv_parse_log_recs(lsn_t checkpoint_lsn, store_t store, bool apply)

if (lsn == checkpoint_lsn) {
if (recv_sys->mlog_checkpoint_lsn) {
/* At recv_reset_logs() we may
write a duplicate MLOG_CHECKPOINT
for the same checkpoint LSN. Thus
recv_sys->mlog_checkpoint_lsn
can differ from the current LSN. */
ut_ad(recv_sys->mlog_checkpoint_lsn
<= recv_sys->recovered_lsn);
break;
@@ -4016,49 +4011,6 @@ recv_recovery_rollback_active(void)
}
}

/******************************************************//**
Resets the logs. The contents of log files will be lost! */
void
recv_reset_logs(
/*============*/
lsn_t lsn) /*!< in: reset to this lsn
rounded up to be divisible by
OS_FILE_LOG_BLOCK_SIZE, after
which we add
LOG_BLOCK_HDR_SIZE */
{
ut_ad(log_mutex_own());

log_sys->lsn = ut_uint64_align_up(lsn, OS_FILE_LOG_BLOCK_SIZE);

log_sys->log.lsn = log_sys->lsn;
log_sys->log.lsn_offset = LOG_FILE_HDR_SIZE;

log_sys->buf_next_to_write = 0;
log_sys->write_lsn = log_sys->lsn;

log_sys->next_checkpoint_no = 0;
log_sys->last_checkpoint_lsn = 0;

memset(log_sys->buf, 0, log_sys->buf_size);
log_block_init(log_sys->buf, log_sys->lsn);
log_block_set_first_rec_group(log_sys->buf, LOG_BLOCK_HDR_SIZE);

log_sys->buf_free = LOG_BLOCK_HDR_SIZE;
log_sys->lsn += LOG_BLOCK_HDR_SIZE;

MONITOR_SET(MONITOR_LSN_CHECKPOINT_AGE,
(log_sys->lsn - log_sys->last_checkpoint_lsn));

log_mutex_exit();

/* Reset the checkpoint fields in logs */

log_make_checkpoint_at(LSN_MAX, TRUE);

log_mutex_enter();
}

/** Find a doublewrite copy of a page.
@param[in] space_id tablespace identifier
@param[in] page_no page number
@@ -2090,7 +2090,7 @@ row_import_cleanup(

DBUG_EXECUTE_IF("ib_import_before_checkpoint_crash", DBUG_SUICIDE(););

log_make_checkpoint_at(LSN_MAX, TRUE);
log_make_checkpoint_at(LSN_MAX);

return(err);
}
@@ -2722,8 +2722,7 @@ row_ins_clust_index_entry_low(

DBUG_EXECUTE_IF(
"row_ins_extern_checkpoint",
log_make_checkpoint_at(
LSN_MAX, TRUE););
log_write_up_to(mtr.commit_lsn(), true););
err = row_ins_index_entry_big_rec(
entry, big_rec, offsets, &offsets_heap, index,
thr_get_trx(thr)->mysql_thd);
@@ -2882,13 +2882,13 @@ row_discard_tablespace_end(
}

DBUG_EXECUTE_IF("ib_discard_before_commit_crash",
log_make_checkpoint_at(LSN_MAX, TRUE);
log_write_up_to(LSN_MAX, true);
DBUG_SUICIDE(););

trx_commit_for_mysql(trx);

DBUG_EXECUTE_IF("ib_discard_after_commit_crash",
log_make_checkpoint_at(LSN_MAX, TRUE);
log_write_up_to(LSN_MAX, true);
DBUG_SUICIDE(););

row_mysql_unlock_data_dictionary(trx);
@@ -1996,7 +1996,7 @@ dberr_t row_truncate_table_for_mysql(dict_table_t* table, trx_t* trx)
DBUG_EXECUTE_IF("ib_trunc_crash_with_intermediate_log_checkpoint",
log_buffer_flush_to_disk();
os_thread_sleep(2000000);
log_checkpoint(TRUE, TRUE);
log_checkpoint(TRUE);
os_thread_sleep(1000000);
DBUG_SUICIDE(););

@@ -2224,7 +2224,7 @@ truncate_t::fixup_tables_in_non_system_tablespace()

if (err == DB_SUCCESS && s_tables.size() > 0) {

log_make_checkpoint_at(LSN_MAX, TRUE);
log_make_checkpoint_at(LSN_MAX);
}

for (ulint i = 0; i < s_tables.size(); ++i) {
@@ -2261,7 +2261,7 @@ srv_master_do_active_tasks(void)
/* Make a new checkpoint */
if (cur_time % SRV_MASTER_CHECKPOINT_INTERVAL == 0) {
srv_main_thread_op_info = "making checkpoint";
log_checkpoint(TRUE, FALSE);
log_checkpoint(true);
MONITOR_INC_TIME_IN_MICRO_SECS(
MONITOR_SRV_CHECKPOINT_MICROSECOND, counter_time);
}
@@ -2349,7 +2349,7 @@ srv_master_do_idle_tasks(void)

/* Make a new checkpoint */
srv_main_thread_op_info = "making checkpoint";
log_checkpoint(TRUE, FALSE);
log_checkpoint(true);
MONITOR_INC_TIME_IN_MICRO_SECS(MONITOR_SRV_CHECKPOINT_MICROSECOND,
counter_time);
}
@@ -495,9 +495,30 @@ create_log_files(
return(DB_ERROR);
}
ut_d(recv_no_log_write = false);
recv_reset_logs(lsn);
log_sys->lsn = ut_uint64_align_up(lsn, OS_FILE_LOG_BLOCK_SIZE);

log_sys->log.lsn = log_sys->lsn;
log_sys->log.lsn_offset = LOG_FILE_HDR_SIZE;

log_sys->buf_next_to_write = 0;
log_sys->write_lsn = log_sys->lsn;

log_sys->next_checkpoint_no = 0;
log_sys->last_checkpoint_lsn = 0;

memset(log_sys->buf, 0, log_sys->buf_size);
log_block_init(log_sys->buf, log_sys->lsn);
log_block_set_first_rec_group(log_sys->buf, LOG_BLOCK_HDR_SIZE);

log_sys->buf_free = LOG_BLOCK_HDR_SIZE;
log_sys->lsn += LOG_BLOCK_HDR_SIZE;

MONITOR_SET(MONITOR_LSN_CHECKPOINT_AGE,
(log_sys->lsn - log_sys->last_checkpoint_lsn));
log_mutex_exit();

log_make_checkpoint_at(LSN_MAX);

return(DB_SUCCESS);
}

@@ -1859,7 +1859,8 @@ trx_commit_low(

DBUG_EXECUTE_IF("ib_crash_during_trx_commit_in_mem",
if (trx->has_logged()) {
log_make_checkpoint_at(LSN_MAX, TRUE);
log_write_up_to(mtr->commit_lsn(),
true);
DBUG_SUICIDE();
});
/*--------------*/

0 comments on commit 3db94d2

Please sign in to comment.