2012-04-24 2 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'? –

+0

Привет - да, они определенно настроены (мне нужно открыть второе соединение для выдачи второй команды LOCK - если бы не было допущено, что второй LOCK завершится с ошибкой). Благодаря! –

ответ

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, и взаимоблокировки могут очень легко произойти. InnoDB вообще не получает внутреннюю блокировку таблицы, если autocommit = 1, чтобы помочь старым приложениям избежать ненужных взаимоблокировок.

Также проверьте эту часть документации (последние 2 абзаца): Locks Set by Different SQL Statements in InnoDB:

LOCK TABLES наборы блокировок таблиц, но чем выше слой MySQL над слоем InnoDB, который устанавливает эти блокировки. InnoDB знает о блокировке таблицы, еслиinnodb_table_locks = 1 (по умолчанию) и autocommit = 0, а уровень MySQL выше InnoDB знает о блокировках на уровне строк.

+0

Спасибо за ваш ответ. Я просто установил autocommit = 0 и повторно выполнил свой тестовый пример - без успеха. Таблицы по-прежнему пусты. –

1

Интересно, что «проблема» заключалась в том, что я пытался заблокировать таблицу непосредственно дважды, что, похоже, не заполняет эту таблицу. Я изменил его на две транзакции, мешающие друг другу, и он работал, как ожидалось.

Смежные вопросы