И так, есть небольшой сервис с одной базой данных, 32 таблицами в ней и примерно 1.2 млн. записей, ~30 запросов в секунду к MariaDB (так говорит PHPMyAdmin, на деле, по идее, должно быть куда меньше) и в последнее время начал замечать что если не делать ночных перезагрузок сервера - днём, а чаще в обед или после него обязательно всё лочится дедлоком и сервис падает, при чём даже завершение всех процессов приложения не помогает, а только перезапуск MariaDB или сразу сервера.
В качестве ОС используется Ubuntu 16.04.
Опишу немного структуру БД, может быть это поможет. При проектировании базы данных я руководствовался простыми правилами:
1) Таблицы к которым идут ТОЛЬКО SELECT (и очень редкие UPDATE/DELETE/INSERT, раз в неделю, а то и месяц) запросы используют MyISAM.
1.0) Сюда я включил: все таблицы со статичными данными, которые не изменяются + одна таблица с редкими INSERT (несколько раз в час) и частыми SELECT.
2) Таблицы к которым идут SELECT + UPDATE + INSERT используют InnoDB (в MariaDB это XtraDB).
2.0) Сюда я включил: таблицу пользователей - очень частые SELECT + UPDATE, и реже INSERT; таблицу чатов - очень частые SELECT, реже UPDATE и INSERT; и другие, с которыми проблемы менее вероятны так как они менее нагружены.
2.1) Высоконагруженная таблица логов (в которой более миллиона записей) и которая использует частые запросы SELECT + INSERT использует также InnoDB (тут сомневаюсь в правильности выбора подсистемы).
Собственно суть вопроса: Правильно ли я поступил при выборе подсистем для таблиц? Какими способами можно вылечить дедлоки?
нужно выяснить какая именно таблица уходит в лок и какой запрос ее вешает. дальше уже думать. Предполагаю, что есть какой-то массовый апдейт таблицы. Пересчет каких-нибудь рейтингов или типо того. В первую очередь проверить.
1. Где их можно посмотреть? Ситуацию следующая - подключаюсь к SSH и вижу что "всё зависло" -> "ребут".
2. Информация о балансе/опыте/дате блокировки и других характеристиках пользователей храняться в этой таблице. То есть нужно прочитать => при необходимости перезаписать.
3. Кэширование на уровне MySQL включено, не знаю есть ли смысл использовать memcached/redis, всё таки не тот уровень.
4. Логи в основном пишутся, но иногда нужно подсчитать количество всех действий связанных с определенным пользователем или количество действий за последние N дней связанных с этим пользователем.
5. Таблица чатов содержит по-большей части настройки для чатов, их в любом случае нужно читать, только одно поле может изменяться довольно часто - раз в несколько минут, остальные либо с неизменными после INSERT'а данными, либо для каждого чата меняются редко.
Boris Korobkov,
1. Потому что кроме них ничего быть не может :)
2. Довольно редко, но меняются. Каждые несколько секунд могут быть UPDATE и каждые несколько минут INSERT, а всё это время идут SELECT'ы.
3. Если можно поподробней.
4. Ну это не только, ещё в логах селектится дата последнего действия пользователя. При чём при каждом обращении пользователя к сервису.
Max Payne, по 4-му пункту уж точно не в мускуле делать такое. либо в памяти того приложения держать, если оно как демон работает. Либо какой-нибудь редис использовать.