
По теме. Имеется веб-хостинг со ста клиентами и до недавнего времени всё было хорошо. Но в последний месяц стал обнаруживать, что mysql-сервер начал зависать при большом количестве запросов в базу. В обычном режиме мускуль съедает примерно 100-300 мегабайт памяти, но при зависании наблюдается следующая картина:
- Объём памяти занятый mysql-сервером 1-1.5гб
- Потребляемое процессорное время колеблется от 10 до 40%
- SHOW PROCESSLIST показывает, что все доступные подключения (max_connections=80) заняты разными клиентами и sql-запросами. Причём видно, что завис один самый первый и долгий sql-запрос на вставку (INSERT), за ним идут 9 запросов на очистку этой-же таблицы (TRUNCATE) в состоянии Locked. После них стоит очередь самых разных запросов других клиентов в состоянии Waiting for table.
Ограничение на число подключений одного клиента (max_user_connections) 10.
Такое чувство, что завис один самый первый запрос, а все остальные стоят в очереди и ждут-недождутся когда он отработает.
Ждать завершения зависшего sql-запроса бесполезно, некоторые запросы висят по нескольку часов.
Просить клиентов использовать качественный код тоже бесполезно - быдлокод был, есть и будет в любом случае.
На сервере 4гб памяти и два процессора по 2ггц, но mysql виснет не использовав и двух гб памяти. Подкрутил настройки my.cnf, но это лишь немного облегчило жизнь.
Пока что решил проблему следующим образом: php-скрипт работает в бекграунде и каждые 10 секунд смотрит SHOW PROCESSLIST на наличие долгих (больше 10 секунд) sql-запросов. При нахождении долгого запроса он убивается командой KILL. Мне кажется это некрасиво, неправильно и нужно курить настройки сервера, либо выставлять какие-то ограничения, вот только какие.... ведь справляются как-то хостеры с этой проблемой.