解决服务器磁盘空间不足问题的两个办法

nginx 如何限定log文件的尺寸

要限定 Nginx 日志文件的尺寸,正确且最常用的方法并非在 Nginx 的配置文件中直接设置,因为 Nginx 本身没有提供按文件大小自动切割日志的功能

正确的做法是使用一个名为 logrotate 的标准 Linux 工具。logrotate 是一个强大的日志管理工具,它可以根据文件大小、时间(每天、每周、每月)等策略来自动轮转、压缩和删除日志文件。

几乎所有的 Linux 发行版(包括 CentOS, Ubuntu, Debian 等)都预装了 logrotate。通过配置 logrotate,您可以实现:

  1. 当日志文件达到指定大小时,将其重命名。
  2. 创建一个新的空日志文件供 Nginx 继续写入。
  3. 压缩旧的日志文件以节省磁盘空间。
  4. 定期删除过旧的日志文件。

下面是具体的操作步骤和配置示例。


使用 logrotate 限定 Nginx 日志大小

第 1 步:创建 logrotate 配置文件

为 Nginx 创建一个专门的 logrotate 配置文件。这个文件通常放在 /etc/logrotate.d/ 目录下。如果您的系统中已经有了一个名为 nginx 的文件,可以直接修改它;如果没有,就创建一个新文件。

使用文本编辑器(如 vimnano)创建文件:

1
sudo vim /etc/logrotate.d/nginx

第 2 步:编写配置文件内容

向该文件中添加以下内容。这是一个非常实用且通用的配置模板,您可以根据自己的需求进行调整。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/var/log/nginx/*.log {
# 当日志文件达到 100M 时进行轮转
size 100M

# 每天检查一次,如果满足条件(如大小)就执行轮转
daily

# 保留 14 个轮转后的日志文件副本
rotate 14

# 对轮转后的旧日志文件进行 gzip 压缩
compress

# 和 compress 指令配合使用,最近一次轮转的日志不压缩,以方便查看
delaycompress

# 如果日志文件不存在,不要报错
missingok

# 不轮转空文件
notifempty

# 使用 root 用户和 adm 组(或 www-data/nginx 组)创建新日志文件
# 权限为 640
create 0640 nginx adm

# 在轮转所有匹配的日志文件后,执行 postrotate 脚本
sharedscripts

# postrotate 和 endscript 之间的命令会在日志文件轮转后执行
postrotate
# 向 Nginx 主进程发送 USR1 信号,使其重新打开日志文件
# 这可以确保日志无缝地写入新创建的文件中,而无需重启 Nginx 服务
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
}

配置参数详解

  • /var/log/nginx/*.log: 指定要管理的日志文件路径。* 是通配符,表示匹配 /var/log/nginx/ 目录下的所有以 .log 结尾的文件(例如 access.logerror.log)。
  • size 100M: 这是限定文件大小的关键指令。当日志文件大小超过 100MB 时,logrotate 就会触发轮转操作。您可以将 100M 修改为任何您需要的大小,如 500M, 1G
  • daily: 指定轮转周期为每天。即使文件大小未达到 size 设定的值,logrotate 每天也会检查一次。其他可用值为 weekly, monthly, yearly。通常 sizedaily 会结合使用。
  • rotate 14: 指定保留多少个归档日志。在这个例子中,会保留14个备份。当生成第15个备份时,最旧的那个(例如 access.log.15.gz)将被删除。
  • compress: 通过 gzip 压缩轮转后的日志文件,节省空间。压缩后的文件通常会带有 .gz 后缀。
  • delaycompress: 延迟压缩,与 compress 选项共用。这可以确保当天的日志文件(例如 access.log.1)不会被立即压缩,方便排查问题。下次轮转时,它才会被压缩成 .gz 文件。
  • missingok: 如果找不到日志文件,不要当作错误处理。
  • notifempty: 如果日志文件是空的,则不执行轮转。
  • create 0640 nginx adm: 创建新日志文件时所使用的权限和所有者/组。请确保这里的用户和组与 Nginx 运行用户匹配。在 Debian/Ubuntu 上可能是 www-data,在 CentOS 上可能是 nginx。您可以通过 ps aux | grep nginx 查看 Nginx 的运行用户。
  • sharedscripts / postrotate: 这部分非常重要。postrotate 块中的脚本会在所有匹配的日志都轮转完毕后执行一次。kill -USR1 $(cat /var/run/nginx.pid) 命令会通知 Nginx 主进程重新打开日志文件句柄。这样,新的日志就会被写入到 logrotate 新创建的空日志文件中,从而实现无缝切换,避免了重启 Nginx 服务导致的中断

第 3 步:测试和强制执行

logrotate 通常由 cron 每日自动执行,您不需要手动干预。但如果您想立即测试配置是否正确,可以使用以下命令:

  1. 调试模式(模拟执行)
    这个命令会模拟执行轮转过程并显示详细输出,但不会真正修改任何文件。这是检查配置语法是否正确的最佳方式。

    1
    sudo logrotate -d /etc/logrotate.d/nginx
  2. 强制执行模式
    这个命令会强制立即执行轮转,即使时间和大小条件不满足。

    1
    sudo logrotate -f /etc/logrotate.d/nginx

    执行后,您可以去 /var/log/nginx 目录下查看是否生成了如 access.log.1 这样的文件。

总结

通过配置 logrotate,您可以非常灵活且可靠地管理 Nginx 的日志文件大小,防止单个日志文件无限增长耗尽磁盘空间,这是生产环境中管理 Nginx 日志的标准实践。

好的,这是一个在 CentOS 7.4 系统上运行的磁盘空间清理脚本。该脚本将帮助您查找并列出占用磁盘空间较大的文件和目录,并提供一些常见的可安全清理的目录路径建议,供您手动验证和清理。

重要提示:

  • 在运行任何删除命令之前,请务ah必仔细检查列出的文件和目录,确保它们不是重要的系统文件或用户数据。
  • 对于不确定的文件,建议先备份再删除。
  • 建议以 root 用户身份或具有 sudo 权限的用户运行此脚本,以便全面扫描系统。
  • 此脚本主要用于查找和列出文件/目录,并不会自动执行任何删除操作,以确保安全。您可以根据脚本的输出,手动执行清理命令。

磁盘空间清理脚本 (clean_disk.sh)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#!/bin/bash

# ==============================================================================
# CentOS 7.4 磁盘空间清理辅助脚本
#
# 功能:
# 1. 查找系统中占用空间最大的文件。
# 2. 查找系统中占用空间最大的目录。
# 3. 列出常见的可以清理的大目录路径,供手动验证。
#
# 使用方法:
# 1. 保存脚本为 clean_disk.sh
# 2. 赋予执行权限: chmod +x clean_disk.sh
# 3. 运行脚本: ./clean_disk.sh
# ==============================================================================

echo "============================================================"
echo " CentOS 7.4 磁盘空间清理辅助脚本"
echo "============================================================"
echo ""
echo "脚本将开始分析磁盘空间占用情况,这可能需要一些时间..."
echo ""

# --- 1. 查找并列出系统中最大的前 20 个文件 ---
echo "--- 正在查找系统中最大的前 20 个文件 (大于 500MB) ---"
find / -type f -size +500M -exec du -h {} + 2>/dev/null | sort -rh | head -n 20
echo ""
echo "提示:请检查以上列出的文件。常见的大文件可能包括日志文件、备份文件、数据库文件或虚拟机镜像。"
echo "对于日志文件,可以直接删除或清空。对于其他文件,请确认不再需要后手动删除。"
echo "例如,清空一个日志文件:> /path/to/large/logfile.log"
echo "删除一个文件:rm /path/to/large/file"
echo ""
echo "------------------------------------------------------------"
echo ""


# --- 2. 查找并列出系统中最大的前 20 个目录 ---
echo "--- 正在查找系统中最大的前 20 个目录 ---"
du -h / 2>/dev/null | sort -rh | head -n 20
echo ""
echo "提示:请检查以上列出的目录。常见的占用空间大的目录可能在 /var, /usr, /home, /opt 等路径下。"
echo "您可以使用 'du -h --max-depth=1 /path/to/large/directory' 命令逐层深入查找具体是哪个子目录占用了空间。"
echo ""
echo "------------------------------------------------------------"
echo ""


# --- 3. 疑似可以清理的大目录和文件类型 ---
echo "--- 疑似可以清理的大目录路径和建议 ---"
echo ""

# 检查 /var/log/journal
journal_size=$(du -sh /var/log/journal/ 2>/dev/null | awk '{print $1}')
if [ -n "$journal_size" ]; then
echo "1. Systemd Journal 日志 (/var/log/journal/):"
echo " - 当前占用空间: $journal_size"
echo " - 这些是 systemd 的日志文件。您可以清理旧的日志。"
echo " - 清理建议:"
echo " # 保留最近 2 天的日志: journalctl --vacuum-time=2d"
echo " # 限制日志文件最大为 500MB: journalctl --vacuum-size=500M"
echo ""
fi

# 检查 /var/cache/yum
yum_cache_size=$(du -sh /var/cache/yum/ 2>/dev/null | awk '{print $1}')
if [ -n "$yum_cache_size" ]; then
echo "2. YUM 软件包缓存 (/var/cache/yum/):"
echo " - 当前占用空间: $yum_cache_size"
echo " - 这是 YUM 包管理器下载的软件包和元数据的缓存。"
echo " - 清理建议 (通常可以安全执行):"
echo " # 清理所有缓存: yum clean all"
echo ""
fi

# 检查 /tmp 和 /var/tmp
tmp_size=$(du -sh /tmp/ 2>/dev/null | awk '{print $1}')
var_tmp_size=$(du -sh /var/tmp/ 2>/dev/null | awk '{print $1}')
if [ -n "$tmp_size" ] || [ -n "$var_tmp_size" ]; then
echo "3. 临时文件目录 (/tmp/ 和 /var/tmp/):"
if [ -n "$tmp_size" ]; then
echo " - /tmp/ 当前占用空间: $tmp_size"
fi
if [ -n "$var_tmp_size" ]; then
echo " - /var/tmp/ 当前占用空间: $var_tmp_size"
fi
echo " - 这些目录存放临时文件,通常可以删除旧的文件。"
echo " - 清理建议:"
echo " # 删除超过 7 天未访问的临时文件 (请谨慎操作):"
echo " # find /tmp -type f -atime +7 -delete"
echo " # find /var/tmp -type f -atime +7 -delete"
echo ""
fi

# 检查旧的内核
old_kernels=$(rpm -q kernel | sed '$d' | wc -l)
if [ "$old_kernels" -gt 1 ]; then
echo "4. 旧的内核版本:"
echo " - 系统中存在多个内核版本。保留一到两个新的即可。"
echo " - 当前已安装的内核:"
rpm -q kernel
echo " - 清理建议:"
echo " # 安装 yum-utils: yum install yum-utils -y"
echo " # 清理旧内核 (将只保留最新的 2 个): package-cleanup --oldkernels --count=2"
echo ""
fi

# 检查日志文件目录 /var/log
log_dir_size=$(du -sh /var/log/ 2>/dev/null | awk '{print $1}')
if [ -n "$log_dir_size" ]; then
echo "5. 日志文件目录 (/var/log/):"
echo " - 当前占用空间: $log_dir_size"
echo " - 这个目录包含各种系统和应用的日志文件。定期归档和清理是好习惯。"
echo " - 查找大的日志文件 (例如大于 100MB):"
echo " # find /var/log -type f -size +100M -ls"
echo " - 对于不再需要的旧日志文件 (.log.1, .log.gz 等),可以直接删除。"
echo ""
fi


echo "============================================================"
echo " 脚本执行完毕"
echo "============================================================"

如何使用脚本

  1. 保存脚本
    将上面的代码内容复制并粘贴到一个新文件中,例如 clean_disk.sh

  2. 赋予执行权限
    在终端中,进入到脚本所在的目录,然后运行以下命令:

    1
    chmod +x clean_disk.sh
  3. 运行脚本
    使用 sudo 或者以 root 用户身份运行脚本:

    1
    sudo ./clean_disk.sh

    或者切换到 root 用户后再执行:

    1
    2
    su -
    ./path/to/clean_disk.sh

脚本输出解读和后续步骤

脚本运行后,会依次输出三个部分的内容:

  1. 系统中最大的前 20 个文件

    • 关注点:重点关注后缀为 .log, .tar.gz, .zip, .bak 的文件,以及一些看起来异常大的文件。
    • 处理方法
      • 对于日志文件,如果您确认日志内容无用,可以直接使用 > 符号清空,例如:> /var/log/some-large-log.log。这比删除文件再创建更好,可以避免因文件句柄被进程占用导致的空间不释放问题。
      • 对于备份文件或压缩包,确认不再需要后,使用 rm 命令删除。
  2. 系统中最大的前 20 个目录

    • 关注点:这可以帮助您快速定位到哪个主目录下包含了大量数据。通常 /var(日志、缓存、数据库)、/home(用户数据)、/usr(软件安装)、/opt(第三方软件)是需要关注的重点。
    • 处理方法:当您发现一个大目录,例如 /var/www/html,您可以使用以下命令进一步分析其子目录的大小:

      1
      sudo du -h --max-depth=1 /var/www/html

      这样逐层深入,直到找到最终占用空间的文件或目录。

  3. 疑似可以清理的大目录路径和建议

    • Systemd Journal 日志:这是 CentOS 7 中常见的日志来源,会持续增长。脚本中提供的 journalctl 命令是官方推荐的安全清理方式。
    • YUM 软件包缓存:每次安装或更新软件时,下载的 RPM 包会留在这里。清理缓存可以释放可观的空间,且对系统无害。
    • 临时文件/tmp/var/tmp 中的文件理论上都可以删除,但为了防止意外中断正在运行的程序,建议只删除一段时间以前的旧文件。
    • 旧的内核:每次内核更新,旧版本的内核都会保留。通常保留最新的一个和前一个作为备用即可,过多的旧内核会占用 /boot/lib/modules 的空间。package-cleanup 是安全的官方清理工具。
    • /var/log 目录:除了 journal 日志,许多应用(如 Nginx, Apache, MySQL等)会在这里生成自己的日志。对于轮转后(rotated)的旧日志(通常以 .1, .2.gz 等结尾),可以安全删除。

通过结合使用这个脚本和您的判断,可以安全有效地清理 CentOS 7.4 服务器上的磁盘空间。

分享到:

评论完整模式加载中...如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理