Не удаляются файлы сессий PHP

Частая проблема — tmp папка web сервера вдруг содержит n миллионов файлов. Скорее всего это файлы сессий. И образовались они там не вдруг, а за пару месяцев/лет.

Диагностируем

Во первых, затруднительно посмотреть, что находится в папке, т.к. ни FAR, ни виндовый проводник (серверы с проблемой были на windows) не хотят такую папку открывать (FAR вылетал забрав 1гб оперативной памяти, где-то на чтении трехмиллионного файла). Как зайти в папку, содержащую много файлов? Переходим в папку в консоле через cd (переходит махом не зависимо от количества файлов) и пишем:

dir /p

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

Исправляем

Что же произошло и почему garbage collector (далее GC) PHP забил на вашу tmp папку и сто лет ее не чистил?

1) Возможно, не правильно заданы параметры php.ini  session.gc_probability и session.gc_divisor. Вероятность запуска GC при каждом запуске скрипта — session.gc_probability / session.gc_divisor. По умолчанию — 1/100. Соответственно, если задать session.gc_probability = 0 GC не запустится никогда. Соответсвующие параметры нужно проверить и в коде приложения.

2) Возможно, вы изменили session.save_path в своем приложении, и теперь она отличается от той, которая в php.ini. В этом случае GC чистить в вашей кастомной папке ничего не будет и вам нужно заботиться об этом самим, т.к. он чистит только папку, которая указана в ini. Цитата из конфигурационного файла:

; NOTE: If you are using the subdirectory option for storing session files
; (see session.save_path above), then garbage collection does *not*
; happen automatically. You will need to do your own garbage
; collection through a shell script, cron entry, or some other method.
; For example, the following script would is the equivalent of
; setting session.gc_maxlifetime to 1440 (1440 seconds = 24 minutes):
; cd /path/to/sessions; find -cmin +24 | xargs rm

3) Последнее, самое непонятное. Возможно, вы стали жертвой бага — https://bugs.php.net/bug.php?id=55333 Не знаю, правда это или нет, и баг ли это php или криворукость админов, но у меня на двух серверах, где не была изменена папка сессий по умолчанию, и все сохранялось в «C:/Windows/Temp», GC не работал. И это при абсолютной идентичности других настроек с серверами, где папка была изменена и все было ок. Решил проблему просто — сменил папку с дефолтной на свою, чего и вам желаю.

Удаляем

В tmp папке на момент решения проблемы было 4 миллиона файлов. Удалил их просто:

del sess_*

Процесс удаления не слишком нагружает сервер, и было решено просто запустить операцию на сутки. Тихо мирно все старые файлы сессий были выкошены. Обязательно перед удалением меняйте tmp папку сессий, т.к. иначе пользователи вашего ресурса будут все сутки без конца разлогиниваться (в лучщем случае), а в худшем будут толстые дата лосы из-за вашей невнимательности. Сначала смените путь в php.ini, потом удаляйте.

Для Linux серверов есть хорошая статья на хабре: http://habrahabr.ru/post/152193/

Спасибо Павлу Кочетову