Linux и дефрагментация

Попробовали бы Вы еще пару лет назад, где-нибудь на ЛОРе, задать вопрос: "Нужна ли дефрагментация в Linux?", "Дайте дефрагментатор под линукс!" или что-то подобное. Вас бы тут же обозвали еретиком и сожгли на костре. Дело в том, что дефрагментатора для файловых систем ext2, ext3 не существует, а создатели различных дистрибутивов Linux упорно распускали слухи, что ext2, ext3 не подвержены фрагментации. Нет, значит не нужно. И тем не менее проблема существует.

Лирическое отступление

Первый раз я столкнулся с фрагментацией в те стародавние времена, когда все компьютеры были одноядерными. Решил я поставить новый диковинный дистрибутив под названием Gentoo, который обещал улучшенную производительность за счет компиляции под конкретное железо. Для еще лучшей производительности, решил я использовать файловую систему ReiserFS. Ставил я его неделю с ночным безлимитом на dialup. Производительность я получил приблизительно такую же как и в других дистрибутивах, а через некоторое время начались жуткие тормоза при работе с жестким диском. Что я тогда ни делал: запускал на ночь проверки на бед-блоки жесткого диска, менял шлейфы, проверял на ошибки файловую систему, ведь везде говорилось, что ReiserFS - сверхбыстрая файловая система, использующая деревья и не подверженная фрагментации, а я, наивный чукотский мальчик, во все это верил. Но, как бы то ни было, все указывало на повышенную фрагментацию файловой системы. Дефрагментатора для ReiserFS я тогда так и не нашел, а сторонние дефрагментаторы не давали никаких результатов. В итоге, очередной попыткой хитрой дефрагментации я убил файловую систему, и поставил RedHat на ext2. Субъективная производительность системы увеличилась в разы. С тех пор я не верю людям.

Оценка фрагментации диска

Все вышесказанное не относится конкретно к ReiserFS, у ext3 фрагментация еще хуже. Но зная врага в лицо можно с ним успешно бороться. Чтобы оценить фрагментацию в своей файловой системе можно воспользоваться командой:

sudo fsck -n /dev/sda1

Где /dev/sda1 нужно заменить на интересующий Вас раздел жесткого диска. В последней строке вывода этой команды выдается фрагментация файловой системы в процентах (x.x% non-contiguous). Но процент этот выдается не всегда и какой-то он очень абстрактный. Более конкретную информацию можно получить с помощью команды filefrag. Это команда выводит количество фрагментов, на которые разбит конкретный файл в файловой системе. Чтобы оценить фрагментацию файлов в каталоге можно выполнить следующую команду:

find "Видео" -type f -exec filefrag {} \; | sort -n -t : -k 2

В результате этой команды будет выведен список всех файлов в каталоге "Видео" отсортированный по количеству фрагментов, самые фрагментированные файлы будут в конце списка. Соответственно, если хотите проверить другой каталог, подставьте его вместо Видео. Если у Вас есть файлы, состоящие из нескольких тысяч фрагментов, то самое время задуматься о дефрагментации.

Собственно, дефрагментация

Самый простой и действенный способ дефрагментации в Linux - это перенос файлов на другой раздел, затем обратно, чем я до недавнего времени и пользовался. Работает независимо от файловой системы, то есть универсален. Этим способом я и пользовался до недавнего времени (и продолжаю пользоваться, но об этом дальше).

Но почему я, собствено, сел за эту статью. Как говорится "свершилось то, о чем так долго говорили большевики", в Ubuntu 12.04 тихо-мирно появилась маленькая утилитка: e4defrag - долгожданный дефрагментатор под Linux. Почему я не видел транспорантов на улице по этому поводу?

Почему я так обрадовался этой утилите? Объясняю. Как выглядит производительность жесткого диска SATA:

$ sudo hdparm -t /dev/sda
/dev/sda:
 Timing buffered disk reads: 312 MB in  3.01 seconds = 103.74 MB/sec

Видно, что скорость чтения с диска чуть больше ста мегабайт в секунду. Не самый производительный у меня диск, ну да ладно. А какова же скорость чтения файла, скачанного с торрента:

$ dd if="Видео/Бобро поржаловать.avi" of=/dev/null
2869488+0 записей получено
2869488+0 записей отправлено
скопировано 1469177856 байт (1,5 GB), 348,53 c, 4,2 MB/c

Вот и почувствовали разницу. Реальная скорость чтения с диска фильма чуть больше ЧЕТЫРЕХ мегабайт в секунду. Я конечно, привел один из самых фрагментированных файлов у себя, чтобы напугать Вас как следует, но мириться даже с двух или четырехкратным падением производительности тоже не хочется. Хочется задать запоздалый вопрос тем, кто говорил, что фрагментации на ext-разделах не существует, как на полуторатерабайтном разделе, заполненном во время скачивания этого фильма где-то наполовину, мог появиться файл, разбитый на 77 тысяч частей?!!

Бороться с этим очень просто (если у Вас ext4):

sudo e4defrag /dev/sda1

И смотреть на весело побежавшие строчки об удачной дефрагментации. В конце работы e4defrag выведет отчет о проделанной работе. Если значение Failure у Вас равно нулю, то считайте что вы родились под счастливой звездой и можете дальше не читать. Те, кому не повезло могут оценить степень своего невезения следующей командой:

sudo e4defrag /dev/sda1 | grep -v '\[ OK \]'

где /dev/sda1 замените на свой раздел. Этой командой можно дефрагментировать отдельные файлы и папки, но есть одно маленькое ограничение при дефрагментации папок - она не обрабатывает вложенные папки и считает их сбойными файлами. После того как посмотрите на свои файлы, которые не удалось дефрагментировать, решите: оставить все как есть и перестать читать эту статью или эти файлы дефрагментировать следующим способом.

Универсальный метод дефрагментации.

Самый универсальный метод дефрагментации - это перемещение файлов на другой раздел с последующим возвратом на место. Если у Вас есть свободный раздел достаточного объема, переместите все файлы на него любым удобным для Вас способом, потом переместите обратно. Все! Ваши файлы дефрагментированы! Если все свободное место уже забито пор познавательными фильмами, то выход все равно есть. Нужен раздел, на котором достаточно места для самого большого фрагментированного файла, хотя бы флешка. В случае с флешкой Вы потеряете информацию о владельце и правах доступа к фрагментированным файлам, если это для Вас важно, ищите раздел с какой-нибудь linux-файловой системой. Приступим. Дефрагментируем 50 самых фрагментированных файлов:

find Видео -type f -exec filefrag {} \; | sort -n -t : -k 2 | tail -n 50 | cut -d ':' -f 1 | xargs -I % sh -c 'mv "%" /media/flash/file.tmp && mv /media/flash/file.tmp "%"'

Неслабая получилась строчка. В ней нужно заменить следующие фрагменты:

  • Видео - каталог, в котором нужно дефрагментировать файлы (файлы в подкаталогах тоже дефрагментируются)
  • 50 - количество файлов для дефрагментации (столько самых фрагментированных файлов будут дефрагментированы)
  • /media/flash/ - раздел с достаточным количеством места для самого большого файла (если файл не поместится, он просто не будет дефрагментирован)

Невещественные доказательства

Чтобы не быть голословным приведу напоследок немного цифр с живой системы. Итак, система Ubuntu на домашнем компьютере, поставленная(точнее скопированная на этот винчестер) года 3 назад. Винчестер объемом 2 Терабайта, из которых 1.5 Терабайта выделено под раздел /home. Файловая система: ext4. Ну и напоследок основной виновник (точно не доказано) фрагментации: transmission.

$ e4defrag "Видео/Бобро поржаловать.avi"
ext4 defragmentation for /home/sveta/Видео/Бобро поржаловать.avi
[1/1]/home/sveta/Видео/Бобро поржаловать.avi:      0%    [ NG ]
 Success:            [0/1]

Как отсюда видно, e4defrag, по одному ему известным причинам, не смог справиться с этим файлом. Посмотрим на файлик поближе:

$ filefrag "Видео/Бобро поржаловать.avi"
/home/sveta/Видео/Бобро поржаловать.avi: 77412 extents found, perfection would be 1 extent

Шалтай-болтай повесился бы от зависти, 77 тысяч фрагментов, попробуй собери. С какой же скоростью читается это чудо?

$ dd if="Видео/Бобро поржаловать.avi" of=/dev/null
2869488+0 записей получено
2869488+0 записей отправлено
скопировано 1469177856 байт (1,5 GB), 348,53 c, 4,2 MB/c

У кого скорость интернета больше 32 мбит/с могут вообще не хранить такие файлы на жестком диске, им из интернета скачать быстрее. Теперь дефрагментируем его.

$ time mv "Видео/Бобро поржаловать.avi" /tmp
real    6m29.676s
user    0m0.128s
sys    0m10.693s
$ time mv "/tmp/Бобро поржаловать.avi" "Видео/Бобро поржаловать.avi"
real    0m49.495s
user    0m0.048s
sys    0m5.404s

6 с половиной минут фильм копировался на соседний раздел жесткого диска, а вот обратно уже всего за 50 секунд, результат налицо. На всякий случай проверим результат.

$ filefrag "Видео/Бобро поржаловать.avi"
Видео/Бобро поржаловать.avi: 103 extents found
$ dd if="Видео/Бобро поржаловать.avi" of=/dev/null
2869488+0 записей получено
2869488+0 записей отправлено
скопировано 1469177856 байт (1,5 GB), 19,9296 c, 73,7 MB/c

Теперь файл разбит всего на 107 фрагментов. Но главное не это, а семнадцатикратное ускорение чтения файла. Таких улучшений я сам не ожидал. За сим откланяюсь. Счастливой Вам дефрагментации.


Uptime. Мониторинг сайтов и серверов.