Определение
Разрежённый файл (англ. sparse file
) — файл, в котором последовательности нулевых байтов заменены на информацию об этих последовательностях (список дыр)
Дыра — последовательность нулевых байт внутри файла, не записанная на диск. Информация о дырах (смещение от начала файла в байтах и количество байт) хранится в метаданных ФС.
Один из самых частых случаев применения можно найти в образах виртуальных машин формата raw, поскольку в отличие от qcow2, образы raw не содержат какой-либо метаинформации для экономии дискового пространства
При этом виртуальный размер такого файла может превышать максимальную емкость на ФС, в которой он расположен
Практика
Попробуем создать такой файл разными способами:
qemu-img create -f raw gigantic_image.img 10T
truncate -s 100G big_file
dd of=sparse-file bs=10G seek=10 count=0
Если посмотреть размер этих файлов привычным всем способом через утилиту ls
, то мы увидим лишь виртуальный размер файлов:
ls -lh
total 4.0K
-rw-r--r-- 1 alexander alexander 100G Sep 18 21:10 big_file
-rw-r--r-- 1 alexander alexander 10T Sep 18 21:10 gigantic_image.img
-rw-r--r-- 1 alexander alexander 100G Sep 18 21:10 sparse-file
Для того чтобы увидеть реальный размер, который эти файлы занимают на диске можно воспользоваться любой из нижеперечисленных команд:
• ls -s
— флаг -s, --size
выведет слева (перед дискреционными правами) реальный размер файлов
• du -h <file>
— флаг -h
нужен для человекочитаемого вывода размера файлов, du
, умеет распознавать такие файлы без дополнительных флагов
• qemu-img info <image>
— для образов (с обычными файлами тоже работает)
• stat <file>
— хоть и показывает виртуальный размер, но число блоков будет соответстовать реальному
На этом список команд не заканчивается, перечислять все возможные способы не имеет смысла
При этом можно конвертировать обычный файл в разрежённый:
dd if=/dev/zero of=sparse_file bs=50M count=5
ls -lhs
total 250M
250M -rw-r--r-- 1 alexander alexander 250M Sep 18 21:26 sparse_file
fallocate -d sparse_file
ls -lhs
total 0
0 -rw-r--r-- 1 alexander alexander 250M Sep 18 21:27 sparse_file
При копировании через cp
можно передать флаг --sparse=always
, который позволит создать разрежённую версию файла из неразрёженного файла
dd if=/dev/zero of=sparse_file bs=50M count=5
cp --sparse=always sparse_file sparse_copy
ls -lsh
total 251M
0 -rw-r--r-- 1 alexander alexander 250M Sep 18 21:32 sparse_copy
251M -rw-r--r-- 1 alexander alexander 250M Sep 18 21:32 sparse_file
Однако, помимо очевидных преимуществ в виде экономии дискового пространства, что особено полезно в виртуальных машинах, есть и ряд существенных недостатков:
- фрагментация файла при частой записи данных в дыры
- копирование разрежённого файла программой, которая не поддерживает работу с таким типом файлов, может создать файл без сжатия размера
- заполнение систем с такими файлами может привести к непредвиденным ошибкам