Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4079931
  • 博文数量: 251
  • 博客积分: 11197
  • 博客等级: 上将
  • 技术积分: 6862
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-05 14:41
个人简介

@HUST张友东 work@taobao zyd_com@126.com

文章分类

全部博文(251)

文章存档

2014年(10)

2013年(20)

2012年(22)

2011年(74)

2010年(98)

2009年(27)

分类: LINUX

2012-11-10 18:45:20

昨日线上一台机器上的nginx rt飙高,@明俨 调查发现这台机器上的metaserver内存占用很高,同时还有个奇怪的现象,df发现/home的空间占用在增长飞快,但metaserver和nginx的日志文件增长都很慢,通过du -sh /home统计home下文件的总大小,发现跟df命令/home占用的空间小10+g,到底谁占用了我的磁盘空间?


后来把nginx进程都停掉后(当时应该先通过lsof或/proc/pid/fd/看看nginx当时打开的文件情况),df显示/home的空间一下降下来了,跟du统计的结果能匹配上,说明这些磁盘空间都被nginx进程占用着。内核组的同事告诉我们,一个文件被进程打开后,在关闭前如果文件被删除,此时这个文件已经在它父目录的目录项中被删除掉(在父目录ls已经看不到这个文件),但该进程依然能够正常的读写文件,直到文件被该进程关闭后,这个文件的空间才会被回收,通过下面一个小例子解释下。


点击(此处)折叠或打开

  1. int main()
  2. {
  3.   int fd = open("afile", O_CREAT | O_RDWR);
  4.   assert(fd > 0);
  5.   unlink("afile");

  6.   while (1)
  7.   {
  8.     char buf[1024]; // 1K
  9.     for (int i = 0; i < 102400; i++)
  10.     {
  11.       int len = write(fd, buf, 1024);
  12.       assert(len == 1024);
  13.     }

  14.     lseek(fd, 0, SEEK_SET); // keep writing, but don't make it increase
  15.     sleep(5);
  16.   }

  17.   return 0;
  18. }

# g++ filetest.cpp

# ls

a.out  filetest.cpp  没有afile这个文件

# du -sh  

  16K     .

# df -m | grep home

  /dev/sda9               639406    521255     85148  86% /home

 

# ./a.out &  执行测试程序,持续写文件前100M的空间

# ls

a.out  filetest.cpp  没有afile这个文件

# du -sh  

  16K     .

# df -m | grep home

/dev/sda9               639406      521355     85048  86% /home

 

# killall a.out  杀掉测试程序

# df -m | grep home

  /dev/sda9               639406    521255     85148  86% /home

 

可以看出,进程在打开afile之后立即unlink掉这个文件,通过ls看不到这个文件,因为父目录中这个文件的信息已经删除,在进程持续写文件的过程中(为了避免空间暴增,一直写前100M,仅供测试观察之用),通过du -sh发现该目录下文件总空间没有变化,因为du是通过遍历文件来统计的,而通过df我们发现home的used刚好增加了100M的空间,接下来我们把测试程序关闭掉,home的used又降了100M,说明afile的空间已经被回收了。

 

nginx有个特性,post请求的body如果超过2个page(可配置),就会把body的数据写到磁盘暂存,等请求处理完后,再删除临时的文件。nginx在open创建临时文件后,会先unlink掉这个文件(为什么要这么做,有什么好处?),然后在请求处理完后close掉文件。告警的服务器当时由于metaserver占用了大部分的内存,已经出现了swap的情况,而通过nginx写的文件平均大小在60-70K左右,基本都要写临时文件,导致nginx的服务越来越慢,积压大量的POST请求,这些请求对应的临时文件一直占用着磁盘空间,但因为文件已经删除,外面已经看不到这些文件的存在,从而导致du,df显示的结果相差很大。

阅读(7443) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~