分类:
2012-05-28 18:25:13
原文地址:磁盘满引发的core 作者:zyd_cu
TFS数据服务器的block是在DS第一次启动前格式化的,所有block的空间是预先分配好的,而物理块对应的index文件,则是block被分配使用时创建的。Index文件的大小是根据block中文件数目增加而增长的,为了提高性能,将整个index文件都mmap到内存直接访问。
在初次mmap index文件时,会计算block中预期的文件数,计算出index文件的理论大小index_size,然后调用ftruncate将index文件的大小改为index_size(保证后面的mmap能成功),然后将0~index_size的内容映射到内存。
由于ftruncate只会改变文件大小,而不会实际分配磁盘空间(man ftruncate),所以index文件的存储空间都是在index文件写的时候动态分配的,当向mmap某个未分配空间的地址写数据时,如果磁盘满,则空间分配会失败,接下来对该地址的写操作将会core掉。下面通过一个实例模拟一下出core的过程。
2. 在该文件上创建文件系统,并以loop形式挂载
3. 在挂载目录下,创建一个文件testfile,并调用ftruncate将其大小改为2G
4. 再向挂载目录中下写入一个1g的文件realfile,由于文件系统空间总共只有983M,故dd时提示磁盘空间不足,只能成功写入983M;可以看出,ftruncate并没有实际的分配磁盘空间。
5. 最后mmap映射testfile的前面一部分文件数据(前10M),并直接向映射的地址写数据。
运行以上程序,会core掉,Program terminated with signal 7, Bus error. 原因是testfile只是个空文件,当需要为其分配磁盘空间时,磁盘已经满了,接下来对testfile映射的地址的访问就会出core,但为什么是SIGBUS,而不是SIGSEGV,我也不得而知,求高人指点。
Block对应的Index的空间是根据平均文件大小的配置项计算出理论值大小,并在格式化前会为index预留对应的存储空间,之后创建的index都只有这部分存储空间,造成index无法分配到空间(磁盘满)主要有以下几个原因: