[Commits] a06da5c848e: MDEV-12258 InnoDB: Fix the bogus debug assertion introduced in MDEV-12219

marko.makela at mariadb.com marko.makela at mariadb.com
Sat Mar 18 21:40:21 EET 2017


revision-id: a06da5c848e6feeef0b1559e84479890a76c446e (mariadb-10.2.4-74-ga06da5c848e)
parent(s): 6c5cfbbf3399887baff489f089641385c112c9a0
author: Marko Mäkelä
committer: Marko Mäkelä
timestamp: 2017-03-18 21:37:36 +0200
message:

MDEV-12258 InnoDB: Fix the bogus debug assertion introduced in MDEV-12219

After a partial rollback, an undo log segment that is empty
may carry a duplicate-looking top_undo_no.

Adjust the debug assertions and add a test.

---
 mysql-test/suite/innodb/r/trigger_error.result | 28 +++++++++++++++++++++++
 mysql-test/suite/innodb/t/trigger_error.test   | 31 ++++++++++++++++++++++++++
 storage/innobase/trx/trx0rec.cc                |  3 +--
 storage/innobase/trx/trx0roll.cc               |  6 ++---
 4 files changed, 63 insertions(+), 5 deletions(-)

diff --git a/mysql-test/suite/innodb/r/trigger_error.result b/mysql-test/suite/innodb/r/trigger_error.result
new file mode 100644
index 00000000000..ef5f910e1a2
--- /dev/null
+++ b/mysql-test/suite/innodb/r/trigger_error.result
@@ -0,0 +1,28 @@
+CREATE TABLE t1 (i INT) ENGINE=InnoDB;
+CREATE TABLE t2 (i INT) ENGINE=InnoDB;
+CREATE OR REPLACE TRIGGER tr1
+AFTER UPDATE ON t2
+FOR EACH ROW
+INSERT INTO tlog (i) VALUES (1);
+INSERT IGNORE INTO t2 VALUES (1);
+CREATE TRIGGER IF NOT EXISTS tr2
+BEFORE INSERT ON t2
+FOR EACH ROW
+INSERT INTO tlog (i) VALUES (2);
+START TRANSACTION;
+INSERT INTO t1 VALUES (1);
+UPDATE t2 SET i = 3;
+ERROR 42S02: Table 'test.tlog' doesn't exist
+INSERT INTO t1 VALUES (2);
+INSERT INTO t2 VALUES (4);
+ERROR 42S02: Table 'test.tlog' doesn't exist
+UPDATE t1 SET i = 4 LIMIT 1;
+COMMIT;
+SELECT * FROM t1;
+i
+4
+2
+SELECT * FROM t2;
+i
+1
+DROP TABLE t1,t2;
diff --git a/mysql-test/suite/innodb/t/trigger_error.test b/mysql-test/suite/innodb/t/trigger_error.test
new file mode 100644
index 00000000000..0334f2b353c
--- /dev/null
+++ b/mysql-test/suite/innodb/t/trigger_error.test
@@ -0,0 +1,31 @@
+--source include/have_innodb.inc
+
+CREATE TABLE t1 (i INT) ENGINE=InnoDB;
+CREATE TABLE t2 (i INT) ENGINE=InnoDB;
+
+CREATE OR REPLACE TRIGGER tr1
+  AFTER UPDATE ON t2
+  FOR EACH ROW
+  INSERT INTO tlog (i) VALUES (1);
+
+INSERT IGNORE INTO t2 VALUES (1);
+
+CREATE TRIGGER IF NOT EXISTS tr2
+  BEFORE INSERT ON t2
+  FOR EACH ROW
+  INSERT INTO tlog (i) VALUES (2);
+
+START TRANSACTION;
+INSERT INTO t1 VALUES (1);
+--error ER_NO_SUCH_TABLE
+UPDATE t2 SET i = 3;
+INSERT INTO t1 VALUES (2);
+--error ER_NO_SUCH_TABLE
+INSERT INTO t2 VALUES (4);
+UPDATE t1 SET i = 4 LIMIT 1;
+COMMIT;
+
+SELECT * FROM t1;
+SELECT * FROM t2;
+
+DROP TABLE t1,t2;
diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc
index 7c757a027d4..481e14d44de 100644
--- a/storage/innobase/trx/trx0rec.cc
+++ b/storage/innobase/trx/trx0rec.cc
@@ -2005,10 +2005,9 @@ trx_undo_report_row_operation(
 			undo->empty = FALSE;
 			undo->top_page_no = page_no;
 			undo->top_offset  = offset;
-			undo->top_undo_no = trx->undo_no;
+			undo->top_undo_no = trx->undo_no++;
 			undo->guess_block = undo_block;
 
-			trx->undo_no++;
 			trx->undo_rseg_space = rseg->space;
 
 			mutex_exit(&trx->undo_mutex);
diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc
index cc41d318188..1a997330a9e 100644
--- a/storage/innobase/trx/trx0roll.cc
+++ b/storage/innobase/trx/trx0roll.cc
@@ -990,11 +990,11 @@ trx_roll_pop_top_rec_of_trx(trx_t* trx, roll_ptr_t* roll_ptr, mem_heap_t* heap)
 	trx_undo_t*	temp	= trx->rsegs.m_noredo.undo;
 	const undo_no_t	limit	= trx->roll_limit;
 
-	ut_ad(!insert || !update || !insert->top_undo_no
+	ut_ad(!insert || !update || insert->empty || update->empty
 	      || insert->top_undo_no != update->top_undo_no);
-	ut_ad(!insert || !temp || !insert->top_undo_no
+	ut_ad(!insert || !temp || insert->empty || temp->empty
 	      || insert->top_undo_no != temp->top_undo_no);
-	ut_ad(!update || !temp || !update->top_undo_no
+	ut_ad(!update || !temp || update->empty || temp->empty
 	      || update->top_undo_no != temp->top_undo_no);
 
 	if (insert && !insert->empty && limit <= insert->top_undo_no) {


More information about the commits mailing list