文件删除详解--磁盘占满的解决办法

第1章 创建文件的时候提示no space left to device的解决办法

1.1 inode被用完。

模拟环境:

[root@LornBlood ~]# dd if=/dev/zero of=/dev/test count=10 bs\=10M
10+0 records in
10+0 records out
104857600 bytes (105 MB) copied, 0.303514 s, 345 MB/s
[root@LornBlood ~]# mkfs.ext4 /dev/test 
mke2fs 1.41.12 (17-May-2010)
/dev/test is not a block special device.
Proceed anyway? (y,n) y
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
Stride=0 blocks, Stripe width=0 blocks
25688 inodes, 102400 blocks
5120 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=67371008
13 block groups
8192 blocks per group, 8192 fragments per group
1976 inodes per group
Superblock backups stored on blocks: 
    8193, 24577, 40961, 57345, 73729

Writing inode tables: done                            
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 20 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
[root@LornBlood ~]# mount -o loop /dev/test /app/logs/
[root@LornBlood ~]# df -Th 
Filesystem     Type     Size  Used Avail Use% Mounted on
/dev/sda3      ext4      19G  1.7G   17G  10% /
tmpfs          tmpfs    2.5G     0  2.5G   0% /dev/shm
/dev/sda1      ext4     190M   66M  115M  37% /boot
/dev/sr0       iso9660  3.7G  3.7G     0 100% /mnt
/dev/test      ext4      93M  1.6M   87M   2% /app/logs
[root@LornBlood ~]# cd /app/logs/
[root@LornBlood logs]# touch test_{1..100000}.txt
[root@LornBlood logs]# mkdir haha.txt
mkdir: cannot create directory `haha.txt': No space left on device

解决排查思路:

碰到这种情况第一时间想到df -Th查看一下磁盘的使用率

[root@LornBlood logs]# df -Th 
Filesystem     Type     Size  Used Avail Use% Mounted on
/dev/sda3      ext4      19G  1.7G   17G  10% /
tmpfs          tmpfs    2.5G     0  2.5G   0% /dev/shm
/dev/sda1      ext4     190M   66M  115M  37% /boot
/dev/sr0       iso9660  3.7G  3.7G     0 100% /mnt
/dev/test      ext4      93M  2.4M   86M   3% /app/logs
发现磁盘使用率才3%,这肯定不是block被用完,因为df -Th查看的是block信息
然后就想到看看是不是inode号被占满。使用df -i
[root@LornBlood logs]# df -i
Filesystem      Inodes IUsed   IFree IUse% Mounted on
/dev/sda3      1250928 71345 1179583    6% /
tmpfs           653285     1  653284    1% /dev/shm
/dev/sda1        51200    44   51156    1% /boot
/dev/sr0             0     0       0     - /mnt
/dev/test        25688 25688       0  100% /app/logs
发现inode使用率已经达到100%了,所以肯定是小文件太多了,才导致这个问题的,于是乎开始想办法查找这些小文件存放在那个地方。于是想小文件过多,说明他的文件名肯定就多,文件名有存放在他的上级目录的block块里面,我们看看那个目录的block大不就说明它里面的文件多吗?我们可以通过find命令来按照大小查找目录,找到最大的那个目录。然后删除它里面的文件。
[root@LornBlood logs]# find / -type d -size +800k|xargs  ls -hdl
drwxr-xr-x 3 root root 884K Jul 29 14:34 /app/logs
记录好这个目录的权限,把这个目录删除,并再把它创建出来

1.2 Block被占满

还在上面那个分区里面进行模拟环境。
[root@LornBlood logs]# seq 100000000000 >>test.txt   #生成一个大文件,时间过长
[root@LornBlood logs]# df -Th 
Filesystem     Type     Size  Used Avail Use% Mounted on
/dev/sda3      ext4      19G  1.7G   17G  10% /
tmpfs          tmpfs    2.5G     0  2.5G   0% /dev/shm
/dev/sda1      ext4     190M   66M  115M  37% /boot
/dev/sr0       iso9660  3.7G  3.7G     0 100% /mnt
/dev/test      ext4      93M   91M     0 100% /app/logs
[root@LornBlood logs]# mkdir test.dir
mkdir: cannot create directory `test.dir': No space left on device
通过du -sh统计根目录下面最大的文件,然后就这样逐级查找,找到最大的那个文件,然后看他的作用是什么,如果能删除就删除,不能删除就剪切到别的地方。
[root@LornBlood logs]# du -sh /*| sort -h
[root@LornBlood logs]# du -sh /app/*| sort -h
90M /app/logs
[root@LornBlood logs]# du -sh /app/log/*| sort -h
90M /app/logs/test.txt
[root@LornBlood logs]# rm -rf /app/logs/test.txt

1.3 inode和block都还有空间,但写数据就是提示磁盘空间不足。

这种原因可能是因为那个大文件还正在被那个进程占用着。
[root@LornBlood logs]# df -Th 
Filesystem     Type     Size  Used Avail Use% Mounted on
/dev/sda3      ext4      19G  5.8G   12G  33% /
/dev/sda1      ext4     190M   66M  115M  37% /boot
/dev/sr0       iso9660  3.7G  3.7G     0 100% /mnt
按照上面排查block的方式,来找出这个大文件,这里不查找
[root@LornBlood logs]# rm -rf /var/log/messages
[root@LornBlood logs]# df -Th 
Filesystem     Type     Size  Used Avail Use% Mounted on
/dev/sda3      ext4      19G  5.8G   12G  33% /
tmpfs          tmpfs    2.5G     0  2.5G   0% /dev/shm
/dev/sda1      ext4     190M   66M  115M  37% /boot
/dev/sr0       iso9660  3.7G  3.7G     0 100% /mnt
/dev/test      ext4      93M  2.4M   86M   3% /app/logs
发现把这个文件删除之后磁盘的使用大小还是没有变化,这是因为/var/log/messages这个文件被rsyslog程序在占用,如何知道呢,我们可以查看lsof标签为delete的文件,看看这个文件还在不在,如果在找到对应调用这个程序的进程。然后重新启动这个进程,即可
[root@LornBlood logs]# lsof | grep delete
bash       2259 root  cwd       DIR  8,3          0     130925 /root (deleted)
rsyslogd  22037 root    1w      REG  8,3 4444445244     130895 /var/log/messages (deleted)
然后重启这个服务即可
[root@LornBlood logs]# /etc/init.d/rsyslog restart
Shutting down system logger:                               [  OK  ]
Starting system logger:                                    [  OK  ]
[root@LornBlood logs]# df -Th
Filesystem     Type     Size  Used Avail Use% Mounted on
/dev/sda3      ext4      19G  1.7G   17G  10% /
tmpfs          tmpfs    2.5G     0  2.5G   0% /dev/shm
/dev/sda1      ext4     190M   66M  115M  37% /boot
/dev/sr0       iso9660  3.7G  3.7G     0 100% /mnt
/dev/test      ext4      93M  2.4M   86M   3% /app/logs

说明:为什么我们这里选择则从其服务,而不是直接杀死这个进程,因为这个文件一直在被这个程序调用,说明这个服务肯定依赖于这个文件,重启服务会重新生成这个文件,服务正常使用,但是直接结束进程并不会有这个效果。所以我们选择重启服务。

第2章 Linux下删除文件的原理

Linux下删除文件是一个既复制有好玩的,在这里简单的描述一下自己对文件删除过程的看法。 Linux删除一个文件或者目录是首先看当前用户对这个文件或目录的父目录有没有权限,因为目录名和文件名是存放在上级目录的block块里面的。删除文件和目录实际上就是操作父目录的block块的内容。

要想搞清楚Linux下文件的删除原理就要弄清楚Linux下文件存储的原理:

1)Linux系统是通过inode(索引节点号)来区分文件的,而不是根据文件名。 2)Linux存储数据分为两部分:inode(存放文件属性),block(存放数据的实际信息) 3)文件名是存放在他的父目录的block里面的。 4)inode和文件名的对应关系是存放在父目录的block里面的。

查找文件的过程:

按照绝对路径查找文件,就按照路径名称一级一级的在block里面查找文件名和inode的对应关系
按照相对路径查找文件,就在当前的目录的block块里面查找文件名和inode的对应关系

找到inode号之后,通过inode来确定相应的属性,根据属性判断能不能操作这个目录或文件。修改完成之后把现在的属性保存到inode块里面。

第3章 进入删除文件过程的正题:

1,先判断删除文件的上级目录是否具有权限,有的话查找inode和文件名的对应关系,通过文件名来确定inode信息(因为我们查找的时候是通过文件名查找的,如果通过inode来找,就是按照inode来找文件名)。 2,有权限我们就删除这个文件名(这个时候删除的知识文件的名字,他的inode和block并没有删除),等到有新的数据写入到这个block块里面的时候数据才是真正的丢失。 3)为什么删除文件要i_count和i_link都为0才是真正的删除呢? 举个例子:一个人(Block块)具有×××(inode号),和姓名(文件名);他现在在一个工厂上班(相当于在被进程调用)。我们删除文件就是删除了这个人的姓名和他的×××信息的对应关系。 但是这个人(block块)和×××(inode)还是存在的。只有等待执行“Linux的垃圾回收机制(有兴趣可以观看:https://blog.csdn.net/wangcong02345/article/details/51823150)” 或者从新有数据写到这个block里面的时候,原始数据才会真正的消失。为什么文件被删除之后进程还能继续使用呢?(可以想成,一个人在工厂里面上班的时候别人是不去查你的个人信息的,不管你有没有身份,你都能一直干活,重启服务就相当于工厂下班在上班,在上班的时候就要查你的个人信息了,如果你信息不存在,那么你就没办法上班了。)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏静默虚空的博客

认识Java Core和Heap Dump

什么是Java Core和Heap Dump Java程序运行时,有时会产生Java Core及Heap Dump文件,它一般发生于Java程序遇到致命问题的情...

44670
来自专栏北京马哥教育

HA专题: corosync+pacemaker实现nginx高可用

前言 这几天都会学习高可用集群, 也会将其中的一些实验写出来分享给大家, 这个专题估计会写5篇左右, 实验介绍 这次的实验比较简单,在CentOS7使用cor...

515100
来自专栏吴伟祥

Tomcat最佳优化方案总结 原

1. BIO由于每个请求都要创建一个线程来处理,线程开销比较大,不能再高并发的场景,性能也是最低的。 2. NIO是一个基于缓冲区、并能提供非阻塞I/O操作的...

2.8K40
来自专栏信安之路

这些命令你用过多少?

在拿到一个 webshell 之后,大家首先会想到去把自己的权限提升到最高,windows 我们会提升到 SYSTEM 权限,而 Linux 我们会提升到 ro...

10010
来自专栏分享达人秀

安装Android模拟器,准备开发

完成以上所有步骤(JDK、ADT Bundle、SDK),那么就可以开始进行Android开发了。 Android程序必须运行在Android系...

3.5K70
来自专栏不忘初心

基于zookeeper的daemon框架方案——支持容灾和心跳监控

在线上项目中,很多时候需要起一个daemon做守护进程,用于不停地或以一定间隔地执行工作,比如每隔20s把内存中的数据做快照写磁盘。

26150
来自专栏PPV课数据科学社区

大数据系列(4)——Hadoop集群VSFTP和SecureCRT安装配置

前言 经过前三篇文章的介绍,已经通过VMware安装了Hadoop的集群环境,当然,我相信安装的过程肯定遇到或多或少的问题,这些都需要自己解决,解决的过程就是学...

35540
来自专栏西安-晁州

spring-boot配置热更新

spring boot使用的时候会遇到不断重启启动类的情况,热更新可以免去手动重启的烦恼,spring boot应用配置热更新主要有两种方式: 1、使用spri...

40100
来自专栏技术专栏

maven 学习笔记

16620
来自专栏FreeBuf

CMSeeK:CMS漏洞检测和利用套件

CMSeeK是由python3编写的,因此你需要安装python3的运行环境。此外,CMSeeK当前仅支持基于unix的系统,对于Windows系统的支持在后续...

18750

扫码关注云+社区

领取腾讯云代金券