diff --git a/mysql-test/suite/innodb/r/undo_log.result b/mysql-test/suite/innodb/r/undo_log.result index a40c6b5b3bf..6fe0da3da47 100644 --- a/mysql-test/suite/innodb/r/undo_log.result +++ b/mysql-test/suite/innodb/r/undo_log.result @@ -140,3 +140,16 @@ CHECK TABLE test_tab; Table Op Msg_type Msg_text test.test_tab check status OK DROP TABLE test_tab; +SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; +SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; +CREATE TEMPORARY TABLE t2(i INT)ENGINE=InnoDB; +CREATE TABLE t1(i TEXT NOT NULL) ENGINE=INNODB; +BEGIN; +INSERT t1 SET i=REPEAT('1234567890',840); +UPDATE t1 SET i=''; +INSERT INTO t2 VALUES(2); +ROLLBACK; +InnoDB 0 transactions not purged +DROP TABLE t1; +DROP TABLE t2; +SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; diff --git a/mysql-test/suite/innodb/t/undo_log.test b/mysql-test/suite/innodb/t/undo_log.test index c1a98793d91..1f4cf9702d9 100644 --- a/mysql-test/suite/innodb/t/undo_log.test +++ b/mysql-test/suite/innodb/t/undo_log.test @@ -137,3 +137,17 @@ ROLLBACK; SELECT COUNT(*) FROM test_tab; CHECK TABLE test_tab; DROP TABLE test_tab; + +SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; +SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; +CREATE TEMPORARY TABLE t2(i INT)ENGINE=InnoDB; +CREATE TABLE t1(i TEXT NOT NULL) ENGINE=INNODB; +BEGIN; +INSERT t1 SET i=REPEAT('1234567890',840); +UPDATE t1 SET i=''; +INSERT INTO t2 VALUES(2); +ROLLBACK; +--source include/wait_all_purged.inc +DROP TABLE t1; +DROP TABLE t2; +SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc index d1f33c2efd6..82592fd3ae4 100644 --- a/storage/innobase/trx/trx0roll.cc +++ b/storage/innobase/trx/trx0roll.cc @@ -1003,7 +1003,7 @@ trx_roll_pop_top_rec_of_trx(trx_t* trx, roll_ptr_t* roll_ptr, mem_heap_t* heap) trx_roll_try_truncate(trx); } - trx_undo_t* undo; + trx_undo_t* undo = NULL; trx_undo_t* insert = trx->rsegs.m_redo.insert_undo; trx_undo_t* update = trx->rsegs.m_redo.update_undo; trx_undo_t* temp = trx->rsegs.m_noredo.undo; @@ -1017,17 +1017,26 @@ trx_roll_pop_top_rec_of_trx(trx_t* trx, roll_ptr_t* roll_ptr, mem_heap_t* heap) || update->top_undo_no != temp->top_undo_no); if (insert && !insert->empty && limit <= insert->top_undo_no) { - if (update && !update->empty - && update->top_undo_no > insert->top_undo_no) { + undo = insert; + } + + if (update && !update->empty && update->top_undo_no >= limit) { + if (!undo) { + undo = update; + } else if (undo->top_undo_no < update->top_undo_no) { undo = update; - } else { - undo = insert; } - } else if (update && !update->empty && limit <= update->top_undo_no) { - undo = update; - } else if (temp && !temp->empty && limit <= temp->top_undo_no) { - undo = temp; - } else { + } + + if (temp && !temp->empty && temp->top_undo_no >= limit) { + if (!undo) { + undo = temp; + } else if (undo->top_undo_no < temp->top_undo_no) { + undo = temp; + } + } + + if (undo == NULL) { trx_roll_try_truncate(trx); /* Mark any ROLLBACK TO SAVEPOINT completed, so that if the transaction object is committed and reused