【问题标题】:Cron sessionclean errors: find: `/proc/xxxxx/fd': No such file or directoryCron sessionclean 错误:find: `/proc/xxxxx/fd': No such file or directory
【发布时间】:2019-09-23 14:49:18
【问题描述】:

PHP 升级后,我开始每天多次收到以下 cron 错误:

find: `/proc/xxxxx/fd': No such file or directory

它来自 PHP sessionclean cron 作业:

[ -x /usr/lib/php5/sessionclean ] && /usr/lib/php5/sessionclean

有什么想法吗?

【问题讨论】:

  • 您是否尝试过重新启动托管它的机器? ;) 另外你能确认session.save_path 配置的路径吗?
  • sessionclean 尝试更新非现有 php 进程的会话。也许你应该重启机器或者至少重启apache来更新php进程信息。
  • 重启没有帮助。会话 save_path 设置为:/var/lib/php5/sessions 这些错误并非每次都会发生(sessionclean 每 30 分钟运行一次,此错误有时一天出现几次,有时几天才出现一次)。除此之外,大多数脚本使用自定义会话处理程序,这意味着会话文件夹几乎总是空的
  • 检查你是否有权限或创建文件如果可能的话设置你自己的 session.save_path 像 ini_set('session.save_path',realpath(dirname($_SERVER['DOCUMENT_ROOT']) .'/ ../会议'));那就试试

标签: php session cron find


【解决方案1】:

现在有一个关于此的 Debian 错误报告(和fixed)。

它提到了稳定版:

在下一次安全上传中,例如5.6.23 后大约两周是 已发布,除非出现其他关键问题。

5.6.23 已经发布,所以我预计会在接下来的两周内发布。

这里的修复是添加

if [ -d "/proc/$pid/fd" ]; then

之前

find "/proc/$pid/fd"

命令。

【讨论】:

    【解决方案2】:

    您可以忽略这些错误,sessionclean 搜索附加到不再存在的 pid 的会话。

    [ -x /usr/lib/php5/sessionclean ] && /usr/lib/php5/sessionclean 2>/dev/null
    

    您应该查看您的会话目录以检查它们是否已正确清理,因为此类消息可能是处理时间过长的症状。

    【讨论】:

    • 感谢您的回复。如果脚本有问题,我不希望抑制这些错误以得到通知。会话文件夹被正确清理并且几乎总是空的,因为大多数脚本都使用自定义会话处理程序。我检查了文件夹的内容——它保存了当前的会话文件,如果有的话,通常只有几个文件。我想知道这个问题的真正原因是什么以及如何解决它(而不是抑制错误)......
    • 没有错:在 sessionclean 脚本执行过程中进程已经结束。如果您不想抑制任何其他错误,则必须修改脚本。
    • @Adam 我也遇到了这个问题,但不知道该怎么想。在 /etc/php5/apache2/php.ini 我没有save_path,但在 /var/lib/php5/sessions 中有两个小时前的会话文件。我认为他们应该在那里,但我不知道如何确定。此外,/proc/xxxx/fd 中的 xxxx 始终用于活动的 apache2 进程。我不知道该怎么想。
    【解决方案3】:

    我找到了一种消除错误的方法,不过,关于您是在消除问题还是只是掩盖问题,所有的赌注都没有了。我有几个容器在运行,有的有这个问题,有的没有。

    会产生错误的 /usr/lib/php5/sessionclean 是:

    #!/bin/sh -e
    
    SAPIS="apache2:apache2\napache2filter:apache2\ncgi:php5\nfpm:php5-fpm\n"
    
    # Iterate through all web SAPIs
    (
    printf "$SAPIS" | { \
    proc_names=""
    while IFS=: read -r conf_dir proc_name; do
        if [ -e /etc/php5/${conf_dir}/php.ini ]; then
            # Get all session variables once so we don't need to start PHP to get each config option
            session_config=$(php5 -c /etc/php5/${conf_dir}/php.ini -d "error_reporting='~E_ALL'" -r 'foreach(ini_get_all("session") as $k => $v) echo "$k=".$v["local_value"]."\n";')
            save_handler=$(echo "$session_config" | sed -ne 's/^session\.save_handler=\(.*\)$/\1/p')
            save_path=$(echo "$session_config" | sed -ne 's/^session\.save_path=\(.*\)$/\1/p')
            gc_maxlifetime=$(($(echo "$session_config" | sed -ne 's/^session\.gc_maxlifetime=\(.*\)$/\1/p')/60))
    
            if [ "$save_handler" = "files" -a -d "$save_path" ]; then
                proc_names="$proc_names $proc_name";
                printf "%s:%s\n" "$save_path" "$gc_maxlifetime"
            fi
        fi
    done
    # first find all open session files and touch them (hope it's not massive amount of files)
    for pid in $(pidof $proc_names); do
        find "/proc/$pid/fd" -ignore_readdir_race -lname "$save_path/sess_\*" -exec touch -c {} \;
    done
    } ) | sort -rn -t: -k2,2 | sort -u -t: -k 1,1 | while IFS=: read -r save_path gc_maxlifetime; do
        # find all files older then maxlifetime and delete them
        find -O3 "$save_path" -depth -mindepth 1 -name 'sess_*' -ignore_readdir_race -type f -cmin "+$gc_maxlifetime" -delete
    done
    
    exit 0
    

    但是,如果我从一个不会产生错误的容器中用 /usr/lib/php5/sessionclean 替换它,那就是:

    #!/bin/sh -e
    
    SAPIS="apache2:apache2\napache2filter:apache2\ncgi:php5\nfpm:php5-fpm\n"
    
    # Iterate through all web SAPIs
    (
    proc_names=""
    printf "$SAPIS" | \
    while IFS=: read -r conf_dir proc_name; do
        if [ -e /etc/php5/${conf_dir}/php.ini ]; then
            # Get all session variables once so we don't need to start PHP to get each config option
            session_config=$(php5 -c /etc/php5/${conf_dir}/php.ini -d "error_reporting='~E_ALL'" -r 'foreach(ini_get_all("session") as $k => $v) echo "$k=".$v["local_value"]."\n";')
            save_handler=$(echo "$session_config" | sed -ne 's/^session\.save_handler=\(.*\)$/\1/p')
            save_path=$(echo "$session_config" | sed -ne 's/^session\.save_path=\(.*\)$/\1/p')
            gc_maxlifetime=$(($(echo "$session_config" | sed -ne 's/^session\.gc_maxlifetime=\(.*\)$/\1/p')/60))
    
            if [ "$save_handler" = "files" -a -d "$save_path" ]; then
                proc_names="$proc_names $proc_name";
                printf "%s:%s\n" "$save_path" "$gc_maxlifetime"
            fi
        fi
    done
    # first find all open session files and touch them (hope it's not massive amount of files)
    for pid in $(pidof $proc_names); do
        find "/proc/$pid/fd" -ignore_readdir_race -lname "$save_path/sess_\*" -exec touch -c {} \;
    done
    ) | sort -rn -t: -k2,2 | sort -u -t: -k 1,1 | while IFS=: read -r save_path gc_maxlifetime; do
        # find all files older then maxlifetime and delete them
        find -O3 "$save_path" -depth -mindepth 1 -name 'sess_*' -ignore_readdir_race -type f -cmin "+$gc_maxlifetime" -delete
    done
    
    exit 0
    

    然后我没有得到错误。

    【讨论】:

      猜你喜欢
      • 2016-11-01
      • 2020-03-19
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      • 2018-09-30
      • 2019-03-25
      相关资源
      最近更新 更多