PHP Session Daten werden unter Debian nicht gelöscht (Einstellung gc_probability)
Unter Debian (und soweit ich weiß Ubuntu) ist der Standard Garbage Collector für PHP Sessions deaktiviert.
Verantwortlich hierfür ist die Einstellung session.gc_probability = 0 in der Default php.ini die dafür sorgt, dass alte Sessiondateien gelöscht werden sollen. Der Standardwert in PHP ist normalerweise 1, so dass der Garbage Collector mit einer Wahrscheinlichkeit von 1/100 beim Skriptaufruf gestartet wird.
Unter Debian ist diese Einstellung deshalb deaktiviert, weil das Standardverzeichnis für Sessions keine Schreibrechte für den Webserver bereitstellt (und auch nicht soll). Das Löschen von alten Session-Dateien übernimmt hier ein CRON-Job.
Hier ein Auszug aus der php.ini:
[pastacode lang=“bash“ message=“php.ini“ highlight=““ provider=“manual“]
; 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.
; php scripts using their own session.save_path should make sure garbage
; collection is enabled by setting session.gc_probability
;session.gc_probability = 0
[/pastacode]
Schlecht ist das allerdings, wenn man eine eigene Session-Verwaltung hat, die mit session_save_handler() eigene Funktionen für das Lesen, Speichern und Ändern von Sessiondaten bereitstellt und natürlich auch eine eigene Funktion für den Garbage Collector.
In diesem Fall führt die Debian-Einstellung dazu, dass diese Garbage Collector Funktion gar nicht aufgerufen wird. Besonders problematisch ist dies, wenn die Sessiondaten in einer MySQL Datenbank Tabelle des Typs MEMORY gespeichert werden. Diese Tabelle ist in ihrer Größe auf die MySQL-Konfigurationseinstellung max_heap_table_size begrenzt. Ist diese Größe erreicht, versagt die Tabelle ihren Dienst und mit ihr natürlich die Session-Verwaltung.
Es ist also unheimlich wichtig in diesem Fall die Einstellung der php.ini in der eigenen Session-Verwaltung zu setzen. Am Beispiel einer kleinen Session-Klasse (gekürzt und ohne Funktion) sieht das etwa so aus:
[pastacode lang=“php“ message=“PHP“ highlight=““ provider=“manual“]
class session {
function __destruct() {
session_write_close();
}
function session() {
@ini_set("session.use_trans_sid","0");
@ini_set('session.gc_probability', 1); // in debian this is disabled by default...
// enable customized session handler functions
session_set_save_handler(Array(&$this,"_sess_open"),
Array(&$this,"_sess_close"),
Array(&$this,"_sess_read"),
Array(&$this,"_sess_write"),
Array(&$this,"_sess_destroy"),
Array(&$this,"_sess_gc"));
@session_start();
}
// declare user defined session handler functions
function _sess_open($sSavePath, $sSessionName) {
return true;
}
function _sess_close() {
return true;
}
function _sess_read($sKey) {
// read and return value
}
function _sess_write($sKey, $val) {
// write new value
}
function _sess_destroy($sKey) {
// destroy session
}
function _sess_gc($iMaxLifeTime) {
// delete old sessions (from db)
}
}
$mySession = new session();
[/pastacode]
Großartig! Genau danach habe ich gesucht. Ich war schon am verzweifeln, weil die Datenbank langsam aber sicher mit Session-Müll voll lief.
Vielen, vielen Dank!