Мы столкнулись с проблемой после перемещения базы данных нашего клиента на дополнительный сервер. Это должно было оказать положительное влияние на производительность сайта, но есть проблема с блокировкой таблицы в MyISAM. (Я слышал об использовании InnoDB вместо MyISAM, но мы не можем изменить движок в ближайшем будущем).
Мы могли бы заметить это по запросу на обновление, который выполняется, когда модератор активирует комментарий на сайте. Это процесс:
- обработан запрос на обновление
SET status = 1 WHERE id = 5
(индекс установлен) - кэшированные файлы страницы удалены
На этом этапе вся страница становится медленной. Сама база данных занята в течение нескольких минут. Я получил список процессов несколько раз и увидел около 60 записей различных запросов выбора, которые все находились в состоянии ожидания блокировки на уровне таблицы .
1. Я не понимаю, почему это обновление таблицы article_comments
может повлиять на операторы выбора для таблицы, ожидающей article
блокировки на уровне таблицы. В списке процессов почти все ожидающие запросы были из этой таблицы. Я читал о том, что обновления / вставки предпочтительнее, чем выбор, и что это может вызвать такие проблемы, но сама таблица статей не обновляется при активации комментариев, поэтому выбор не должен ждать. Я неправильно понял это?
2. Есть ли что-то кроме изменения InnoDB, чтобы предотвратить это поведение или, по крайней мере, получить лучший баланс? Меня очень раздражает тот факт, что эта проблема не появилась до переноса базы данных на новый сервер. Я предполагаю, что есть некоторая неправильная конфигурация, но я не знаю, как идентифицировать.
key_buffer_size
был настроен на1GB
. Увеличение этого, чтобы10GB
уменьшить проблему.Ответы:
MyISAM Storage Engine чрезвычайно известен тем, что выполняет полные блокировки таблиц для любого DML (INSERT, UPDATEs, DELETEs). InnoDB определенно решит эту проблему в долгосрочной перспективе.
Я писал о плюсах и минусах использования MyISAM против InnoDB
Что касается вашего текущего вопроса, вот возможный сценарий:
article
иarticle_comments
обе таблицы MyISAMarticle_comments
имеет один или несколько индексовstatus
в качестве столбцаarticle_comments
кэшируются в буфере ключа MyISAM (размер по ключу key_buffer_size ), в результате чего старые страницы индекса выходят из буфера ключа MyISAMarticle
иarticle_comments
В моем предложенном сценарии SELECTs для
article
таблицы могут быть запрещены для записи из-за необходимости ждатьarticle_comments
освобождения от любого DML (в данном случае, anUPDATE
)источник
Пахнет, как будто у тебя большой Query_cache?
Для производственных систем с большим количеством записей вы также можете отключить query_cache.
Все записи в query_cache для данной таблицы очищаются при любой записи в эту таблицу. Чем больше КК, тем медленнее эта задача.
MyISAM использует блокировки на уровне таблицы. Чтение и запись не могут происходить одновременно (в одной таблице). Грубый, но эффективный.
источник