//
Linux之inodes溢出问题
//
今天线上出现了一个inode耗尽的问题,最后通过清理磁盘上的小文件来解决问题。大概分享下inode的相关知识。
1
inodes是什么?
在Linux操作系统中,文件存储在磁盘上,而磁盘的最小单位是"扇区",每个扇区的大小是512字节,多个扇区组成了"磁盘块"的概念,通常情况下,磁盘的一个块是4kb,也就是8个扇区的大小。
我们知道,"磁盘块"时存储文件数据的,而文件的信息,例如文件创建者、文件创建日期,文件大小等等都存储在文件的索引中,我们把这种文件索引,就叫做inode。
inode除了存储上述内容,还要存储以下内容:
文件的用户id (userid)
文件的用户组id (groupid)
文件的权限(读、写执行权限)
磁盘块的位置以及磁盘块的数量
文件的生成日期
...
我们可以通过stat命令来查看当前文件的inode内容:
[root@VM-0-14-centos scripts]# stat quick_mysql_login File: ‘quick_mysql_login’ Size: 158 Blocks: 8 IO Block: 4096 regular file Device: fd01h/64769d Inode: 1067653 Links: 1 Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2020-08-19 23:29:19.144121551 +0800 Modify: 2020-07-20 11:17:55.993595671 +0800 Change: 2020-07-20 11:17:55.998595670 +0800 Birth: -
磁盘文件中inode空间的介绍如下:
我们可以使用df -i命令来查看inode的使用情况,也可以使用ls -i +文件名字来查看当前文件的inode值:
[root@VM-0-14-centos scripts]# df -i Filesystem Inodes IUsed IFree IUse% Mounted on devtmpfs 232544 321 232223 1% /dev tmpfs 235274 7 235267 1% /dev/shm tmpfs 235274 481 234793 1% /run tmpfs 235274 16 235258 1% /sys/fs/cgroup /dev/vda1 3276800 107681 3169119 4% / tmpfs 235274 1 235273 1% /run/user/0 overlay 3276800 107681 3169119 4% /var/lib/docker/overlay2/c1d0b9753911263c8859bfc0bcc8cbcb4a92868be07a766a76ca654496709cb3/merged overlay 3276800 107681 3169119 4% /var/lib/docker/overlay2/25e6ce9d769f0ac46fb3a87de148ee59a7926da83dc7c71e2f0006798d94cfcd/merged
从上面的说明中我们不难看出:由于每个文件都必须有一个inode,因此有可能发生inode已经用光,但是硬盘还未存满的情况。这时,就无法在硬盘上创建新文件。也就是说你使用df -h命令查看磁盘空间还有剩余,但是touch文件不成功。
inodes的大小在磁盘格式化分区时确定,跟分区的大小相关,分区越大,inodes越大,反之亦然
2
inodes耗尽的原因
通常情况下,磁盘空间使用完之前,不会有inodes空间被占用满的情况,在一些场景下,会出现inode已经空间耗尽的情况,例如:
1、linux的根目录有大批量的小文件产生而没有清理,则会导致inodes被占满
2、linux在执行cron时,会将cron执行脚本中的output和warning信息,都会以邮件的形式发送给cron所有者。由于客户环境中的sendmail和postfix没有正常运行,邮件发送不成功,导致全部小文件都堆积在maildrop目录下,再加上缺乏自动清理的机制,最终导致目录下堆积了大量的文件。常见的问题是/var/spool/postfix/maildrop目录下小文件过多
3、典型错误场景:root用户下有个每分钟进行一次时钟同步的定时任务,该定时任务每分钟产生一个小文件,不旧就会导致inodes被耗尽。
如何清理或者杜绝?
1、进入当前目录,使用:ls | xargs -n 1000 rm -rf命令来清理当前路径下的小文件。
2、不需要日志输出的定时任务可以将日志重定向到/dev/null
3、使用inodes监控
3
补充说明硬链接和软链接
Linux中存在两种常见的链接方式,分别是硬链接和软连接,所谓的硬链接,是指文件A和文件B拥有相同的inode,指向相同的磁盘数据,如下的文件a.txt和b.txt,就是使用命令:
ln a.txt b.txt
创建的:
[root@VM-0-14-centos scripts]# ll -i total 8 1074070 -rw-r--r-- 2 root root 0 Aug 24 23:20 a.txt 1074070 -rw-r--r-- 2 root root 0 Aug 24 23:20 b.txt
可以发现,这两个文件的inode编号是一样的。
硬链接在MySQL清理大表的时候经常会遇到,当有多个文件名(如硬链接)指向同一inode时,这个innode的引用数大于1,此时,删除其中任何一个文件名都只会删除指向inode的指针而并不会直接删除物理文件块,因此会非常快,直至inode的引用计数等于1时才会真正删除对应的物理文件块,真正删除物理文件块时才会比较耗时,所以当我们需要drop一个大表的时候,可以给这个表做一个硬链接,然后再进行drop table的操作,这样可以快速得到MySQL的响应。
软连接是指文件A指向文件B的路径,一旦文件B被删除了,那么文件A就会出现no such file or direction的错误,它主要用来规范一些操作目录。例如我们经常会将mysql的软连接创建为/usr/local/mysql,而实际上mysql的真实路径可能带有版本号,比如/usr/local/mysql_5.7.16等等。创建这个软连接的方法如下:
ln -s /usr/local/mysql_5.7.16 /usr/local/mysql
相比硬链接,多了个s的选项,s代表symbolic link
4
关于inode的几点注意
1、有时,文件名包含特殊字符,无法正常删除。这时,直接删除inode节点,就能起到删除文件的作用。
2、移动文件或重命名文件,只是改变文件名,不影响inode号码。
3、打开一个文件以后,系统就以inode号码来识别这个文件,不再考虑文件名。因此,通常来说,系统无法从inode号码得知文件名。