草庐IT

RHEL6删除文件后未释放空间

justin_peng 2023-03-28 原文
早上一个网站页面打开空白,后来查看是磁盘空间满了,查看是nginx的access.log占用了170多个G,于是通过rm将其删除,后重启nginx问题依然,此时再查看磁盘发现空间并未释放

[root@localhost logs]# du -h * 176G access.log 0 error.log 4.0K nginx.pid [root@localhost logs]# du -sh  176G . [root@localhost logs]# rm access.log  [root@localhost logs]# df -Th 文件系统      类型    容量  已用 可用 已用% 挂载点 /dev/mapper/VolGroup00-LogVol00               ext3    189G  180G     0 100% / /dev/sda1     ext3     99M   13M   82M  13% /boot tmpfs        tmpfs    2.0G     0  2.0G   0% /dev/shm [root@localhost logs]# du -sh  26M . [root@localhost logs]#这个郁闷啊,明明删除文件了,怎么空间没有被释放啊,rm命令应该是直接删除啊,在查看/opt/nginx/longs/显示空间已经释放了

du命令返回的值,显示出减去了该文件后的总大小
df命令返回的值,则不显示减去该文件后的大小(文件句柄还在被使用),直到该运行的应用程序关闭了这个打开的文件(才会真正释放空间)

未释放磁盘空间原因:

在Linux或者Unix系统中,通过rm或者文件管理器删除文件将会从文件系统的目录结构上解除链接(unlink).然而如果文件是被打开的(有一个进程正在使用),那么进程将仍然可以读取该文件,磁盘空间也一直被占用。

此时想起来在rm前我查看了下access.log,这不是关键,问题是我结束查看的时候使用ctrl+c时候将c按成了z,因为文件175G,cat会一致在后面运行,

解决方法:

首先获得一个已经被删除但是仍然被应用程序占用的文件列表

[root@localhost logs]# lsof |grep deleted cat       4435      root    3r      REG         8,3     184549376     399932 /opt/nginx/logs/access.log (deleted) [root@localhost logs]#从输出结果可以看到/opt/nginx/logs/access.log还被使用,未被释放空间,

如何让进程释放呢?

一种方法是kill掉相应的进程,或者停掉使用这个文件的应用,让os自动回收磁盘空间。

当linux打开一个文件的时候,Linux内核会为每一个进程在/proc/ 『/proc/nnnn/fd/目录(nnnn为pid)』建立一个以其pid为名的目录用来保存进程的相关信息,而其子目录fd保存的是该进程打开的所有文件的fd(fd:file descriptor)。

kill进程是通过截断proc文件系统中的文件可以强制要求系统回收分配给正在使用的的文件。这是一项高级技术,仅到管理员确定不会对运行中的进程造成影响时使用。应用程序对这种方式支持的并不好,当一个正在使用的文件被截断可能会引发不可预知的问题

我这里直接使用了kill

[root@localhost logs]# kill -9 4435 [root@localhost ~]# df -Th 文件系统      类型    容量  已用 可用 已用% 挂载点 /dev/mapper/VolGroup00-LogVol00               ext3    189G  3.4G  185G   2% / /dev/sda1     ext3     99M   13M   82M  13% /boot tmpfs        tmpfs    2.0G     0  2.0G   0% /dev/shm [root@localhost ~]#在查看磁盘空间的使用情况,发现空间已经回收了。


关于lsof命令

lsof(list open files)是一个列出当前系统打开文件的工具。在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。所以如传输控制协议 (TCP) 和用户数据报协议 (UDP) 套接字等,系统在后台都为该应用程序分配了一个文件描述符,无论这个文件的本质如何,该文件描述符为应用程序与基础操作系统之间的交互提供了通用接口。因为应用程序打开文件的描述符列表提供了大量关于这个应用程序本身的信息,因此通过lsof工具能够查看这个列表对系统监测以及排错将是很有帮助的

[root@localhost ~]# lsof|more COMMAND    PID      USER   FD      TYPE     DEVICE  SIZE/OFF       NODE NAME init         1      root  cwd       DIR        8,3      4096          2 / init         1      root  rtd       DIR        8,3      4096          2 / init         1      root  txt       REG        8,3    149284     130607 /sbin/init

TYPE:文件类型,如DIR、REG等
DEVICE:指定磁盘的名称
NODE:索引节点(文件在磁盘上的标识)
FD:文件描述符,应用程序通过文件描述符识别该文件。如cwd、txt等
cwd 值表示应用程序的当前工作目录,这是该应用程序启动的目录,除非它本身对这个目录进行更改。
txt 类型的文件是程序代码,如应用程序二进制文件本身或共享库,如上列表中显示的 /sbin/init 程序。其次数值表示应用程序的文件描述符,这是打开该文件时返回的一个整数。如上的最后一行文件/dev/initctl,其文件描述符为 10。u 表示该文件被打开并处于读取/写入模式,而不是只读  或只写 (w) 模式。同时还有大写 的W 表示该应用程序具有对整个文件的写锁。该文件描述符用于确保每次只能打开一个应用程序实例。初始打开每个应用程序时,都具有三个文件描述符,从 0 到 2,分别表示标准输入、输出和错误流。所以大多数应用程序所打开的文件的 FD 都是从 3 开始。
与 FD 列相比,Type 列则比较直观。文件和目录分别称为 REG 和 DIR。而CHR 和 BLK,分别表示字符和块设备;或者 UNIX、FIFO 和 IPv4,分别表示 UNIX 域套接字、先进先出 (FIFO) 队列和网际协议 (IP) 套接字。

lsof参数:
-c<进程名> 列出指定进程所打开的文件
-g  列出GID号进程详情
-d<文件号> 列出占用该文件号的进程
+d<目录>  列出目录下被打开的文件
+D<目录>  递归列出目录下被打开的文件
-n<目录>  列出使用NFS的文件
-i<条件>  列出符合条件的进程。(4、6、协议、:端口、 @ip )
-p<进程号> 列出指定进程号所打开的文件
-u  列出UID号进程详情
-h 显示帮助信息
-v 显示版本信息

-i 用以显示符合条件的进程情况

eg、查看22端口现在运行的情况

[root@localhost ~]# lsof -i :22 COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME sshd    1568 root    3u  IPv4  10443      0t0  TCP *:ssh (LISTEN)-a 表示两个参数都必须满足时才显示结果

[root@localhost ~]# lsof -a -u root -d txt|more COMMAND    PID USER  FD      TYPE DEVICE SIZE/OFF   NODE NAME init         1 root txt       REG    8,3   149284 130607 /sbin/initlsof输出信息:

COMMAND:进程的名称
PID:进程标识符
PPID:父进程标识符(需要指定-R参数)
USER:进程所有者
PGID:进程所属组
FD:文件描述符,应用程序通过文件描述符识别该文件。如cwd、txt等
    1)cwd:表示current work dirctory,即:应用程序的当前工作目录,这是该应用程序启动的目录,除非它本身对这个目录进行更改
    2)txt :该类型的文件是程序代码,如应用程序二进制文件本身或共享库,如上列表中显示的 /sbin/init 程序
    3)lnn:library references (AIX);
    4)er:FD information error (see NAME column);
    5)jld:jail directory (FreeBSD);
    6)ltx:shared library text (code and data);
    7)mxx :hex memory-mapped type number xx.
    8)m86:DOS Merge mapped file;
    9)mem:memory-mapped file;
    10)mmap:memory-mapped device;
    11)pd:parent directory;
    12)rtd:root directory;
    13)tr:kernel trace file (OpenBSD);
    14)v86  VP/ix mapped file;
    15)0:表示标准输出
    16)1:表示标准输入
    17)2:表示标准错误
    一般在标准输出、标准错误、标准输入后还跟着文件状态模式:r、w、u等
    1)u:表示该文件被打开并处于读取/写入模式
    2)r:表示该文件被打开并处于只读模式
    3)w:表示该文件被打开并处于
    4)空格:表示该文件的状态模式为unknow,且没有锁定
    5)-:表示该文件的状态模式为unknow,且被锁定
    同时在文件状态模式后面,还跟着相关的锁
    1)N:for a Solaris NFS lock of unknown type;
    2)r:for read lock on part of the file;
    3)R:for a read lock on the entire file;
    4)w:for a write lock on part of the file;(文件的部分写锁)
    5)W:for a write lock on the entire file;(整个文件的写锁)
    6)u:for a read and write lock of any length;
    7)U:for a lock of unknown type;
    8)x:for an SCO OpenServer Xenix lock on part      of the file;
    9)X:for an SCO OpenServer Xenix lock on the      entire file;
    10)space:if there is no lock.

TYPE:文件类型,如DIR、REG等,常见的文件类型
    1)DIR:表示目录
    2)CHR:表示字符类型
    3)BLK:块设备类型
    4)UNIX: UNIX 域套接字
    5)FIFO:先进先出 (FIFO) 队列
    6)IPv4:网际协议 (IP) 套接字

DEVICE:指定磁盘的名称
SIZE:文件的大小
NODE:索引节点(文件在磁盘上的标识)
NAME:打开文件的确切名称


实例:查看谁正在使用某个文件,也就是说查找某个文件相关的进程

[root@ProxyServer ~]# lsof /var/log/messages COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME rsyslogd 1316 root    1w   REG    8,3  9629155 9701151 /var/log/messages [root@ProxyServer ~]#

实例:递归查看某个目录的文件信息

[root@ProxyServer ~]# lsof +D /var/log COMMAND    PID   USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME auditd    1291   root    5w   REG    8,3  3133843 9700134 /var/log/audit/audit.log rsyslogd  1316   root    1w   REG    8,3  9629155 9701151 /var/log/messages使用了+D,对应目录下的所有子目录和文件都会被列出


实例:列出某个用户打开的文件信息

[root@ProxyServer ~]# lsof -u zabbix COMMAND    PID   USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME zabbix_ag 1847 zabbix  cwd    DIR    8,3     4096       2 / zabbix_ag 1847 zabbix  rtd    DIR    8,3     4096       2 / zabbix_ag 1847 zabbix  txt    REG    8,3   837426 2888704 /usr/local/zabbix/sbin/zabbix_agentd zabbix_ag 1847 zabbix  mem    REG    8,3   156928 7078304 /lib64/ld-2.12.so实例:列出除某个用户外的被打开的文件信息

[root@ProxyServer ~]# lsof -u ^zabbix |more

实例:列出某个程序进程所打开的文件信息

[root@ProxyServer ~]# lsof -c zabbix|more COMMAND    PID   USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME zabbix_ag 1847 zabbix  cwd    DIR    8,3     4096       2 / zabbix_ag 1847 zabbix  rtd    DIR    8,3     4096       2 / zabbix_ag 1847 zabbix  txt    REG    8,3   837426 2888704 /usr/local/zabbix/sbin/zabbix_agentd-c 选项将会列出所有以zabbix这个进程开头的程序的文件,其实你也可以写成 lsof | grep zabbix


实例:列出某个用户以及某个进程所打开的文件信息

[root@ProxyServer ~]# lsof -u zabbix -c zabbix|more COMMAND    PID   USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME zabbix_ag 1847 zabbix  cwd    DIR    8,3     4096       2 / zabbix_ag 1847 zabbix  rtd    DIR    8,3     4096       2 / zabbix_ag 1847 zabbix  txt    REG    8,3   837426 2888704 /usr/local/zabbix/sbin/zabbix_agentd实例:通过某个进程号显示该进行打开的文件

[root@ProxyServer ~]# lsof -p 1825 COMMAND  PID USER   FD   TYPE             DEVICE SIZE/OFF    NODE NAME nginx   1825 root  cwd    DIR                8,3     4096       2 / nginx   1825 root  rtd    DIR                8,3     4096       2 / nginx   1825 root  txt    REG                8,3  7555879 3806770 /opt/nginx/sbin/nginx列出多个进程号对应的文件信息

[root@ProxyServer ~]# lsof -p 1825,1826.1827

列出除了某个进程号,其他进程号所打开的文件信息

[root@ProxyServer ~]# lsof -p ^1825


列出所有的网络连接:lsof -i
列出所有tcp 网络连接信息:lsof -i tcp
列出所有udp网络连接信息:lsof -i udp
列出谁在使用某个端口:lsof -i :3306
列出谁在使用某个特定的udp端口:lsof -i udp:55
特定的tcp端口:lsof -i tcp:80
列出某个用户的所有活跃的网络端口:lsof -a -u test -i
列出所有网络文件系统:lsof -N
域名socket文件:lsof -u
某个用户组所打开的文件信息:lsof -g 5555

有关RHEL6删除文件后未释放空间的更多相关文章

  1. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  2. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  3. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  4. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  5. ruby - 将差异补丁应用于字符串/文件 - 2

    对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl

  6. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  7. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  8. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  9. ruby - 我可以使用 Ruby 从 CSV 中删除列吗? - 2

    查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html

  10. Ruby 写入和读取对象到文件 - 2

    好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信

随机推荐