免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4094 | 回复: 14
打印 上一主题 下一主题

一个Linux下的文件系统碎片整理工具 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-04-12 21:53 |只看该作者 |倒序浏览
一个Linux下的文件系统碎片整理工具,请参阅:

1, http://sourceforge.net/projects/defragfs
2, http://defragfs.sourceforge.net

论坛徽章:
0
2 [报告]
发表于 2007-04-12 22:16 |只看该作者
像linux上的杀毒软件。不需要。

论坛徽章:
0
3 [报告]
发表于 2007-04-12 22:21 |只看该作者
原帖由 cuichaox 于 2007-4-12 22:16 发表于 2楼  
像linux上的杀毒软件。不需要。

如果您是这样认为的话,不妨看看这里: http://defragfs.sourceforge.net/theory.html

论坛徽章:
0
4 [报告]
发表于 2007-04-13 17:00 |只看该作者

论坛徽章:
0
5 [报告]
发表于 2007-04-15 04:57 |只看该作者
在linux 世界极少有人关心这样的问题
不要受windows的毒太深

论坛徽章:
0
6 [报告]
发表于 2007-04-15 05:02 |只看该作者
#!/usr/bin/perl
# defragfs.pl -- Measurement and Report and Defrag fs/file fragmentation
# CanHao Xu <xucanhao@gmail.com>, 2007

($DIR, $FORCE) = @ARGV;

if (($DIR eq "") || ($DIR eq "-f")) {
        die "Usage: defragfs.pl DIRECTORY [-f], -f means force defragmentation";
}

if (!(-e $DIR) || !(-d $DIR)) {
        die "You must specify a correct directory name!";
}

#number of files
my $files = 0;
#number of fragment before defrag
my $fragments_before = 0;
#number of fragmented files before defrag
my $fragfiles_before = 0;
#number of fragment after defrag
my $fragments_after = 0;
#number of fragmented files after defrag
my $fragfiles_after = 0;
my $TMP_filefrag_before_1 = "/tmp/frags-result-before-tmp";
my $TMP_filefrag_before_2 = "/tmp/frags-result-before";
my $TMP_filefrag_after_1 = "/tmp/frags-result-after-tmp";
my $TMP_filefrag_after_2 = "/tmp/frags-result-after";
my $TMP_defrag_filelist_1 = "/tmp/defrag-filelist-tmp";
my $TMP_defrag_filelist_2 = "/tmp/defrag-filelist";
#max "File Fragmentation Rate" used to determine whether worth defrag.
my $max_fragrate = 20;
#max "Avg File Fragments" used to determine whether worth defrag.
my $max_avgfrags = 60;
#default defragmentation ratio in percentage
my $default_defrag_ratio;
#display how much files in report
my $max_display_num = 10;
#which files to be defrag, determined after user input the ratio
my $total_defrag_files = 0;
#sub routine measurefs measure before/after
my $measure_ba = "before";

#search fs for all file
system("rm -f $TMP_filefrag_before_1");
system("rm -f $TMP_filefrag_before_1");
system("rm -f $TMP_filefrag_after_1");
system("rm -f $TMP_filefrag_after_2");
system("rm -f $TMP_defrag_filelist_1");
system("rm -f $TMP_defrag_filelist_2");

sub measurefs {
        open (FILES, "find \"" . $DIR . "\" -xdev -type f |");
        while (defined (my $file = <FILES>)) {
                $file =~ s/!/\\!/g;
                $file =~ s/#/\\#/g;
                $file =~ s/&/\\&/g;
                $file =~ s/>/\\>/g;
                $file =~ s/</\\</g;
                $file =~ s/\$/\\\$/g;
                $file =~ s/\(/\\\(/g;
                $file =~ s/\)/\\\)/g;
                $file =~ s/\|/\\\|/g;
                $file =~ s/'/\\'/g;
                $file =~ s/ /\\ /g;
                open (FRAG, "filefrag $file |");
                my $res = <FRAG>;
                if ($res =~ m/.*:\s+(\d+) extents? found/) {
                        if ($_[0] eq "before") {
                                system("echo \"$res\" >> $TMP_filefrag_before_1");
                                my $fragment = $1;
                                $fragments_before+=$fragment;
                                if ($fragment > 1) {
                                        $fragfiles_before++;
                                }
                                $files++;
                        }
                        else {
                                system("echo \"$res\" >> $TMP_filefrag_after_1");
                                my $fragment = $1;
                                $fragments_after+=$fragment;
                                if ($fragment > 1) {
                                        $fragfiles_after++;
                                }
                                $files++;
                        }
                }
                close (FRAG);
        }
        close (FILES);
}
print ("defragfs 0.8, Released under GPL by xucanhao\@gmail.com\n");
print ("Analysis in progress...\n");
print ("NOTE: if the directory you specified contains too much files(e.g. tens of thousands), it could take you several minutes on analysis, you may disturb it by CTRL+C at anytime. And BTW: the program is CURRENTLY not accurate on Reiser4 due to its default tailing policy(you may see a high fragment rate before and even after)\n");
$measure_ba = "before";
&measurefs($measure_ba);
if ($files eq 0) {
        print ("The selected directory contains no file!\n");
        exit;
}
system("sort $TMP_filefrag_before_1 -g -t : -k 2 -r | sed \"/^\$/d\" > $TMP_filefrag_before_2");

print ("Statistics for $DIR\n");
print ("Total Files:\t\t\t" . $files . "\n");
print ("Fragmented Files:\t\t" . $fragfiles_before . "\n");
print ("File Fragmentation Rate:\t" . $fragfiles_before / $files * 100 . "%\n");
print ("Avg File Fragments(1 is best):\t" . $fragments_before / $files . "\n");
print ("Most Fragmented Files(for details see $TMP_filefrag_before_2):\n");
system("head $TMP_filefrag_before_2 -n $max_display_num");

$default_defrag_ratio = int($fragfiles_before / $files * 100);
if ($default_defrag_ratio > 50) {
        $default_defrag_ratio = 50;
}
if ((($fragfiles_before / $files * 100) > $max_fragrate) || (($fragments_before / $files) > $max_avgfrags) || ($FORCE eq "-f")) {
        print ("You need a defragmentation!\n");
}
else {
        print ("You do not need a defragmentation!\n");
        exit;
}

defrag:
print ("Please specify the percentage of files should be defrag(1-100, default $default_defrag_ratio):");
$defrag_ratio = <STDIN>;
chop($defrag_ratio);
if (!($defrag_ratio eq "") && (($defrag_ratio < 1) || ($defrag_ratio > 100))) {
        print ("Error percentage numbers, please re-enter!\n");
        goto defrag;
}
else {
        $default_defrag_ratio = ($defrag_ratio || $default_defrag_ratio);
}
$total_defrag_files = int($default_defrag_ratio * $files / 100);
print ("Preparing defragmentation, please wait...");

print ("\nFiles to be defragmented:" . $total_defrag_files . "\n");
if ($total_defrag_files eq 0) {
        exit;
}
system("head $TMP_filefrag_before_2 -n $total_defrag_files > $TMP_defrag_filelist_1");

open TMPFRAGLIST, "$TMP_defrag_filelist_1";
while (<TMPFRAGLIST>) {
        m/(.*):\s+(\d+) extents? found/;
        my $filename = $1;
        system("echo \"$1\" >> $TMP_defrag_filelist_2");
}

open GETSIZE, "$TMP_defrag_filelist_2";
my $max = 0;
while (<GETSIZE>) {
        s/(.*)\n/$1/;
        $size = -s "$_";
        if ($size > $max) {
                $max = $size;
        }
}

print ("You need AT LEAST " . $max . " Bytes temporarily used for defragmentation(at the directory where you specified), continue(Y/N)?[N] ");
$confirm = <STDIN>;
chop($confirm);
if (($confirm eq "y") || ($confirm eq "Y")) {
        print ("OK, please drink a cup of tea and wait...\n");

        open DEFRAG, "$TMP_defrag_filelist_2";
        while (<DEFRAG>) {
                s/(.*)\n/$1/;
                $from = $_;
                s/(.*)/$1.fragstmp/;
                $to = $_;
                system("cp -af \"$from\" \"$to\" 2>/dev/null");
                system("rm -f \"$from\"");

                #NOTE: CTIME will change here!!
                system("cp -af \"$to\" \"$from\" 2>/dev/null");
                system("rm -f \"$to\"");
                print "#";
        }

        system("sync");
        print ("Done!\n");
        print ("Now lets see the results...\n");

        $files = 0;
        $measure_ba = "after";
        &measurefs($measure_ba);
        system("sort $TMP_filefrag_after_1 -g -t : -k 2 -r | sed \"/^\$/d\" > $TMP_filefrag_after_2");

        print ("Statistics for $DIR\n");
        print ("Total Files:\t\t\t" . $files . "\n");
        print ("Fragmented Files:\t\t" . $fragfiles_after . "\n");
        print ("File Fragmentation Rate:\t" . $fragfiles_after / $files * 100 . "%\n");
        print ("Avg File Fragments(1 is best):\t" . $fragments_after / $files . "\n");
        print ("Most Fragmented Files(for details see $TMP_filefrag_after_2):\n");
        system("head $TMP_filefrag_after_2 -n $max_display_num");
}
else {
        exit;
}

这就是源码

论坛徽章:
0
7 [报告]
发表于 2007-04-15 14:50 |只看该作者
原帖由 showboy 于 2007-4-15 04:57 发表于 5楼  
在linux 世界极少有人关心这样的问题
不要受windows的毒太深

实践是检验真理的唯一标准。Linux世界有太多神话,文件系统无需碎片整理就是其一,实践证明这是错误的。许多文件系统例如JFS、XFS、Reiser3受文件碎片的影响还相当大。

如果您有时间,不妨看看这个链接: http://defragfs.sourceforge.net/theory.html ,里面包含了相应的测试脚本和测试文件样本。

在ext3默认模式下,一个1GB的分区在测试前文件碎片率为0%,测试结束后文件碎片率达到约23%,性能下降至开始时的约60%。测试的数据集合大约是500MB,即空间占用率约50%,如果在更小的分区中(例如512MB,空间占用率90%以上)碎片率还会更加糟糕。碎片整理后
文件碎片率降至约13%,性能恢复至开始时的约90%。

论坛徽章:
0
8 [报告]
发表于 2008-09-01 17:03 |只看该作者
没有碎片的文件系统,还没有发明呢!

论坛徽章:
0
9 [报告]
发表于 2008-09-03 12:18 |只看该作者
不需要. 我很负责任的告诉你.

论坛徽章:
0
10 [报告]
发表于 2008-09-03 12:21 |只看该作者
原帖由 nntp 于 2008-9-3 12:18 发表
不需要. 我很负责任的告诉你.


?????????????????????
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP