Reputation: 301
I create a dummy table:
CREATE TABLE `lock_test` (
`name` varchar(32) NOT NULL,
PRIMARY KEY (`name`)
) ENGINE=InnoDB ;
I lock it:
LOCK TABLE lock_test write;
Then I try to lock it again (same query). The second lock request obviously just hangs there.
select * from INFORMATION_SCHEMA.INNODB_LOCKS;
select * from INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
Are both empty (return zero results) - I would have expected them to be populated. I have PROCESS
permission (showing PROCESSLIST
shows the lock working).
Do I have the complete wrong end of the stick with regards to these tables? The Information Schema plugins and the InnoDB engine are definitely installed (Checked by running SHOW PLUGINS;).
Thanks
Upvotes: 2
Views: 1727
Reputation: 301
Interestingly - the 'issue' was me trying to lock the table directly twice, which doesn't seem to populate that table. I changed it to two transactions interfering with each other, and it worked as expected.
Upvotes: 1
Reputation: 115630
Do you have autocommit = 1
? If yes, that's the reason. There are two types of locks, taken at different layers, one at the MySQL layer and one at the storage engine (InnoDB) layer.
From MySQL docs, Interaction of Table Locking and Transactions:
When you call
LOCK TABLES
, InnoDB internally takes its own table lock, and MySQL takes its own table lock. InnoDB releases its internal table lock at the next commit, but for MySQL to release its table lock, you have to callUNLOCK TABLES
. You should not haveautocommit = 1
, because then InnoDB releases its internal table lock immediately after the call ofLOCK TABLES
, and deadlocks can very easily happen. InnoDB does not acquire the internal table lock at all ifautocommit = 1
, to help old applications avoid unnecessary deadlocks.
Also check this part of the docs (last 2 paragraphs): Locks Set by Different SQL Statements in InnoDB:
LOCK TABLES
sets table locks, but it is the higher MySQL layer above the InnoDB layer that sets these locks. InnoDB is aware of table locks ifinnodb_table_locks = 1
(the default) andautocommit = 0
, and the MySQL layer above InnoDB knows about row-level locks.
Upvotes: 0