Description:
In 5.7 and 8.0, no redo log is written during DDL progress, and it need to flush the dirty pages and write a MLOG_INDEX_LOAD redo log before finish the DDL. (WL#7277, https://dev.mysql.com/worklog/task/?id=7277)
WL#14283 introduces the Parallel DDL, and the above steps are put into Builder::finish.
```
dberr_t Builder::finish() noexcept {
if (get_error() != DB_SUCCESS) {
set_next_state();
return get_error();
}
ut_a(m_n_sort_tasks == 0);
ut_a(get_state() == State::FINISH);
for (auto thread_ctx : m_thread_ctxs) {
thread_ctx->m_file.m_file.close();
}
dberr_t err{DB_SUCCESS};
if (get_error() != DB_SUCCESS || !m_ctx.m_online) {
/* Do not apply any online log. */
} else if (m_ctx.m_old_table != m_ctx.m_new_table) {
ut_a(!m_index->online_log);
ut_a(m_index->online_status == ONLINE_INDEX_COMPLETE);
auto observer = m_ctx.m_trx->flush_observer;
observer->flush();
} else {
err = finalize();
if (err != DB_SUCCESS) {
set_error(err);
}
}
set_next_state();
return get_error();
}
```
But I found that if the DDL do not need to rebuild table, it will call finalize and it will call write_redo inside. But if the DDL need to rebuild table(like OPTIMIZE TABLE), it will call `observer->flush` only, which forgets to record MLOG_INDEX_LOAD.
This will not affect the correctness of the data, but it may lead to failures in the backup(Xtrabackup).
How to repeat:
No need.
Suggested fix:
@@ -2066,6 +2067,7 @@ dberr_t Builder::finish() noexcept {
auto observer = m_ctx.m_trx->flush_observer;
observer->flush();
+ write_redo(m_index);
} else {
err = finalize();