在进程启动时调整 oom_score

在进程启动时调整 oom_score

我有几个服务器已经开始 oom-kill 他们的备份进程,虽然我知道遇到 oom 情况本身就很糟糕,但我需要这个过程来不是以便在解决内存问题的同时能够正常进行备份。

为此,我尝试创建一种方式来启动具有调整后的 oom_scores 的进程,其方式类似于使用 启动进程nice

#!/bin/bash

function oom_adj_exec() {
    while getopts ':n:' opt; do
        case $opt in
            n)
                if grep -q '^-\?[0-9]\+$' <(echo "$OPTARG"); then
                    if [ "$OPTARG" -ge -1000 -a "$OPTARG" -le 1000 ]; then
                        oom_score_adjust=$OPTARG
                    else
                        echo "Acceptable values for -n are from -1000 to 1000" >&2
                        return 255
                    fi
                else
                    echo "Improper format for -n: $OPTARG" >&2
                    return 255
                fi
                break
                ;;
            :)
                echo "option -$OPTARG requires a value" >&2
                return 255
                ;;
            *)
                echo "Unknown option -$opt" >&2
                return 255
                ;;
        esac
    done

    command=${@:$OPTIND}

    # job control requires the monitor option which
    # is usually not set for non-interactive shells
    prev_state=$(set +o | grep monitor)
    set -o monitor

    $command &
    pid=$!

    echo "$oom_score_adjust" > /proc/$pid/oom_score_adj

    fg %% > /dev/null

    ecode=$?

    # restore the previous state of the shell
    $prev_state

    return $ecode
}

oom_adj_exec $@

使用示例:

./oom_adj_exec.sh -n -500 /usr/bin/mem_bloater

虽然这似乎行得通,但我还是无法摆脱一种感觉,好像有什么事情正在等着发生可怕的错误。有什么事情明显是真正糟糕的想法和/或即将发生的灾难吗?

答案1

我也这样做过,但效果不太好,就像这样:

(echo 1000 > /proc/self/oom_score_adj && exec /usr/bin/blah)

由于它位于括号中,因此它会启动一个子 shell,为该 shell 设置 OOM 分数(在本例中为 1000,使其在 OOM 情况下极有可能被终止),然后exec用目标程序替换子 shell,同时保持新的 OOM 分数不变。它也不会影响父进程/shell 的 OOM 分数,因为所有操作都在子 shell 内部进行。

相关内容