summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Petrunia <psergey@askmonty.org>2018-07-13 16:23:04 +0300
committerSergei Petrunia <psergey@askmonty.org>2018-07-13 16:23:04 +0300
commitb528b069a169d6e3d9ef4f9c7de68ead3e29186f (patch)
treecce4dbed25c3e2e98b05faee8686da82c10709e6
parentaf1568668f6a910b5739fe1d7181c59f94a95196 (diff)
downloadmariadb-git-bb-10.2-mdev16428.tar.gz
MDEV-16710, Issue#857: MyRocks: Incorrect behavior when miltiple statements fail inside a transactionbb-10.2-mdev16428
rollback_to_stmt_savepoint() calls do_rollback_to_savepoint(). This removes the changes made by this statement, and also removes the set savepoint. Before we start processing the next statement, we need to set the new savepoint, so we will have something to rollback to if the next statement fails. Since rollback_to_stmt_savepoint always sets a new savepoint now, m_n_savepoints is now redundant and is removed.
-rw-r--r--storage/rocksdb/ha_rocksdb.cc16
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/transaction.result17
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/transaction.test23
3 files changed, 48 insertions, 8 deletions
diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc
index bd2e0bfde4f..25bab1d97a9 100644
--- a/storage/rocksdb/ha_rocksdb.cc
+++ b/storage/rocksdb/ha_rocksdb.cc
@@ -1918,8 +1918,6 @@ protected:
bool m_is_two_phase = false;
private:
- /* Number of RockDB savepoints taken */
- int m_n_savepoints;
/*
Number of write operations this transaction had when we took the last
savepoint (the idea is not to take another savepoint if we haven't made
@@ -2493,7 +2491,6 @@ public:
entire transaction.
*/
do_set_savepoint();
- m_n_savepoints= 1;
m_writes_at_last_savepoint= m_write_count;
}
@@ -2510,7 +2507,6 @@ public:
{
do_set_savepoint();
m_writes_at_last_savepoint= m_write_count;
- m_n_savepoints++;
}
}
@@ -2521,10 +2517,14 @@ public:
void rollback_to_stmt_savepoint() {
if (m_writes_at_last_savepoint != m_write_count) {
do_rollback_to_savepoint();
- if (!--m_n_savepoints) {
- do_set_savepoint();
- m_n_savepoints= 1;
- }
+ /*
+ RollbackToSavePoint "removes the most recent SetSavePoint()", so
+ we need to set it again so that next statement can roll back to this
+ stage.
+ It's ok to do it here at statement end (instead of doing it at next
+ statement start) because setting a savepoint is cheap.
+ */
+ do_set_savepoint();
m_writes_at_last_savepoint= m_write_count;
}
}
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/transaction.result b/storage/rocksdb/mysql-test/rocksdb/r/transaction.result
index 006baaf1339..7664a11e50b 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/transaction.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/transaction.result
@@ -958,3 +958,20 @@ a
rollback;
drop function func;
drop table t1,t2,t3;
+#
+# MDEV-16710: Slave SQL: Could not execute Update_rows_v1 event with RocksDB and triggers
+# Issue#857: MyRocks: Incorrect behavior when miltiple statements fail inside a transaction
+#
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=RocksDB;
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 (b INT PRIMARY KEY) ENGINE=RocksDB;
+CREATE TRIGGER tr AFTER INSERT ON t2 FOR EACH ROW INSERT INTO non_existing_table VALUES (NULL);
+BEGIN;
+DELETE FROM t1;
+INSERT INTO t2 VALUES (1);
+INSERT INTO t2 VALUES (2);
+# Must return empty result:
+SELECT * FROM t1;
+a
+COMMIT;
+drop table t1,t2;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/transaction.test b/storage/rocksdb/mysql-test/rocksdb/t/transaction.test
index 3350db99dab..2503cbc8215 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/transaction.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/transaction.test
@@ -133,3 +133,26 @@ rollback;
drop function func;
drop table t1,t2,t3;
+--echo #
+--echo # MDEV-16710: Slave SQL: Could not execute Update_rows_v1 event with RocksDB and triggers
+--echo # Issue#857: MyRocks: Incorrect behavior when miltiple statements fail inside a transaction
+--echo #
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=RocksDB;
+INSERT INTO t1 VALUES (1);
+
+CREATE TABLE t2 (b INT PRIMARY KEY) ENGINE=RocksDB;
+
+CREATE TRIGGER tr AFTER INSERT ON t2 FOR EACH ROW INSERT INTO non_existing_table VALUES (NULL);
+
+BEGIN;
+DELETE FROM t1;
+--error 0,ER_NO_SUCH_TABLE
+INSERT INTO t2 VALUES (1);
+--error 0,ER_NO_SUCH_TABLE
+INSERT INTO t2 VALUES (2);
+--echo # Must return empty result:
+SELECT * FROM t1;
+COMMIT;
+
+drop table t1,t2;
+