2008-12-16 12:44:18 +01:00
|
|
|
-- source include/have_partition.inc
|
|
|
|
-- source include/not_embedded.inc
|
|
|
|
-- source include/have_innodb.inc
|
|
|
|
|
|
|
|
--disable_warnings
|
|
|
|
drop table if exists t1;
|
|
|
|
--enable_warnings
|
|
|
|
|
|
|
|
# basic tests of semi-consistent reads
|
|
|
|
# for verifying Bug#40595: Non-matching rows not released with READ-COMMITTED
|
|
|
|
# on tables with partitions
|
|
|
|
|
|
|
|
connect (a,localhost,root,,);
|
|
|
|
connect (b,localhost,root,,);
|
|
|
|
connection a;
|
|
|
|
set binlog_format=mixed;
|
2009-01-13 23:12:16 +01:00
|
|
|
set session transaction isolation level repeatable read;
|
2008-12-16 12:44:18 +01:00
|
|
|
create table t1(a int not null)
|
|
|
|
engine=innodb
|
|
|
|
DEFAULT CHARSET=latin1
|
|
|
|
PARTITION BY RANGE(a)
|
|
|
|
(PARTITION p0 VALUES LESS THAN (20),
|
|
|
|
PARTITION p1 VALUES LESS THAN MAXVALUE);
|
|
|
|
insert into t1 values (1),(2),(3),(4),(5),(6),(7);
|
|
|
|
set autocommit=0;
|
|
|
|
# this should lock the entire table
|
|
|
|
select * from t1 where a=3 lock in share mode;
|
|
|
|
connection b;
|
|
|
|
set binlog_format=mixed;
|
2009-01-13 23:12:16 +01:00
|
|
|
set session transaction isolation level repeatable read;
|
2008-12-16 12:44:18 +01:00
|
|
|
set autocommit=0;
|
|
|
|
-- error ER_LOCK_WAIT_TIMEOUT
|
|
|
|
update t1 set a=10 where a=5;
|
|
|
|
connection a;
|
|
|
|
#DELETE FROM t1 WHERE a=5;
|
|
|
|
commit;
|
|
|
|
connection b;
|
2009-01-13 23:12:16 +01:00
|
|
|
# perform a semi-consisent read (and unlock non-matching rows)
|
|
|
|
set session transaction isolation level read committed;
|
2008-12-16 12:44:18 +01:00
|
|
|
update t1 set a=10 where a=5;
|
|
|
|
connection a;
|
|
|
|
-- error ER_LOCK_WAIT_TIMEOUT
|
|
|
|
select * from t1 where a=2 for update;
|
|
|
|
# this should lock the records (1),(2)
|
|
|
|
select * from t1 where a=2 limit 1 for update;
|
|
|
|
connection b;
|
2009-01-13 23:12:16 +01:00
|
|
|
# semi-consistent read will skip non-matching locked rows a=1, a=2
|
2008-12-16 12:44:18 +01:00
|
|
|
update t1 set a=11 where a=6;
|
|
|
|
-- error ER_LOCK_WAIT_TIMEOUT
|
|
|
|
update t1 set a=12 where a=2;
|
|
|
|
-- error ER_LOCK_WAIT_TIMEOUT
|
|
|
|
update t1 set a=13 where a=1;
|
|
|
|
connection a;
|
|
|
|
commit;
|
|
|
|
connection b;
|
|
|
|
update t1 set a=14 where a=1;
|
|
|
|
commit;
|
|
|
|
connection a;
|
|
|
|
--sorted_result
|
|
|
|
select * from t1;
|
|
|
|
drop table t1;
|
|
|
|
|
|
|
|
connection default;
|
|
|
|
disconnect a;
|
|
|
|
disconnect b;
|
|
|
|
|
|
|
|
#
|
|
|
|
# Bug #31310: Locked rows silently skipped in read-committed isolation level.
|
|
|
|
# (This also tests the '*_semi_consistent*' functions in partitioning)
|
|
|
|
# Copied from include/mix1.inc
|
|
|
|
|
|
|
|
connect (con1,localhost,root,,);
|
|
|
|
connect (con2,localhost,root,,);
|
|
|
|
SET SESSION AUTOCOMMIT = 0;
|
|
|
|
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
|
|
|
set binlog_format=mixed;
|
|
|
|
--echo # Switch to connection con1
|
|
|
|
connection con1;
|
|
|
|
|
|
|
|
eval
|
|
|
|
CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(256))
|
|
|
|
ENGINE = InnoDB
|
|
|
|
PARTITION BY RANGE (a)
|
|
|
|
(PARTITION p0 VALUES LESS THAN (300),
|
|
|
|
PARTITION p1 VALUES LESS THAN MAXVALUE);
|
|
|
|
INSERT INTO t1 VALUES (1,2);
|
|
|
|
|
|
|
|
--echo # 1. test for locking:
|
|
|
|
|
|
|
|
BEGIN;
|
|
|
|
--enable_info
|
|
|
|
UPDATE t1 SET b = 12 WHERE a = 1;
|
|
|
|
--disable_info
|
|
|
|
SELECT * FROM t1;
|
|
|
|
|
|
|
|
--echo # Switch to connection con2
|
|
|
|
connection con2;
|
|
|
|
|
|
|
|
--enable_info
|
|
|
|
--disable_abort_on_error
|
|
|
|
--error ER_LOCK_WAIT_TIMEOUT
|
|
|
|
UPDATE t1 SET b = 21 WHERE a = 1;
|
|
|
|
--disable_info
|
|
|
|
|
|
|
|
--echo # Switch to connection con1
|
|
|
|
connection con1;
|
|
|
|
SELECT * FROM t1;
|
|
|
|
ROLLBACK;
|
|
|
|
|
|
|
|
--echo # 2. test for serialized update:
|
|
|
|
|
|
|
|
CREATE TABLE t2 (a INT);
|
|
|
|
|
|
|
|
TRUNCATE t1;
|
|
|
|
INSERT INTO t1 VALUES (1,'init');
|
|
|
|
|
|
|
|
DELIMITER |;
|
|
|
|
CREATE PROCEDURE p1()
|
|
|
|
BEGIN
|
|
|
|
UPDATE t1 SET b = CONCAT(b, '+con2') WHERE a = 1;
|
|
|
|
INSERT INTO t2 VALUES ();
|
|
|
|
END|
|
|
|
|
DELIMITER ;|
|
|
|
|
|
|
|
|
BEGIN;
|
|
|
|
--enable_info
|
|
|
|
UPDATE t1 SET b = CONCAT(b, '+con1') WHERE a = 1;
|
|
|
|
--disable_info
|
|
|
|
SELECT * FROM t1;
|
|
|
|
|
|
|
|
--echo # Switch to connection con2
|
|
|
|
connection con2;
|
|
|
|
|
|
|
|
--send CALL p1;
|
|
|
|
|
|
|
|
--echo # Switch to connection con1
|
|
|
|
connection con1;
|
|
|
|
SELECT * FROM t1;
|
|
|
|
COMMIT;
|
|
|
|
|
|
|
|
let $bug31310 = 1;
|
|
|
|
while ($bug31310)
|
|
|
|
{
|
|
|
|
let $bug31310= `SELECT 1 - COUNT(*) FROM t2`;
|
|
|
|
}
|
|
|
|
|
|
|
|
SELECT * FROM t1;
|
|
|
|
|
|
|
|
--echo # Switch to connection con2
|
|
|
|
connection con2;
|
|
|
|
--reap
|
|
|
|
SELECT * FROM t1;
|
|
|
|
|
|
|
|
--echo # Switch to connection con1
|
|
|
|
connection con1;
|
|
|
|
|
|
|
|
--echo # 3. test for updated key column:
|
|
|
|
|
|
|
|
TRUNCATE t1;
|
Backport of revno ## 2617.31.1, 2617.31.3, 2617.31.4, 2617.31.5,
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.
2009-12-05 02:02:48 +03:00
|
|
|
DELETE FROM t2;
|
2008-12-16 12:44:18 +01:00
|
|
|
|
|
|
|
INSERT INTO t1 VALUES (1,'init');
|
|
|
|
|
|
|
|
BEGIN;
|
|
|
|
--enable_info
|
|
|
|
UPDATE t1 SET a = 2, b = CONCAT(b, '+con1') WHERE a = 1;
|
|
|
|
--disable_info
|
|
|
|
SELECT * FROM t1;
|
|
|
|
|
|
|
|
--echo # Switch to connection con2
|
|
|
|
connection con2;
|
|
|
|
|
|
|
|
--send CALL p1;
|
|
|
|
|
|
|
|
--echo # Switch to connection con1
|
|
|
|
connection con1;
|
|
|
|
SELECT * FROM t1;
|
|
|
|
COMMIT;
|
|
|
|
|
|
|
|
let $bug31310 = 1;
|
|
|
|
while ($bug31310)
|
|
|
|
{
|
|
|
|
let $bug31310= `SELECT 1 - COUNT(*) FROM t2`;
|
|
|
|
}
|
|
|
|
|
|
|
|
SELECT * FROM t1;
|
|
|
|
|
|
|
|
--echo # Switch to connection con2
|
|
|
|
connection con2;
|
2010-01-07 11:22:45 +01:00
|
|
|
reap;
|
2008-12-16 12:44:18 +01:00
|
|
|
SELECT * FROM t1;
|
|
|
|
|
|
|
|
connection default;
|
|
|
|
disconnect con1;
|
|
|
|
disconnect con2;
|
|
|
|
DROP PROCEDURE p1;
|
|
|
|
DROP TABLE t1, t2;
|
|
|
|
|