Программист Сандер Маречал (Sander Marechal) в своём блоге задался вопросом - нужна ли дефрагментация в Linux? Результаты достаточно интересные. Но обо всём по порядку.
Во-первых он предложил воспользоваться простым скриптом, для определения количества фрагментированных файлов и их фрагментов:
#!/usr/bin/perl -w #this script search for frag on a fs use strict; #number of files my $files = 0; #number of fragment my $fragments = 0; #number of fragmented files my $fragfiles = 0; #search fs for all file open (FILES, "find " . $ARGV[0] . " -xdev -type f -print0 |"); $/ = "\0"; while (defined (my $file = <FILES>)) { open (FRAG, "-|", "filefrag", $file); my $res = <FRAG>; if ($res =~ m/.*:\s+(\d+) extents? found/) { my $fragment = $1; $fragments += $fragment; if ($fragment > 1) { $fragfiles++; } $files++; } else { print ("$res : not understand for $file.\n"); } close (FRAG); } close (FILES); print ( $fragfiles / $files * 100 . "% non contiguous files, " . $fragments / $files . " average fragments.\n");
Этот скрипт нужно сохранить как frag.pl, сделать его исполняемым:
#chmod +x frag.pl
И дальше запускать таким образом:
#./frag.pl <<argument>>
Пример запуска и полученного результата:
# sudo ./frag.pl /root Password: 3.2258064516129% non contiguous files, 1.04838709677419 average fragments.
Проведённые эксперименты показывают что количество фрагментированных файлов обычно не превышает четырёх процентов, а среднее количество фрагментов на файл - меньше двух. Отсюда вывод - дефрагментация хоть и не очень, но всё же нужна.
В качестве самого простого решения для дефрагментации предлагается скрипт, написанный Коном Коливасом (Con Kolivas) - разработчиком знаменитой ck-ветки ядра.
#!/bin/sh # defrag v0.06 by Con Kolivas <kernel@kolivas.org> # Braindead fs-agnostic defrag to rewrite files in order largest to smallest # Run this in the directory you want all the files and subdirectories to be # reordered. It will only affect one partition. trap 'abort' 1 2 15 renice 19 $$ > /dev/null abort() { echo -e "\nAborting" rm -f tmpfile dirlist exit 1 } fail() { echo -e "\nFailed" abort } declare -i filesize=0 declare -i numfiles=0 #The maximum size of a file we can easily cache in ram declare -i maxsize=`awk '/MemTotal/ {print $2}' /proc/meminfo` (( maxsize-= `awk '/Mapped/ {print $2}' /proc/meminfo` )) (( maxsize/= 2)) if [[ -a tmpfile || -a dirlist ]] ; then echo dirlist or tmpfile exists exit 1 fi # Sort in the following order: # 1) Depth of directory # 2) Size of directory descending # 3) Filesize descending echo "Creating list of files..." #stupid script to find max directory depth find -xdev -type d -printf "%d\n" | sort -n | uniq > dirlist #sort directories in descending size order cat dirlist | while read d; do find -xdev -type d -mindepth $d -maxdepth $d -printf "\"%p\"\n" | \ xargs du -bS --max-depth=0 | \ sort -k 1,1nr -k 2 |\ cut -f2 >> tmpfile if (( $? )) ; then fail fi done rm -f dirlist #sort files in descending size order cat tmpfile | while read d; do find "$d" -xdev -type f -maxdepth 1 -printf "%s\t%p\n" | \ sort -k 1,1nr | \ cut -f2 >> dirlist if (( $? )) ; then fail fi done rm -f tmpfile numfiles=`wc -l dirlist | awk '{print $1}'` echo -e "$numfiles files will be reordered\n" #copy to temp file, check the file hasn't changed and then overwrite original cat dirlist | while read i; do (( --numfiles )) if [[ ! -f $i ]]; then continue fi #We could be this paranoid but it would slow it down 1000 times #if [[ `lsof -f -- "$i"` ]]; then # echo -e "\n File $i open! Skipping" # continue #fi filesize=`find "$i" -printf "%s"` # read the file first to cache it in ram if possible if (( filesize < maxsize )) then echo -e "\r $numfiles files left \c" cat "$i" > /dev/null else echo -e "\r $numfiles files left - Reordering large file sized $filesize ... \c" fi datestamp=`find "$i" -printf "%s"` cp -a -f "$i" tmpfile if (( $? )) ; then fail fi # check the file hasn't been altered since we copied it if [[ `find "$i" -printf "%s"` != $datestamp ]] ; then continue fi mv -f tmpfile "$i" if (( $? )) ; then fail fi done echo -e "\nSucceeded" rm -f dirlist
Автор скрипта сразу предупреждает что если вы в качестве загрузчика используете lilo и дефрагментируете раздел, на котором лежит ядро - вам может понадобиться переустановить загрузчик.
2007-12-11 12:57:49 (#)