Как решить проблемы с тупиками в движке InnoDB?

Я слышал об этой проблеме и теперь ищу более конкретную информацию?

Как это происходит, каковы причины этого, подробное объяснение механизма возникновения тупика, чтобы попытаться его избежать. Как обнаружить тупик, решить его и защитить данные от порчи из-за него. Так обстоит дело при использовании MySQL с PHP.

И можно ли смешивать InnoDB и MyISAM? Я намереваюсь использовать innoDB для некоторых основных таблиц со многими отношениями, а не с таким большим количеством данных, таких как пользователи, роли, привилегии, компании и т. Д., И использовать MyISAM для таблиц, которые содержат больше данных: данные о клиентах, данные о действиях и т. Д. Я хотел бы использовать только InnoDB, но переход с MyISAM меня немного пугает скоростью и стабильностью. А теперь это тупики :(


person Yasen Zhelev    schedule 18.10.2010    source источник
comment
Не должно возникнуть проблем с переходом с MyISAM на InnoDB, если вам не нужна особая функция MyISAM, такая как полнотекстовый поиск или быстрая полная таблица COUNT(*)s. MyISAM НЕ быстрее InnoDB, и InnoDB не быстрее MyISAM. Один работает лучше в одном случае, другой - в другом. Я фактически перешел на InnoDB, потому что он был более производительным для таблиц с большим количеством операций записи, потому что он использовал блокировку на уровне строк вместо блокировки на уровне таблиц MyISAM. Итак, если вам не нужна какая-либо специфическая функция MyISAM, не бойтесь переключаться;)   -  person NikiC    schedule 18.10.2010
comment
как насчет тупика, который может быть моей главной болью в ** я иду на InnoDB. Я использовал этот движок раньше, но никогда не работал с большой БД. Сейчас я работаю над приложением, которое использует много БД (более 40), каждая из которых занимает 10-20 МБ. Это не так уж и много, но данных все же достаточно.   -  person Yasen Zhelev    schedule 18.10.2010


Ответы (1)


Тупиковые ситуации могут возникнуть, если у вас есть два или более независимых запроса, одновременно обращающихся к одним и тем же ресурсам (таблицам / строкам). Пример из реального мира:

На двух машинах работают два механика. В какой-то момент во время ремонта им обоим понадобятся отвертка и молоток, чтобы открутить какую-то сильно застрявшую деталь. Механик А хватает отвертку, механик Б хватает молоток, и теперь никто из них не может продолжить, поскольку второй инструмент, который им нужен, недоступен: они заблокированы.

Теперь люди умны, и один из механиков будет любезным и передаст свой инструмент другому: оба могут продолжать работать. Базы данных несколько глупы, и ни один запрос не будет любезным и разблокирует любой ресурс, вызывающий тупик. На этом этапе СУБД включит Рэмбо и принудительно откатит (или просто убьет) один или несколько взаимно заблокированных запросов. Это позволит продолжить выполнение одного удачного запроса и продолжить получение необходимых ему блокировок / транзакций, и, надеюсь, у прерванных запросов есть достаточно умные приложения, обрабатывающие их, которые позже снова перезапустят транзакции. На старых / более простых СУБД вся система зависала до тех пор, пока администратор базы данных не зашел и не произвел некоторую ручную очистку.

Существует множество способов справиться с тупиками и, в первую очередь, их избежать. Один из важных моментов - никогда не блокировать ресурсы в «случайном» порядке. В случае с нашими механиками оба должны сначала потянуться за отверткой, а затем за молотком. Таким образом, один может успешно работать немедленно, а другой будет знать, что ему нужно ждать.

Что касается смешивания InnodB / MyISAM - MySQL полностью поддерживает смешивание / сопоставление типов таблиц в запросах. Вы можете выбрать / присоединиться / обновить / вставить / удалить / изменить в любом порядке, просто помните, что выполнение каких-либо действий с таблицей MyISAM в рамках транзакции InnoDB НЕ сделает MyISAM волшебным образом осведомленным о транзакции. Части MyISAM будут выполняться / фиксироваться немедленно, и если вы откатите сторону InnoDB, MyISAM также не откатится.

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

person Marc B    schedule 18.10.2010
comment
Спасибо, хороший ответ, но как предотвратить взаимоблокировки в приложении? Любой пример PHP будет полезен. Получу ли я тупиковую ситуацию, если я просто выполню несколько обновлений, вставок, выборок и удалений одновременно без фактической блокировки какой-либо таблицы из сценария? Я имею в виду простые запросы, без ТАБЛИЦЫ БЛОКИРОВКИ и тому подобного. - person Yasen Zhelev; 19.10.2010
comment
Еще один вопрос. Может ли взаимоблокировка произойти только тогда, когда 2 транзакции обращаются к одной и той же строке (строкам) одновременно, и у них есть заблокированные ресурсы, необходимые для завершения транзакции. Я имею в виду, что я не понимаю, как простые атомарные запросы могут вызвать тупик. Я прав? - person Yasen Zhelev; 19.10.2010
comment
Если нет блокировок, то не может быть мертвого LOCK. Однако, если оба запроса работают с одними и теми же строками, то это состояние гонки, и вы можете получить несогласованные результаты, в зависимости от того, в каком порядке запросы фактически выполняются. - person Marc B; 19.10.2010
comment
Неправильно. InnoDB автоматически блокирует строку, если вы выполняете вставку, обновление или удаление. Из dev.mysql.com/doc/refman/5.0/en /innodb-deadlocks.html: InnoDB использует автоматическую блокировку на уровне строк. Вы можете получить взаимоблокировки даже в случае транзакций, которые просто вставляют или удаляют одну строку. Это потому, что эти операции на самом деле не «атомарны»; они автоматически устанавливают блокировки для (возможно, нескольких) индексных записей вставленной или удаленной строки. - person Craig Andrews; 31.08.2012