Commit 033e29b6 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-26007 Rollback unnecessarily initiates redo log write

trx_t::commit_in_memory(): Do not initiate a redo log write if
the transaction has no visible effect. If anything for this
transaction had been made durable, crash recovery will roll back
the transaction just fine even if the end of ROLLBACK is not
durably written.

Rollbacks of transactions that are associated with XA identifiers
(possibly internally via the binlog) will always be persisted.
The test rpl.rpl_gtid_crash covers this.
parent b4c9cd20
...@@ -19,7 +19,8 @@ SET DEBUG_SYNC='now WAIT_FOR committed'; ...@@ -19,7 +19,8 @@ SET DEBUG_SYNC='now WAIT_FOR committed';
SET GLOBAL innodb_flush_log_at_trx_commit=1; SET GLOBAL innodb_flush_log_at_trx_commit=1;
BEGIN; BEGIN;
INSERT INTO t VALUES(-10000); INSERT INTO t VALUES(-10000);
ROLLBACK; DELETE FROM t WHERE a=-10000;
COMMIT;
# restart: --innodb-force-recovery=3 # restart: --innodb-force-recovery=3
disconnect con1; disconnect con1;
disconnect con2; disconnect con2;
......
...@@ -13,7 +13,8 @@ FLUSH TABLES; ...@@ -13,7 +13,8 @@ FLUSH TABLES;
SET GLOBAL innodb_flush_log_at_trx_commit=1; SET GLOBAL innodb_flush_log_at_trx_commit=1;
BEGIN; BEGIN;
INSERT INTO t VALUES(0); INSERT INTO t VALUES(0);
ROLLBACK; DELETE FROM t WHERE a=0;
COMMIT;
# restart: --innodb-force-recovery=3 # restart: --innodb-force-recovery=3
disconnect con1; disconnect con1;
SELECT * FROM t; SELECT * FROM t;
...@@ -40,4 +41,3 @@ SELECT * FROM t; ...@@ -40,4 +41,3 @@ SELECT * FROM t;
a a
3 3
DROP TABLE t; DROP TABLE t;
FOUND 1 /Rolled back recovered transaction [^0]/ in mysqld.1.err
...@@ -45,7 +45,8 @@ SET DEBUG_SYNC='now WAIT_FOR committed'; ...@@ -45,7 +45,8 @@ SET DEBUG_SYNC='now WAIT_FOR committed';
SET GLOBAL innodb_flush_log_at_trx_commit=1; SET GLOBAL innodb_flush_log_at_trx_commit=1;
BEGIN; BEGIN;
INSERT INTO t VALUES(-10000); INSERT INTO t VALUES(-10000);
ROLLBACK; DELETE FROM t WHERE a=-10000;
COMMIT;
--let $restart_parameters= --innodb-force-recovery=3 --let $restart_parameters= --innodb-force-recovery=3
--let $shutdown_timeout= 0 --let $shutdown_timeout= 0
--source include/restart_mysqld.inc --source include/restart_mysqld.inc
......
...@@ -19,7 +19,8 @@ FLUSH TABLES; ...@@ -19,7 +19,8 @@ FLUSH TABLES;
SET GLOBAL innodb_flush_log_at_trx_commit=1; SET GLOBAL innodb_flush_log_at_trx_commit=1;
BEGIN; BEGIN;
INSERT INTO t VALUES(0); INSERT INTO t VALUES(0);
ROLLBACK; DELETE FROM t WHERE a=0;
COMMIT;
--let $restart_parameters= --innodb-force-recovery=3 --let $restart_parameters= --innodb-force-recovery=3
--let $shutdown_timeout= 0 --let $shutdown_timeout= 0
--source include/restart_mysqld.inc --source include/restart_mysqld.inc
...@@ -41,6 +42,3 @@ SELECT * FROM t; ...@@ -41,6 +42,3 @@ SELECT * FROM t;
--source include/restart_mysqld.inc --source include/restart_mysqld.inc
SELECT * FROM t; SELECT * FROM t;
DROP TABLE t; DROP TABLE t;
let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
--let SEARCH_PATTERN= Rolled back recovered transaction [^0]
--source include/search_pattern_in_file.inc
...@@ -68,9 +68,11 @@ connection default; ...@@ -68,9 +68,11 @@ connection default;
# Make durable the AUTO_INCREMENT in the above incomplete transaction. # Make durable the AUTO_INCREMENT in the above incomplete transaction.
connect flush_redo_log,localhost,root,,; connect flush_redo_log,localhost,root,,;
SET GLOBAL innodb_flush_log_at_trx_commit=1; SET GLOBAL innodb_flush_log_at_trx_commit=1;
SET SQL_MODE = NO_AUTO_VALUE_ON_ZERO;
BEGIN; BEGIN;
DELETE FROM articles LIMIT 1; UPDATE articles SET id=0 WHERE id=1;
ROLLBACK; UPDATE articles SET id=1 WHERE id=0;
COMMIT;
disconnect flush_redo_log; disconnect flush_redo_log;
connection default; connection default;
# restart # restart
......
...@@ -143,9 +143,11 @@ connection default; ...@@ -143,9 +143,11 @@ connection default;
--echo # Make durable the AUTO_INCREMENT in the above incomplete transaction. --echo # Make durable the AUTO_INCREMENT in the above incomplete transaction.
--connect (flush_redo_log,localhost,root,,) --connect (flush_redo_log,localhost,root,,)
SET GLOBAL innodb_flush_log_at_trx_commit=1; SET GLOBAL innodb_flush_log_at_trx_commit=1;
SET SQL_MODE = NO_AUTO_VALUE_ON_ZERO;
BEGIN; BEGIN;
DELETE FROM articles LIMIT 1; UPDATE articles SET id=0 WHERE id=1;
ROLLBACK; UPDATE articles SET id=1 WHERE id=0;
COMMIT;
--disconnect flush_redo_log --disconnect flush_redo_log
--connection default --connection default
......
...@@ -1347,7 +1347,7 @@ inline void trx_t::commit_in_memory(const mtr_t *mtr) ...@@ -1347,7 +1347,7 @@ inline void trx_t::commit_in_memory(const mtr_t *mtr)
serialize all commits and prevent a group of transactions from serialize all commits and prevent a group of transactions from
gathering. */ gathering. */
commit_lsn= mtr->commit_lsn(); commit_lsn= undo_no || !xid->is_null() ? mtr->commit_lsn() : 0;
if (!commit_lsn) if (!commit_lsn)
/* Nothing to be done. */; /* Nothing to be done. */;
else if (flush_log_later) else if (flush_log_later)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment