Skip to content

Commit 7aa86eb

Browse files
janlindstromsysprg
authored andcommitted
MDEV-33828 : Transactional commit not supported by involved engine(s)
Problem was too tight condition on ha_commit_trans to not allow non transactional storage engines participate 2pc in Galera case. This is required because transaction using e.g. procedures might read mysql.proc table inside a trasaction and these tables use at the moment Aria storage engine that does not support 2pc. Fixed by allowing read only transactions to storage engines that do not support two phase commit to participate 2pc transaction. These will be committed later separately. Signed-off-by: Julius Goryavsky <julius.goryavsky@mariadb.com>
1 parent 3003a3d commit 7aa86eb

File tree

6 files changed

+140
-29
lines changed

6 files changed

+140
-29
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
connection node_2;
2+
connection node_1;
3+
SET AUTOCOMMIT=ON;
4+
SELECT @@autocommit;
5+
@@autocommit
6+
1
7+
SET LOCAL enforce_storage_engine=InnoDB;
8+
CREATE TABLE t1(id int not null primary key auto_increment, name varchar(64)) ENGINE=InnoDB;
9+
INSERT INTO t1(name) VALUES ('name1'),('name3'),('name6'),('name2');
10+
CREATE PROCEDURE sel_proc()
11+
BEGIN
12+
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
13+
SELECT * FROM t1;
14+
END|
15+
CREATE PROCEDURE ins_proc()
16+
BEGIN
17+
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
18+
INSERT INTO t1 VALUES ('name_proc');
19+
END|
20+
SET AUTOCOMMIT=OFF;
21+
SELECT @@autocommit;
22+
@@autocommit
23+
0
24+
START TRANSACTION;
25+
insert into t1(name) values('name10');
26+
select param_list, returns, db, type from mysql.proc where name='sel_proc';
27+
param_list returns db type
28+
test PROCEDURE
29+
call ins_proc();
30+
COMMIT;
31+
SET AUTOCOMMIT=ON;
32+
SELECT * FROM t1;
33+
id name
34+
1 name1
35+
3 name3
36+
5 name6
37+
7 name2
38+
9 name10
39+
DROP TABLE t1;
40+
DROP PROCEDURE sel_proc;
41+
DROP PROCEDURE ins_proc;

mysql-test/suite/galera/r/mdev-22063.result

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ INSERT INTO t3(id) SELECT seq FROM seq_1_to_1000;
7979
REPLACE INTO t4 SELECT * FROM t1;
8080
REPLACE INTO t5 SELECT * FROM t2;
8181
REPLACE INTO t6 SELECT * FROM t3;
82-
ERROR HY000: Transactional commit not supported by involved engine(s)
8382
REPLACE INTO t7 SELECT * FROM t2;
8483
REPLACE INTO t8 SELECT * FROM t3;
8584
SELECT COUNT(*) AS EXPECT_1000 FROM t1;
@@ -97,9 +96,9 @@ EXPECT_1000
9796
SELECT COUNT(*) AS EXPECT_1000 FROM t5;
9897
EXPECT_1000
9998
1000
100-
SELECT COUNT(*) AS EXPECT_0 FROM t6;
101-
EXPECT_0
102-
0
99+
SELECT COUNT(*) AS EXPECT_1000 FROM t6;
100+
EXPECT_1000
101+
1000
103102
SELECT COUNT(*) AS EXPECT_1000 FROM t7;
104103
EXPECT_1000
105104
1000
@@ -122,9 +121,9 @@ EXPECT_1000
122121
SELECT COUNT(*) AS EXPECT_1000 FROM t5;
123122
EXPECT_1000
124123
1000
125-
SELECT COUNT(*) AS EXPECT_0 FROM t6;
126-
EXPECT_0
127-
0
124+
SELECT COUNT(*) AS EXPECT_1000 FROM t6;
125+
EXPECT_1000
126+
1000
128127
SELECT COUNT(*) AS EXPECT_1000 FROM t7;
129128
EXPECT_1000
130129
1000
@@ -148,7 +147,6 @@ INSERT INTO t3(id) SELECT seq FROM seq_1_to_1000;
148147
INSERT INTO t4 SELECT * FROM t1;
149148
INSERT INTO t5 SELECT * FROM t2;
150149
INSERT INTO t6 SELECT * FROM t3;
151-
ERROR HY000: Transactional commit not supported by involved engine(s)
152150
INSERT INTO t7 SELECT * FROM t2;
153151
INSERT INTO t8 SELECT * FROM t3;
154152
SELECT COUNT(*) AS EXPECT_1000 FROM t1;
@@ -166,9 +164,9 @@ EXPECT_1000
166164
SELECT COUNT(*) AS EXPECT_1000 FROM t5;
167165
EXPECT_1000
168166
1000
169-
SELECT COUNT(*) AS EXPECT_0 FROM t6;
170-
EXPECT_0
171-
0
167+
SELECT COUNT(*) AS EXPECT_1000 FROM t6;
168+
EXPECT_1000
169+
1000
172170
SELECT COUNT(*) AS EXPECT_1000 FROM t7;
173171
EXPECT_1000
174172
1000
@@ -191,9 +189,9 @@ EXPECT_1000
191189
SELECT COUNT(*) AS EXPECT_1000 FROM t5;
192190
EXPECT_1000
193191
1000
194-
SELECT COUNT(*) AS EXPECT_0 FROM t6;
195-
EXPECT_0
196-
0
192+
SELECT COUNT(*) AS EXPECT_1000 FROM t6;
193+
EXPECT_1000
194+
1000
197195
SELECT COUNT(*) AS EXPECT_1000 FROM t7;
198196
EXPECT_1000
199197
1000
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
!include ../galera_2nodes.cnf
2+
3+
[mysqld]
4+
log-bin
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
--source include/galera_cluster.inc
2+
--source include/have_innodb.inc
3+
--source include/have_aria.inc
4+
5+
SET AUTOCOMMIT=ON;
6+
SELECT @@autocommit;
7+
8+
SET LOCAL enforce_storage_engine=InnoDB;
9+
10+
CREATE TABLE t1(id int not null primary key auto_increment, name varchar(64)) ENGINE=InnoDB;
11+
INSERT INTO t1(name) VALUES ('name1'),('name3'),('name6'),('name2');
12+
13+
DELIMITER |;
14+
CREATE PROCEDURE sel_proc()
15+
BEGIN
16+
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
17+
SELECT * FROM t1;
18+
END|
19+
20+
CREATE PROCEDURE ins_proc()
21+
BEGIN
22+
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
23+
INSERT INTO t1 VALUES ('name_proc');
24+
END|
25+
DELIMITER ;|
26+
27+
SET AUTOCOMMIT=OFF;
28+
SELECT @@autocommit;
29+
30+
START TRANSACTION;
31+
32+
insert into t1(name) values('name10');
33+
34+
select param_list, returns, db, type from mysql.proc where name='sel_proc';
35+
36+
call ins_proc();
37+
38+
COMMIT;
39+
40+
SET AUTOCOMMIT=ON;
41+
42+
SELECT * FROM t1;
43+
DROP TABLE t1;
44+
DROP PROCEDURE sel_proc;
45+
DROP PROCEDURE ins_proc;

mysql-test/suite/galera/t/mdev-22063.test

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,6 @@ INSERT INTO t3(id) SELECT seq FROM seq_1_to_1000;
8181

8282
REPLACE INTO t4 SELECT * FROM t1;
8383
REPLACE INTO t5 SELECT * FROM t2;
84-
# For some reason Aria storage engine does register_ha
85-
--error ER_ERROR_DURING_COMMIT
8684
REPLACE INTO t6 SELECT * FROM t3;
8785
REPLACE INTO t7 SELECT * FROM t2;
8886
REPLACE INTO t8 SELECT * FROM t3;
@@ -92,7 +90,7 @@ SELECT COUNT(*) AS EXPECT_1000 FROM t2;
9290
SELECT COUNT(*) AS EXPECT_1000 FROM t3;
9391
SELECT COUNT(*) AS EXPECT_1000 FROM t4;
9492
SELECT COUNT(*) AS EXPECT_1000 FROM t5;
95-
SELECT COUNT(*) AS EXPECT_0 FROM t6;
93+
SELECT COUNT(*) AS EXPECT_1000 FROM t6;
9694
SELECT COUNT(*) AS EXPECT_1000 FROM t7;
9795
SELECT COUNT(*) AS EXPECT_1000 FROM t8;
9896

@@ -107,7 +105,7 @@ SELECT COUNT(*) AS EXPECT_1000 FROM t2;
107105
SELECT COUNT(*) AS EXPECT_1000 FROM t3;
108106
SELECT COUNT(*) AS EXPECT_1000 FROM t4;
109107
SELECT COUNT(*) AS EXPECT_1000 FROM t5;
110-
SELECT COUNT(*) AS EXPECT_0 FROM t6;
108+
SELECT COUNT(*) AS EXPECT_1000 FROM t6;
111109
SELECT COUNT(*) AS EXPECT_1000 FROM t7;
112110
SELECT COUNT(*) AS EXPECT_1000 FROM t8;
113111

@@ -131,8 +129,6 @@ INSERT INTO t3(id) SELECT seq FROM seq_1_to_1000;
131129

132130
INSERT INTO t4 SELECT * FROM t1;
133131
INSERT INTO t5 SELECT * FROM t2;
134-
# For some reason Aria storage engine does register_ha
135-
--error ER_ERROR_DURING_COMMIT
136132
INSERT INTO t6 SELECT * FROM t3;
137133
INSERT INTO t7 SELECT * FROM t2;
138134
INSERT INTO t8 SELECT * FROM t3;
@@ -142,7 +138,7 @@ SELECT COUNT(*) AS EXPECT_1000 FROM t2;
142138
SELECT COUNT(*) AS EXPECT_1000 FROM t3;
143139
SELECT COUNT(*) AS EXPECT_1000 FROM t4;
144140
SELECT COUNT(*) AS EXPECT_1000 FROM t5;
145-
SELECT COUNT(*) AS EXPECT_0 FROM t6;
141+
SELECT COUNT(*) AS EXPECT_1000 FROM t6;
146142
SELECT COUNT(*) AS EXPECT_1000 FROM t7;
147143
SELECT COUNT(*) AS EXPECT_1000 FROM t8;
148144

@@ -157,7 +153,7 @@ SELECT COUNT(*) AS EXPECT_1000 FROM t2;
157153
SELECT COUNT(*) AS EXPECT_1000 FROM t3;
158154
SELECT COUNT(*) AS EXPECT_1000 FROM t4;
159155
SELECT COUNT(*) AS EXPECT_1000 FROM t5;
160-
SELECT COUNT(*) AS EXPECT_0 FROM t6;
156+
SELECT COUNT(*) AS EXPECT_1000 FROM t6;
161157
SELECT COUNT(*) AS EXPECT_1000 FROM t7;
162158
SELECT COUNT(*) AS EXPECT_1000 FROM t8;
163159

sql/handler.cc

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1531,6 +1531,29 @@ ha_check_and_coalesce_trx_read_only(THD *thd, Ha_trx_info *ha_list,
15311531
return rw_ha_count;
15321532
}
15331533

1534+
#ifdef WITH_WSREP
1535+
/**
1536+
Check if transaction contains storage engine not supporting
1537+
two-phase commit and transaction is read-write.
1538+
1539+
@retval
1540+
true Transaction contains storage engine not supporting
1541+
two phase commit and transaction is read-write
1542+
@retval
1543+
false otherwise
1544+
*/
1545+
static bool wsrep_have_no2pc_rw_ha(Ha_trx_info* ha_list)
1546+
{
1547+
for (Ha_trx_info *ha_info=ha_list; ha_info; ha_info= ha_info->next())
1548+
{
1549+
handlerton *ht= ha_info->ht();
1550+
// Transaction is read-write and handler does not support 2pc
1551+
if (ha_info->is_trx_read_write() && ht->prepare==0)
1552+
return true;
1553+
}
1554+
return false;
1555+
}
1556+
#endif /* WITH_WSREP */
15341557

15351558
/**
15361559
@retval
@@ -1734,14 +1757,18 @@ int ha_commit_trans(THD *thd, bool all)
17341757
*/
17351758
if (run_wsrep_hooks)
17361759
{
1737-
// This commit involves more than one storage engine and requires
1738-
// two phases, but some engines don't support it.
1739-
// Issue a message to the client and roll back the transaction.
1740-
if (trans->no_2pc && rw_ha_count > 1)
1760+
// This commit involves storage engines that do not support two phases.
1761+
// We allow read only transactions to such storage engines but not
1762+
// read write transactions.
1763+
if (trans->no_2pc && rw_ha_count > 1 && wsrep_have_no2pc_rw_ha(trans->ha_list))
17411764
{
1742-
// REPLACE|INSERT INTO ... SELECT uses TOI for MyISAM|Aria
1743-
if (WSREP(thd) && thd->wsrep_cs().mode() != wsrep::client_state::m_toi)
1744-
{
1765+
// This commit involves more than one storage engine and requires
1766+
// two phases, but some engines don't support it.
1767+
// Issue a message to the client and roll back the transaction.
1768+
1769+
// REPLACE|INSERT INTO ... SELECT uses TOI for MyISAM|Aria
1770+
if (WSREP(thd) && thd->wsrep_cs().mode() != wsrep::client_state::m_toi)
1771+
{
17451772
my_message(ER_ERROR_DURING_COMMIT, "Transactional commit not supported "
17461773
"by involved engine(s)", MYF(0));
17471774
error= 1;

0 commit comments

Comments
 (0)