本篇文章给大家分享一个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) 점유된 디스크 공간을 해제합니다
프로세스가 가리키는 서비스를 다시 시작하면 점유된 디스크 공간이 해제됩니다. 온라인 프로덕션 작업 중에는 프로세스를 직접 종료하지 마십시오. 프로세스 서비스 자체에 대한 다시 시작 명령이 있는지 평가하고 서비스를 다시 시작할 수 있는지 평가하십시오.
(4) 비고 부록
1 프로세스에서 파일을 사용 중일 때 사용자가 파일을 삭제하면 파일은 디렉터리 구조에서만 삭제되고 디스크에서는 삭제되지 않습니다.
2 이 파일을 사용하는 프로세스가 끝나면 해당 파일은 실제로 디스크에서 삭제되고 점유 공간이 해제됩니다. Linux에서 파일을 열면 커널은 /proc/
『/proc/{nnnn}/fd/
폴더({ nnnn}
(pid)" 프로세스 관련 정보를 저장하기 위해 pid 이름을 딴 폴더를 생성하고, 하위 폴더 fd에는 프로세스에서 연 모든 파일의 fd(fd: 파일 설명자)가 저장됩니다. /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
및 Ctrl + Z
는 모두 인터럽트 명령입니다. Ctrl + C
는 프로그램 실행을 강제로 중단하고 프로세스가 종료된 것입니다. Ctrl + Z
는 작업을 중단(일시 중지한다는 의미)합니다. 아직 진행 중이며 시작이 일시 중지된 상태로 남아 있습니다. rm -rf xxx.log
"를 사용하지 마세요. 일반적으로 "echo "" > xxx.log
"를 사용하세요.
echo "" > xxx.log
"가 "" 내용은 원본 파일 내용을 덮어쓰므로 디스크 공간이 즉시 해제됩니다!
위 내용은 자주 묻는 Linux 인터뷰 질문: 대용량 파일을 찾아 안전하게 삭제의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!