Задавайте вопросы, мы ответим
Вы не зашли.
Бодрое время суток!
Есть таблица InnoDB, в которой происходят частые апдейты. Не редко возникает ошибка:
Deadlock found when trying to get lock; try restarting transaction
Вопроса два:
1. Кто такой deadlock и с чем его едят? Своими словами плз
2. Обновились ли значения полей при генерации такой ошибки?
ЗЫ Раньше таблица была MyISAM, но из-за частых апдейтов порою достучаться до неё было проблематично, потому конвертнули в InnoDB и имеем теперь другие грабли.
Неактивен
1. Своими словами: клиент А заблокировал строку №1, а клиент В строку №2. Для завершения транзакции клиенту А нужно изменить значение в строке №2, а В в №1.
Неактивен
Хм, очень интересная ситуация... А как может быть такая проблема, если строки независимы между собой? Все апдейты последовательны, пересечений не наблюдается. Не думаю, что проблема связана с индексами...
Неактивен
Если каждое изменение делать в своей транзакции (например, не начинать
транзакции явно), то проблема исчезнет. Искать «BEGIN» или «START TRANSACTION».
Неактивен
paulus написал:
Если каждое изменение делать в своей транзакции (например, не начинать
транзакции явно), то проблема исчезнет.
Пардон, но кажися тут противоречие Предлагаете апдейты запускать в транзакциях? Сейчас они выполняются одним апдейтовым запросом и при этом основная масса апдейтов выполняется успешно.
Неактивен
Вы в любом случае запускаете в транзакциях. Я предлагаю не начинать их явно
так, чтобы каждое обновление проходило в одной короткой транзакции.
Неактивен
Слово "явно" я понимаю как "с использованием START TRANSACTION", всё остальное (на уровне движка базы) вроде как наоборот, неявно. Собственно этим я сбит с толку и не могу понять как же всё-таки нужно выполнять запрос: с вызовом транзакции "вручную" или без него?
Неактивен
Одиночные обновления таблиц, каждая в своей транзакции, не могут сделал
deadlock по той причине, что обращаются внутри транзакции максимум к одной
таблице. Варианта два — или у Вас не точечные транзакции, или есть запросы
вида INSERT INTO b SELECT … FROM a; INSERT INTO a SELECT … FROM b.
Неактивен
Это вполне логично, собственно по тому и бучу поднял Вот пример запроса:
Отредактированно Neval (23.12.2009 21:36:27)
Неактивен
Ну, Вы сами сказали, что у Вас есть триггер, который идет в другую таблицу что-то изменять.
Значит, у Вас как раз тот случай. Попробуйте сконвертировать вторую табличку тоже в InnoDB,
может помочь.
Неактивен
Так триггер же просто удаляет записи из проблемной таблицы и даже не вызывается если в этой таблице что-то происходит, он же привязан к другой таблице...
Неактивен
Но удаляет то в этой таблице?
Неактивен
Удаляет - да Хотите сказать, что он может удалять в момент апдейтов?
Возник вопрос по InnoDB. Сегодня обнаружилось, что не отработал запрос инсерта на вставку 17 тысяч записей. При чём как-то странно, функция вызова запроса не вернула ошибку, но тем не менее результата запроса нету. Отсюда вопрос, есть ли лимит на количество вставок для одного запроса? При MyISAM проблемы не наблюдалось.
Неактивен
Ошибка должна была вернуться (ну, кроме случая INSERT DELAYED). Скорее всего,
проблема в приложении, которое не отработало ошибку (или, например, не отработало
оборвавшееся соединение). Т.е. нужно уметь отличать «ничего не вернулось»
(=ошибка) от «вернулся ответ успешной операции».
Неактивен
После выполнения запроса, приложение всегда проверяет результат PHP функции mysql_errno (). Если результата нет, значит и ошибки нет. Или данный подход не достаточен для определния успешного выполнения запроса? Тут я сам немного confused (пардон, не могу подобрать соответствующее русское слово), как-то на полтергейтс смахивает... В приложении идёт обычное ветвление:
if (выполнение_запроса) {
что-то делаем
}
При этом выполнился код в блоке. Данная конструкция работает уже 3 года, первая проблема возникла сегодня, потому подозреваю, что это связано с типом таблицы InnoDB.
Да, ещё хочу отметить, что триггер удаления вызывается пару раз в год, в лучшем случае :\
Неактивен
Значит, это не триггер удаления, раз он не срабатывает
mysql_errno() должно быть достаточно; можете придумать
testcase, в котором бы не вставлялись 17к строк и при этом
возвращался бы ноль в errno?
Неактивен
Про триггер я имел ввиду, что записи из первой таблицы удаляются очень-очень редко, потому он и не вызывается почти, что исключает совпадение его вызова и апдейтов
Конечно плохо когда проблема не решена, но всё же вернёмся пока к MyISAM, время дороже...
можете придумать
testcase, в котором бы не вставлялись 17к строк и при этом
возвращался бы ноль в errno?
Я могу сформировать тот же запрос на 17к строк, но уверен, в этот раз он отработает нормально
Неактивен