Skip to content

Commit

Permalink
MDEV-13267 At startup with crash recovery: mtr_t::commit_checkpoint(l…
Browse files Browse the repository at this point in the history
…sn_t, bool): Assertion `!recv_no_log_write' failed

This is a bogus debug assertion failure that should be possible
starting with MariaDB 10.2.2 (which merged WL#7142 via MySQL 5.7.9).

While generating page-change redo log records is strictly out of the
question during tat certain parts of crash recovery, the
fil_names_clear() is only emitting informational MLOG_FILE_NAME
and MLOG_CHECKPOINT records to guarantee that if the server is killed
during or soon after the crash recovery, subsequent crash recovery
will be possible.

The metadata buffer that fil_names_clear() is flushing to the redo log
is being filled by recv_init_crash_recovery_spaces(), right before
starting to apply redo log, by invoking fil_names_dirty() on every
discovered tablespace for which there are changes to apply.

When it comes to Mariabackup (xtrabackup --prepare), it is strictly out
of the question to generate any redo log whatsoever, because that could
break the restore of incremental backups by causing LSN deviation.
So, the fil_names_dirty() call must be skipped when restoring backups.

recv_recovery_from_checkpoint_start(): Do not invoke fil_names_clear()
when restoring a backup.

mtr_t::commit_checkpoint(): Remove the failing assertion. The only
caller is fil_names_clear(), and it must be called by
recv_recovery_from_checkpoint_start() for normal server startup to be
crash-safe. The debug assertion in mtr_t::commit() will still
catch rogue redo log writes.
  • Loading branch information
dr-m committed Jul 7, 2017
1 parent f20693c commit 42f657c
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 5 deletions.
9 changes: 7 additions & 2 deletions storage/innobase/log/log0recv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3126,6 +3126,9 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn)
byte* buf;
dberr_t err = DB_SUCCESS;

ut_ad(srv_operation == SRV_OPERATION_NORMAL
|| srv_operation == SRV_OPERATION_RESTORE);

/* Initialize red-black tree for fast insertions into the
flush_list during recovery process. */
buf_flush_init_flush_rbt();
Expand Down Expand Up @@ -3342,9 +3345,11 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn)

log_sys->last_checkpoint_lsn = checkpoint_lsn;

if (!srv_read_only_mode) {
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. */
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);
}

Expand Down
3 changes: 0 additions & 3 deletions storage/innobase/mtr/mtr0mtr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -599,9 +599,6 @@ mtr_t::commit_checkpoint(
ut_d(m_impl.m_state = MTR_STATE_COMMITTING);
ut_ad(write_mlog_checkpoint || m_impl.m_n_log_recs > 1);

/* This is a dirty read, for debugging. */
ut_ad(!recv_no_log_write);

switch (m_impl.m_n_log_recs) {
case 0:
break;
Expand Down

0 comments on commit 42f657c

Please sign in to comment.