本篇文章给大家分享一个Linux 线上面试高频问题:如何查找大文件并安全地清除?,给大家分析分析,大家也可以对照着自己分析一下,希望对大家有所帮助!
服务线上环境,会出现一些磁盘使用率过高而告警的情况,可能是某个日志文件过大,没有及时清理回收,如何找到大目录和大文件?
如何安全的清理大文件?
如何使占用的磁盘空间快速释放掉?
(这里以当前目录 ./ 为例,统计 top5)
【du -k --max-depth=1 ./ |sort -nr|head -n5】
[root@test-001 /]# du -k --max-depth=1 ./ |sort -nr|head -n5 137450839518./ 6785876./data 2182577./usr 1830341./home 446856./var //du -k # 显示目录或文件大小时,以 kB 为单位; //du --max-depth=1 [目录] # 只显示指定目录下第一层目录(不含单个文件)的大小; //sort -nr # 以行为单位,根据数字大小从大到小排序; //head -n5 # 显示内容的开头 5 行,这里显示就是 top5 内容;
(这里以当前目录 ./ 为例,统计 top5)
(1)命令详情和说明
【du -sk * ./ | sort -nr | head -n5 | awk -F'\t' '{if(1024 * 1024 * 1024 * 1024 > $1 && $1 >= 1024 * 1024 * 1024) {printf "%.2fT\t\t %s\n", $1/(1024 * 1024 * 1024), $2} else if(1024 * 1024 * 1024 > $1 && $1 >= 1024 * 1024) {printf "%.2fG\t\t %s\n", $1/(1024 * 1024), $2} else if (1024 * 1024 > $1 && $1 >= 1024) {printf "%.2fM\t\t %s\n", $1/1024, $2} else {printf "%sk\t\t %s\n", $1, $2}}' 】
[root@test-001 /]# du -sk * ./ | sort -nr | head -n5 | awk -F'\t' '{if(1024 * 1024 * 1024 * 1024 > $1 && $1 >= 1024 * 1024 * 1024) {printf "%.2fT\t\t %s\n", $1/(1024 * 1024 * 1024), $2} else if(1024 * 1024 * 1024 > $1 && $1 >= 1024 * 1024) {printf "%.2fG\t\t %s\n", $1/(1024 * 1024), $2} else if (1024 * 1024 > $1 && $1 >= 1024) {printf "%.2fM\t\t %s\n", $1/1024, $2} else {printf "%sk\t\t %s\n", $1, $2}}' 7.13G data 2.17G usr 1.75G home 447.04M var 408.50M run //du -sk * # 显示当前目录下每个文件夹和文件的大小以KB为单位(最常用),s表示汇总,k是以KB为统计单位; //./ #当前目录下 //sort -nr # 以行为单位,根据数字大小从大到小排序; //awk -F'\t'# 以水平制表符进行分割,后面的程序就是进行换算单位,格式化输出成易懂的形式;
(2)du、head、sort、awk 详细说明参考已有文章附录
(3)Linux 中 printf 命令使用参考
// Linux 中 printf 命令使用参考 // https://www.linuxprobe.com/linux-printf-example.html '{ if(1024 * 1024 * 1024 * 1024 > $1 && $1 >= 1024 * 1024 * 1024) { printf "%.2fT\t\t %s\n", $1/(1024 * 1024 * 1024), $2 } else if(1024 * 1024 * 1024 > $1 && $1 >= 1024 * 1024) { printf "%.2fG\t\t %s\n", $1/(1024 * 1024), $2 } else if (1024 * 1024 > $1 && $1 >= 1024) { printf "%.2fM\t\t %s\n", $1/1024, $2 } else { printf "%sk\t\t %s\n", $1, $2 } }'
(1)rm 命令有哪些坑?
rm -rf / # 这个命令绝逼不能操作,删除根目录下的文件,就是系统中的所有文件都要被删除。如果是线上服务机器操作了,那就悲剧了!误操作了怎么办?赶快ctrl+c、ctrl+z 能保住多少是多少吧。
rm -rf / home/apps/logs/ # 这也是个天坑命令!目的是删除日志文。结果书写时“多了一个空格”的 bug,看懂了么?这就变成了 [rm -rf /] !
埋藏隐患的日志清理 shell 脚本!脚本关键内容如下。
cd ${log_path} rm -rf *
目的是:进入到日志目录,然后把日志都删除。隐患:当目录不存在时,悲剧就发生了!
(2)如何安全使用 rm 命令?
在生产环境把 [rm -rf] 命令替换为 [mv],再写个脚本程序定期清理,模拟回收站的功能。
把日志清理 shell 脚本,改用逻辑与 && 进行连接。
cd ${log_path} rm -rf *
改用逻辑与 && 进行连接,合并成一句,前半句逻辑失败,后半句命令不执行:
```shell
cd ${log_path} && rm -rf *
完整的日志清理 shell 脚本如下:
```shell #!/bin/bash base_home="/home/apps" log_path=${base_home}/logs cd ${log_path} && rm -rf *
(1)问题情景
1 磁盘使用率监控报警,进入机器可以 (df -h) 命令看到磁盘使用率确实超过了报警阀值。
2 使用命令查看大目录,并进入到目录下 【du -sk * ./ | sort -nr | head -n5 | awk -F'\t' '{if(1024 * 1024 * 1024 * 1024 > $1 && $1 >= 1024 * 1024 * 1024) {printf "%.2fT\t\t %s\n", $1/(1024 * 1024 * 1024), $2} else if(1024 * 1024 * 1024 > $1 && $1 >= 1024 * 1024) {printf "%.2fG\t\t %s\n", $1/(1024 * 1024), $2} else if (1024 * 1024 > $1 && $1 >= 1024) {printf "%.2fM\t\t %s\n", $1/1024, $2} else {printf "%sk\t\t %s\n", $1, $2}}'
】
3 依然没找到大文件,该怎么办呢?
(2)排查思路
1 思考:是不是有文件已经被删除了,但进程还在占用该文件,进程未结束,空间未释放?
2 使用「lsof |grep -i deleted
」命令查看,能查看到已删除,空间没有释放的文件,包含文件大小,进程和服务名等信息。
lsof(List Open Files) 用于查看进程打开的文件,打开文件的进程,进程打开的端口(TCP、UDP),找回/恢复删除的文件。是十分方便的系统监视工具,因为 lsof 命令需要访问核心内存和各种文件,所以需要root 用户权限执行。
(3) Libérez l'espace disque occupé
Redémarrez le service pointé par le processus et l'espace disque occupé sera libéré. Soyez prudent lors des opérations de production en ligne. Ne tuez pas le processus directement. Évaluez s'il existe une commande de redémarrage pour le service de processus lui-même et évaluez si le service peut être redémarré.
(4) Remarques Annexe
1 Lorsqu'un fichier est utilisé par un processus et que l'utilisateur supprime le fichier, le fichier sera uniquement supprimé de la structure de répertoires, mais pas supprimé du disque.
2 Lorsque le processus utilisant ce fichier sera terminé, le fichier sera véritablement supprimé du disque et l'espace occupé sera libéré. Lorsque Linux ouvre un fichier, le noyau crée un fichier pour chaque processus dans le dossier /proc/
『/proc/{nnnn}/fd/
({ nnnn}
(pid)" Créez un dossier nommé d'après son pid pour enregistrer les informations pertinentes du processus, et son sous-dossier fd enregistre le fd (fd : descripteur de fichier) de tous les fichiers ouverts par le processus. /proc/
『/proc/{nnnn}/fd/
文件夹({nnnn}
为 pid)』建立一个以其 pid 为名的文件夹用来保存进程的相关信息,而其子文件夹 fd 保存的是该进程打开的全部文件的 fd(fd:file descriptor)。
3 Ctrl + C
和 Ctrl + Z
都是中断命令。Ctrl + C
是强制中断程序的执行,进程已经终止;Ctrl + Z
是将任务中止(暂停的意思),他仍然在进程中他只是维持挂起的状态。
6 生产环境常用的安全清理大文件命令
生产环境安全清理大文件的诉求是什么?既要不影响服务的正常运行,又要让磁盘占用的空间快速释放掉(让文件消失掉不是我们的目的,我们的目的是快速释放掉占用的磁盘空间)。
不要使用 「rm -rf xxx.log
」;常用 「echo "" > xxx.log
」。
这里假设 xxx.log 为大文件,如这个 xxx.log 有几十个 GB,「echo "" > xxx.log
」是用一个 ""
Ctrl + C
et Ctrl + Z
sont tous deux des commandes d'interruption. Ctrl + C
consiste à interrompre de force l'exécution du programme, et le processus est terminé ; Ctrl + Z
consiste à abandonner la tâche (c'est-à-dire à mettre en pause), c'est le cas. toujours en cours, et il reste simplement suspendu. rm -rf xxx.log
" ; utilisez couramment "echo "" > xxx.log
".
echo "" > xxx.log
" est utilisé comme <. le contenu code>"" écrase le contenu du fichier d'origine, de sorte que l'espace disque soit instantanément libéré !
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!