PHP Session Files Unexpectedly Deleted

A recent debugging session regarding session timeouts went on far longer than it needed to.   I’m going to share one aspect of it here in hopes that it saves someone (possibly hours of) debugging time.  If you’re running a Debian based environment (e.g. Ubuntu Server) and you find odd session behavior, like session data being cleared unexpectedly, there are 2 things this post will surface that should help.

Discovery #1: Debian-Based Distros Delete Session Files Via Cron Job

The first thing my debugging uncovered is that Debian-based distros (Linux Mint, Ubuntu Server, etc.) use a cron job to garbage collect PHP session files.  Thats to say that if you take a peek at the PHP session.gc_probability ini setting, it’ll be set to 0, indicating that PHP’s stock session garbage collection should never run.  You’ll also find a nifty cron job at /etc/cron.d/php5 that handles deleting session files.  Both indicate a complete work around to PHP’s default session garbage collection.  So if you don’t know this much, you likely don’t have the control you think you do regarding session management.

The good news though, is that the cron job is set to detect any changes made to the session.gc_maxlifetime ini setting, and if the changes result in a setting higher than 24 minutes, it’ll use that value.  Otherwise it falls back to using a 24 minute default.

So in most cases everything still works pretty reliably, but the deviation from PHP’s stock gc handling is still a surprise and another layer of discovery to work through.

Discovery #2:  With XDebug, Problems Arise

The second thing I learned, which was the real problem, is that the cron job becomes unreliable when XDebug enters the mix. If you’re unsure whether XDebug is enabled in your environment, you can check phpinfo() or check your php.ini file.  Depictions are below:

XDebug shown in phpinfo().

XDebug shown in phpinfo().

 

XDebug in php.ini.

XDebug in php.ini.

A problem occurs because the session cron job relies on a shell script at /usr/lib/php5/maxlifetime to determine what session.gc_maxlifetime ini value it should assume.  And that’s a good thing, because we want this cron job to respect when we want sessions gc’d (which is what session.gc_maxlifetime is for).  But when that script runs with xdebug enabled, it produces erroneous output, as shown below:

maxlifetime_error

XDebug error output

And because that shell script returns erroneous text and not a valid maxlifetime value, the cron job proceeds to delete session files either unpredictably, or on a 24 minute interval (the original default).  In either case it’s best to solve this problem.

Luckily that’s easy.  Just disable xdebug.  Once I did, maxlifetime completed without error and returned a proper value.  Now my session files are being garbage collected on a predictable schedule again.

Conclusion

I can only guess that Debian based distros went with their own session garbage collection to better manage that process; the cron job, while an unexpected surprise, does add predictability and perhaps better resource management to the session gc proccess.  However, if you’re not aware of it, it can lead to some lengthy debugging efforts if you find your session data acting funny.

This entry was posted in General. Bookmark the permalink.

2 Responses to PHP Session Files Unexpectedly Deleted

  1. Thank you, I’ve just been searching for information about this
    subject for a long time and yours is the best I have came upon so far.
    However, what about the conclusion? Are you certain concerning the source?

  2. Rubin says:

    Debian does this for security, so the session directory cannot be read by apache.

    See debian bug #267720

    It is QUITE rude of them not to include a comment in the stock php.ini to this effect ,though.

Leave a Reply

Your email address will not be published. Required fields are marked *