mirror of
https://github.com/MariaDB/server.git
synced 2025-01-22 23:04:20 +01:00
0b39c189ba
2617.31.12, 2617.31.15, 2617.31.15, 2617.31.16, 2617.43.1 - initial changeset that introduced the fix for Bug#989 and follow up fixes for all test suite failures introduced in the initial changeset. ------------------------------------------------------------ revno: 2617.31.1 committer: Davi Arnaut <Davi.Arnaut@Sun.COM> branch nick: 4284-6.0 timestamp: Fri 2009-03-06 19:17:00 -0300 message: Bug#989: If DROP TABLE while there's an active transaction, wrong binlog order WL#4284: Transactional DDL locking Currently the MySQL server does not keep metadata locks on schema objects for the duration of a transaction, thus failing to guarantee the integrity of the schema objects being used during the transaction and to protect then from concurrent DDL operations. This also poses a problem for replication as a DDL operation might be replicated even thought there are active transactions using the object being modified. The solution is to defer the release of metadata locks until a active transaction is either committed or rolled back. This prevents other statements from modifying the table for the entire duration of the transaction. This provides commitment ordering for guaranteeing serializability across multiple transactions. - Incompatible change: If MySQL's metadata locking system encounters a lock conflict, the usual schema is to use the try and back-off technique to avoid deadlocks -- this schema consists in releasing all locks and trying to acquire them all in one go. But in a transactional context this algorithm can't be utilized as its not possible to release locks acquired during the course of the transaction without breaking the transaction commitments. To avoid deadlocks in this case, the ER_LOCK_DEADLOCK will be returned if a lock conflict is encountered during a transaction. Let's consider an example: A transaction has two statements that modify table t1, then table t2, and then commits. The first statement of the transaction will acquire a shared metadata lock on table t1, and it will be kept utill COMMIT to ensure serializability. At the moment when the second statement attempts to acquire a shared metadata lock on t2, a concurrent ALTER or DROP statement might have locked t2 exclusively. The prescription of the current locking protocol is that the acquirer of the shared lock backs off -- gives up all his current locks and retries. This implies that the entire multi-statement transaction has to be rolled back. - Incompatible change: FLUSH commands such as FLUSH PRIVILEGES and FLUSH TABLES WITH READ LOCK won't cause locked tables to be implicitly unlocked anymore.
217 lines
4.2 KiB
Text
217 lines
4.2 KiB
Text
#
|
|
# WL#1756
|
|
#
|
|
-- source include/have_innodb.inc
|
|
|
|
# Save the initial number of concurrent sessions
|
|
--source include/count_sessions.inc
|
|
|
|
--disable_warnings
|
|
drop table if exists t1, t2;
|
|
--enable_warnings
|
|
create table t1 (a int) engine=innodb;
|
|
xa start 'test1';
|
|
insert t1 values (10);
|
|
xa end 'test1';
|
|
xa prepare 'test1';
|
|
xa rollback 'test1';
|
|
select * from t1;
|
|
|
|
xa start 'test2';
|
|
--error ER_XAER_RMFAIL
|
|
xa start 'test-bad';
|
|
insert t1 values (20);
|
|
--error ER_XAER_RMFAIL
|
|
xa prepare 'test2';
|
|
xa end 'test2';
|
|
xa prepare 'test2';
|
|
xa commit 'test2';
|
|
select * from t1;
|
|
|
|
xa start 'testa','testb';
|
|
insert t1 values (30);
|
|
|
|
--error ER_XAER_RMFAIL
|
|
commit;
|
|
|
|
xa end 'testa','testb';
|
|
|
|
--error ER_XAER_RMFAIL
|
|
begin;
|
|
--error ER_XAER_RMFAIL
|
|
create table t2 (a int);
|
|
|
|
connect (con1,localhost,root,,);
|
|
connection con1;
|
|
|
|
--error ER_XAER_DUPID
|
|
xa start 'testa','testb';
|
|
--error ER_XAER_DUPID
|
|
xa start 'testa','testb', 123;
|
|
|
|
# gtrid [ , bqual [ , formatID ] ]
|
|
xa start 0x7465737462, 0x2030405060, 0xb;
|
|
insert t1 values (40);
|
|
xa end 'testb',' 0@P`',11;
|
|
xa prepare 'testb',0x2030405060,11;
|
|
|
|
--error ER_XAER_RMFAIL
|
|
start transaction;
|
|
|
|
xa recover;
|
|
|
|
# uncomment the line below when binlog will be able to prepare
|
|
#disconnect con1;
|
|
connection default;
|
|
|
|
xa prepare 'testa','testb';
|
|
|
|
xa recover;
|
|
|
|
--error ER_XAER_NOTA
|
|
xa commit 'testb',0x2030405060,11;
|
|
xa rollback 'testa','testb';
|
|
|
|
--error ER_PARSE_ERROR
|
|
xa start 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz';
|
|
|
|
select * from t1;
|
|
|
|
disconnect con1;
|
|
connection default;
|
|
drop table t1;
|
|
|
|
#
|
|
# Bug#28323: Server crashed in xid cache operations
|
|
#
|
|
|
|
--disable_warnings
|
|
drop table if exists t1;
|
|
--enable_warnings
|
|
|
|
create table t1(a int, b int, c varchar(20), primary key(a)) engine = innodb;
|
|
insert into t1 values(1, 1, 'a');
|
|
insert into t1 values(2, 2, 'b');
|
|
|
|
connect (con1,localhost,root,,);
|
|
connect (con2,localhost,root,,);
|
|
|
|
--connection con1
|
|
xa start 'a','b';
|
|
update t1 set c = 'aa' where a = 1;
|
|
--connection con2
|
|
xa start 'a','c';
|
|
update t1 set c = 'bb' where a = 2;
|
|
--connection con1
|
|
--send update t1 set c = 'bb' where a = 2
|
|
--connection con2
|
|
--sleep 1
|
|
--error ER_LOCK_DEADLOCK
|
|
update t1 set c = 'aa' where a = 1;
|
|
select count(*) from t1;
|
|
--error ER_XA_RBDEADLOCK
|
|
xa end 'a','c';
|
|
xa rollback 'a','c';
|
|
--disconnect con2
|
|
|
|
connect (con3,localhost,root,,);
|
|
--connection con3
|
|
xa start 'a','c';
|
|
|
|
--disconnect con1
|
|
--disconnect con3
|
|
--connection default
|
|
drop table t1;
|
|
|
|
--echo End of 5.0 tests
|
|
|
|
#
|
|
# Bug#44672: Assertion failed: thd->transaction.xid_state.xid.is_null()
|
|
#
|
|
|
|
xa start 'a';
|
|
xa end 'a';
|
|
xa rollback 'a';
|
|
xa start 'a';
|
|
xa end 'a';
|
|
xa rollback 'a';
|
|
|
|
#
|
|
# Bug#45548: XA transaction without access to InnoDB tables crashes the server
|
|
#
|
|
|
|
xa start 'a';
|
|
xa end 'a';
|
|
xa prepare 'a';
|
|
xa commit 'a';
|
|
|
|
xa start 'a';
|
|
xa end 'a';
|
|
xa prepare 'a';
|
|
xa commit 'a';
|
|
|
|
#
|
|
# BUG#43171 - Assertion failed: thd->transaction.xid_state.xid.is_null()
|
|
#
|
|
CREATE TABLE t1(a INT, KEY(a)) ENGINE=InnoDB;
|
|
INSERT INTO t1 VALUES(1),(2);
|
|
connect(con1,localhost,root,,);
|
|
|
|
# Part 1: Prepare to test XA START after regular transaction deadlock
|
|
BEGIN;
|
|
UPDATE t1 SET a=3 WHERE a=1;
|
|
|
|
connection default;
|
|
BEGIN;
|
|
UPDATE t1 SET a=4 WHERE a=2;
|
|
|
|
connection con1;
|
|
let $conn_id= `SELECT CONNECTION_ID()`;
|
|
SEND UPDATE t1 SET a=5 WHERE a=2;
|
|
|
|
connection default;
|
|
let $wait_timeout= 2;
|
|
let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
|
|
WHERE ID=$conn_id AND STATE='Searching rows for update';
|
|
--source include/wait_condition.inc
|
|
|
|
--error ER_LOCK_DEADLOCK
|
|
UPDATE t1 SET a=5 WHERE a=1;
|
|
ROLLBACK;
|
|
|
|
# Part 2: Prepare to test XA START after XA transaction deadlock
|
|
connection con1;
|
|
REAP;
|
|
ROLLBACK;
|
|
BEGIN;
|
|
UPDATE t1 SET a=3 WHERE a=1;
|
|
|
|
connection default;
|
|
XA START 'xid1';
|
|
UPDATE t1 SET a=4 WHERE a=2;
|
|
|
|
connection con1;
|
|
SEND UPDATE t1 SET a=5 WHERE a=2;
|
|
|
|
connection default;
|
|
let $wait_timeout= 2;
|
|
let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
|
|
WHERE ID=$conn_id AND STATE='Searching rows for update';
|
|
--source include/wait_condition.inc
|
|
|
|
--error ER_LOCK_DEADLOCK
|
|
UPDATE t1 SET a=5 WHERE a=1;
|
|
--error ER_XA_RBDEADLOCK
|
|
XA END 'xid1';
|
|
XA ROLLBACK 'xid1';
|
|
|
|
XA START 'xid1';
|
|
XA END 'xid1';
|
|
XA ROLLBACK 'xid1';
|
|
|
|
disconnect con1;
|
|
DROP TABLE t1;
|
|
|
|
# Wait till all disconnects are completed
|
|
--source include/wait_until_count_sessions.inc
|
|
|