2012-04-24 69 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

有趣的是,'問題'是我試圖直接鎖定表兩次,似乎並沒有填充該表。我將其更改爲兩個互相干擾的交易,並按預期工作。