Mysql Lock времена в медленном журнале запросов
У меня есть приложение, которое уже довольно давно работает нормально, но недавно в медленном журнале запросов появилось несколько пунктов. Все запросы являются сложными и уродливыми операторами выбора нескольких соединений, которые могут использовать рефакторинг. Я полагаю, что у всех есть капли, то есть они записываются на диск. Часть, которая заставляет меня любопытно, - то, почему у некоторых из них есть время блокировки, связанное с ними. Ни один из запросов не имеет конкретных протоколов блокировки, установленных приложением. Насколько я знаю, по умолчанию вы можете читать против блокировок, если явно не указано.
поэтому мой вопрос: какие сценарии могут привести к тому, что оператор SELECT будет вынужден ожидать блокировки (и, следовательно, будет отображаться в журнале медленных запросов)? Предположим, что среды INNODB и MYISAM.
Может ли взаимодействие с диском быть указано как какое-то время блокировки? Если да, есть ли документация, подтверждающая это?
заранее спасибо.
2 ответа
MyISAM создаст проблемы с параллелизмом, когда во время вставки вся таблица будет полностью заблокирована.
У InnoDB не должно быть проблем с чтением, даже когда выполняется запись / транзакция из-за его MVCC.
Однако то, что запрос отображается в журнале медленных запросов, не означает, что запрос медленный - сколько секунд, сколько записей проверяется?
Поставьте "EXPLAIN" перед запросом, чтобы получить разбивку экзаменов, проводимых по запросу.
Вот хороший ресурс для изучения EXPLAIN (кроме отличной документации по MySQL)
Я не уверен насчет MySql, но я знаю, что в SQL Server операторы выбора НЕ читаются против блокировок. Это позволит вам прочитать незафиксированные данные и, возможно, увидеть повторяющиеся записи или полностью пропустить запись. Причина этого в том, что, если другой процесс записывает данные в таблицу, ядро базы данных может решить, что пришло время реорганизовать некоторые данные и перенести их на диск. Таким образом, он перемещает запись, которую вы уже прочитали, в конец, и вы видите ее снова, или он перемещает одну из концов вверх, где вы уже прошли.
Где-то в сети есть парень, который на самом деле написал пару сценариев, чтобы доказать, что это происходит, и я попробовал их один раз, и прошло всего несколько секунд, прежде чем появился дубликат. Конечно, он разработал сценарии таким образом, чтобы это было более вероятным, но это доказывает, что это определенно может произойти.
Это нормальное поведение, если ваши данные не должны быть точными и, безусловно, могут помочь предотвратить взаимные блокировки. Однако, если вы работаете над приложением, имеющим дело с чем-то вроде денег людей, это очень плохо.
В SQL Server вы можете использовать подсказку WITH NOLOCK, чтобы указать оператору select игнорировать блокировки. Я не уверен, каким будет эквивалент в MySql, но, возможно, кто-то еще скажет здесь.