Expire Anonymous user sessions

kbahey - July 9, 2006 - 05:38
Project:Drupal
Version:7.x-dev
Component:user system
Category:bug report
Priority:normal
Assigned:kbahey
Status:needs work
Description

Is anyone else bothered by thousands of rows in the sessions table?

Here is a patch that uses cron to expire session entries for anonymous users. This only happens once a day so as not to load the database unnecessarily, and the expiry period is configurable.

AttachmentSize
session-expire.patch.txt1.41 KB

#1

Dries - July 9, 2006 - 10:28

Ehm, this is a "won't fix". PHP is responsible for this. You can configure the session lifetime in setting.php. PHP's garbage collector will then periodically call Drupal's sess_gc() function with the proper argument.

#2

kbahey - July 9, 2006 - 14:54

In my case, it is set to 1440 (Debian default in php.ini), but it never had any effect.

Are you sure sess_gc() gets called on Drupal.org?

Could it be because the default in php.ini for save_handler is set to files and not user, and overridden in .htaccess?

Anyone has this working at all the way it should?

Also note that my patch limits what it does to anonymous sessions, not all sessions like what is in sess_gc().

#3

pwolanin - July 9, 2006 - 15:04

chheck your settings.php- that's probably superceeding the setting you have in php.ini.

At the least, I know that changing session cookie lifeting in settings.php does afffect how sessions are handled.

#4

kbahey - July 9, 2006 - 15:15

This is standard drupal stuff that I did not change.

Here is how php is setup:

$ grep lifetime /etc/xxx/php.ini
session.cookie_lifetime = 0
; /etc/cron.d/php5, which uses the session.gc_maxlifetime setting below
session.gc_maxlifetime = 1440

Here is how Drupal is setup:

$ grep lifetime xxx/.htaccess

$ grep lifetime sites/xxx/settings.php
ini_set('session.cookie_lifetime',  2000000);
ini_set('session.gc_maxlifetime',   200000);

The cron stuff is standard Debian fare.

$ cat /etc/cron.d/php5
# Look for and purge old sessions every 30 minutes
09,39 *     * * *     root   [ -d /var/lib/php5 ] && find /var/lib/php5/ -type f -cmin +$(/usr/lib/php5/maxlifetime) -print0 | xargs -r -0 rm


$ cat /usr/lib/php5/maxlifetime
#!/bin/sh -e

max=1440

for ini in /etc/php5/*/php.ini; do
        cur=$(sed -n -e 's/^[[:space:]]*session.gc_maxlifetime[[:space:]]*=[[:space:]]*\([0-9]\+\).*$/\1/p' $ini 2>/dev/null || true);
        [ -z "$cur" ] && cur=0
        [ "$cur" -gt "$max" ] && max=$cur
done

echo $(($max/60))

exit 0

Nothing there handles non-file sessions ...

#5

Dries - July 10, 2006 - 08:10
Status:needs review» won't fix

Have you looked at your settings.php?

#6

kbahey - July 10, 2006 - 12:58

Yes, and I listed what is in it:

$ grep lifetime sites/xxx/settings.php
ini_set('session.cookie_lifetime', 2000000);
ini_set('session.gc_maxlifetime',  200000);

These are the standard settings that ship with Drupal, and still, no cleanup happens.

My question agains is: does it happen on Drupal.org? Anyone else having sess_gc() called automatically?

#7

kbahey - July 17, 2007 - 23:57
Version:x.y.z» 6.x-dev
Status:won't fix» needs review

In view of people complaining of us delegating session cleanup to PHP garbage collection, for example this issue, I like to revive this.

If it has a chance of getting in, let me know, I will reroll and test.

#8

catch - October 24, 2007 - 15:24
Category:feature request» bug report
Status:needs review» needs work

If this isn't being handled properly, then it's a bug (or someone else should won't fix it again if it is). Either way it needs a re-roll.

#9

kbahey - November 5, 2007 - 16:24

Well, to solve the problem at hand, I created a separate session expire module http://drupal.org/project/session_expire

It is more configurable than this patch can ever be.

#10

David_Rothstein - January 4, 2008 - 23:40
Status:needs work» needs review

I can definitely confirm that sess_gc() never gets called. This is on a Debian Etch system with a standard PHP5 installation. The reason it doesn't work on Debian/Ubuntu is explained at http://drupal.org/node/160046 (which is marked as a duplicate of this issue).

As a start at fixing this, what about patching settings.php as suggested over two years ago (http://drupal.org/node/35834)?:

ini_set('session.gc_probability',   1);
ini_set('session.gc_divisor',   100);

A patch for 6.x is attached. I can confirm that this works for me (note that for testing purposes you may want to set session.gc_probability to 100 so that garbage collection is triggered on all page loads rather than on 1% of them). I believe this will fix the problem for a very large chunk of Debian/Ubuntu users out there.

However, I agree with the original poster that the best way to solve this problem in the long run is to call the garbage collection from within cron... that way it's guaranteed to happen for everyone regardless of their PHP configuration....

#11

David_Rothstein - January 4, 2008 - 23:41

This is like the third time this has happened to me on Drupal. I know I attached the patch but it didn't get posted. Anyway....

AttachmentSize
debian_sess_gc.patch 829 bytes

#12

Samat Jain - October 10, 2008 - 18:52

Debian reports this "fixed;" Debian's php.ini now includes a better warning. See Debian bug 388808.

With Debian's fix, Drupal still needs to handle this.

#13

quicksketch - November 12, 2008 - 02:13

I like David's fix in #11 (just ran into this on a client site also, 15 million session rows, ugh). That's the exact approach I used to fix for our client. I don't think that properly configuring PHP for Drupal is outside the realm of fixing at all. We already set several other variables to sensible defaults to avoid problems with a plethora of different platforms that Drupal runs on. Unfortunately I only just applied the changes today, so I'll need to let it go for a few weeks to see if it has the intended effect.

So, +1 for #11.

#14

chx - November 12, 2008 - 15:30
Version:6.x-dev» 7.x-dev

This is actually needed but you want a probability of 0 and curtail on cron. Performance++

#15

jvandyk - November 12, 2008 - 15:35

Well then, we probably want to get something like #9 into core. And we'll need to make sure that cron actually runs. In the meantime, here's a patch for D7. I agree with chx that it would be good to have more fine-grained control of this.

AttachmentSize
probabilityjv.patch 780 bytes
Testbed results
probabilityjv.patchfailedFailed: Failed to apply patch. a href=http://testing.drupal.org/pifr/file/1/probabilityjv.patchDetailed results/a

#16

catch - November 12, 2008 - 15:50

Automatic/failsafe cron runs are here #331611: Add a poormanscron-like feature to core. I think this patch is a good idea.

#17

c960657 - November 12, 2008 - 19:38

I suggest adding a brief comment explaining how these settings affect Drupal. default.settings.php currently contains several ini_set() calls whose purpose is far from obvious (see #303154: Document ini_set() calls in default.settings.php).

#18

System Message - November 16, 2008 - 22:05
Status:needs review» needs work

The last submitted patch failed testing.

#19

jvandyk - November 17, 2008 - 14:54
Status:needs work» needs review

I agree that we should document the ini settings, but this issue is not about that. This issue is essentially about making Drupal work as expected on Debian/Ubuntu versions that have default PHP settings that prevent garbage collection.

#20

Dries - November 22, 2008 - 14:16

If we're going to force the GC to run all the time, I'd like to better understand the performance impact. It seems like some quick performance tests are in order.

#21

quicksketch - November 22, 2008 - 16:15

We're not forcing it to run all the time, in fact we're setting it to the usual default (check the gc_probability and gc_divisor settings on Drupal.org, I bet they're the same thing). It just so happens that Debian and Ubuntu turn off these settings in their out-of-box installations, versus nearly every other installation uses these settings that we're now specifically setting. So for most installations, we're not changing anything at all.

#22

mvc - December 16, 2008 - 20:55

It's also possible to solve this on Debian/Ubuntu by explicitly calling sess_gc() in sess_close() in includes/session.inc.

#23

System Message - December 24, 2008 - 10:15
Status:needs review» needs work

The last submitted patch failed testing.

#24

quicksketch - July 4, 2009 - 05:54
Status:needs work» needs review

This is still a problem, but maybe now that docs have been added in #303154: Document ini_set() calls in default.settings.php these changes will be better understood. Here's a reroll.

AttachmentSize
drupal_session_cleanup.patch 1.22 KB
Testbed results
drupal_session_cleanup.patchfailedFailed: Failed to apply patch. Detailed results

#25

Dries - July 4, 2009 - 06:22

You're right! Committed to CVS HEAD. Thanks.

#26

Dries - July 4, 2009 - 06:22
Status:needs review» fixed

You're right! Committed to CVS HEAD. Thanks.

#27

quicksketch - July 4, 2009 - 06:25

w00t! Thanks Dries... feeling core rejected recently. This helps. :-)

#28

neilnz - July 17, 2009 - 04:23
Status:fixed» needs review

I'd like to revisit the approach taken here and contribute two patches I have for D6 and D7 that approach this in a different way.

We run many Drupal sites on Debian servers that don't run a settings.php derived from settings.default.php, so the fix to this issue doesn't help us. Futhermore, I believe Debian turned off the gc_probability stuff for good reason - this kind of maintenance is properly handled from cron, not during a page request (even if it is quick).

My patches add to the cleanup jobs performed by system_cron() to call either sess_gc() or _drupal_session_garbage_collection() as appropriate.

I don't believe any harm can come from running these from cron in addition to standard session garbage collection, and it will provide a fix for users with existing configuration files who upgrade core on Debian.

AttachmentSize
system.module.sessclean.d6.patch 467 bytes
system.module.sessclean.d7.patch 486 bytes
Testbed results
system.module.sessclean.d7.patchfailedFailed: Failed to apply patch. Detailed results

#29

System Message - July 17, 2009 - 04:35
Status:needs review» needs work

The last submitted patch failed testing.

#30

neilnz - July 19, 2009 - 21:31
Status:needs work» needs review

Resubmitting just the D7 patch. It seems to apply cleanly to HEAD for me, think the patch bot might've got confused by D6 and D7 at the same time.

AttachmentSize
system.module.sessclean.d7.patch 486 bytes
Testbed results
system.module.sessclean.d7.patchfailedFailed: Failed to apply patch. Detailed results

#31

System Message - July 19, 2009 - 21:40
Status:needs review» needs work

The last submitted patch failed testing.

#32

Dane Powell - November 6, 2009 - 00:38

+1 for some sort of fix - I just discovered that my sessions table was 1,000,000 rows and over 1 GB in size. Setting session.gc_probability in settings.php worked for me, but I agree that this is better taken care of in cron.

 
 

Drupal is a registered trademark of Dries Buytaert.