Un tiempo atrás actualicé un sistema Debian en forma rutinaria y hace un par de días comenzó a producir problemas extraños en las aplicaciones: desde pérdida de sesión al editar páginas web, errores para escribir en las bases de datos, hasta problemas de permisos en los archivos temporales.
El problema resultó ser la temida y oscura: tabla de inodos llena.
# df -i Filesystem Inodes IUsed IFree IUse% Mounted on /dev/sda1 5120000 5120000 0 100% /
Entonces, a salir a buscar dónde estaban los millones de archivos que ocupaban todos los inodos:
# find / -xdev -printf '%h\n' | sort | uniq -c | sort -k 1 -n ... 3945231 /var/lib/php5/
y resulta que en ese directorio se mantenían unos casi cuatro millones de archivos llamados como sess_dn5m6oc4fcpfo0c95pq1se4rp0
.
Aparte de iniciar un proceso de borrado masivo:
# cd /var/lib/php5 # find . -name "sess_*" -print | xargs rm -v
Inicié la búsqueda de las causas de fondo para evitar que el problema se vuelva a repetir en el futuro.
En Debian/Ubuntu el encargado de mantener los archivos de sesiones que se generan en /var/lib/php5
es el script
# cat /etc/cron.d/php5 # /etc/cron.d/php5: crontab fragment for php5 # This purges session files older than X, where X is defined in seconds # as the largest value of session.gc_maxlifetime from all your php.ini # files, or 24 minutes if not defined. See /usr/lib/php5/maxlifetime # Look for and purge old sessions every 30 minutes 09,39 * * * * root [ -x /usr/lib/php5/maxlifetime ] && [ -x /usr/lib/php5/sessionclean ] && [ -d /var/lib/php5 ] && /usr/lib/php5/sessionclean /var/lib/php5 $(/usr/lib/php5/maxlifetime)
que como se puede ver, utiliza la salida de la ejecución de /usr/lib/php5/maxlifetime
para determinar el tiempo de mantenimiento de los archivos de sesión de php.
El problema se generó en la ejecución de /usr/lib/php5/maxlifetime
que producía el error de al ejecutar por la presencia de la directiva safe_mode en el archivo php.ini
:
# grep safe_mode /etc/php5/apache2/php.ini safe_mode = On
en razón de que:
42 | WARNING | INI directive ‘safe_mode’ is deprecated from PHP 5.3 and forbidden from PHP 5.4.
Así la actualización a PHP 5.4 hizo que el archivo /usr/lib/php5/maxlifetime
dejara de devolver un valor para devolver un error. Entonces el proceso de limpieza, dejó de limpiar y se juntaron cuatro millones de archivos que llenaron la tabla de inodos.
Solución permanente: comentar safe_mode = On
en el archivo php.ini.