1. 概要
とんと知らなかったのですが。
「PHP」は、セッションデータをファイルとして保存しているそうで・・・。
2. 状況
「/tmp」に。
/tmp/sess_05nsesfp1apdn6s6fg4t0sg0bj
/tmp/sess_0hmb1g7mc1uedhqr1qcothblg7
/tmp/sess_0r423ilf7n8kjcujlh5l2uei0p
...
という大量のファイルがありまして。
1つのサイズは、さほど大きくないのですが・・・。
なんじゃろかと「Gemini」伍長に尋ねてみたら。
それらのファイルは、PHPのセッションデータ(Session Data)です。
ウェブサイトにアクセスしたユーザーのログイン状態やカートの中身などを、サーバー側で一時的に保持するために作成される管理ファイルになります。
なぜこれが生成されるのか?
PHPはデフォルトの設定(php.ini)で、セッションの保存先(session.save_path)が /tmp に指定されていることが多く、ユーザーがサイトにアクセスするたびに sess_ で始まるファイルが自動生成されます。
通常はPHPの「ガベージコレクション(不要ファイルを自動で掃除する機能)」が働き、古いセッションファイルを自動的に消去してくれるのですが、FreeBSDなどの環境やPHPの設定によっては、この自動掃除がうまく機能せずに /tmp に大量に残ってしまうことがあります。
ということです。
3. 調査
2026年5月21日時点で。
最古のものが、2026年4月1日 01:19、205件存在します。
現在の「php.ini」の設定は。
session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 1440
で、これは。
・ゴミ掃除ガベージコレクションを実行する(gc_probability)
・ユーザーからアクセスがあった際、1/1000(0.1%)の確率でガベージコレクション)を実行(gc_divisor)
・24分間(1440秒)アクセスがないセッションを「ゴミ(削除対象)」とみなす(gc_maxlifetime)
という設定なのですが、なぜこんなに残っているかと言うと。
原因1:アクセス数が少なくて掃除が実行されていない(確率の問題)
0.1%の確率は、大規模サイトであれば頻繁に掃除が走りますが、アクセス数が少ないサイト(社内ツールや個人開発など)だと、何日も掃除が実行されないことがあります。
原因2:PHPが「ファイル所有者」の権限で掃除できない(FreeBSDで一番多い原因)
FreeBSDで /tmp にセッションを保存している場合、これが一番疑わしいです。
PHPの自動掃除機能は、「今動いているPHPプロセス」の権限で、/tmp 内にある他人のセッションファイルを消そうとします。
しかし、もし複数のユーザーや異なるWebサーバー権限(www や nobody、あるいはPHP-FPMの個別ユーザー)が混在して /tmp にセッションファイルを作っている場合、権限不足(Permission Denied)でPHPが古いファイルを消せずにスキップしてしまい、結果としてファイルが無限に溜まり続ける現象が起きます。
本サイトは、貧相ではありますが、原因1 が考えられるほどアクセスが少ないわけではない。
なので原因2 が想定されますが、ファイルの所有者は「www wheel」になっております。
さらに状況を「Gemini」に説明すると。
ファイルの所有者が www:wheel(あるいは www ユーザー)で作成されているということは、WebサーバーやPHP-FPM(www 権限)から正しく書き込みが行われている証拠です。
しかし、最古のものが4月1日(1ヶ月以上前)のまま200件以上も残っているとなると、PHPのデフォルト設定(1440秒=24分)を遥かに過ぎているため、PHPの内製ガベージコレクションが実質的に機能していない(動いていない)状態と見て間違いありません。
FreeBSDの /tmp に www 権限で置かれているにもかかわらず消えない場合、以下の「FreeBSDならではの仕組み」が干渉している可能性が非常に高いです。
原因:なぜ www 権限なのにPHPが消せないのか?
FreeBSDの /tmp ディレクトリには、セキュリティのために スティッキービット(Sticky Bit) という特殊な権限が設定されています(drwxrwxrwt の t の部分です)。
スティッキービットの特性:
ディレクトリ内のファイルは、「そのファイルの所有者」 または 「root(wheel)」 しか削除・名前変更ができません。
「www が作ったファイルなら、www 権限で動くPHPが消せるのでは?」と思いがちですが、ここに罠があります。
PHPのガベージコレクションは、/tmp 内のファイルを全スキャンして条件に合うものを消そうとします。しかし、FreeBSDの /tmp のようなスティッキービット環境下で、PHP-FPMのプロセスがマルチスレッドや別の子プロセス(一瞬権限が変わる、あるいは完全に同一オーナーとして認識されないシステムコールの制限など)で動いていると、OSのファイルシステム側から「他人のファイルを消そうとした」と判定されて拒否されるケースが多々ありま。
結果として、PHPはエラーを出さずに「消せなかったからスキップ」を繰り返し、1ヶ月前のファイルがそのまま居座り続けることになります。
で、対策としては、2つあるそうです。
・システムの定期タスク(cron)に抹殺を任せる(一番手軽)
・セッションの保存先を /tmp から避難させる(王道)
わたしは、「cron」の処理をあまり増やしたくないし、「/tmp」を整理したいので、後者の方法をとりたいと思います。
4. 対策
以下、「root」ユーザ権限で。
セッションファイルの置き場所を作成して、所有者を「www」にします。
mkdir -pv /var/session/php
chown www:www /var/session/php
chmod 755 /var/session/php
設定を変更します。
vi /usr/local/etc/php.ini
下記を記述します。
session.gc_probability = 1
session.save_path = "/var/session/php"
session.gc_divisor = 10
session.gc_maxlifetime = 1440
設定後、念のため。
service apache24 configtest
して問題なければ、再起動します。
service apache24 restart
service php_fpm restart