mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
Merge 5.5 into 10.1
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
# 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);
|
|||||||
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;
|
||||||
|
310
mysql-test/suite/innodb/r/xa_debug.result
Normal file
310
mysql-test/suite/innodb/r/xa_debug.result
Normal file
@@ -0,0 +1,310 @@
|
|||||||
|
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);
|
|||||||
--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;
|
||||||
|
45
mysql-test/suite/innodb/t/xa_debug.test
Normal file
45
mysql-test/suite/innodb/t/xa_debug.test
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
-- 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)
|
|||||||
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(
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 */
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
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 */
|
|||||||
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{
|
|||||||
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:
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
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(
|
|||||||
#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);
|
||||||
|
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
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 {
|
|||||||
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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
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(
|
|||||||
{
|
{
|
||||||
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--;
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
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(
|
|||||||
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(
|
|||||||
|
|
||||||
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(
|
|||||||
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 @@ fake_prepared:
|
|||||||
}
|
}
|
||||||
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;
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
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(
|
|||||||
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(
|
|||||||
|
|
||||||
/* 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(
|
|||||||
/* 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(
|
|||||||
/* 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(
|
|||||||
|
|
||||||
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(
|
|||||||
(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(
|
|||||||
(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(
|
|||||||
|
|
||||||
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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 */
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
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 */
|
|||||||
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{
|
|||||||
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:
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
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(
|
|||||||
#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);
|
||||||
|
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
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 {
|
|||||||
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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
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(
|
|||||||
{
|
{
|
||||||
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--;
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
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(
|
|||||||
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(
|
|||||||
|
|
||||||
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(
|
|||||||
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 @@ fake_prepared:
|
|||||||
}
|
}
|
||||||
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;
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
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(
|
|||||||
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(
|
|||||||
|
|
||||||
/* 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(
|
|||||||
/* 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(
|
|||||||
/* 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(
|
|||||||
|
|
||||||
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(
|
|||||||
(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(
|
|||||||
(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(
|
|||||||
|
|
||||||
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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user