SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 20.12.2009 16:35:51

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Ошибка с deadlock

Бодрое время суток!
Есть таблица InnoDB, в которой происходят частые апдейты. Не редко возникает ошибка:
Deadlock found when trying to get lock; try restarting transaction

Вопроса два:
1. Кто такой deadlock и с чем его едят? Своими словами плз wink
2. Обновились ли значения полей при генерации такой ошибки?

ЗЫ Раньше таблица была MyISAM, но из-за частых апдейтов порою достучаться до неё было проблематично, потому конвертнули в InnoDB и имеем теперь другие грабли.


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#2 20.12.2009 22:33:20

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Ошибка с deadlock

1. Своими словами: клиент А заблокировал строку №1, а клиент В строку №2. Для завершения транзакции клиенту А нужно изменить значение в строке №2, а В в №1.

Неактивен

 

#3 21.12.2009 15:48:54

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Ошибка с deadlock

Хм, очень интересная ситуация... А как может быть такая проблема, если строки независимы между собой? Все апдейты последовательны, пересечений не наблюдается. Не думаю, что проблема связана с индексами...


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#4 22.12.2009 17:05:26

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Ошибка с deadlock

Если каждое изменение делать в своей транзакции (например, не начинать
транзакции явно), то проблема исчезнет. Искать «BEGIN» или «START TRANSACTION».

Неактивен

 

#5 22.12.2009 19:14:33

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Ошибка с deadlock

paulus написал:

Если каждое изменение делать в своей транзакции (например, не начинать
транзакции явно), то проблема исчезнет.

Пардон, но кажися тут противоречие smile Предлагаете апдейты запускать в транзакциях? Сейчас они выполняются одним апдейтовым запросом и при этом основная масса апдейтов выполняется успешно.


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#6 23.12.2009 16:55:15

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Ошибка с deadlock

Вы в любом случае запускаете в транзакциях. Я предлагаю не начинать их явно
так, чтобы каждое обновление проходило в одной короткой транзакции.

Неактивен

 

#7 23.12.2009 17:23:05

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Ошибка с deadlock

Слово "явно" я понимаю как "с использованием START TRANSACTION", всё остальное (на уровне движка базы) вроде как наоборот, неявно. Собственно этим я сбит с толку и не могу понять как же всё-таки нужно выполнять запрос: с вызовом транзакции "вручную" или без него? smile


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#8 23.12.2009 21:00:58

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Ошибка с deadlock

Одиночные обновления таблиц, каждая в своей транзакции, не могут сделал
deadlock по той причине, что обращаются внутри транзакции максимум к одной
таблице. Варианта два — или у Вас не точечные транзакции, или есть запросы
вида INSERT INTO b SELECT … FROM a; INSERT INTO a SELECT … FROM b.

Неактивен

 

#9 23.12.2009 21:35:27

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Ошибка с deadlock

Это вполне логично, собственно по тому и бучу поднял smile Вот пример запроса:

UPDATE `sms_numbers` SET `sms_numbers`.`status`='SENDED' WHERE `sms_numbers`.`sms_id`='657025' AND `sms_numbers`.`route_id`='2' AND `sms_numbers`.`status`='UNSENDED' AND `sms_numbers`.`number_id`='14477'

Собственно ничего сложного, но получаем "Deadlock found when trying to get lock; try restarting transaction". Большинство подобных запросов отрабатывает без проблем.

Раз зашли в тупик, немного добавлю описание БД, может что-то подтолкнёт на мысль, хотя вроде как зависимостей нет.
Есть две таблицы: `sms` (MyISAM) и `sms_numbers` (InnoDB). В таблице `sms` прописан триггер на удаление соответствующих записей из таблицы `sms_numbers`, т.е. с условием `sms_numbers`.`sms_id`=`sms`.`id`. Поле `sms_id` находится в многостолбцовом индексе вместе с полем `status`.

Собственно на этом доп.инфо заканчивается smile ИМХО, никаких зависимости и связей по сабжу не имеется. Новые мысли имеются? ПамажЫте кто чем может big_smile В крайнем случае придётся вернуться обратно к MyISAM smile

Отредактированно Neval (23.12.2009 21:36:27)


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#10 24.12.2009 17:41:33

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Ошибка с deadlock

Ну, Вы сами сказали, что у Вас есть триггер, который идет в другую таблицу что-то изменять.
Значит, у Вас как раз тот случай. Попробуйте сконвертировать вторую табличку тоже в InnoDB,
может помочь.

Неактивен

 

#11 24.12.2009 18:29:06

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Ошибка с deadlock

Так триггер же просто удаляет записи из проблемной таблицы и даже не вызывается если в этой таблице что-то происходит, он же привязан к другой таблице...


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#12 24.12.2009 19:33:22

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Ошибка с deadlock

Но удаляет то в этой таблице?

Неактивен

 

#13 24.12.2009 20:51:24

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Ошибка с deadlock

Удаляет - да smile Хотите сказать, что он может удалять в момент апдейтов? smile

Возник вопрос по InnoDB. Сегодня обнаружилось, что не отработал запрос инсерта на вставку 17 тысяч записей. При чём как-то странно, функция вызова запроса не вернула ошибку, но тем не менее результата запроса нету. Отсюда вопрос, есть ли лимит на количество вставок для одного запроса? При MyISAM проблемы не наблюдалось.


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#14 24.12.2009 21:20:49

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Ошибка с deadlock

Ошибка должна была вернуться (ну, кроме случая INSERT DELAYED). Скорее всего,
проблема в приложении, которое не отработало ошибку (или, например, не отработало
оборвавшееся соединение). Т.е. нужно уметь отличать «ничего не вернулось»
(=ошибка) от «вернулся ответ успешной операции».

Неактивен

 

#15 24.12.2009 21:37:36

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Ошибка с deadlock

После выполнения запроса, приложение всегда проверяет результат PHP функции mysql_errno (). Если результата нет, значит и ошибки нет. Или данный подход не достаточен для определния успешного выполнения запроса? Тут я сам немного confused (пардон, не могу подобрать соответствующее русское слово), как-то на полтергейтс смахивает... В приложении идёт обычное ветвление:

if (выполнение_запроса) {
что-то делаем
}

При этом выполнился код в блоке. Данная конструкция работает уже 3 года, первая проблема возникла сегодня, потому подозреваю, что это связано с типом таблицы InnoDB.

Да, ещё хочу отметить, что триггер удаления вызывается пару раз в год, в лучшем случае :\


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#16 24.12.2009 21:47:19

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Ошибка с deadlock

Значит, это не триггер удаления, раз он не срабатывает smile

mysql_errno() должно быть достаточно; можете придумать
testcase, в котором бы не вставлялись 17к строк и при этом
возвращался бы ноль в errno?

Неактивен

 

#17 25.12.2009 08:16:26

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Ошибка с deadlock

Про триггер я имел ввиду, что записи из первой таблицы удаляются очень-очень редко, потому он и не вызывается почти, что исключает совпадение его вызова и апдейтов smile

Конечно плохо когда проблема не решена, но всё же вернёмся пока к MyISAM, время дороже...

можете придумать
testcase, в котором бы не вставлялись 17к строк и при этом
возвращался бы ноль в errno?

Я могу сформировать тот же запрос на 17к строк, но уверен, в этот раз он отработает нормально smile


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson