From a06da5c848e6feeef0b1559e84479890a76c446e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Sat, 18 Mar 2017 21:37:36 +0200 Subject: [PATCH] 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. --- .../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(-) create mode 100644 mysql-test/suite/innodb/r/trigger_error.result create mode 100644 mysql-test/suite/innodb/t/trigger_error.test 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) {