Очистка старых сессий в 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 такая проблема:

Значит, не зря я тут волну поднял.

Скрипт автоустановки обновил, теперь правильные значения сборщика будут выставляться при создании нового сайта.

← Предыдущая заметка
HybridAuth Авторизация в контексте mgr
Следующая заметка →
Переключение контекстов мультиязычного сайта
Комментарии (13)
sergantСергей Шлоков
05.01.2014 16:27

Отличное исследование. Периодически задавался вопросом, почему сессии не чистятся. Особенно заметно, когда переносишь базу. Такое полотенце. Напиши когда ответят.

bezumkinВасилий Наумкин
05.01.2014 16:28

Уже, смотри обновление.

Всё выходит еще интереснее - похоже виноваты стандартные настройки моей ОС.

Чикин Артур
05.01.2014 16:44

Я то думаю почему сегодня раза 3-4 на безумкин надо было авторизироваться)

bezumkinВасилий Наумкин
05.01.2014 16:44

Это я еще заодно проверил, есть ли смысл перейти на обычные файловые сессии?

Нет, нету.

Чикин Артур
05.01.2014 19:04

Обновлено 06.12.2014 Что то с датами?

bezumkinВасилий Наумкин
06.01.2014 02:39

Нет, в датами всё нормально - у меня часовой пояс Новосибирска и новые дни наступают немного раньше, чем в столицах.

Дошло, что месяц неверный - поправил.

Чикин Артур
06.01.2014 05:09

Я из Абакана. У меня еще раньше чем в Новосибирске:)

argnistВиталий Киреев
06.01.2014 02:22

А session.gc_maxlifetime в php.ini должен быть, как в настройках MODX или тут он не влияет? У меня сейчас стоит 1440 секунд.

bezumkinВасилий Наумкин
06.01.2014 02:41

Настройка MODX выставляет свою lifetime. Просто смотри Отчеты → Информация о системе → phpinfo() из админки, и будет ясно, какие параметры используются.

argnistВиталий Киреев
06.01.2014 02:30

А вообще у SessionHandler class написано PHP 5 >= 5.4.0, т.е. на более ранних версиях этот код все же совсем не используется? А у MODX заявлена поддержка от 5.2.0.

bezumkinВасилий Наумкин
06.01.2014 02:44

Я так понимаю, это документация актуальна с версии 5.0 по 5.4.

Функция session_set_save_handler работает вообще с PHP 4.

Igor Ostancov
06.01.2014 10:41

Сорри промахнулся веткой... Может добавить возможность удалять комментарии? ))

bezumkinВасилий Наумкин
06.01.2014 10:56

Эта возможность есть - у меня.

bezumkin
Василий Наумкин
30.06.2022 03:58
Есть ли возможность формировать &quot;friendly URL aliases&quot;, используя аналог translit MODx? ...
bezumkin
Василий Наумкин
27.06.2022 03:32
Спасибо за исправления, очень выручаешь =) Но учитывая количество не описаных в заметке дополнительн...
bezumkin
Василий Наумкин
27.06.2022 03:10
что будет использоваться для вывода многоуровневого меню Посмотри как работают комментарии на этом ...
bezumkin
Василий Наумкин
25.06.2022 11:56
Поправил, спасибо!
bezumkin
Василий Наумкин
22.06.2022 10:08
Я обычно не пользуюсь RTE редакторами, потому что они пишут всякое непонятное что в HTML. Но можно в...
bezumkin
Василий Наумкин
21.06.2022 01:58
onLoad(data) { this.total = data.total }, и onLoad({total}) { this.total = total }, В нашем случ...
bezumkin
Василий Наумкин
20.06.2022 14:01
Прекрасно тебя понимаю, я когда сам в этом разбирался - голова дымилась. Но зато теперь прямо-таки п...
bezumkin
Василий Наумкин
20.06.2022 09:30
Не надо, оно по умолчанию так - я просто чуть более подробно написал.
bezumkin
Василий Наумкин
19.06.2022 13:42
А можно же из 1 файла сделать 2 экспорта. По-умолчанию, и отдельно для футера: export const Footer =...
bezumkin
Василий Наумкин
19.06.2022 09:44
Тебе спасибо, что поддерживаешь рублём мои начинания!