Commit bfb0726f authored by Marko Mäkelä's avatar Marko Mäkelä

Merge 5.5 into 10.1

parents 9dcfd6be d5da8ae0
# Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2008, 2018, MariaDB Corporation # Copyright (c) 2008, 2019, MariaDB Corporation
# #
# This program is free software; you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
......
...@@ -101,7 +101,15 @@ ALTER IGNORE TABLE t1 ADD FOREIGN KEY (a) REFERENCES t2 (b); ...@@ -101,7 +101,15 @@ ALTER IGNORE TABLE t1 ADD FOREIGN KEY (a) REFERENCES t2 (b);
ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
SHOW WARNINGS; SHOW WARNINGS;
Level Code Message Level Code Message
Warning 150 Alter table test/#sql-temporary with foreign key constraint failed. Referenced table `test`.`t2` not found in the data dictionary near 'FOREIGN KEY (a) REFERENCES t2 (b)'. Warning 150 Alter table `test`.`t1` with foreign key constraint failed. Referenced table `test`.`t2` not found in the data dictionary near 'FOREIGN KEY (a) REFERENCES t2 (b)'.
Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
Warning 1215 Cannot add foreign key constraint Warning 1215 Cannot add foreign key constraint
DROP TABLE t1; DROP TABLE t1;
#
# MDEV-18139 ALTER IGNORE ... ADD FOREIGN KEY causes bogus error
#
CREATE TABLE t1 (f1 INT, f2 INT, f3 INT, KEY(f1)) ENGINE=InnoDB;
CREATE TABLE t2 (f INT, KEY(f)) ENGINE=InnoDB;
ALTER TABLE t1 ADD FOREIGN KEY (f2) REFERENCES t2 (f);
ALTER IGNORE TABLE t1 ADD FOREIGN KEY (f3) REFERENCES t1 (f1);
DROP TABLE t1, t2;
call mtr.add_suppression("Found 50 prepared XA transactions");
create table t1 (a int) engine=innodb;
insert into t1 values(1);
xa start 'test50';
insert into t1 values(1);
xa end 'test50';
xa prepare 'test50';
xa start 'test49';
insert into t1 values(1);
xa end 'test49';
xa prepare 'test49';
xa start 'test48';
insert into t1 values(1);
xa end 'test48';
xa prepare 'test48';
xa start 'test47';
insert into t1 values(1);
xa end 'test47';
xa prepare 'test47';
xa start 'test46';
insert into t1 values(1);
xa end 'test46';
xa prepare 'test46';
xa start 'test45';
insert into t1 values(1);
xa end 'test45';
xa prepare 'test45';
xa start 'test44';
insert into t1 values(1);
xa end 'test44';
xa prepare 'test44';
xa start 'test43';
insert into t1 values(1);
xa end 'test43';
xa prepare 'test43';
xa start 'test42';
insert into t1 values(1);
xa end 'test42';
xa prepare 'test42';
xa start 'test41';
insert into t1 values(1);
xa end 'test41';
xa prepare 'test41';
xa start 'test40';
insert into t1 values(1);
xa end 'test40';
xa prepare 'test40';
xa start 'test39';
insert into t1 values(1);
xa end 'test39';
xa prepare 'test39';
xa start 'test38';
insert into t1 values(1);
xa end 'test38';
xa prepare 'test38';
xa start 'test37';
insert into t1 values(1);
xa end 'test37';
xa prepare 'test37';
xa start 'test36';
insert into t1 values(1);
xa end 'test36';
xa prepare 'test36';
xa start 'test35';
insert into t1 values(1);
xa end 'test35';
xa prepare 'test35';
xa start 'test34';
insert into t1 values(1);
xa end 'test34';
xa prepare 'test34';
xa start 'test33';
insert into t1 values(1);
xa end 'test33';
xa prepare 'test33';
xa start 'test32';
insert into t1 values(1);
xa end 'test32';
xa prepare 'test32';
xa start 'test31';
insert into t1 values(1);
xa end 'test31';
xa prepare 'test31';
xa start 'test30';
insert into t1 values(1);
xa end 'test30';
xa prepare 'test30';
xa start 'test29';
insert into t1 values(1);
xa end 'test29';
xa prepare 'test29';
xa start 'test28';
insert into t1 values(1);
xa end 'test28';
xa prepare 'test28';
xa start 'test27';
insert into t1 values(1);
xa end 'test27';
xa prepare 'test27';
xa start 'test26';
insert into t1 values(1);
xa end 'test26';
xa prepare 'test26';
xa start 'test25';
insert into t1 values(1);
xa end 'test25';
xa prepare 'test25';
xa start 'test24';
insert into t1 values(1);
xa end 'test24';
xa prepare 'test24';
xa start 'test23';
insert into t1 values(1);
xa end 'test23';
xa prepare 'test23';
xa start 'test22';
insert into t1 values(1);
xa end 'test22';
xa prepare 'test22';
xa start 'test21';
insert into t1 values(1);
xa end 'test21';
xa prepare 'test21';
xa start 'test20';
insert into t1 values(1);
xa end 'test20';
xa prepare 'test20';
xa start 'test19';
insert into t1 values(1);
xa end 'test19';
xa prepare 'test19';
xa start 'test18';
insert into t1 values(1);
xa end 'test18';
xa prepare 'test18';
xa start 'test17';
insert into t1 values(1);
xa end 'test17';
xa prepare 'test17';
xa start 'test16';
insert into t1 values(1);
xa end 'test16';
xa prepare 'test16';
xa start 'test15';
insert into t1 values(1);
xa end 'test15';
xa prepare 'test15';
xa start 'test14';
insert into t1 values(1);
xa end 'test14';
xa prepare 'test14';
xa start 'test13';
insert into t1 values(1);
xa end 'test13';
xa prepare 'test13';
xa start 'test12';
insert into t1 values(1);
xa end 'test12';
xa prepare 'test12';
xa start 'test11';
insert into t1 values(1);
xa end 'test11';
xa prepare 'test11';
xa start 'test10';
insert into t1 values(1);
xa end 'test10';
xa prepare 'test10';
xa start 'test9';
insert into t1 values(1);
xa end 'test9';
xa prepare 'test9';
xa start 'test8';
insert into t1 values(1);
xa end 'test8';
xa prepare 'test8';
xa start 'test7';
insert into t1 values(1);
xa end 'test7';
xa prepare 'test7';
xa start 'test6';
insert into t1 values(1);
xa end 'test6';
xa prepare 'test6';
xa start 'test5';
insert into t1 values(1);
xa end 'test5';
xa prepare 'test5';
xa start 'test4';
insert into t1 values(1);
xa end 'test4';
xa prepare 'test4';
xa start 'test3';
insert into t1 values(1);
xa end 'test3';
xa prepare 'test3';
xa start 'test2';
insert into t1 values(1);
xa end 'test2';
xa prepare 'test2';
xa start 'test1';
insert into t1 values(1);
xa end 'test1';
xa prepare 'test1';
xa recover;
formatID gtrid_length bqual_length data
1 5 0 test1
1 5 0 test2
1 5 0 test3
1 5 0 test4
1 5 0 test5
1 5 0 test6
1 5 0 test7
1 5 0 test8
1 5 0 test9
1 6 0 test10
1 6 0 test11
1 6 0 test12
1 6 0 test13
1 6 0 test14
1 6 0 test15
1 6 0 test16
1 6 0 test17
1 6 0 test18
1 6 0 test19
1 6 0 test20
1 6 0 test21
1 6 0 test22
1 6 0 test23
1 6 0 test24
1 6 0 test25
1 6 0 test26
1 6 0 test27
1 6 0 test28
1 6 0 test29
1 6 0 test30
1 6 0 test31
1 6 0 test32
1 6 0 test33
1 6 0 test34
1 6 0 test35
1 6 0 test36
1 6 0 test37
1 6 0 test38
1 6 0 test39
1 6 0 test40
1 6 0 test41
1 6 0 test42
1 6 0 test43
1 6 0 test44
1 6 0 test45
1 6 0 test46
1 6 0 test47
1 6 0 test48
1 6 0 test49
1 6 0 test50
xa recover;
formatID gtrid_length bqual_length data
1 5 0 test1
1 5 0 test2
1 5 0 test3
1 5 0 test4
1 5 0 test5
1 5 0 test6
1 5 0 test7
1 5 0 test8
1 5 0 test9
1 6 0 test10
1 6 0 test11
1 6 0 test12
1 6 0 test13
1 6 0 test14
1 6 0 test15
1 6 0 test16
1 6 0 test17
1 6 0 test18
1 6 0 test19
1 6 0 test20
1 6 0 test21
1 6 0 test22
1 6 0 test23
1 6 0 test24
1 6 0 test25
1 6 0 test26
1 6 0 test27
1 6 0 test28
1 6 0 test29
1 6 0 test30
1 6 0 test31
1 6 0 test32
1 6 0 test33
1 6 0 test34
1 6 0 test35
1 6 0 test36
1 6 0 test37
1 6 0 test38
1 6 0 test39
1 6 0 test40
1 6 0 test41
1 6 0 test42
1 6 0 test43
1 6 0 test44
1 6 0 test45
1 6 0 test46
1 6 0 test47
1 6 0 test48
1 6 0 test49
1 6 0 test50
xa recover;
formatID gtrid_length bqual_length data
drop table t1;
...@@ -125,3 +125,12 @@ ALTER IGNORE TABLE t1 ADD FOREIGN KEY (a) REFERENCES t2 (b); ...@@ -125,3 +125,12 @@ ALTER IGNORE TABLE t1 ADD FOREIGN KEY (a) REFERENCES t2 (b);
--replace_regex /#sql-[0-9_a-f-]*/#sql-temporary/ --replace_regex /#sql-[0-9_a-f-]*/#sql-temporary/
SHOW WARNINGS; SHOW WARNINGS;
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # MDEV-18139 ALTER IGNORE ... ADD FOREIGN KEY causes bogus error
--echo #
CREATE TABLE t1 (f1 INT, f2 INT, f3 INT, KEY(f1)) ENGINE=InnoDB;
CREATE TABLE t2 (f INT, KEY(f)) ENGINE=InnoDB;
ALTER TABLE t1 ADD FOREIGN KEY (f2) REFERENCES t2 (f);
ALTER IGNORE TABLE t1 ADD FOREIGN KEY (f3) REFERENCES t1 (f1);
DROP TABLE t1, t2;
-- source include/have_innodb.inc
-- source include/have_debug.inc
-- source include/not_embedded.inc
call mtr.add_suppression("Found 50 prepared XA transactions");
create table t1 (a int) engine=innodb;
insert into t1 values(1);
let $trial = 50;
while ($trial)
{
--connect (con$trial, localhost, root,,)
let $st_pre = `select concat('test', $trial)`;
eval xa start '$st_pre';
insert into t1 values(1);
eval xa end '$st_pre';
eval xa prepare '$st_pre';
dec $trial;
}
connection default;
# Kill and restart the server.
-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
-- shutdown_server 0
-- source include/wait_until_disconnected.inc
-- exec echo "restart:--debug_dbug=+d,min_xa_len" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
-- enable_reconnect
-- source include/wait_until_connected_again.inc
-- disable_reconnect
--sorted_result
xa recover;
--sorted_result
xa recover;
--disable_query_log
let $trial = 50;
while ($trial)
{
let $st_pre = `select concat('test', $trial)`;
eval xa commit '$st_pre';
dec $trial;
}
--enable_query_log
xa recover;
drop table t1;
...@@ -1949,6 +1949,7 @@ int ha_recover(HASH *commit_list) ...@@ -1949,6 +1949,7 @@ int ha_recover(HASH *commit_list)
for (info.len= MAX_XID_LIST_SIZE ; for (info.len= MAX_XID_LIST_SIZE ;
info.list==0 && info.len > MIN_XID_LIST_SIZE; info.len/=2) info.list==0 && info.len > MIN_XID_LIST_SIZE; info.len/=2)
{ {
DBUG_EXECUTE_IF("min_xa_len", info.len = 16;);
info.list=(XID *)my_malloc(info.len*sizeof(XID), MYF(0)); info.list=(XID *)my_malloc(info.len*sizeof(XID), MYF(0));
} }
if (!info.list) if (!info.list)
......
...@@ -4445,12 +4445,20 @@ dict_create_foreign_constraints_low( ...@@ -4445,12 +4445,20 @@ dict_create_foreign_constraints_low(
} }
orig = ptr; orig = ptr;
for (;;) {
ptr = dict_accept(cs, ptr, "TABLE", &success); ptr = dict_accept(cs, ptr, "TABLE", &success);
if (success) {
break;
}
ptr = dict_accept(cs, ptr, "ONLINE", &success);
if (success) {
continue;
}
ptr = dict_accept(cs, ptr, "IGNORE", &success);
if (!success) { if (!success) {
goto loop; goto loop;
} }
}
/* We are doing an ALTER TABLE: scan the table name we are altering */ /* We are doing an ALTER TABLE: scan the table name we are altering */
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2015, 2018, MariaDB Corporation. Copyright (c) 2015, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
...@@ -526,7 +526,7 @@ non-locking select */ ...@@ -526,7 +526,7 @@ non-locking select */
ut_ad(!trx_is_autocommit_non_locking((t))); \ ut_ad(!trx_is_autocommit_non_locking((t))); \
switch ((t)->state) { \ switch ((t)->state) { \
case TRX_STATE_PREPARED: \ case TRX_STATE_PREPARED: \
/* fall through */ \ case TRX_STATE_PREPARED_RECOVERED: \
case TRX_STATE_ACTIVE: \ case TRX_STATE_ACTIVE: \
case TRX_STATE_COMMITTED_IN_MEMORY: \ case TRX_STATE_COMMITTED_IN_MEMORY: \
continue; \ continue; \
...@@ -719,6 +719,7 @@ struct trx_t{ ...@@ -719,6 +719,7 @@ struct trx_t{
TRX_STATE_NOT_STARTED TRX_STATE_NOT_STARTED
TRX_STATE_ACTIVE TRX_STATE_ACTIVE
TRX_STATE_PREPARED TRX_STATE_PREPARED
TRX_STATE_PREPARED_RECOVERED (special case of TRX_STATE_PREPARED)
TRX_STATE_COMMITTED_IN_MEMORY (alias below COMMITTED) TRX_STATE_COMMITTED_IN_MEMORY (alias below COMMITTED)
Valid state transitions are: Valid state transitions are:
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2016, MariaDB Corporation. All Rights Reserved. Copyright (c) 2016, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
...@@ -49,6 +49,7 @@ trx_state_eq( ...@@ -49,6 +49,7 @@ trx_state_eq(
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
switch (trx->state) { switch (trx->state) {
case TRX_STATE_PREPARED: case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
ut_ad(!trx_is_autocommit_non_locking(trx)); ut_ad(!trx_is_autocommit_non_locking(trx));
return(trx->state == state); return(trx->state == state);
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
...@@ -48,7 +49,11 @@ enum trx_que_t { ...@@ -48,7 +49,11 @@ enum trx_que_t {
enum trx_state_t { enum trx_state_t {
TRX_STATE_NOT_STARTED, TRX_STATE_NOT_STARTED,
TRX_STATE_ACTIVE, TRX_STATE_ACTIVE,
TRX_STATE_PREPARED, /* Support for 2PC/XA */ /** XA PREPARE has been executed; only XA COMMIT or XA ROLLBACK
are possible */
TRX_STATE_PREPARED,
/** XA PREPARE transaction that was returned to ha_recover() */
TRX_STATE_PREPARED_RECOVERED,
TRX_STATE_COMMITTED_IN_MEMORY TRX_STATE_COMMITTED_IN_MEMORY
}; };
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2014, 2018, MariaDB Corporation. Copyright (c) 2014, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
...@@ -7908,7 +7908,8 @@ lock_trx_release_locks( ...@@ -7908,7 +7908,8 @@ lock_trx_release_locks(
{ {
assert_trx_in_list(trx); assert_trx_in_list(trx);
if (trx_state_eq(trx, TRX_STATE_PREPARED)) { if (trx_state_eq(trx, TRX_STATE_PREPARED)
|| trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED)) {
mutex_enter(&trx_sys->mutex); mutex_enter(&trx_sys->mutex);
ut_a(trx_sys->n_prepared_trx > 0); ut_a(trx_sys->n_prepared_trx > 0);
trx_sys->n_prepared_trx--; trx_sys->n_prepared_trx--;
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2016, 2018, MariaDB Corporation. Copyright (c) 2016, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
...@@ -203,6 +203,7 @@ trx_rollback_for_mysql( ...@@ -203,6 +203,7 @@ trx_rollback_for_mysql(
return(trx_rollback_for_mysql_low(trx)); return(trx_rollback_for_mysql_low(trx));
case TRX_STATE_PREPARED: case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
ut_ad(!trx_is_autocommit_non_locking(trx)); ut_ad(!trx_is_autocommit_non_locking(trx));
return(trx_rollback_for_mysql_low(trx)); return(trx_rollback_for_mysql_low(trx));
...@@ -255,6 +256,7 @@ trx_rollback_last_sql_stat_for_mysql( ...@@ -255,6 +256,7 @@ trx_rollback_last_sql_stat_for_mysql(
return(err); return(err);
case TRX_STATE_PREPARED: case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
case TRX_STATE_COMMITTED_IN_MEMORY: case TRX_STATE_COMMITTED_IN_MEMORY:
/* The statement rollback is only allowed on an ACTIVE /* The statement rollback is only allowed on an ACTIVE
transaction, not a PREPARED or COMMITTED one. */ transaction, not a PREPARED or COMMITTED one. */
...@@ -421,6 +423,7 @@ trx_rollback_to_savepoint_for_mysql( ...@@ -421,6 +423,7 @@ trx_rollback_to_savepoint_for_mysql(
return(trx_rollback_to_savepoint_for_mysql_low( return(trx_rollback_to_savepoint_for_mysql_low(
trx, savep, mysql_binlog_cache_pos)); trx, savep, mysql_binlog_cache_pos));
case TRX_STATE_PREPARED: case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
case TRX_STATE_COMMITTED_IN_MEMORY: case TRX_STATE_COMMITTED_IN_MEMORY:
/* The savepoint rollback is only allowed on an ACTIVE /* The savepoint rollback is only allowed on an ACTIVE
transaction, not a PREPARED or COMMITTED one. */ transaction, not a PREPARED or COMMITTED one. */
...@@ -710,6 +713,7 @@ trx_rollback_resurrected( ...@@ -710,6 +713,7 @@ trx_rollback_resurrected(
} }
return(FALSE); return(FALSE);
case TRX_STATE_PREPARED: case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
goto func_exit; goto func_exit;
case TRX_STATE_NOT_STARTED: case TRX_STATE_NOT_STARTED:
break; break;
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2015, 2018, MariaDB Corporation. Copyright (c) 2015, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
...@@ -314,6 +314,7 @@ trx_free_prepared( ...@@ -314,6 +314,7 @@ trx_free_prepared(
trx_t* trx) /*!< in, own: trx object */ trx_t* trx) /*!< in, own: trx object */
{ {
ut_a(trx_state_eq(trx, TRX_STATE_PREPARED) ut_a(trx_state_eq(trx, TRX_STATE_PREPARED)
|| trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED)
|| (trx->is_recovered || (trx->is_recovered
&& (trx_state_eq(trx, TRX_STATE_ACTIVE) && (trx_state_eq(trx, TRX_STATE_ACTIVE)
|| trx_state_eq(trx, TRX_STATE_COMMITTED_IN_MEMORY)) || trx_state_eq(trx, TRX_STATE_COMMITTED_IN_MEMORY))
...@@ -568,8 +569,7 @@ trx_resurrect_insert( ...@@ -568,8 +569,7 @@ trx_resurrect_insert(
/* trx_start_low() is not called with resurrect, so need to initialize /* trx_start_low() is not called with resurrect, so need to initialize
start time here.*/ start time here.*/
if (trx->state == TRX_STATE_ACTIVE if (trx->state != TRX_STATE_COMMITTED_IN_MEMORY) {
|| trx->state == TRX_STATE_PREPARED) {
trx->start_time = ut_time(); trx->start_time = ut_time();
} }
...@@ -1536,6 +1536,7 @@ trx_commit_or_rollback_prepare( ...@@ -1536,6 +1536,7 @@ trx_commit_or_rollback_prepare(
/* fall through */ /* fall through */
case TRX_STATE_ACTIVE: case TRX_STATE_ACTIVE:
case TRX_STATE_PREPARED: case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
/* If the trx is in a lock wait state, moves the waiting /* If the trx is in a lock wait state, moves the waiting
query thread to the suspended state */ query thread to the suspended state */
...@@ -1661,6 +1662,7 @@ trx_commit_for_mysql( ...@@ -1661,6 +1662,7 @@ trx_commit_for_mysql(
/* fall through */ /* fall through */
case TRX_STATE_ACTIVE: case TRX_STATE_ACTIVE:
case TRX_STATE_PREPARED: case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
trx->op_info = "committing"; trx->op_info = "committing";
trx_commit(trx); trx_commit(trx);
MONITOR_DEC(MONITOR_TRX_ACTIVE); MONITOR_DEC(MONITOR_TRX_ACTIVE);
...@@ -1706,6 +1708,7 @@ trx_mark_sql_stat_end( ...@@ -1706,6 +1708,7 @@ trx_mark_sql_stat_end(
switch (trx->state) { switch (trx->state) {
case TRX_STATE_PREPARED: case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
case TRX_STATE_COMMITTED_IN_MEMORY: case TRX_STATE_COMMITTED_IN_MEMORY:
break; break;
case TRX_STATE_NOT_STARTED: case TRX_STATE_NOT_STARTED:
...@@ -1764,6 +1767,7 @@ trx_print_low( ...@@ -1764,6 +1767,7 @@ trx_print_low(
(ulong) difftime(time(NULL), trx->start_time)); (ulong) difftime(time(NULL), trx->start_time));
goto state_ok; goto state_ok;
case TRX_STATE_PREPARED: case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
fprintf(f, ", ACTIVE (PREPARED) %lu sec", fprintf(f, ", ACTIVE (PREPARED) %lu sec",
(ulong) difftime(time(NULL), trx->start_time)); (ulong) difftime(time(NULL), trx->start_time));
goto state_ok; goto state_ok;
...@@ -1908,6 +1912,7 @@ wsrep_trx_print_locking( ...@@ -1908,6 +1912,7 @@ wsrep_trx_print_locking(
(ulong) difftime(time(NULL), trx->start_time)); (ulong) difftime(time(NULL), trx->start_time));
goto state_ok; goto state_ok;
case TRX_STATE_PREPARED: case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
fprintf(f, ", ACTIVE (PREPARED) %lu sec", fprintf(f, ", ACTIVE (PREPARED) %lu sec",
(ulong) difftime(time(NULL), trx->start_time)); (ulong) difftime(time(NULL), trx->start_time));
goto state_ok; goto state_ok;
...@@ -2035,6 +2040,7 @@ trx_assert_started( ...@@ -2035,6 +2040,7 @@ trx_assert_started(
switch (trx->state) { switch (trx->state) {
case TRX_STATE_PREPARED: case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
return(TRUE); return(TRUE);
case TRX_STATE_ACTIVE: case TRX_STATE_ACTIVE:
...@@ -2200,7 +2206,7 @@ trx_recover_for_mysql( ...@@ -2200,7 +2206,7 @@ trx_recover_for_mysql(
XID* xid_list, /*!< in/out: prepared transactions */ XID* xid_list, /*!< in/out: prepared transactions */
ulint len) /*!< in: number of slots in xid_list */ ulint len) /*!< in: number of slots in xid_list */
{ {
const trx_t* trx; trx_t* trx;
ulint count = 0; ulint count = 0;
ut_ad(xid_list); ut_ad(xid_list);
...@@ -2222,6 +2228,7 @@ trx_recover_for_mysql( ...@@ -2222,6 +2228,7 @@ trx_recover_for_mysql(
trx_sys->mutex. It may change to PREPARED, but not if trx_sys->mutex. It may change to PREPARED, but not if
trx->is_recovered. It may also change to COMMITTED. */ trx->is_recovered. It may also change to COMMITTED. */
if (trx_state_eq(trx, TRX_STATE_PREPARED)) { if (trx_state_eq(trx, TRX_STATE_PREPARED)) {
trx->state = TRX_STATE_PREPARED_RECOVERED;
xid_list[count] = trx->xid; xid_list[count] = trx->xid;
if (count == 0) { if (count == 0) {
...@@ -2246,11 +2253,22 @@ trx_recover_for_mysql( ...@@ -2246,11 +2253,22 @@ trx_recover_for_mysql(
count++; count++;
if (count == len) { if (count == len) {
break; goto partial;
}
}
} }
/* After returning the full list, reset the state, because
there will be a second call to recover the transactions. */
for (trx = UT_LIST_GET_FIRST(trx_sys->rw_trx_list);
trx != NULL;
trx = UT_LIST_GET_NEXT(trx_list, trx)) {
if (trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED)) {
trx->state = TRX_STATE_PREPARED;
} }
} }
partial:
mutex_exit(&trx_sys->mutex); mutex_exit(&trx_sys->mutex);
if (count > 0){ if (count > 0){
...@@ -2293,7 +2311,8 @@ trx_get_trx_by_xid_low( ...@@ -2293,7 +2311,8 @@ trx_get_trx_by_xid_low(
the same */ the same */
if (trx->is_recovered if (trx->is_recovered
&& trx_state_eq(trx, TRX_STATE_PREPARED) && (trx_state_eq(trx, TRX_STATE_PREPARED)
|| trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED))
&& !trx->xid.is_null() && !trx->xid.is_null()
&& xid->gtrid_length == trx->xid.gtrid_length && xid->gtrid_length == trx->xid.gtrid_length
&& xid->bqual_length == trx->xid.bqual_length && xid->bqual_length == trx->xid.bqual_length
...@@ -2373,6 +2392,7 @@ trx_start_if_not_started_xa_low( ...@@ -2373,6 +2392,7 @@ trx_start_if_not_started_xa_low(
case TRX_STATE_ACTIVE: case TRX_STATE_ACTIVE:
return; return;
case TRX_STATE_PREPARED: case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
case TRX_STATE_COMMITTED_IN_MEMORY: case TRX_STATE_COMMITTED_IN_MEMORY:
break; break;
} }
...@@ -2395,6 +2415,7 @@ trx_start_if_not_started_low( ...@@ -2395,6 +2415,7 @@ trx_start_if_not_started_low(
case TRX_STATE_ACTIVE: case TRX_STATE_ACTIVE:
return; return;
case TRX_STATE_PREPARED: case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
case TRX_STATE_COMMITTED_IN_MEMORY: case TRX_STATE_COMMITTED_IN_MEMORY:
break; break;
} }
...@@ -2436,6 +2457,7 @@ trx_start_for_ddl_low( ...@@ -2436,6 +2457,7 @@ trx_start_for_ddl_low(
ut_ad(trx->will_lock > 0); ut_ad(trx->will_lock > 0);
return; return;
case TRX_STATE_PREPARED: case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
case TRX_STATE_COMMITTED_IN_MEMORY: case TRX_STATE_COMMITTED_IN_MEMORY:
break; break;
} }
......
...@@ -4454,12 +4454,20 @@ dict_create_foreign_constraints_low( ...@@ -4454,12 +4454,20 @@ dict_create_foreign_constraints_low(
} }
orig = ptr; orig = ptr;
for (;;) {
ptr = dict_accept(cs, ptr, "TABLE", &success); ptr = dict_accept(cs, ptr, "TABLE", &success);
if (success) {
break;
}
ptr = dict_accept(cs, ptr, "ONLINE", &success);
if (success) {
continue;
}
ptr = dict_accept(cs, ptr, "IGNORE", &success);
if (!success) { if (!success) {
goto loop; goto loop;
} }
}
/* We are doing an ALTER TABLE: scan the table name we are altering */ /* We are doing an ALTER TABLE: scan the table name we are altering */
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2015, 2018, MariaDB Corporation. Copyright (c) 2015, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
...@@ -575,7 +575,7 @@ non-locking select */ ...@@ -575,7 +575,7 @@ non-locking select */
ut_ad(!trx_is_autocommit_non_locking((t))); \ ut_ad(!trx_is_autocommit_non_locking((t))); \
switch ((t)->state) { \ switch ((t)->state) { \
case TRX_STATE_PREPARED: \ case TRX_STATE_PREPARED: \
/* fall through */ \ case TRX_STATE_PREPARED_RECOVERED: \
case TRX_STATE_ACTIVE: \ case TRX_STATE_ACTIVE: \
case TRX_STATE_COMMITTED_IN_MEMORY: \ case TRX_STATE_COMMITTED_IN_MEMORY: \
continue; \ continue; \
...@@ -768,6 +768,7 @@ struct trx_t{ ...@@ -768,6 +768,7 @@ struct trx_t{
TRX_STATE_NOT_STARTED TRX_STATE_NOT_STARTED
TRX_STATE_ACTIVE TRX_STATE_ACTIVE
TRX_STATE_PREPARED TRX_STATE_PREPARED
TRX_STATE_PREPARED_RECOVERED (special case of TRX_STATE_PREPARED)
TRX_STATE_COMMITTED_IN_MEMORY (alias below COMMITTED) TRX_STATE_COMMITTED_IN_MEMORY (alias below COMMITTED)
Valid state transitions are: Valid state transitions are:
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2016, MariaDB Corporation. All Rights Reserved. Copyright (c) 2016, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
...@@ -49,6 +49,7 @@ trx_state_eq( ...@@ -49,6 +49,7 @@ trx_state_eq(
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
switch (trx->state) { switch (trx->state) {
case TRX_STATE_PREPARED: case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
ut_ad(!trx_is_autocommit_non_locking(trx)); ut_ad(!trx_is_autocommit_non_locking(trx));
return(trx->state == state); return(trx->state == state);
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
...@@ -48,7 +49,11 @@ enum trx_que_t { ...@@ -48,7 +49,11 @@ enum trx_que_t {
enum trx_state_t { enum trx_state_t {
TRX_STATE_NOT_STARTED, TRX_STATE_NOT_STARTED,
TRX_STATE_ACTIVE, TRX_STATE_ACTIVE,
TRX_STATE_PREPARED, /* Support for 2PC/XA */ /** XA PREPARE has been executed; only XA COMMIT or XA ROLLBACK
are possible */
TRX_STATE_PREPARED,
/** XA PREPARE transaction that was returned to ha_recover() */
TRX_STATE_PREPARED_RECOVERED,
TRX_STATE_COMMITTED_IN_MEMORY TRX_STATE_COMMITTED_IN_MEMORY
}; };
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2014, 2018, MariaDB Corporation. Copyright (c) 2014, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
...@@ -8010,7 +8010,8 @@ lock_trx_release_locks( ...@@ -8010,7 +8010,8 @@ lock_trx_release_locks(
{ {
assert_trx_in_list(trx); assert_trx_in_list(trx);
if (trx_state_eq(trx, TRX_STATE_PREPARED)) { if (trx_state_eq(trx, TRX_STATE_PREPARED)
|| trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED)) {
mutex_enter(&trx_sys->mutex); mutex_enter(&trx_sys->mutex);
ut_a(trx_sys->n_prepared_trx > 0); ut_a(trx_sys->n_prepared_trx > 0);
trx_sys->n_prepared_trx--; trx_sys->n_prepared_trx--;
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2016, 2018, MariaDB Corporation. Copyright (c) 2016, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
...@@ -208,6 +208,7 @@ trx_rollback_for_mysql( ...@@ -208,6 +208,7 @@ trx_rollback_for_mysql(
return(trx_rollback_for_mysql_low(trx)); return(trx_rollback_for_mysql_low(trx));
case TRX_STATE_PREPARED: case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
ut_ad(!trx_is_autocommit_non_locking(trx)); ut_ad(!trx_is_autocommit_non_locking(trx));
return(trx_rollback_for_mysql_low(trx)); return(trx_rollback_for_mysql_low(trx));
...@@ -260,6 +261,7 @@ trx_rollback_last_sql_stat_for_mysql( ...@@ -260,6 +261,7 @@ trx_rollback_last_sql_stat_for_mysql(
return(err); return(err);
case TRX_STATE_PREPARED: case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
case TRX_STATE_COMMITTED_IN_MEMORY: case TRX_STATE_COMMITTED_IN_MEMORY:
/* The statement rollback is only allowed on an ACTIVE /* The statement rollback is only allowed on an ACTIVE
transaction, not a PREPARED or COMMITTED one. */ transaction, not a PREPARED or COMMITTED one. */
...@@ -433,6 +435,7 @@ trx_rollback_to_savepoint_for_mysql( ...@@ -433,6 +435,7 @@ trx_rollback_to_savepoint_for_mysql(
return(trx_rollback_to_savepoint_for_mysql_low( return(trx_rollback_to_savepoint_for_mysql_low(
trx, savep, mysql_binlog_cache_pos)); trx, savep, mysql_binlog_cache_pos));
case TRX_STATE_PREPARED: case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
case TRX_STATE_COMMITTED_IN_MEMORY: case TRX_STATE_COMMITTED_IN_MEMORY:
/* The savepoint rollback is only allowed on an ACTIVE /* The savepoint rollback is only allowed on an ACTIVE
transaction, not a PREPARED or COMMITTED one. */ transaction, not a PREPARED or COMMITTED one. */
...@@ -722,6 +725,7 @@ trx_rollback_resurrected( ...@@ -722,6 +725,7 @@ trx_rollback_resurrected(
} }
return(FALSE); return(FALSE);
case TRX_STATE_PREPARED: case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
goto func_exit; goto func_exit;
case TRX_STATE_NOT_STARTED: case TRX_STATE_NOT_STARTED:
break; break;
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2015, 2018, MariaDB Corporation. Copyright (c) 2015, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
...@@ -480,6 +480,7 @@ trx_free_prepared( ...@@ -480,6 +480,7 @@ trx_free_prepared(
trx_t* trx) /*!< in, own: trx object */ trx_t* trx) /*!< in, own: trx object */
{ {
ut_a(trx_state_eq(trx, TRX_STATE_PREPARED) ut_a(trx_state_eq(trx, TRX_STATE_PREPARED)
|| trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED)
|| (trx->is_recovered || (trx->is_recovered
&& (trx_state_eq(trx, TRX_STATE_ACTIVE) && (trx_state_eq(trx, TRX_STATE_ACTIVE)
|| trx_state_eq(trx, TRX_STATE_COMMITTED_IN_MEMORY)) || trx_state_eq(trx, TRX_STATE_COMMITTED_IN_MEMORY))
...@@ -747,8 +748,7 @@ trx_resurrect_insert( ...@@ -747,8 +748,7 @@ trx_resurrect_insert(
/* trx_start_low() is not called with resurrect, so need to initialize /* trx_start_low() is not called with resurrect, so need to initialize
start time here.*/ start time here.*/
if (trx->state == TRX_STATE_ACTIVE if (trx->state != TRX_STATE_COMMITTED_IN_MEMORY) {
|| trx->state == TRX_STATE_PREPARED) {
trx->start_time = ut_time(); trx->start_time = ut_time();
} }
...@@ -1790,6 +1790,7 @@ trx_commit_or_rollback_prepare( ...@@ -1790,6 +1790,7 @@ trx_commit_or_rollback_prepare(
/* fall through */ /* fall through */
case TRX_STATE_ACTIVE: case TRX_STATE_ACTIVE:
case TRX_STATE_PREPARED: case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
/* If the trx is in a lock wait state, moves the waiting /* If the trx is in a lock wait state, moves the waiting
query thread to the suspended state */ query thread to the suspended state */
...@@ -1927,6 +1928,7 @@ trx_commit_for_mysql( ...@@ -1927,6 +1928,7 @@ trx_commit_for_mysql(
/* fall through */ /* fall through */
case TRX_STATE_ACTIVE: case TRX_STATE_ACTIVE:
case TRX_STATE_PREPARED: case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
trx->op_info = "committing"; trx->op_info = "committing";
trx_commit(trx); trx_commit(trx);
MONITOR_DEC(MONITOR_TRX_ACTIVE); MONITOR_DEC(MONITOR_TRX_ACTIVE);
...@@ -1983,6 +1985,7 @@ trx_mark_sql_stat_end( ...@@ -1983,6 +1985,7 @@ trx_mark_sql_stat_end(
switch (trx->state) { switch (trx->state) {
case TRX_STATE_PREPARED: case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
case TRX_STATE_COMMITTED_IN_MEMORY: case TRX_STATE_COMMITTED_IN_MEMORY:
break; break;
case TRX_STATE_NOT_STARTED: case TRX_STATE_NOT_STARTED:
...@@ -2041,6 +2044,7 @@ trx_print_low( ...@@ -2041,6 +2044,7 @@ trx_print_low(
(ulong) difftime(time(NULL), trx->start_time)); (ulong) difftime(time(NULL), trx->start_time));
goto state_ok; goto state_ok;
case TRX_STATE_PREPARED: case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
fprintf(f, ", ACTIVE (PREPARED) %lu sec", fprintf(f, ", ACTIVE (PREPARED) %lu sec",
(ulong) difftime(time(NULL), trx->start_time)); (ulong) difftime(time(NULL), trx->start_time));
goto state_ok; goto state_ok;
...@@ -2185,6 +2189,7 @@ wsrep_trx_print_locking( ...@@ -2185,6 +2189,7 @@ wsrep_trx_print_locking(
(ulong) difftime(time(NULL), trx->start_time)); (ulong) difftime(time(NULL), trx->start_time));
goto state_ok; goto state_ok;
case TRX_STATE_PREPARED: case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
fprintf(f, ", ACTIVE (PREPARED) %lu sec", fprintf(f, ", ACTIVE (PREPARED) %lu sec",
(ulong) difftime(time(NULL), trx->start_time)); (ulong) difftime(time(NULL), trx->start_time));
goto state_ok; goto state_ok;
...@@ -2313,6 +2318,7 @@ trx_assert_started( ...@@ -2313,6 +2318,7 @@ trx_assert_started(
switch (trx->state) { switch (trx->state) {
case TRX_STATE_PREPARED: case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
return(TRUE); return(TRUE);
case TRX_STATE_ACTIVE: case TRX_STATE_ACTIVE:
...@@ -2478,7 +2484,7 @@ trx_recover_for_mysql( ...@@ -2478,7 +2484,7 @@ trx_recover_for_mysql(
XID* xid_list, /*!< in/out: prepared transactions */ XID* xid_list, /*!< in/out: prepared transactions */
ulint len) /*!< in: number of slots in xid_list */ ulint len) /*!< in: number of slots in xid_list */
{ {
const trx_t* trx; trx_t* trx;
ulint count = 0; ulint count = 0;
ut_ad(xid_list); ut_ad(xid_list);
...@@ -2500,6 +2506,7 @@ trx_recover_for_mysql( ...@@ -2500,6 +2506,7 @@ trx_recover_for_mysql(
trx_sys->mutex. It may change to PREPARED, but not if trx_sys->mutex. It may change to PREPARED, but not if
trx->is_recovered. It may also change to COMMITTED. */ trx->is_recovered. It may also change to COMMITTED. */
if (trx_state_eq(trx, TRX_STATE_PREPARED)) { if (trx_state_eq(trx, TRX_STATE_PREPARED)) {
trx->state = TRX_STATE_PREPARED_RECOVERED;
xid_list[count] = trx->xid; xid_list[count] = trx->xid;
if (count == 0) { if (count == 0) {
...@@ -2524,11 +2531,22 @@ trx_recover_for_mysql( ...@@ -2524,11 +2531,22 @@ trx_recover_for_mysql(
count++; count++;
if (count == len) { if (count == len) {
break; goto partial;
}
}
} }
/* After returning the full list, reset the state, because
there will be a second call to recover the transactions. */
for (trx = UT_LIST_GET_FIRST(trx_sys->rw_trx_list);
trx != NULL;
trx = UT_LIST_GET_NEXT(trx_list, trx)) {
if (trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED)) {
trx->state = TRX_STATE_PREPARED;
} }
} }
partial:
mutex_exit(&trx_sys->mutex); mutex_exit(&trx_sys->mutex);
if (count > 0){ if (count > 0){
...@@ -2571,7 +2589,8 @@ trx_get_trx_by_xid_low( ...@@ -2571,7 +2589,8 @@ trx_get_trx_by_xid_low(
the same */ the same */
if (trx->is_recovered if (trx->is_recovered
&& trx_state_eq(trx, TRX_STATE_PREPARED) && (trx_state_eq(trx, TRX_STATE_PREPARED)
|| trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED))
&& !trx->xid.is_null() && !trx->xid.is_null()
&& xid->gtrid_length == trx->xid.gtrid_length && xid->gtrid_length == trx->xid.gtrid_length
&& xid->bqual_length == trx->xid.bqual_length && xid->bqual_length == trx->xid.bqual_length
...@@ -2651,6 +2670,7 @@ trx_start_if_not_started_xa_low( ...@@ -2651,6 +2670,7 @@ trx_start_if_not_started_xa_low(
case TRX_STATE_ACTIVE: case TRX_STATE_ACTIVE:
return; return;
case TRX_STATE_PREPARED: case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
case TRX_STATE_COMMITTED_IN_MEMORY: case TRX_STATE_COMMITTED_IN_MEMORY:
break; break;
} }
...@@ -2677,6 +2697,7 @@ trx_start_if_not_started_low( ...@@ -2677,6 +2697,7 @@ trx_start_if_not_started_low(
case TRX_STATE_ACTIVE: case TRX_STATE_ACTIVE:
return; return;
case TRX_STATE_PREPARED: case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
case TRX_STATE_COMMITTED_IN_MEMORY: case TRX_STATE_COMMITTED_IN_MEMORY:
break; break;
} }
...@@ -2722,6 +2743,7 @@ trx_start_for_ddl_low( ...@@ -2722,6 +2743,7 @@ trx_start_for_ddl_low(
ut_ad(trx->will_lock > 0); ut_ad(trx->will_lock > 0);
return; return;
case TRX_STATE_PREPARED: case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
case TRX_STATE_COMMITTED_IN_MEMORY: case TRX_STATE_COMMITTED_IN_MEMORY:
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment