Очистка старых сессий в MODX
Есть давнишний вопрос про большую таблицу modx_session, лично у меня она занимает 1.1 гигабайт и содержит около 500 000 записей. С одной стороны - не напрягает, а с другой непонятно, почему она понемногу растёт?
Таблица состоит из 3х колонок: идентификатор, время изменения и собственно данные сессии. У меня самая старая сессия от 30 октября 2013 года, то есть менялась она 3 месяца назад.
В настройках же установлена session_gc_maxlifetime = 604800, то есть старые сессии должны удаляться через 7 дней. По умолчанию, все сессии хранятся в БД, значит настройки хостинга и стандартный сборщик мусора тут не помогут - это должен делать сам MODX. Поправка - см. обновление в конце заметки.
Я полез искать, а где собственно у MODX сборщик старых сессий? Он нашелся в классе modSessionHandler - которая и рулит сессиями по умолчанию.
/**
* Remove any expired sessions.
*/
public function gc($max) {
$maxtime= time() - $this->gcMaxLifetime;
$result = $this->modx->removeCollection('modSession', array("{$this->modx->escape('access')} < {$maxtime}"));
return $result;
}
Во-первых, здесь неиспользуемый аргумент $max. А во-вторых, этот метод не вызывается в коде MODX, вообще.
Он есть, но его никто ни разу не вызывает, поэтому сессии и не удаляются. Ну, или я не нашел, как именно они очищаются, кроме как "завершить все сеансы в админке" - там делается просто TRUNCATE всей таблицы.
Как же нам почистить старые сессии? Очень просто:
$session = new modSessionHandler($modx);
$session->gc();
Метод использует modX::getCollection(), поэтому в первый раз скрипт будет выполняться ооочень долго и может даже выпасть по таймауту.
Теперь осталось дождаться ответа от авторов MODX, почему метод modSessionHandler::gc() не используется.
Обновлено 06.01.2014
Jason Coward говорит, что PHP сам вызывает этот метод, без MODX. Звучит логично, и проблема, наверное, в дефолтных настройках моей Ubuntu - там session.gc_probability = 0.
То есть, стандартный сборщик никогда не запусается и ОС чистит сессии своим скриптом по cron. Понятно, что консольный скрипт ничего не знает ни про modSessionHandler, ни про другие нестандартные способы хранения сессий. Но непонятно. зачем так сделано? На багтрекере Ubuntu этот вопрос повис аж с 2009 года.
Поставил session.gc_probability = 1, а session.gc_divisor = 10, теперь сессии должны очищаться в 10% новых стартов. Пока изменений нет, буду наблюдать. Всё почистилось, переставил divisor на 100.
Проверять возраст сессий можно в phpMyAdmin:
SELECT id, FROM_UNIXTIME(access) as access FROM `modx_session`
ORDER BY access ASC LIMIT 10
Будет вот так:
В общем, владельцы Ubuntu, заходите в /etc/php5/fpm/php.ini и меняйте session.gc_probability на 1. Divisor можно оставить на 1000 или поменять на 100 - зависит от посещаемости сайта. Чем больше ходит народу, тем больше должен быть session.gc_divisor.
Сам механизм расширения сессий описан в документации, и действительно, PHP запускает всё самостоятельно - поэтому в коде MODX нет вызова ни одного из методов modSessionHandler.
Судя по количеству вопросов в поисковиках про большую modx_session - много кто использует хостинги с отключенной сборкой старых сессий. Вроде как, даже на http://modx.com такая проблема:
Скрипт автоустановки обновил, теперь правильные значения сборщика будут выставляться при создании нового сайта.
0
👍
👎
❤️
🔥
😮
😢
😀
😡
7 930
05.01.2014, 19:33:18
13 комментариев
bezumkin.ru
Личный сайт Василия Наумкина
Прямой эфир
Василий Наумкин
01.07.2024, 11:56:41
Да, верно, именно так.
А в контроллере, скорее всего, ловить данные методом post.
Василий Наумкин
26.06.2024, 09:38:15
О, точно, вылезает если не залогинен.
Спасибо, исправил!
Василий Наумкин
09.04.2024, 04:45:01
> Ошибка 500
Это не похоже на ошибку Nginx, это скорее всего ошибка PHP - надо смотреть его логи.
...
russel gal
09.03.2024, 20:17:18
> А этот стоило написать хотя бы затем, чтобы получить комментарий от юзера, который ничего не писал...
Александр Наумов
27.01.2024, 03:06:18
Василий, спасибо!
Извини, тупанул.
Нет, в датами всё нормально - у меня часовой пояс Новосибирска и новые дни наступают немного раньше, чем в столицах.