Bug #57174 UNLOCK TABLES does not release transactional locks
Submitted: 1 Oct 2010 14:00 Modified: 4 Apr 2011 19:08
Reporter: Konstantin Osipov (OCA) Email Updates:
Status: Won't fix Impact on me:
None 
Category:MySQL Server: Locking Severity:S3 (Non-critical)
Version:mysql-next-mr-wl3561, 5.6.99 OS:Any
Assigned to: CPU Architecture:Any

[1 Oct 2010 14:00] Konstantin Osipov
Description:
Contrary to the common sense expectation, UNLOCK TABLES does not release
transactional locks.

I.e.:
mysql> drop table t1;
Query OK, 0 rows affected (0.01 sec)

mysql> create table t1 (a int) engine=innodb;
Query OK, 0 rows affected (0.00 sec)

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> lock table t1 in share mode;
Query OK, 0 rows affected (0.00 sec)

mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)

-- in another connection:
mysql> drop table t1;
-- (hangs)

If you issue COMMIT in the first connection, DROP TABLE goes through.

Strictly speaking, this is not a bug, because WL#3561 specification
says in one place:
--quote
UNLOCK TABLE works exactly as before, no changes.
--end quote

However, the specification contradicts itself, because it says 
in another place:
--quote
Current behaviour:
UNLOCK TABLE automatically commits a transaction
--end quote

The assumption made in the spec, that UNLOCK TABLES automatically commits a transaction is incorrect. In reality, this is only done if there were LOCK TABLE READ|WRITE locks (i.e. non-transactional locks). UNLOCK TABLES is also used to release locks taken for FLUSH TABLES WITH READ LOCK, and for this statement, it does not commit a transaction (this is documented).

To sum up, the only reliable way to release transactional locks in WL#3561 
is COMMIT/ROLLBACK.

How to repeat:
drop table t1;

create table t1 (a int) engine=innodb;

begin;

lock table t1 in share mode;
unlock tables;

-- in another connection:
drop table t1;
-- (hangs)

Suggested fix:
At least fix the test case to not issue UNLOCK TABLES all over the place, they are useless.
Then there are two choices:
- make sure UNLOCK TABLES commits a transaction if there are transactional locks. This is dangerous, I would not recommend it, since you can take transactional locks after FLUSH TABLES WITH READ LOCK, and UNLOCK TABLES is already documented to *not* commit a transaction if done after FLUSH TABLES WITH READ LCOK.
- document that UNLOCK TABLES does not release transactional locks, and COMMIT|ROLLBACK should be used instead. 

A side note on the second approach: the whole idea with implicit lock conversion sounds questionable, since to release transactional and non-transactional locks a user has to use different syntax. People will be forced to write COMMIT; UNLOCK TABLES; to make sure all locks are released, even those that were implicitly converted, and this looks ugly.
[1 Oct 2010 17:22] Valeriy Kravchuk
Verified with current mysql-next-mr-wl3561 tree on Mac OS X.
[4 Apr 2011 19:08] Dmitry Lenev
Since was bug was reported against feature tree for WL#3561 "Transactional LOCK TABLES" and this worklog got cancelled I am closing this bug as "Won't fix".