trx_release_impl_and_expl_locks(trx, serialised);
...
lsn_t lsn = mtr->commit_lsn();
if (lsn == 0) {
/* Nothing to be done. */
} else if (trx->flush_log_later) {
/* Do nothing yet */
trx->must_flush_log_later = true;
/* Remember current ddl_operation, because trx_init()
later will set ddl_operation to false. And the final
flush is even later. */
trx->ddl_must_flush = trx->ddl_operation;
} else if ((srv_flush_log_at_trx_commit == 0 ||
thd_requested_durability(trx->mysql_thd) ==
HA_IGNORE_DURABILITY) &&
(!trx->ddl_operation)) {
/* Do nothing */
} else {
trx_flush_log_if_needed(lsn, trx);
}
trx->commit_lsn = lsn;
In innodb, trx will release lock before flush redo log into disk. If T1 release lock before log flushing, T2 can read the modification of T1. There is a crash before T1 flushing log. T2 may return incorrect result to client before crash. Because the redo log of T1 can’t found on disk and T1 can’t be recoverd.