Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Базы Данных > Ложится сервер, ломается MyISAM таблица


Автор: Elfer 17.11.2016, 14:15
Всем привет. Нужны советы в настройке сервера, который часто падает. Ниже опишу все траблы и возможные пути решения.

Недавно арендовал выделенный сервер: 2Гб оперативы, 1 процессор, 30 Гб HDD, ОС CentOS 6.7. Стоит PHP 7.0, MySQL 5.1.73.
До этого хостился на обычном хостинге, где также хостились несколько клиентов. Арендованный сервер мощный, скрипты стали быстрее работать, сама PHP 7 еще ускорило загрузку страниц, но появилась одна большая проблема, которую нужно срочно решить.

На сервере 1 сайт с посещалкой 5 000 пользователей в сутки. Примерно раз в сутки падает MySQL сервер. На обычном хостинге такого не замечал, а тут каждый день, а то и чаще. В базе есть таблица `hit`, которая имеет 50 000 - 200 000 записей (периодически подчищается кроном). Каждый раз при загрузке любой страницы на сайте из этой таблицы происходит чтение нужной инфы и запись. Т.е. т-ца постоянно дергается и считается самой высоконагруженной. В ней много индексов.

Код
DESCRIBE `hit`

user posted image

Код
SHOW INDEX FROM `hit`

user posted image

Что случается, когда сервер падает. Как мы поняли с хостерами, что идут запросы к этой таблице и они начинают накапливаться. Т.е. кол-во обращений увеличивается, пока обрабатывается первый запрос и в итоге увеличивается потребление ресурсов. Пока не происходит падение сервера. После того, как сервер восстановил, смотрю логи. Около десятка, а то и больше запросов на чтение данных в этой таблице обрабатывались больше минуты. Запросы не тяжелые, без join'ов и вложнных. Самые обычные, селект одной строки по индексу.

Какие я вижу варианты решения, но не знаю как настроить сервер:
  •  Не позволять запросы выстраивать в огромную очередь. Ограничить их оптимальным кол-вом. Каким кол-вом? Не знаю, нужно будет практически проверять. Возможно не более 5;
  •  Как-то ограничить время чтения информации в т-це. Чтобы она не была бесконечной. Ограничить 1-2 секундами;
  •  Те запросы, которые выстраиваются в очередь более 5, не позволять ими нагружать сервер, а тут же выдавать ошибку 503. На многих сайтах кстати такое вижу, когда запрос страницы сразу же выдает 503. А через пару секунд перезагружаешь страницу и уже нормально отображается.
В моем случае, при возникновении данной ситуации страница просто грузится, грузится, грузится... Т.е. не выдает сразу же ответ о том, что сервер занят. В итоге через минут 5 браузер выводит сообщение, что сервер не дает ответа, либо ошибка MySQL. А хочется, чтобы была сразу же ошибка 503, а не падение сервера.

Автор: igorold 18.11.2016, 09:19
Зачем у вас дублирующие ключи?
Ключей у вас много, поэтому много времени должно теряться на перестроение ключей.
т.к. таблица у вас MyISAM, то при записи в таблицу, вся таблица блокируется.

Попробуйте изменить тип этой таблицы на InnoDB.

Ну и я бы на вашем месте такой вопрос задавал бы не в ветке PHP, а в ветке MySQL

Автор: Elfer 18.11.2016, 09:39
Цитата
Зачем у вас дублирующие ключи?

Ага, guest_id и guest_id2 только теперь заметил, удалю один.

Цитата
Попробуйте изменить тип этой таблицы на InnoDB.

Ага, тоже подумывал об этом. Но хочу еще проще сделать. Сделать еще одну таблицу `hit_history` и кроном перемещать туда строки из т-цы `hit`. На самом деле в `hit` нужны и юзаются только примерно 3000 свежих строк, остальные - в качестве истории. Т.к. индексов много, то любая запись сказывается на скорости, а любое чтение среди такой большой массы строк - тоже сказывается. Сделав в 3000 строк, не должно вызывать никаких торможений.
Если перевести т-цу в InnoDB, то запись будет занимать больше времени. Но в качестве эксперимента, попробую.
Но всё же для опыта на будущее хотелось бы узнать ответы, как настроить сервер и MySQL согласно тем вариантам, что я привел в описании темы.

Автор: MoLeX 22.12.2016, 14:16
Тема не относиться к PHP не каким боком. Вам в настройку надо идти MySQL сервера

Автор: Elfer 22.12.2016, 14:29
Тема находится в разделе Базы данных, всё верно.

Проблему решил тем, что настроил автоматическое восстановление т-ц. В конфиге MySQL прописал для опции `myisam_recover_options` значение "BACKUP,FORCE", до этого стояло OFF. Поэтому каждый раз приходилось вручную чинить.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)