Модераторы: skyboy
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> InnoDB: проблема взаимной блокировки ХП, [помогите с дедлоками] 
:(
    Опции темы
leniviy
Дата 14.1.2009, 11:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: нет
Всего: 5



Привет. Я только недавно начал работать с MySQL. Сейчас делаю процедуру подсчета статистики.

Все таблицы в базе на движке innodb.
1 поток начинает транзакцию и построчно вставляет в таблицу 100 000 строк, затем коммитит;
во втором потоке во время этой транзакции вызывается хранимая процедура, которая пытается выбрать часть строк из этой таблицы по условию, сгруппировать и вставить в другую таблицу. Затем удаляет выбранные строки.

Оба потока зависают на 50 секунд, потом во втором потоке вылазит:
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

В коде процедуры есть проверка: в самом начале выбирается max(id) from таблица и потом используется в условии where id <= @maxid, чтобы новые записи не попадали в выборку. Но это не помогает.
Если в коде процедуры закоментировать строку "insert into...", то данные возвращаются пользователю, и ничего не зависает. Еще можно выбирать данные в переменною. Зависает только когда я пытаюсь вставить результат запроса в другую таблицу. (та другая таблица точно никем не заблокирована). 

После того, как начал вылазить lock timeout, в начале процедуры я добавил: 
Код

declare continue handler for 1205 begin
    rollback;
    IF @selectflag=1 THEN 
        select 'lock timeout' as msg;
    END IF;
    set @retry:=1;
    SET @X:= SLEEP(150);
    IF @selectflag=1 THEN 
        select 'retrying' as msg;
    END IF;
end;


Этот код должен был предотвратить завершение процедуры и позволить первому потоку завершить транзакцию. Он действительно несколько раз отлавливает Lock wait timeout, но через несколько итераций, если таблица всё еще заблокирована, процедура вылетает с той же ошибкой. Я заметил, что, вроде бы, lock timeout отлавливается, если он возник на операции insert, и не отлавливает если insert прошел успешно, а ошибка вылезла на delete. (и insert и delete выполняются в одной транзакции).

1) Почему зависает только при вставке в другую таблицу, но не зависает при простой выборке? Может дело в isolation level?
2) Можно ли в начале процедуры проверить, что таблица заблокирована, не ожидая 50 секунд, и отложить операцию с помощью SLEEP()?
3) Почему "declare continue handler for 1205" иногда срабатывает, а иногда нет?

Версия MySQL 5.0.18-nt.

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MySQL | Следующая тема »


 




[ Время генерации скрипта: 0.0372 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.