共计 3077 个字符,预计需要花费 8 分钟才能阅读完成。
问题说明
IDC 里的一台服务器的 / 分区使用率爆满了!已达到 100%!经查看发现有个文件过大(80G),于是在跟有关同事确认后 rm - f 果断删除该文件。但是发现删除该文件后,/ 分区的磁盘空间压根没有释放出来,使用率还是 100%!这是为什么呢??
[root@linux-node1 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup00-LogVol00
58G 7.8G 47G 100% /
tmpfs 1.9G 0 1.9G 0% /dev/shm
/dev/vda1 190M 72M 108M 40% /boot
原因分析:
在 Linux 系统中,通过 rm 或者文件管理器删除文件,只是将它会从文件系统的目录结构上解除链接 (unlink),也就是说只是删除了文件和系统目录结构的链接;如果文件在删除时是被打开的(有一个进程正在使用该文件,文件被进程锁定或者有进程一直在向这个文件写数据等)状态,那么进程将仍然可以读取该文件,也就是说没有删除掉文件在读取的状态,所以磁盘空间也就会一直被占用。
一个文件在文件系统中的存放分为两个部分:数据部分和指针部分,指针位于文件系统的 meta-data 中,数据被删除后,这个指针就从 meta-data 中清除了,而数据部分存储在磁盘中,数据对应的指针从 meta-data 中清除后,文件数据部分占用的空间就可以被覆盖并写入新的内容,之所以出现删除文件后,空间还没释放,就是因为有进程还在一直向这个文件写入内容,导致虽然删除了文件,但文件对应的指针部分由于进程锁定,并未从 meta-data 中清除,而由于指针并未被删除,那么系统内核就认为文件并未被删除,因此通过 df 命令查询空间并未释放也就不足为奇了。
解决措施有以下几种
1,通过 lsof|grep deleted 命令获取到已经被删除但是仍然被应用程序占用的文件列表,然后 kill 掉还在占用所删除文件的进程。需要注意的是:如果有很多进程都在使用所删除文件,那么采用第 1 种方式 kill 进程就有点麻烦了,而且风险也比较大。因为 kill 进程是通过截断 proc 文件系统中的文件可以强制要求系统回收分配给正在使用的的文件。必须要确定不会对运行中的进程造成影响时才能使用,应用程序对这种方式支持的并不好,当一个正在使用的文件被截断可能会引发不可预知的问题。
2,或停掉或重启使用这个所删除文件的应用,让 OS 自动回收磁盘空间。
3,也可以重启操作系统,不过这并不是最好的方法
4,对待这种进程不停对文件写日志的操作,要释放文件占用的磁盘空间,最好的方法是在线清空这个文件。通过这种方法,磁盘空间不但可以马上释放,也可保障进程继续向文件写入日志。
在线清空文件(比如 /home/wangshibo.log)的方式:
a)# echo "" > /home/wangshibo.log
b)# cat /dev/null > /home/wangshibo.log
c)# > /home/wangshibo.log
还有一种磁盘空间使用问题的现象:明明使用 df - h 命令查看磁盘空间使用率不算高,还有很多空余空间,但是创建文件或写入数据时一直报错磁盘写满:” no space left on device”!
一般这种问题都是由于分区目录下 deleted 删除后的资源空间没有真正释放出来导致的, 具体处理流程如下:
1. 先 df -lh 查看一下磁盘使用状况, 发现 /data 分区下的 Used 已用空间很大, 但是实际查看并没有占用那么大的空间!
2. 找到被删除文件所在的分区, 比如 /data 分区
3. 查看被删除了的所有文件:lsof -n /data |grep deleted
4. 杀死这些文件的 delete 进程, 释放空间: lsof -n /data |grep deleted|awk ‘{print $2}’|xargs kill -9
5. 接着再运行 lsof -n /data |grep delete,应该就没有结果了。
6. 注意: 刚杀死 deleted 进程时, df - h 查看 /data 分区, Used 已用空间可能时瞬间显示过大, 但随着 deleted 进程杀死, 资源逐渐释放, /data 分区下的 Used 已用空间会逐渐变小, Avail 可用空间会逐渐变大 )
大多数文件系统都会保留一部分空间留作紧急情况时用(比如硬盘空间满了),这样能保证有些关键应用(比如数据库)在硬盘满的时候有点余地,不致于马上就 crash,给监控系统和管理员一点时间去察觉。不过有时候这部分预留的硬盘空间不用的话有点浪费。
在 Linux 系统中,ext2、ext3、ext4 文件系统上通常会默认预留 5%的磁盘空间,比如磁盘如果是 2TB,这就意味着有 100GB 的空间会被预留下来,这样的话会不会显得有点浪费了。可以通过 ”tune2fs” 命令来改变 5%的默认设置,比如只预留 2%的空间。但是不建议设成 0%,现实环境中这样做不安全。
[root@ss-server ~]# df -T
Filesystem Type 1K-blocks Used Available Use% Mounted on
/dev/vda1 ext4 41151808 4962148 34076228 13% /
devtmpfs devtmpfs 1931468 0 1931468 0% /dev
tmpfs tmpfs 1941204 0 1941204 0% /dev/shm
tmpfs tmpfs 1941204 652 1940552 1% /run
tmpfs tmpfs 1941204 0 1941204 0% /sys/fs/cgroup
tmpfs tmpfs 388244 0 388244 0% /run/user/0
[root@ss-server ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 40G 4.8G 33G 13% /
devtmpfs 1.9G 0 1.9G 0% /dev
tmpfs 1.9G 0 1.9G 0% /dev/shm
tmpfs 1.9G 620K 1.9G 1% /run
tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
tmpfs 380M 0 380M 0% /run/user/0
比如上面 ”/” 分区是 ext4 文件系统,默认系统预留了 5% 也就是 2G 的空间。现在可以通过 ”tune2fs” 命令将系统预留空间改为 2%。
[root@ss-server ~]# tune2fs -m 2 /dev/vda1
tune2fs 1.42.9 (28-Dec-2013)
Setting reserved blocks percentage to 2% (209704 blocks)
执行后,发现 ”/” 分区腾出了 1G 的空间,这时系统预留空间也就是 2% 了。
[root@ss-server ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 40G 4.8G 34G 13% /
devtmpfs 1.9G 0 1.9G 0% /dev
tmpfs 1.9G 0 1.9G 0% /dev/shm
tmpfs 1.9G 620K 1.9G 1% /run
tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
tmpfs 380M 0 380M 0% /run/user/0
注意:Linux 下只有 ext2、ext3、ext4 文件系统时,系统才会默认预留 5% 的磁盘空间。如果文件系统是 xfs、tmpfs、devtmpfs、overlay 等,则系统默认不会预留磁盘空间。
好啦!今天的分享到这里就结束了,希望大家持续关注马哥教育官网,每天都会有大量优质内容与大家分享!