1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

MDEV-11236 Failing assertion: state == TRX_STATE_NOT_STARTED

trx_state_eq(): Add the parameter bool relaxed=false, to
allow trx->state==TRX_STATE_NOT_STARTED where a different
state is expected, if an error has been reported.

trx_release_savepoint_for_mysql(): Pass relaxed=true to
trx_state_eq(). That is, allow the transaction to be idle
when ROLLBACK TO SAVEPOINT is attempted after an error
has been reported to the client.
This commit is contained in:
Marko Mäkelä
2016-12-02 16:25:47 +02:00
parent cb78555f30
commit 33ed16c750
8 changed files with 119 additions and 10 deletions

View File

@ -0,0 +1,28 @@
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
CREATE TABLE t2 (b INT) ENGINE=InnoDB;
CREATE TABLE t3 (c INT) ENGINE=InnoDB;
CREATE TRIGGER tr BEFORE INSERT ON t3 FOR EACH ROW BEGIN SAVEPOINT sv; INSERT INTO t2 VALUES (0); END $$
START TRANSACTION;
DELETE FROM t1;
connect con1,localhost,root,,test;
START TRANSACTION;
INSERT INTO t2 VALUES (2);
UPDATE t2 SET b = b+1;
INSERT INTO t1 VALUES (1);
connection default;
COMMIT;
connection con1;
COMMIT;
disconnect con1;
connection default;
SELECT * FROM t1;
a
1
SELECT * FROM t2;
b
3
SELECT * FROM t3;
c
DROP TABLE t1, t2, t3;
DROP TRIGGER tr;
ERROR HY000: Trigger does not exist

View File

@ -0,0 +1,47 @@
--source include/have_innodb.inc
--source include/count_sessions.inc
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
CREATE TABLE t2 (b INT) ENGINE=InnoDB;
CREATE TABLE t3 (c INT) ENGINE=InnoDB;
--delimiter $$
CREATE TRIGGER tr BEFORE INSERT ON t3 FOR EACH ROW BEGIN SAVEPOINT sv; INSERT INTO t2 VALUES (0); END $$
--delimiter ;
START TRANSACTION;
DELETE FROM t1;
connect (con1,localhost,root,,test);
START TRANSACTION;
INSERT INTO t2 VALUES (2);
UPDATE t2 SET b = b+1;
--send
INSERT INTO t1 VALUES (1);
connection default;
let $wait_condition=
select count(*) = 1 from information_schema.processlist
where state = 'update' and info = 'INSERT INTO t1 VALUES (1)'
--source include/wait_condition.inc
--error ER_LOCK_DEADLOCK
INSERT INTO t3 VALUES (2);
COMMIT;
connection con1;
reap;
COMMIT;
disconnect con1;
connection default;
SELECT * FROM t1;
SELECT * FROM t2;
SELECT * FROM t3;
DROP TABLE t1, t2, t3;
--error ER_TRG_DOES_NOT_EXIST
DROP TRIGGER tr;
--source include/wait_until_count_sessions.inc

View File

@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -432,8 +433,15 @@ bool
trx_state_eq(
/*=========*/
const trx_t* trx, /*!< in: transaction */
trx_state_t state) /*!< in: state */
MY_ATTRIBUTE((warn_unused_result));
trx_state_t state, /*!< in: state;
if state != TRX_STATE_NOT_STARTED
asserts that
trx->state != TRX_STATE_NOT_STARTED */
bool relaxed = false)
/*!< in: whether to allow
trx->state == TRX_STATE_NOT_STARTED
after an error has been reported */
MY_ATTRIBUTE((nonnull, warn_unused_result));
# ifdef UNIV_DEBUG
/**********************************************************************//**
Asserts that a transaction has been started.

View File

@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -36,7 +37,14 @@ bool
trx_state_eq(
/*=========*/
const trx_t* trx, /*!< in: transaction */
trx_state_t state) /*!< in: state */
trx_state_t state, /*!< in: state;
if state != TRX_STATE_NOT_STARTED
asserts that
trx->state != TRX_STATE_NOT_STARTED */
bool relaxed)
/*!< in: whether to allow
trx->state == TRX_STATE_NOT_STARTED
after an error has been reported */
{
#ifdef UNIV_DEBUG
switch (trx->state) {
@ -60,7 +68,9 @@ trx_state_eq(
/* These states are not allowed for running transactions. */
ut_a(state == TRX_STATE_NOT_STARTED
|| state == TRX_STATE_FORCED_ROLLBACK);
|| state == TRX_STATE_FORCED_ROLLBACK
|| (relaxed
&& thd_get_error_number(trx->mysql_thd)));
ut_ad(!trx->in_rw_trx_list);

View File

@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -581,7 +582,8 @@ trx_release_savepoint_for_mysql(
{
trx_named_savept_t* savep;
ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE) || trx_state_eq(trx, TRX_STATE_PREPARED));
ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE, true)
|| trx_state_eq(trx, TRX_STATE_PREPARED, true));
ut_ad(trx->in_mysql_trx_list);
savep = trx_savepoint_find(trx, savepoint_name);

View File

@ -1,7 +1,8 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2015, MariaDB Corporation
Copyright (c) 2015, 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -393,10 +394,14 @@ ibool
trx_state_eq(
/*=========*/
const trx_t* trx, /*!< in: transaction */
trx_state_t state) /*!< in: state;
trx_state_t state, /*!< in: state;
if state != TRX_STATE_NOT_STARTED
asserts that
trx->state != TRX_STATE_NOT_STARTED */
bool relaxed = false)
/*!< in: whether to allow
trx->state == TRX_STATE_NOT_STARTED
after an error has been reported */
MY_ATTRIBUTE((nonnull, warn_unused_result));
# ifdef UNIV_DEBUG
/**********************************************************************//**

View File

@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -36,10 +37,14 @@ ibool
trx_state_eq(
/*=========*/
const trx_t* trx, /*!< in: transaction */
trx_state_t state) /*!< in: state;
trx_state_t state, /*!< in: state;
if state != TRX_STATE_NOT_STARTED
asserts that
trx->state != TRX_STATE_NOT_STARTED */
bool relaxed)
/*!< in: whether to allow
trx->state == TRX_STATE_NOT_STARTED
after an error has been reported */
{
#ifdef UNIV_DEBUG
switch (trx->state) {
@ -57,7 +62,9 @@ trx_state_eq(
case TRX_STATE_NOT_STARTED:
/* This state is not allowed for running transactions. */
ut_a(state == TRX_STATE_NOT_STARTED);
ut_a(state == TRX_STATE_NOT_STARTED
|| (relaxed
&& thd_get_error_number(trx->mysql_thd)));
ut_ad(!trx->in_rw_trx_list);
ut_ad(!trx->in_ro_trx_list);
return(state == trx->state);

View File

@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2016, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -507,7 +508,8 @@ trx_release_savepoint_for_mysql(
{
trx_named_savept_t* savep;
ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE) || trx_state_eq(trx, TRX_STATE_PREPARED));
ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE, true)
|| trx_state_eq(trx, TRX_STATE_PREPARED, true));
ut_ad(trx->in_mysql_trx_list);
savep = trx_savepoint_find(trx, savepoint_name);