เดิมที่ไล่แกะดูการทำงานของตารางนี้คือ ปกติ php จะจัดการ session ด้วยตัวเอง ซึ่งจะสร้างเป็นแฟ้ม session ไว้ใน /var/lib/php5/ แต่ใน drupal จะจัดการ session ด้วยฐานข้อมูล คือเก็บลงตาราง sessions แล้วเขียน function มา handle ซึ่งดูรายละเอียดฟังก์ชันเหล่านี้ได้จาก includes/session.inc และกำหนดให้ใช้ฟังก์ชันเหล่านี้ในการจัดการ session ใน includes/bootstrap.inc ซึ่งก็ดูปกติดี โดยเฉพาะตรงฟังก์ชัน sess_gc() ซึ่งมีไว้เคลียร์ session ที่อายุเกิน maxlifetime ทิ้ง โดยการลบ record ทิ้งด้วยเงื่อนไข ก็ดูเรียบร้อยดี
วันนี้อยากเคลียร์ปัญหานี้ให้จบเลยแกะดูการทำงานต่อ เริ่มจากตรวจล็อกของ mysql พบว่า ไม่เคยมีคำสั่ง "DELETE FROM sessions ...." ถูกรันเลย แปลว่า sess_gc() ไม่เคยถูกเรียกใช้จาก php เลย คำถามจึงมีอยู่ว่า เมื่อไหร่ที่ php จะเรียกใช้ sess_gc() ทำให้ต้องย้อนไปแกะดูใหม่
เปิดดู php.ini อีกครั้ง (ก่อนนี้ก็เคยแกะดูแล้ว แต่ไม่พบอะไรผิดปกติ) คราวนี้เน้นไปที่เรื่อง gc ก็พบตรงนี้เข้า
; Define the probability that the 'garbage collection' process is started
; on every session initialization.
; The probability is calculated by using gc_probability/gc_divisor,
; e.g. 1/100 means there is a 1% chance that the GC process starts
; on each request.
; 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
;session.gc_probability = 0
session.gc_divisor = 100
นั่นคือ ปกติ session.gc_probability = 1 จะทำให้ทุกครั้งที่ php ทำงาน จะมีโอกาส 1/100 ที่ gc ทำงาน หรือพอจะตีความว่า รัน php 100 ครั้ง gc จะถูกเรียก 1 ครั้งก็พอได้ แต่ใน debian ไม่ใช่อย่างนั้น debian จะ comment ค่านี้ไว้ ทำให้มีค่าเป็น 0 เสมอ gc จะไม่ถูกเรียกใช้งาน แต่จะมี cron สำหรับลบ session ที่หมดอายุแทน เหตุผลก็อธิบายไว้ใน comment แล้ว
ตรงนี้แหละคือปัญหา เพราะนั่นเท่ากับว่า sess_gc() ที่ drupal เตรียมไว้ให้ php เรียกใช้ จะไม่ถูกเรียกใช้เลย นั่นคือสาเหตุที่ opentle.org มีปัญหาดังกล่าว
การแก้ปัญหา
การแก้ไฟล์ php.ini ไม่ใช่ทางออกที่ดี ควรแก้ใน drupal ในไฟล์ sites/default/settings.php แทน โดยเพิ่ม
ini_set('session.gc_probability', 1);
ini_set('session.gc_divisor', 100);
เข้าไป เท่านี้ก็เรียบร้อย ทิ้งไว้สักพัก session ก็ถูกจัดการได้ถูกต้องตามปกติแล้ว