PHP应用运行过程中会频繁生成临时文件,比如文件上传时的临时缓存、session存储文件、脚本执行过程中的临时数据文件等,这些文件默认会存储到系统tmp目录或者PHP配置的upload目录中。当这些目录所在的磁盘分区空间被完全占满时,新的文件读写操作会直接失败,PHP进程无法正常处理请求,数据库连接也可能因为无法写入日志而中断,最终整个服务就会出现宕机情况。
临时文件目录写满宕机的原理
PHP的临时文件存储逻辑主要分为两类,不同场景下的临时文件写入路径不同:
- 文件上传场景:默认会将上传的文件先存储到
upload_tmp_dir配置指定的目录,如果没有配置该参数,则使用系统默认的tmp目录 - 其他临时文件场景:比如调用
tmpfile()函数生成的临时文件、session默认存储的临时文件,默认都会写入系统tmp目录
当目录所在磁盘使用率达到100%时,所有针对该磁盘的文件写入操作都会返回错误,PHP脚本无法完成文件处理流程,请求就会卡住或者抛出异常,大量请求堆积后就会导致PHP-FPM进程池被占满,最终服务无法响应。
如何清理tmp目录空间
第一步:排查空间占用情况
首先通过命令查看磁盘空间使用情况,确认是否是tmp目录所在分区被写满:
# 查看所有磁盘分区使用情况 df -h # 查看tmp目录下的文件大小分布 du -sh /tmp/*
第二步:清理无用临时文件
清理tmp目录时需要注意,不要直接删除正在被进程使用的临时文件,否则可能导致进程异常。可以先删除修改时间超过一定天数的文件:
# 删除/tmp目录下7天内未被修改的文件,可根据实际情况调整天数 find /tmp -type f -mtime +7 -delete # 如果需要先确认要删除的文件,可以先执行查看命令 find /tmp -type f -mtime +7
如果是PHP的session临时文件占用过多空间,可以单独清理session目录,默认session存储路径可以通过phpinfo()查看session.save_path配置:
# 假设session存储路径为/var/lib/php/session,清理超过3天的session文件 find /var/lib/php/session -type f -mtime +3 -delete
如何修改PHP的upload目录
第一步:准备新的upload目录
首先创建一个空间充足的新目录作为upload目录,并且设置正确的权限,确保PHP进程有权限读写该目录:
# 创建新的upload目录 mkdir -p /data/php_upload # 设置目录所有者为PHP-FPM运行的用户,比如www-data chown www-data:www-data /data/php_upload # 设置目录权限 chmod 755 /data/php_upload
第二步:修改PHP配置文件
找到PHP的配置文件php.ini,修改upload_tmp_dir配置项,指定新的目录路径:
; 找到php.ini中的upload_tmp_dir配置,去掉前面的分号注释,修改为新路径 upload_tmp_dir = /data/php_upload ; 同时可以根据需求调整上传文件大小限制 upload_max_filesize = 20M post_max_size = 20M
如果是使用PHP-FPM的话,有些配置可能会在PHP-FPM的池配置文件中,比如/etc/php/8.1/fpm/pool.d/www.conf,也可以在池配置中单独设置:
; 在www.conf中添加如下配置 php_admin_value[upload_tmp_dir] = /data/php_upload php_admin_value[upload_max_filesize] = 20M php_admin_value[post_max_size] = 20M
第三步:重启PHP服务生效
修改配置后需要重启PHP-FPM服务让配置生效:
# 不同系统重启命令可能不同,以下是常见系统的重启命令 # Ubuntu/Debian系统 systemctl restart php8.1-fpm # CentOS系统 systemctl restart php-fpm
长期预防临时文件写满的措施
- 定期清理临时文件:可以设置定时任务,每天自动清理超过一定天数的临时文件
- 监控磁盘空间:对tmp目录和upload目录所在磁盘设置监控告警,当使用率超过80%时及时通知运维人员
- 分离临时目录磁盘:将tmp目录和upload目录挂载到独立的磁盘分区,避免和业务数据抢占磁盘空间
- 调整临时文件过期时间:针对session等临时文件,合理设置过期回收时间,避免文件长期堆积