Description:
If the database run as --skip-log-bin, the steps to commit in innodb are as follows:
1. The mtr of modifying undo log header commits.
2. Erase the trx_id from rw_trx_ids
3. Wait for the redo sync.
If there is a session run a query after step-2 and before step-3, then it can see the modification of the transaction that hasn't been really committed.
How to repeat:
1. Inject a part of the code and compile it in debug mode.
diff --git a/storage/innobase/log/log0write.cc b/storage/innobase/log/log0write.cc
index 74cbcbe1b03..bf451b71a26 100644
--- a/storage/innobase/log/log0write.cc
+++ b/storage/innobase/log/log0write.cc
@@ -1786,6 +1786,12 @@ static dberr_t log_write_buffer(log_t &log, byte *buffer, size_t buffer_size,
srv_stats.os_log_pending_writes.inc();
+ DBUG_EXECUTE_IF("stop_write_blocks_when_write_redo", {
+ std::this_thread::sleep_for(
+ std::chrono::seconds(2));
+ DBUG_SUICIDE();
+ });
+
/* Now, we know, that we are going to write completed
blocks only (originally or copied and completed). */
const dberr_t err = write_blocks(log, write_buf, write_size, real_offset);
2. Write a MTR test-cases, which might called as trx_text.test
connect (con1,localhost,root,,);
connection default;
create table t1 (id int primary key);
begin;
insert into t1 values (1);
SET GLOBAL DEBUG="+d, stop_write_blocks_when_write_redo";
--send commit
connection con1;
sleep 1;
let $cnt1 = `select count(1) from test.t1`;
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
connection default;
--error 2013
--reap
--enable_reconnect
--source include/wait_until_connected_again.inc
let $cnt2 = `select count(1) from test.t1`;
--let $assert_text= Assert value should not be same
--let $assert_cond = ($cnt1 = $cnt2)
--source include/assert.inc
3. Write a configure file for the testcase, which might be called mysql-test/t/trx_test-master.opt:
--skip-log-bin
4. Run the testcase, and the it will fail.