2012-04-24 79 views
2

我创建一个虚拟表:MySQL的INFORMATION_SCHEMA表不填充

CREATE TABLE `lock_test` (
    `name` varchar(32) NOT NULL, 
    PRIMARY KEY (`name`) 
) ENGINE=InnoDB ; 

我锁定:

LOCK TABLE lock_test write; 

然后我尝试再次锁定(同查询)。第二个锁定请求显然只是挂在那里。

select * from INFORMATION_SCHEMA.INNODB_LOCKS; 
select * from INFORMATION_SCHEMA.INNODB_LOCK_WAITS; 

都是空的(返回零结果) - 我会期望他们被填充。我有PROCESS权限(显示PROCESSLIST显示锁定工作)。

对于这些表格,我有没有完全错误的结束?信息模式插件和InnoDB引擎肯定是安装的(通过运行SHOW PLUGINS进行检查;)。

感谢

+0

你有'autocommit = 1'吗? – 2012-04-25 00:41:30

+0

嗨 - 是的,他们肯定是承诺(我必须打开第二个连接来发出第二个LOCK命令 - 如果它没有提交第二个LOCK会失败)。谢谢! – 2012-04-25 01:31:22

回答

0

你有autocommit = 1?如果是,那就是原因。有两种类型的锁,分别位于不同的层,一个位于MySQL层,一个位于存储引擎(InnoDB)层。

从MySQL的文档,Interaction of Table Locking and Transactions

当你调用LOCK TABLES,InnoDB的内部需要它自己的表锁,和MySQL取其自己的表锁。 InnoDB在下次提交时释放内部表锁,但是为了释放其表锁,MySQL必须调用UNLOCK TABLES。你不应该有autocommit = 1,因为然后InnoDB在LOCK TABLES的调用后立即释放它的内部表锁,并且死锁很容易发生。如果autocommit = 1 InnoDB完全不获取内部表锁,以帮助旧应用程序避免不必要的死锁。

同时检查文档(最后2个段落)的这一部分:Locks Set by Different SQL Statements in InnoDB

LOCK TABLES集表锁,但它是设置这些锁InnoDB的层之上的更高的MySQL层。 InnoDB知道表锁如果innodb_table_locks = 1(默认)和autocommit = 0,并且InnoDB上面的MySQL层知道行级锁。

+0

感谢您的回答。我只是设置autocommit = 0,并重新运行我的测试用例 - 没有成功。表格仍然是空的。 – 2012-04-25 02:53:47

1

有趣的是,'问题'是我试图直接锁定表两次,似乎并没有填充该表。我将其更改为两个互相干扰的交易,并按预期工作。