Shell: Sehr große Verzeichnisse löschen (PHP Sessions)

Szenario:

  • Fehler bei PHP’s Sessionbereinigung (garbage collection)
  • große Anzahl Dateien in einem Ordner, die nicht mehr gebraucht werden (hier: über 17 mio)
  • Löschen muss im laufenden Betrieb stattfinden, da Produktiv-Server.

Methode 1 (langsam und sicher):

find /var/lib/php/sessions -type f -mtime +3 -delete

Hier werden alle Dateien (-type f) gelöscht, deren Modifikation 3 Tage zurücklag (mtime +3) – dieser Parameter kann angepasst/weggelassen werden. Es empfiehlt sich, den vollen Pfad anzugeben, um versehentliches Löschen in einem anderen verzeichnis (zb ./) auszuschliessen. Sollte der Hauptspeicher knapp sein: Shell: RAM und Swap freigeben ohne Reboot

Methode 2 mit rm:

rm -rf /var/lib/php/sessions && mkdir /var/lib/php/sessions && chmod 1733 /var/lib/php/sessions

Setzt voraus, dass alle Dateien gelöscht werden können (ging in obigem Fall nicht, da es aktive Sessions gab). Der Ordner wird gelöscht, danach wird ein neuer Ordner mit gleichen Rechten angelegt. „chmod 1733“ sind die linux permissions für /var/lib/php/sessions . Die führende „1“vor 733 steht für das „sticky“-Bit. In den Linux Permissions sieht das folgendermßen aus: „drwx-wx-wt“.

Methode 3 mit rsync:

mkdir /var/lib/php/empty_sessions && chmod 1733 empty_sessions
rsync -a --delete /var/lib/php/empty_sessions/ /var/lib/php/sessions/

Hier wird rsync missbraucht, indem ein leeres Verzeichnis (mit gleichen Rechten – sonst gibt es Probleme mit den PHP-Sessions) angelegt wird um dann einen Sync mit delete auszuführen. Resourcenverbrauch im Auge behalten (Speicher).

Methode 4 mit Perl:

cd /var/lib/php/sessions
perl -e 'unlink for <*>'

Setzt natürlich Perl voraus, soll aber schneller sein, als die rsync-Fassung. Deutlich mehr Resourcen als find benötigt.

PS: Hintergrund des Session-Desasters:

PHP führt normalerweise eine eigene Garbage-Collection aus, die zweimal die Stunde ausgeführt wird und alte Sessions löschen soll. Dazu wird über einen crontab (/etc/cron.d/php) ein Script „sessionclean“ aufgerufen (/usr/lib/php/sessionclean).

Existiert dieses Script nicht, gibt es einen Eintrag in /var/log/syslog – ABER: exisitiert die /usr/lib/php/php-helper Datei nicht (wird inkludiert) gibt es keinen Eintrag, die Sessions werden aber auch nicht gelöscht!