[MDEV-24587] xa transactions can commit in read_only Created: 2021-01-14  Updated: 2023-04-27

Status: Open
Project: MariaDB Server
Component/s: XA
Affects Version/s: 10.2.36, 10.2, 10.3, 10.4, 10.5
Fix Version/s: 10.4, 10.5

Type: Bug Priority: Major
Reporter: Daniel Black Assignee: Sergei Golubchik
Resolution: Unresolved Votes: 0
Labels: None


 Description   

connection1

MariaDB [test]> create table t ( i int primary key);
Query OK, 0 rows affected (0.00 sec)
 
MariaDB [test]> XA START 'test';
Query OK, 0 rows affected (0.00 sec)
 
MariaDB [test]> insert into t values (41), (3324),(14);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

connection2

MariaDB [(none)]> set global read_only=1;
Query OK, 0 rows affected (0.00 sec)

connection1

MariaDB [test]> XA END 'test';
Query OK, 0 rows affected (0.00 sec)
 
MariaDB [test]> XA PREPARE 'test';
Query OK, 0 rows affected (0.00 sec)
 
MariaDB [test]> XA COMMIT 'test';
Query OK, 0 rows affected (0.00 sec)
 
MariaDB [test]> select * from t;
+------+
| i    |
+------+
|   14 |
|   41 |
| 3324 |
+------+
3 rows in set (0.00 sec)

A non-XA transaction would of errored on the `COMMIT`. XA has no such limitations.



 Comments   
Comment by Alice Sherepa [ 2021-01-14 ]

Repeatable on 10.2-10.5, but I am not sure what the expected behaviour should be here.
KB says "Attempting to set this variable to 1 will fail if the current session has table locks or transactions pending, while if other sessions hold table locks, the statement will wait until these locks are released before completing. While the attempt to set read_only is waiting, other requests for table locks or transactions will also wait until read_only has been set."
so I suppose set read_only=1 should wait.
But currently in the test below read_only sets to 1 and xa transactions are allowed, but innodb transactions not.

--source include/have_innodb.inc
 
create user u1@localhost;
grant all on test.* to u1@localhost;
create table t ( i int primary key) engine=innodb;
 
--connect (con1,localhost,u1,,test)
--connection con1
xa start 'test';
insert into t values (1), (2),(3);
 
--connect (con2,localhost,u1,,test)
--connection con2
start transaction;
insert into t values (4);
 
--connect (con3,localhost,root,,test)
--connection con3
set global read_only=1; 
 
--connection con1
xa end 'test';
xa prepare 'test';
#show  variables like 'read_only';  # why is it forbidden?
xa commit 'test';
 
--error 1290
insert into t values (5);
 
--connection con2
--error 1290
commit ;
select * from t;
 
#cleanup
--disconnect con1
--disconnect con2
--disconnect con3
connection default;
drop table t;
set global read_only=0;
drop user u1@localhost;

Comment by Daniel Black [ 2021-01-14 ]

thanks for confirming alice. On expectant behaviour I'd expect the "XA PREPARE" to fail. In XA I though the commit was never meant to fail.

I also noticed that read_only=1 doesn't wait on standard transactions that have updates that aren't committed either (while investigating MDEV-23755) (which might be worthy of another bug, at least a doc fix).

Generated at Thu Feb 08 09:31:07 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.