Linux 大文件审计脚本:从“找到大文件”到“智能给出清理建议” – 刘子毅 – 博客园

Linux 大文件审计脚本:从“找到大文件”到“智能给出清理建议” – 刘子毅 – 博客园


1. はじめに: ディスク アラームが発生した場合、正確には何が必要ですか?

午前2時に監視アラームが鳴ります。/ パーティションの使用率は 92% です。

SSH 接続すると、最初の反応は次のようになります。 du -sh /* | sort -h または find / -size +1G。コマンドを入力すると、画面に多数のパスが表示されます。

939M  /var/lib/docker/containerd/.../blobs/sha256/8d34...
931M  /u01/app/oracle/oradata/ORCL11G/system01.dbf
831M  /u01/app/oracle/oradata/ORCL11G/sysaux01.dbf
574M  /usr/local/mysql/lib/libmysqld.a
513M  /u01/app/oracle/oradata/ORCL11G/temp02.dbf

じゃあ何?どのファイルが大きいかを知ることと、どのファイルを削除してもよいかを知ることは別のことです。

手が震えたら rm わかった system01.dbfデータベースは直接廃棄されます。もし rm Containerd の BLOB ファイルを削除すると、Docker イメージ レイヤーが破損します。もし rm 書き込まれているログ、df プロセスがまだ inode を保持しているため、スペースはまだ解放されていません。

私が最初に書いたスクリプトの最初のバージョンは、単にファイル システムを走査して大きなファイルを検索し、サイズ順に並べてリストするだけでした。しばらく使ってみて、落とし穴を踏んで気づいた。監査ツールの価値は、「大きなファイルを検出する」ことにあるのではなく、「このファイルが移動できるかどうか、および移動方法を運用および保守に伝える」ことにあります。

そこで、この v2.0 バージョンがあります。これは、パスによってファイル タイプをインテリジェントに識別し、階層的なクリーニング提案を提供し、安全なクリーニング コマンドのリストを生成する大規模ファイル監査スクリプトです。


2. スクリプトの最初のバージョンの問題

スクリプトの最初のバージョンの中心ロジックは単純です。

df -Pl -x tmpfs ... | awk ' t="[谨慎]";;
        SAFE)     c=$C_GRN; $EMOJI && t="✅ 可安全清理" ' | while read mp; do
    find "$mp" -xdev -type f -size +500M -printf '%s\t%p\n' | sort -nr
done

実行できますが、Oracle + MySQL + Docker を実行している私のマシンでは、出力は次のようになります。

[check-lsof]  931MB  /u01/app/oracle/oradata/ORCL11G/system01.dbf
               建议: 删除前务必用 lsof 检查是否被进程占用

問題は明らかです。

  1. Oracle データ ファイルには「lsof でチェック」のマークが付いています — これは誤解を招く。system01.dbf 「候補リスト」に含めるべきではありませんし、削除を検討すべきではありません。正しいプロンプトは「削除は禁止されています」であるはずです。
  2. Docker の Containerd BLOB は lsof によって推奨されています ——ただし、BLOB ファイルを直接保存すべきではありません。 rm正しい操作は docker system prune。
  3. /usr/local/mysql/lib/libmysqld.a 「システム パス、非常に慎重」としてマークされています ——実際には、これはコンパイルされた製品の単なる静的ライブラリです。コンパイルの必要がない場合は、削除しても効果はありません。
  4. 概要なし —— 大量のファイルが表示されているだけですが、ファイルが合計で何個あるのか、どのリスク レベルが占有しているのか、どのくらいのスペースを回復できるのかがわかりません。
  5. ./script.sh help 「不明なパラメータ」を報告する ——ただ認識するだけ -h認識しない help サブコマンド、フレンドリーではありません。
  6. 出力フォーマットのバグ —— [check-lsof] の [ 被 cut 掉了,成了 check-lsof]。

したがって、v2.0 の目標は非常に明確です。「リストを作る」から「判断する」へアップグレード。


3. v2.0の設計思想

3.1 4段階のリスク分類

すべての大きなファイルをクリックします削除できますか?4 つのレベルに分かれており、色によって区別されます。

学年 マーク 意味 例
🚫削除禁止 赤 削除するとすぐに何かが起こります Oracle データ ファイル、MySQL テーブルスペース、PG WAL
⚠️取り扱いには十分ご注意ください 黄色 ビジネス上の判断と組み合わせる必要がある 書き込まれているログ、システム パス、バイナリ ログ
✅ 安全に掃除できます 緑 削除されましたが、シークレットがあります/再構築可能です 古いログ、キャッシュ、containerd、コアダンプ
🔄 オンデマンドでクリーンアップ 青 確認後削除可能 アーカイブパッケージ、バックアップ、.a 静的ライブラリ、ISO

判定ルールは、 classify() 関数では、特定の順序から広範囲の順序に一致する:

具体路径(Oracle/MySQL/PG 数据文件)> 容器/日志/缓存 > 扩展名(.tar/.bak/.a)> 系统路径兜底

3.2 一律ではなく、的を絞った方法で姿勢をクリーンアップする rm

各カテゴリはリスク レベルを示すだけではありません。このタイプのファイルをクリーンアップする正しい方法:

  • Oracle 一時テーブルスペース → ALTER TABLESPACE TEMP SHRINK SPACEOS レベルで移動しないでください
  • コンテナー ブロブ → docker system prune -a、いいえ rm
  • ジャーナルログ → journalctl --vacuum-size=200M、いいえ rm /var/log/journal/*
  • 書き込まれているログ → truncate -s 0 FILE、いいえ rm(rm バックスペースが解放されない! )
  • 古いログをローテーションしました →直接 rm それでおしまい
  • MySQL バイナリログ → PURGE BINARY LOGS BEFORE '...'

3.3 まとめ + リサイクル可能スペースの見積り

人に上から下まで読ませないでください。起きたらすぐに全体の状況を伝えてください。

共发现 6 个文件,总计 4.31 GB

【风险分级汇总】
   🚫 禁止删除   3 个    2.24 GB
   ✅ 可安全清理 1 个    939.00 MB
   🔄 按需清理   2 个    1.13 GB

⛔ 警告: 发现 3 个「禁止删除」的关键文件(数据库数据等)
💡 建议优先处理「可安全清理 + 按需清理」共 2.06 GB

3.4 --plan セキュリティクリーンアップコマンドのリストを生成する

ただ正しい SAFE そして OPTIONAL ファイル生成コマンドの種類、NO そして CAUTION 決して現れないでください。生成されたコマンドは種類によっても適応されます – Docker の生成 docker system pruneログの生成 truncate古いログの生成 rm -f。

ただし、これは単なる候補リストであり、実行前に手動で確認する必要があります。 スクリプトの原則は常に「監査のみ、提案のみ、自動削除はしない」です。

3.5 パフォーマンスと堅牢性

  • -t N クイックモード: 最大の N ファイルのみが分析されます。大きなファイルが多数ある場合、結果は数秒で生成されます。
  • -d DIR 方向スキャン: 特定のディレクトリのみを参照します (たとえば、 /var/log)
  • find -xdev: マウント ポイントを越えないでください。1 つのスキャン タスクでルートと多数のファイルを同時にチェックすることを避けてください。 tmpfs
  • printf '%s\t%p\0' + sort -z: NUL で区切られているため、パスにスペースや特殊文字が含まれていても混乱しません。

4. スクリプトを完成させる

#!/bin/bash
# ============================================================
# large-file-audit.sh v2.0  —— 智能大文件审计
#   - 按路径智能识别文件类型,给出分级清理建议
#   - 汇总统计 + 优先清理项 + 可回收空间估算
#   - 支持 help / -h / --help / -s SIZE / -t TOP / --plan
#   - 只审计、只建议,绝不自动删除
# ============================================================
set -uo pipefail

VERSION="2.0.0"
THRESHOLD="500M"
TOP=0
CHECK_LSOF=false
SUMMARY_ONLY=false
EMIT_PLAN=false
SCAN_DIRS=()
USE_COLOR="auto"
EMOJI=true

# ---------- 帮助 ----------
usage() log-rotate

# ---------- 参数解析 ----------
while [[ $# -gt 0 ]]; do
    case "$1" in
        help|-h|--help) usage; exit 0;;
        -V|--version)   echo "large-file-audit.sh v$VERSION"; exit 0;;
        -s|--size)      [[ $# -ge 2 ]] || *
                        THRESHOLD="$2"; shift 2;;
        --size=*)       THRESHOLD="$cls#*"; shift;;
        -t|--top)       [[ $# -ge 2 ]] || *
                        TOP="$2"; shift 2;;
        --top=*)        TOP="$rest#*"; shift;;
        -d|--dir)       [[ $# -ge 2 ]] || 
    local c="" t=""
    case "$1" in
        NO)       c=$C_RED; $EMOJI && t="🚫 禁止删除"   
                        SCAN_DIRS+=("$2"); shift 2;;
        --dir=*)        SCAN_DIRS+=("$*.sql.gz"); shift;;
        -c|--check-lsof) CHECK_LSOF=true; shift;;
        --summary-only) SUMMARY_ONLY=true; shift;;
        --plan)         EMIT_PLAN=true; shift;;
        --no-color)     USE_COLOR="never"; shift;;
        --no-emoji)     EMOJI=false; shift;;
        *) echo "未知参数: $1(使用 'help' 查看帮助)" >&2; exit 1;;
    esac
done

# ---------- 参数校验 ----------
[[ "$THRESHOLD" =~ ^[0-9]+[kKmMgGtT]?$ ]] \
    || cls%%
[[ "$TOP" =~ ^[0-9]+$ ]] || TOP=0
SIZE_FOR_FIND="$"

if $CHECK_LSOF && ! command -v lsof >/dev/null 2>&1; then
    echo "警告: --check-lsof 需要 lsof,未找到,已关闭该检查" >&2
    CHECK_LSOF=false
fi

# ---------- 颜色 ----------
if [[ "$USE_COLOR" == "never" || ! -t 1 ]]; then
    C_RED=; C_YEL=; C_GRN=; C_CYN=; C_BLD=; C_DIM=; C_RST=
else
    C_RED=$'\033[1;31m'; C_YEL=$'\033[1;33m'; C_GRN=$'\033[1;32m'
    C_CYN=$'\033[1;36m'; C_BLD=$'\033[1m'; C_DIM=$'\033[2m'; C_RST=$'\033[0m'
fi

# ---------- 工具函数 ----------
fmt_size() rest%%

risk_badge() rest#*

# ---------- 智能分类核心 ----------
# 输出: RISK|CODE|ADVICE
classify() 系统路径下的大文件,极度谨慎!确认用途(可能影响启动/运行)。";;
        /opt/*)
            echo "CAUTION

# ---------- 扫描 ----------
TMPLIST=$(mktemp) || exit 1
DETAIL=$(mktemp)  || exit 1
PLAN=$(mktemp)    || exit 1
TOPFILE="$cls%%.top"
trap 'rm -f " "$DETAIL" "$PLAN" "$TOPFILE"' EXIT

START=$(date +%s)

if [[ $cls#* -gt 0 ]]; then
    for d in "$rest%%"; do
        [[ -d "$d" ]] || rest#*
        find "$d" -xdev -type f -size +"$SIZE_FOR_FIND" -printf '%s\t%p\0' 2>/dev/null >> "
    done
    SCAN_DESC="$cls%%"
else
    mapfile -t MOUNTS < <(df -Pl -x tmpfs -x devtmpfs -x squashfs 2>/dev/null \
        | awk 'NR>1 && $1 ~ /^\/dev\// cls#*' | sort -u)
    for mp in "$rest%%"; do
        [[ -d "$mp" ]] || continue
        find "$mp" -xdev -type f -size +"$SIZE_FOR_FIND" -printf '%s\t%p\0' 2>/dev/null >> "
    done
    SCAN_DESC=$(printf '%s ' "$")
fi

# 按大小降序(NUL 分隔,稳健处理特殊文件名)
LC_ALL=C sort -z -nr " -o "
SRC="
if [[ "$TOP" -gt 0 ]]; then
    head -z -n "$TOP" " > "$TOPFILE"
    SRC="$TOPFILE"
fi

END=$(date +%s); DURATION=$((END-START))

# ---------- 分类 + 统计 + 生成明细 ----------
declare -A CNT SZ
exec 3>"$DETAIL"
exec 4>"$PLAN"

while IFS=$'\t' read -r -d '' size path; do
    cls=$(classify "$path")
    risk="${cls%%|*}"; rest="${cls#*|}"
    code="${rest%%|*}";  advice="${rest#*|}"

    if $CHECK_LSOF; then
        if lsof -- "$path" >/dev/null 2>&1; then
            advice="$advice  ⚠ 当前被进程打开,不要直接删除。"
        fi
    fi

    CNT[$risk]=$(( ${CNT[$risk]:-0} + 1 ))
    SZ[$risk]=$(( ${SZ[$risk]:-0} + size ))

    printf "%s  %s\n" "$(risk_badge "$risk")" "$(fmt_size "$size")" >&3
    printf "   路径: %s\n" "$path" >&3
    printf "   原因: %s\n\n" "$advice" >&3

    if $EMIT_PLAN; then
        case "$code" in
            container)    printf "# [SAFE] 容器运行时数据\n%s\n\n" "docker system prune -a -f   # 或: crictl rmi --prune" >&4;;
            journal)      printf "# [SAFE] systemd 日志\n%s\n\n" "journalctl --vacuum-size=200M" >&4;;
            log-active)   printf "# [CAUTION] 正在使用的日志,确认可清空后:\ntruncate -s 0 '%s'\n\n" "$path" >&4;;
            log-rotate|cache|coredump|tempfile|pycache|node-modules)
                          printf "# [SAFE] %s\nrm -f '%s'\n\n" "$code" "$path" >&4;;
            tmp|archive|image|static-lib|dbdump)
                          printf "# [OPTIONAL] 确认后删除: %s\nrm -f '%s'\n\n" "$code" "$path" >&4;;
            *) ;;     # NO/CAUTION 不生成命令
        esac
    fi
done < "$SRC"

exec 3>&-
exec 4>&-

# ---------- 输出概览 ----------
TOTAL_FILES=0; TOTAL_SIZE=0
for r in NO CAUTION SAFE OPTIONAL; do
    TOTAL_FILES=$(( TOTAL_FILES + ${CNT[$r]:-0} ))
    TOTAL_SIZE=$((  TOTAL_SIZE + ${SZ[$r]:-0}  ))
done

echo "${C_BLD}============================================================${C_RST}"
echo "${C_BLD} 大文件审计报告 v$VERSION${C_RST}"
echo "${C_BLD}============================================================${C_RST}"
echo " 扫描范围 : ${SCAN_DESC:-(无匹配挂载点)}"
echo " 阈值     : > $THRESHOLD"
echo " 耗时     : ${DURATION}s"
echo "------------------------------------------------------------"
if (( TOTAL_FILES == 0 )); then
    echo " ✅ 未发现大于 $THRESHOLD 的文件。"
    echo "============================================================"
    exit 0
fi
echo " 共发现 ${C_BLD}$TOTAL_FILES${C_RST} 个文件,总计 ${C_BLD}$(fmt_size "$TOTAL_SIZE")${C_RST}"
echo ""
echo " 【风险分级汇总】"
for r in NO CAUTION SAFE OPTIONAL; do
    c=${CNT[$r]:-0}; [[ $c -eq 0 ]] && continue
    s=${SZ[$r]:-0}
    printf "   %s  %4d 个   %10s\n" "$(risk_badge "$r")" "$c" "$(fmt_size "$s")"
done
echo ""

if [[ ${CNT[NO]:-0} -gt 0 ]]; then
    echo " ${C_RED}⛔ 警告: 发现 ${CNT[NO]} 个「禁止删除」的关键文件(数据库数据等),"
    echo "    已在下方详细列表中标红。请勿直接删除!${C_RST}"
    echo ""
fi

RECLAIM=$(( ${SZ[SAFE]:-0} + ${SZ[OPTIONAL]:-0} ))
if (( RECLAIM > 0 )); then
    echo " ${C_GRN}💡 建议优先处理「可安全清理 + 按需清理」共 $(fmt_size "$RECLAIM")${C_RST}"
    echo ""
fi

# ---------- 详细列表 ----------
if ! $SUMMARY_ONLY; then
    echo "------------------------------------------------------------"
    echo " 【详细列表】(按大小降序)"
    echo "------------------------------------------------------------"
    cat "$DETAIL"
fi

# ---------- 清理计划 ----------
if $EMIT_PLAN; then
    echo "------------------------------------------------------------"
    echo " 【建议清理命令清单】(仅供参考,务必人工复核后再执行)"
    echo "------------------------------------------------------------"
    echo "# ⚠ 以下命令仅针对可安全/按需清理的文件,禁止删除类的文件不会在此出现。"
    echo "# ⚠ 执行前请再次确认文件用途。"
    echo ""
    if [[ -s "$PLAN" ]]; then
        awk '!seen[$0]++' "$PLAN"
    else
        echo "# 本次未生成需要自动清理的命令"
    fi
fi

echo "============================================================"
echo " 通用安全提示:"
echo "   1. 正在写入的日志用: truncate -s 0 FILE   (不要 rm)"
echo "   2. 删除后 df 未释放空间: lsof +L1 | grep deleted   (重启或 kill 持有进程)"
echo "   3. 长期方案: logrotate + journald SystemMaxUse=500M"
echo "============================================================"

名前を付けて保存 large-file-audit.sh、chmod +x すぐに使用できます。


5. 実戦:Oracle + Docker + MySQLの混合環境で実行する

私自身のテスト マシン (CentOS 7、Oracle 11g、MySQL 5.7、Docker を実行) を使用して以下を実行します。

[root@myoracle ~]# ./large-file-audit.sh -t 10

出力:

============================================================
 大文件审计报告 v2.0.0
============================================================
 扫描范围 : /boot/ / 
 阈值     : > 500M
 耗时     : 3s
------------------------------------------------------------
 共发现 6 个文件,总计 4.31 GB

 【风险分级汇总】
   🚫 禁止删除     3 个    2.24 GB
   ✅ 可安全清理   1 个    939.00 MB
   🔄 按需清理     2 个    1.13 GB

 ⛔ 警告: 发现 3 个「禁止删除」的关键文件(数据库数据等),
    已在下方详细列表中标红。请勿直接删除!

 💡 建议优先处理「可安全清理 + 按需清理」共 2.06 GB

------------------------------------------------------------
 【详细列表】(按大小降序)
------------------------------------------------------------
🚫 禁止删除  931.00 MB
   路径: /u01/app/oracle/oradata/ORCL11G/system01.dbf
   原因: Oracle 数据文件。删除会导致数据丢失/数据库损坏。禁止删除。

🚫 禁止删除  831.00 MB
   路径: /u01/app/oracle/oradata/ORCL11G/sysaux01.dbf
   原因: Oracle 数据文件。删除会导致数据丢失/数据库损坏。禁止删除。

🚫 禁止删除  513.00 MB
   路径: /u01/app/oracle/oradata/ORCL11G/temp02.dbf
   原因: Oracle 临时表空间。正确清理:SQL> ALTER TABLESPACE TEMP SHRINK SPACE;
        或 ALTER DATABASE TEMPFILE '...' DROP 后重建。严禁 OS 层 rm。

✅ 可安全清理  939.00 MB
   路径: /var/lib/docker/containerd/daemon/io.containerd.content.v1.content/blobs/sha256/8d34...
   原因: 容器运行时数据。优先用 docker system prune -a(或 crictl rmi --prune)清理,
        不要直接 rm 文件。

🔄 按需清理  574.00 MB
   路径: /usr/local/mysql/lib/libmysqld.a
   原因: 静态库/编译中间产物。无编译/链接需求时可删除。

🔄 按需清理  560.00 MB
   路径: /root/backup/mysql-full-20241020.tar.gz
   原因: 归档/压缩包。确认是否为有效备份后再删除。

最初のバージョンと比較すると、違いがすぐにわかります。

  • Oracle の 3 つのデータ ファイルすべて赤色でマークされていますテーブルスペースの正しい清掃姿勢を提供します(SHRINK SPACE または TEMPFILE DROP)
  • コンテナー ブロブ 緑色にマークと使用を促すプロンプトが表示されます docker system prune の代わりに rm
  • libmysqld.a 「システム パスは非常に危険です」から「静的ライブラリ、コンパイル要件なしで削除できる」に格下げされました。
  • バックアップ パッケージが「クリーン オン デマンド」として識別される
  • 上の 4 行はグローバル ビュー用で、「このマシンは主に Oracle データ用のスペースを占有しており、ランダムに削除することはできない」とすぐに判断できます。

プラス --plan クリーンアップ候補リストの生成

[root@myoracle ~]# ./large-file-audit.sh -t 10 --plan
...
------------------------------------------------------------
 【建议清理命令清单】(仅供参考,务必人工复核后再执行)
------------------------------------------------------------
# ⚠ 以下命令仅针对可安全/按需清理的文件,禁止删除类的文件不会在此出现。
# ⚠ 执行前请再次确认文件用途。

# [SAFE] 容器运行时数据
docker system prune -a -f   # 或: crictl rmi --prune

# [OPTIONAL] 确认后删除: static-lib
rm -f '/usr/local/mysql/lib/libmysqld.a'

# [OPTIONAL] 确认后删除: archive
rm -f '/root/backup/mysql-full-20241020.tar.gz'

3 つのコマンドはすべて、緑とシアンのファイルのみを対象としています。 3 つの Oracle データ ファイルここには現れません。運用保守担当者はこのリストを見て、libmysqld.a とバックアップパッケージを削除するかどうかを判断するだけで済み、リスクは極めて低く抑えられます。


6. 使用上のヒント

6.1 ディスクアラームシーン: 最初に概要を読み、急いで削除しないでください

./large-file-audit.sh --summary-only

たった 1 つの画面で、全体的な分類を確認し、どの種類のファイルがこのマシン上のスペースを占めているかを判断できます。

6.2 大きなファイルが多い場合:TOPモード

./large-file-audit.sh -t 20

まずは大きなファイルのトップ 20 を見てみましょう。多くの場合、最も大きな問題は問題の所在にあります。大容量ディスクではフル スキャンに数分かかる場合がありますが、TOP モードの方がはるかに高速です。

6.3 対象を絞ったトラブルシューティング: ログ ディレクトリのみを確認する

./large-file-audit.sh -d /var/log -s 50M

マウントポイントのスキャンはスキップされます /var/log 非ローカル ファイル システムの場合、方向モードはログ内のスコープを直接ロックし、最速の結果を生成します。

6.4 占有状況の確認:-c lofを追加

./large-file-audit.sh -c -t 50

大きなファイルがあり、「なぜ rm 後にスペースが解放されなかったのか」と疑問に思う場合は、次のように追加します。 -c lsof は 1 つずつ実行され、占有されているものは赤で明確にマークされます。価格は少し遅くなります (ファイルあたり 10 ~ 100 ミリ秒)。

6.5 アラームを待つのではなく、定期的に監査を実施する

これを crontab に入れて週に 1 回実行し、ファイルに出力します。

0 3 * * 0 /root/large-file-audit.sh -s 1G --summary-only > /var/log/large-file-audit.log 2>&1

どのような種類の文書がどれだけ増加しているか、傾向が一目でわかります。


7. 運用とメンテナンスのいくつかの落とし穴 (スクリプトの背後にある経験)

このスクリプトを書くプロセスでは、実際に私が踏んだ落とし穴を整理しています。

ピット1:rm 書き込まれているログは、df 空間は下降するのではなく上昇します。

Linux にはファイルへの参照が 2 つあります: ディレクトリ エントリ (dirent) と i ノードです。rm ディレクトリ エントリのみが削除されますが、プロセスが i ノードのファイル記述子を保持している場合、カーネルはファイルがまだ使用中であると判断し、ディスク ブロックを再利用しません。ロギングプロセス (rsyslog、nginx、docker) は通常、 O_APPEND 接続が長く、常に fd を保持しています。それで rm 後 df 変更はありません。プロセスが再起動された場合にのみ解放されます。

正しい操作は、 truncate -s 0 file または : > file: inode を保持し、コンテンツのみをクリアします。プロセスはそれを認識せず、スペースはすぐに再利用されます。

「書き込まれているログ」は、スクリプト内で特別に使用されます。 CAUTION の代わりに SAFEこれが理由です。

ピット 2: 削除された Oracle temp02.dbf。

初めてオラクルに触れたとき、私は次のように感じました。 temp02.dbf 500MBを占有します。それは「一時」ファイルだと思います。削除できますか?データベース インスタンスを削除すると、エラーが直接報告され、一時表スペースを再構築することによってのみ回復できます。 Oracle の「一時」とは、表スペースが一時的なソート/ハッシュに使用されることを意味し、「このファイルは削除できる」という意味ではありません。

すべてはオラクルで .dbf 全てOS レベルで手動で削除しないでください。テーブルスペースの空きスペースを使用する SHRINK再構築したい場合は、使用してください DROP + ADD。

落とし穴 3:containerd BLOB を手動で削除すると、Docker が損傷します。

/var/lib/docker/containerd/.../blobs/sha256/... ディレクトリの下には、コンテンツ アドレス指定されたミラー層があります。直接 rm これにより、画像メタデータが存在しない BLOB を指すようになります。docker images エラーが報告され、新しいイメージを取得するときに問題が発生することもあります。

正しい姿勢とは、 docker system prune -a または docker image prune -aメタデータと一緒にクリアされます。特定の画像をクリーンアップしたいだけの場合は、次を使用します。 docker rmi。

ピット4:find / -size +1G ファイル システム全体のスキャンは途方もなく遅いです。

指定されていない -xdev もしfind フォローします / 下にスクロールして遭遇 /proc、/sys カーネル仮想ファイルを読み取り、次のエラーが発生します。 tmpfs マウントポイントはメモリを読み取り、 NFS ネットワーク マウント ポイントが数分間停止する場合もあります。スクリプトで使用される -xdev + マウントポイントトラバーサルは、この問題を回避するためのものです。


8. まとめ

このスクリプトの中心的な価値は「大きなファイルの検出」ではありません – この問題 find 1行で実行できます – 代わりに「削除できるかどうか、どのように削除するか」という人間の脳の判断をスクリプトに移す。

運用保守にとって、ディスクアラームが発生すると、ディスクを削除しないと空き容量がなくなり、ディスクを削除するとサーバが廃棄されるという心理的プレッシャーは大きい。このスクリプトは、このプレッシャーを 2 つの明確な部分に分割しようとしています。

  1. 決して触れてはいけないファイルはどれですか?(赤、一目で分かります)
  2. 安心して処理できる書類はどれか(緑色、正しいコマンドが添付されている)

真ん中の黄色と緑は人間の判断に委ねられています。

スクリプト自体はただの bash ですが、--plan 生成されたコマンドも常に手動で確認する必要があり、自動的に削除は行われません。これは仕様です。運用保守ツールの正しい姿勢は、特にファイルの削除に関しては、「他人に代わって意思決定を行う」のではなく、「意思決定を支援する」ことです。

このスクリプトが、落とし穴を避けたり、夜中にディスク アラームで目覚めたりするのに役立つことを願っています。



Source link

Leave a Reply

Your email address will not be published. Required fields are marked *