Skip to content

Commit 341eddd

Browse files
MDEV-15826 Purge attempts to free BLOB page after BEGIN;INSERT;UPDATE;ROLLBACK
- During rollback, redo segments priorities over no-redo rollback segments and it leads to failure of redo rollback segment undo logs truncation.
1 parent 1d98333 commit 341eddd

File tree

3 files changed

+46
-10
lines changed

3 files changed

+46
-10
lines changed

mysql-test/suite/innodb/r/undo_log.result

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,3 +140,16 @@ CHECK TABLE test_tab;
140140
Table Op Msg_type Msg_text
141141
test.test_tab check status OK
142142
DROP TABLE test_tab;
143+
SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
144+
SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
145+
CREATE TEMPORARY TABLE t2(i INT)ENGINE=InnoDB;
146+
CREATE TABLE t1(i TEXT NOT NULL) ENGINE=INNODB;
147+
BEGIN;
148+
INSERT t1 SET i=REPEAT('1234567890',840);
149+
UPDATE t1 SET i='';
150+
INSERT INTO t2 VALUES(2);
151+
ROLLBACK;
152+
InnoDB 0 transactions not purged
153+
DROP TABLE t1;
154+
DROP TABLE t2;
155+
SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;

mysql-test/suite/innodb/t/undo_log.test

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,17 @@ ROLLBACK;
137137
SELECT COUNT(*) FROM test_tab;
138138
CHECK TABLE test_tab;
139139
DROP TABLE test_tab;
140+
141+
SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
142+
SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
143+
CREATE TEMPORARY TABLE t2(i INT)ENGINE=InnoDB;
144+
CREATE TABLE t1(i TEXT NOT NULL) ENGINE=INNODB;
145+
BEGIN;
146+
INSERT t1 SET i=REPEAT('1234567890',840);
147+
UPDATE t1 SET i='';
148+
INSERT INTO t2 VALUES(2);
149+
ROLLBACK;
150+
--source include/wait_all_purged.inc
151+
DROP TABLE t1;
152+
DROP TABLE t2;
153+
SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;

storage/innobase/trx/trx0roll.cc

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,7 +1003,7 @@ trx_roll_pop_top_rec_of_trx(trx_t* trx, roll_ptr_t* roll_ptr, mem_heap_t* heap)
10031003
trx_roll_try_truncate(trx);
10041004
}
10051005

1006-
trx_undo_t* undo;
1006+
trx_undo_t* undo = NULL;
10071007
trx_undo_t* insert = trx->rsegs.m_redo.insert_undo;
10081008
trx_undo_t* update = trx->rsegs.m_redo.update_undo;
10091009
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)
10171017
|| update->top_undo_no != temp->top_undo_no);
10181018

10191019
if (insert && !insert->empty && limit <= insert->top_undo_no) {
1020-
if (update && !update->empty
1021-
&& update->top_undo_no > insert->top_undo_no) {
1020+
undo = insert;
1021+
}
1022+
1023+
if (update && !update->empty && update->top_undo_no >= limit) {
1024+
if (!undo) {
1025+
undo = update;
1026+
} else if (undo->top_undo_no < update->top_undo_no) {
10221027
undo = update;
1023-
} else {
1024-
undo = insert;
10251028
}
1026-
} else if (update && !update->empty && limit <= update->top_undo_no) {
1027-
undo = update;
1028-
} else if (temp && !temp->empty && limit <= temp->top_undo_no) {
1029-
undo = temp;
1030-
} else {
1029+
}
1030+
1031+
if (temp && !temp->empty && temp->top_undo_no >= limit) {
1032+
if (!undo) {
1033+
undo = temp;
1034+
} else if (undo->top_undo_no < temp->top_undo_no) {
1035+
undo = temp;
1036+
}
1037+
}
1038+
1039+
if (undo == NULL) {
10311040
trx_roll_try_truncate(trx);
10321041
/* Mark any ROLLBACK TO SAVEPOINT completed, so that
10331042
if the transaction object is committed and reused

0 commit comments

Comments
 (0)