磁盘满了主要分为inode满了和block满了。
inode被用光了
故障模拟:
[root@guilin ~]# dd if=/dev/zero of=/dev/sdd bs=5M count=10 10+0 records in 10+0 records out 52428800 bytes (52 MB) copied, 0.0551933 s, 950 MB/s [root@guilin ~]# ll -hi /dev/sdd 29961 -rw-r--r--. 1 root root 50M Jul 15 21:34 /dev/sdd [root@guilin ~]# mkfs -t ext4 /dev/sdd mke2fs 1.41.12 (17-May-2010) /dev/sdd 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 12824 inodes, 51200 blocks 2560 blocks (5.00%) reserved for the super user First data block=1 Maximum filesystem blocks=52428800 7 block groups 8192 blocks per group, 8192 fragments per group 1832 inodes per group Superblock backups stored on blocks: 8193, 24577, 40961 Writing inode tables: done Creating journal (4096 blocks): done Writing superblocks and filesystem accounting information: done This filesystem will be automatically checked every 38 mounts or 180 days, whichever comes first. Use tune2fs -c or -i to override. [root@guilin ~]# tune2fs -c -1 /dev/sdd tune2fs 1.41.12 (17-May-2010) Setting maximal mount count to -1 [root@guilin ~]# mkdir /ct99 [root@guilin ~]# mount -o loop /dev/sdd /ct99 [root@guilin ~]# ll -d /ct99 drwxr-xr-x. 3 root root 1024 Jul 15 21:36 /ct99 [root@guilin ~]# touch /ct99/ct99{1..12812}.txt [root@guilin ~]# mkdir /ct99/test.txt mkdir: cannot create directory `/ct99/test.txt': No space left on device
当前已经不能再创建新文件,但是磁盘空间依然还有:
[root@guilin ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/sda3 19G 12G 6.2G 65% / tmpfs 491M 0 491M 0% /dev/shm /dev/sda1 190M 35M 146M 19% /boot /dev/sdd 45M 1.2M 41M 3% /ct99
磁盘空间还有,那么可以检查inode是否用光:
[root@guilin ~]# df -i Filesystem Inodes IUsed IFree IUse% Mounted on /dev/sda3 1250928 68228 1182700 6% / tmpfs 125514 1 125513 1% /dev/shm /dev/sda1 51200 38 51162 1% /boot /dev/sdd 12824 12824 0 100% /ct99
由此可见可用inode用0,而磁盘空间还有。因此考虑删除这个分区下的一些无用的小文件。
[root@guilin ~]# rm /ct99/ct99* -f [root@guilin ~]# ll /ct99/ total 14 drwx------. 2 root root 12288 Jul 15 21:36 lost+found -rw-r--r--. 1 root root 13 Jul 15 21:38 messages.log [root@guilin ~]# df -i Filesystem Inodes IUsed IFree IUse% Mounted on /dev/sda3 1250928 68228 1182700 6% / tmpfs 125514 1 125513 1% /dev/shm /dev/sda1 51200 38 51162 1% /boot /dev/sdd 12824 12 12812 1% /ct99
模拟block满了:
[root@guilin ~]# dd if=/dev/zero of=/ct99/1.txt bs=1M count=42 dd: writing `/ct99/1.txt': No space left on device 42+0 records in 41+0 records out 43511808 bytes (44 MB) copied, 0.15678 s, 278 MB/s [root@guilin ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/sda3 19G 12G 6.2G 65% / tmpfs 491M 0 491M 0% /dev/shm /dev/sda1 190M 35M 146M 19% /boot /dev/sdd 45M 44M 0 100% /ct99 [root@guilin ~]# mkdir /ct99/dd mkdir: cannot create directory `/ct99/dd': No space left on device
首先通过查看我们发现是ct99分区满了,于是我们可以对下面的文件进行统计。
[root@guilin ~]# du -sh /ct99/* 42M /ct99/1.txt
发现下面一个42M的文件,可以确认后删除?
inode和block都还有可,就是空间没了:
[root@guilin ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/sda3 19G 12G 6.2G 65% / tmpfs 491M 0 491M 0% /dev/shm /dev/sda1 190M 35M 146M 19% /boot /dev/sdd 45M 43M 0 100% /ct99 [root@guilin ~]# du -sh /ct99/ 1.2M /ct99/ [root@guilin ~]# du -sh /ct99/* du: cannot access `/ct99/*': No such file or directory
经过查看发现之前的一个大文件并没有删除彻底:
[root@guilin ~]# lsof |grep delete tail 2863 root 3r REG 7,0 42991626 11 /ct99/1.txt (deleted)
进程杀掉后,空间马上回来了,生产环境中要注意,不要用这种方法来杀。
[root@guilin ~]# kill 2863 [root@guilin ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/sda3 19G 12G 6.2G 65% / tmpfs 491M 0 491M 0% /dev/shm /dev/sda1 190M 35M 146M 19% /boot /dev/sdd 45M 2.0M 40M 5% /ct99
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块里面。
进入删除文件过程的正题:
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里面的时候,原始数据才会真正的消失。为什么文件被删除之后进程还能继续使用呢?(可以想成,一个人在工厂里面上班的时候别人是不去查你的个人信息的,不管你有没有身份,你都能一直干活,重启服务就相当于工厂下班在上班,在上班的时候就要查你的个人信息了,如果你信息不存在,那么你就没办法上班了。)