Php не удаляет файлы сессий

Обновлено: 19.05.2024

У меня стоит на сервере Debian

Проблема в том, что ISPManager создавая нового пользователя, все сессии хранит в его директории

В php.ini в Debian написано, что для очистки директорий применяется скрипт

Но этот скрипт я так понял очищает только

Вопрос в том как сделать так, чтобы очищались директории пользователей, созданные ISPManager в соответствии с настройками php.ini ?

Кто-нибудь сталкивался с такой проблемой?

Написать свой собственный скрипт типа


/usr/bin/find /var/www -name 'mod-tmp' -maxdepth 3 | xargs -J % /usr/bin/find % -type f -delete

P.S. не тестировал

2. Включите встроенный в PHP механизм удаления сессий (в некоторых ОСях он отключен в дефолтном конфиге) через параметры
session.gc_probability и session.gc_divisor
в php.ini

просто Debian не рекомендует использовать директивы эти, из за проблемы прав доступа каких-то

Полностью аналогичная проблема. У всех пользователей забиваются mod-tmp и приходится вручную очищать. Что делать? Отправлял тикеты - все ответы идут в духе отписок "попробуйте копнуть туда-то", хотя я хотел бы видеть конкретную команду для добавления в cron.

/usr/bin/find /var/www -name 'mod-tmp' -maxdepth 3 | xargs -J % /usr/bin/find % -type f -delete
Не работает.

find /var -wholename "*/data/tmp/*" -type f -cmin +120 -print0 | xargs -r -0 rm
Выполняется, но вообще ничего не удаляет в результате.

Всего-то надо очищать /var/www/some_user/data/mod-tmp/ Как это сделать?

Полностью аналогичная проблема. У всех пользователей забиваются mod-tmp и приходится вручную очищать. Что делать? Отправлял тикеты - все ответы идут в духе отписок "попробуйте копнуть туда-то", хотя я хотел бы видеть конкретную команду для добавления в cron.

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

Всего-то надо очищать /var/www/some_user/data/mod-tmp/ Как это сделать?
Зачем городить огород с find и exec?

cd /var/www; rm -rf '*/data/mod-tmp/*'

Зачем городить огород с find и exec?

cd /var/www; rm -rf '*/data/mod-tmp/*'

На все открытые в момент очистки сессии "забиваем болт"?
Ню ню :) Посетители сайтов клиентов будут в восторге.

А если окажется, что файлов слишком много, то rm подавится и ничего не сделает.

А этого в условии задачи нет :)

Я же не знаю, зачем это нужно. Может, перед бэкапом вычистить лишнее?

session.gc_probability, session.gc_divisor, session.gc_maxlifetime - и никаких проблем и заморочек.

session.gc_probability, session.gc_divisor, session.gc_maxlifetime - и никаких проблем и заморочек.

Вопрос: прописываем это в глобальном php.ini или у каждого пользователя (при php as cgi)? Если у каждого пользователя, то при создании нового снова придется все ручками. И так каждый день/час?
Пробовал в глобальном php.ini - что-то не особо заметил, что удаляет.

Разработчикам: Если где возможность в панели, чтобы пользователю php.ini создавался сразу с определенными записями? Например подключить Zend и т.д.

Проще создать в /conf.d/ ini файл и туда прописать что то подобное


session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 1440


мы так делаем. настройки применятся на все режимы php.

session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 1440

при включении данного кода в /etc/php5/apache2/php.ini
сервер быстро наращивает нагрузку, апач работает из-за этого как то неверно.

папка с сессиями уже дико засорена, удаление средствами rm не работает.
Подскажите, как быть?

Естественно нагрузка будет расти.
У нас до 65 (8 ядер) доходила.
Переждать надобно. Пока там такое количество файлов поудаляет.
А код рабочий. На всех серверах наших стоит и проблем с сессиями не замечено.

Естественно нагрузка будет расти.
У нас до 65 (8 ядер) доходила.
Переждать надобно. Пока там такое количество файлов поудаляет.
А код рабочий. На всех серверах наших стоит и проблем с сессиями не замечено.

а всё таки если использовать вариант из серии find /var/www/user/data/mod-tmp/ -type f -mmin +60 -delete через крон?

помимо высокой нагрузки апач по сути лежит и недоступен пользователям.

сейчас запустил удаление через find, нагрузка не более 2 итого, я так понимаю щас он разово удалит мертвые файлы, а потом поставить в крон.
что может пойти не так при таком подходе?

find /var/www/user/data/mod-tmp/ -type f -mmin +60 -delete - вот эта строка че-то не отработала как я понял.

вот так - очистка происходит find /var -wholename "*/data/mod-tmp/*" -type f -cmin +120 -print0 | xargs -r -0 rm

У меня вот какая проблема. Пришел всё таки к включению
session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 1440

Уже вроде и файлы все удалились, 600k inodes занято, но всё равно нагрузка на сервере от 50 до 100. Уже не знаю что делать.

Ну так раз так сильно засорилось, ждите теперь, пока почистит.
В дальнейшем шанс запуска механизма будет 1/1000, если слишком редко, уменьшите, будет чистить чаще.

данная проблема действительно существует. конкретно в случае с Debian 5.
по умолчанию в php.ini опция session.gc_probability отключена и т.к. панель изменяет опцию session.save_path персонально для каждого виртуалхоста, то и панель должна отслеживать данное изменение!

вот кусок из php.ini с комментариями к данному случаю:

; This is disabled in the Debian packages, due to the strict permissions
; on /var/lib/php5. Instead of setting this here, see the cronjob at
; /etc/cron.d/php5, which uses the session.gc_maxlifetime setting below.
; php scripts using their own session.save_path should make sure garbage
; collection is enabled by setting session.gc_probability
;session.gc_probability = 0

нужно либо раскомментировать эту строку и заменить 0 на 1, либо (что более правильно) создать /etc/php5/conf.d/session-gc.ini с содержимым:

session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 1440
либо добавить в скрипт /etc/cron.d/php5 к строке

09,39 * * * * root [ -x /usr/lib/php5/maxlifetime ] && [ -d /var/lib/php5 ] && find /var/lib/php5/ -type f -cmin +$(/usr/lib/php5/maxlifetime) -print0 | xargs -n 200 -
r -0 rm
дополнительную строку

09,39 * * * * root [ -x /usr/lib/php5/maxlifetime ] && [ -d /var/www ] && /usr/bin/find /var/www/ -regextype posix-egrep -regex '.*/sess_[a-f0-9]$' -type f -cmin +
$(/usr/lib/php5/maxlifetime) -print0 | xargs -n 200 -r -0 rm
я специально уточнил условия поиска т.к. папки mod_tmp используются еще и для upload_tmp_dir

все это ручной тюнинг, но хотелось бы чтобы в панель были внесены нужные изменения. раз панель создает виртуалхосты меняя session.save_path то нужно контролировать и session.gc_probability добавляя этот параметр со значением 1 рядом.

ничем удалить не получается все тупо виснет, как почистить?? боюсь как бы после

на моем сайте я использую PHP-сессии. Информация о сеансе хранится в файлах в my ./ путь сеанса. Через несколько месяцев я обнаружил, что эти файлы сеанса никогда не удаляются, теперь в этом каталоге их 145.000.

как они должны быть очищены? Должен ли я делать это программно, или это параметр, который я могу использовать где-то, где эта очистка произойдет автоматически?

там вы найдете эти переменные:

  • сессии.gc_probability
  • сессии.gc_divisor
  • сессии.gc_maxlifetime

Они контролируют вероятность запуска сборщика мусора (GC) с каждым запросом страницы.

вы можете установить их с безопасность() в начале ваш сценарий или .htaccess файл, так что вы получите уверенность в какой-то степени они будут удалены когда-нибудь.

Debian /Ubuntu обрабатывает это с помощью cronjob, определенного в/etc / cron.д/рнр5

скрипт maxlifetime просто возвращает количество минут, которое сеанс должен поддерживать, проверяя php.ini, это выглядит так

если кто-то хочет сделать это с помощью cronjob, пожалуйста, имейте в виду, что это:

очень медленно, когда у вас много файлов.

попробуйте использовать этот:

если у вас есть пробелы в именах файлов, используйте это:

xargs заполнит командную строку файлами для удаления, а затем запустите rm команда намного меньше, чем -exec rm <> \; , который будет вызывать для каждого файл.

просто мои два цента

используйте cron с find для удаления файлов старше заданного порога. Например, для удаления файлов, к которым не обращались по крайней мере неделю.

вы можете создать скрипт / etc / cron.почасово / php и поставить там:

затем сделайте скрипт исполняемым (chmod +x).

теперь каждый час будут удалены все файлы сеанса с данными, измененными более 24 минут назад.

Срыв: Только файлы:найти /var/lib/ php5 / - тип f
Старше минуты: - cmin
Получить настройки php:$(echo "' php-I|grep-i сессия.gc_maxlifetime
Посчитайте: / cut-d ''- f3 '/ 60" / bc)
РМ соответствующие файлы: - exec rm-f <> \;

Я бы предположил, что вы находитесь на общем сервере, и файлы сеанса смешаны со всеми пользователями, поэтому вы не можете и не должны их удалять. Что вы можете сделать, если вас беспокоит масштабирование и / или конфиденциальность сеансов пользователей, - это переместить сеансы в базу данных.

начните писать этот файл Cookie в базу данных, и у вас есть долгий путь к масштабированию приложения на нескольких серверах, когда придет время.

кроме того, я бы не беспокоиться с 145.000 файлов.

cd в каталог сеансов, а затем:

1) просмотр сеансов старше 40 мин: find . -amin +40 -exec stat -c "%n %y" <> \;


Почему стандартный комплект из коробки не чистит сессии? Надо что то дополнительно донастроить?
Спасибо.

  • Вопрос задан 14 дек. 2020
  • 533 просмотра
Причиной проблемы было наличие функции ini_get_all в disable_functions.
Убрал её и всё заработало как надо.

find /var/lib/php/sessions/sess_* -mmin +240 -delete;

ну так чистите нужную директорию в лоб ;)
например таким таском раз в час. что старее min +240 (240 минут = 4 часа)

это понятно, что можно чистить своим скриптом по крону. Я такое решение уже делал.
Хочу разобраться почему не отрабатывает стандартный вариант после установки php

find -O3 "$save_path/" -ignore_readdir_race -depth -mindepth 1 -name 'sess_*' -type f -cmin "+$gc_maxlifetime" -delete

вот эту строку переделайте в вывод на консоль и посмотрите, что скрипт пытается делать

Что-то не то с настройкой session.gc_maxlifetime, похоже.

Сделайте для каждого конфига PHP:

где VERSION - версия, CONFD - директории с конфигами в /etc/php/VERSION (т.е. cli, fpm, apache2. ).
И проверьте, что в session.gc_maxlifetime

Т.е. у вас ini_get_all("session") возвращает NULL?
Это нездоровая канитель. galaxy, коробочный вариант. А у вас после чистой установки php-fpm что возвращает? vebmaster, массив со всеми параметрами session.*, как в документации и написано.

До конца проверьте по линкам:

Посмотрите, что за файл /usr/bin/php7.4, сравните размер или даже хеш с файлом из дистрибутива.
Просто такие глюки бывают, когда система взломана, например. Надеюсь, это не ваш случай.

galaxy, я наблюдаю эту ошибку уже больше года и не только на своём сервере. На троих серверах уже минимум, а то и больше.

С ppa ставили? Вроде в 18.04 пока еще 7.2.
Может, кривой ppa?

Сейчас создал впс с чистой Ubuntu 18.04, подключил ppa. Все ок:


Может, с php.ini у вас что-то не то? Попробуйте скопировать дефолтный с репозитория.

galaxy, странно. Спасибо, проверю ради интереса с нуля на чистую впс. Но я больше года уже наблюдаю эту ошибку на разных серверах. galaxy, проверил, причиной выдачи NULL было наличие функции ini_get_all в disable_functions.
Убрал, теперь выдаёт всё правильно.
И сессии начали чиститься. Спасибо большое за помощь!

galaxy, теперь возникла другая проблема. Крон выполняется, но сам скрипт не запускается.

В файле крона /etc/cron.d/php имеется следующая команда для запуска:


Как видно /usr/lib/php/sessionclean запустится, только, если /run/systemd/system НЕ каталог. А в на моём впс такой каталог существует и скрипт не выполняется никогда.
Подскажите пожалуйста, почему так?

на моем сайте я использую PHP сессии. Информация о сеансе хранится в файлах в my ./ путь к сеансу. Через несколько месяцев я обнаружил, что эти файлы сессий не удаляются, сейчас есть 145.000 их в этот каталог.

как они должны быть очищены? Должен ли я делать это программно, или это параметр, который я могу использовать где-то, чтобы эта очистка происходила автоматически?

  • сессии.gc_probability
  • сессии.gc_divisor
  • сессии.gc_maxlifetime

Debian /Ubuntu обрабатывает это с помощью cronjob, определенного в/etc / cron.d / php5

скрипт maxlifetime просто возвращает количество минут, которое сеанс должен поддерживать, проверяя php.ini, это выглядит так

в случае если кто-то хочет сделать это с cronjob, пожалуйста, имейте в виду, что это:

очень медленно, когда у вас много файлов.

рассмотрите возможность использования этого вместо:

если у вас есть пробелы в именах файлов, используйте это:

xargs заполнит командную строку с файлами, которые будут удалены, а затем запустите rm команда намного меньше, чем -exec rm <> \; , который будет вызывать для каждого файл.

просто мои два цента

используйте cron с find для удаления файлов старше заданного порога. Например, чтобы удалить файлы, которые не были доступны в течение по крайней мере недели.

вы можете создать скрипт / etc / cron.ежечасно / php и ставлю туда:

затем сделайте скрипт исполняемым (chmod +x).

теперь каждый час будут удаляться все файлы сеанса с данными, измененными более 24 минут назад.

Срыв: Только файлы:найти /var / lib/ php5 / - type f
Старше минуты: - cmin
Получить настройки php:$(echo "`php-I|grep-i сессия.gc_maxlifetime
Сделайте математику: / cut-d ''- f3 '/ 60" / bc)
РМ соответствующие файлы: - exec rm-f <> \;

Я думаю, что вы находитесь на общем сервере, и файлы сеанса смешиваются со всеми пользователями, поэтому вы не можете и не должны их удалять. То, что вы можете сделать, если вы беспокоитесь о масштабировании и/или конфиденциальности сеанса ваших пользователей, - это переместить сеансы в базу данных.

начните писать этот файл Cookie в базу данных, и у вас есть долгий путь к масштабированию вашего приложения на нескольких серверах, когда придет время.

кроме того, я бы не стал сильно беспокоиться 145.000 файлов.

cd в каталог сеансов, а затем:

1) просмотр сеансов старше 40 мин: find . -amin +40 -exec stat -c "%n %y" <> \;

2) удалить сеансы старше 40 мин: find . -amin +40 -exec rm <> \;

Читайте также: