Образ занимает мало места, а копия огромная: разбираем sparse-файлы
Файл образа имеет размер 200 ГиБ, но занимает на диске 12 ГиБ. После переноса резервная копия неожиданно требует почти 200 ГиБ. Возможная причина — разрежённость: незаписанные диапазоны представлены пустотами, и программа копирования материализовала их как обычные нулевые блоки.
Измерить два разных размера
ls -lh /srv/images/data.img
du -h /srv/images/data.img
du -h --apparent-size /srv/images/data.img
stat -c 'size=%s blocks=%b block_unit=%B' /srv/images/data.imgЛогический размер задаёт длину файла, которую видит приложение. Число выделенных блоков показывает другой аспект хранения. У sparse-файла эти величины могут существенно различаться. В stat число blocks умножается на block_unit; не подставляйте автоматически размер блока файловой системы.
Например, size равен 214748364800, а blocks=25165824 при block_unit=512. Это 200 ГиБ логически и 12 ГиБ выделенных блоков. Разница не является потерянным местом: часть диапазонов читается как нули без выделенного хранения. На сжатых или copy-on-write файловых системах расхождение может иметь и дополнительные причины.
Проверить путь копирования
На GNU cp для управления sparse есть параметр --sparse. Автоматическое поведение не следует переносить на все программы передачи и архиваторы. Посмотрите, сохраняет ли выбранный инструмент пустоты, и выполните маленький тест на той же целевой файловой системе. Поддержка разрежённости назначения тоже важна.
truncate -s 1G sparse-lab.img
du -h sparse-lab.img
du -h --apparent-size sparse-lab.img
cp --sparse=always sparse-lab.img sparse-lab-copy.img
stat -c '%n size=%s blocks=%b unit=%B' sparse-lab*.imgЗапускайте в новом учебном каталоге. truncate создаёт логическую длину, но не записывает весь гигабайт. Это проверка сохранения пустот, а не производительности чтения образа базы. Документация du поясняет apparent size и обычный расход блоков.
Не спутать сохранность данных с экономией места
Две копии могут давать одинаковое содержимое при разном физическом расходе. Поэтому проверка контрольной суммы подтверждает байты, но не сохранение разрежённости. Для резервной копии нужны оба результата: данные совпадают, выделенное место укладывается в бюджет.
Кроме того, живая программа может продолжать менять файл во время копирования. Sparse-параметры не дают согласованного снимка. Для образов дисков и баз используйте поддерживаемую процедуру остановки, snapshot или резервного копирования приложения. Иначе компактная копия может оказаться непригодной для восстановления.
В учебном тесте apparent size исходника и копии должен оставаться 1 ГиБ. Выделенные блоки на обычной файловой системе будут существенно меньше, если пустоты сохранены. Если копия заняла примерно гигабайт, сначала проверьте поддержку sparse у назначения и параметры реального инструмента. Если оба файла компактны, это подтверждает только конкретный путь копирования. Повторите проверку с вашим архиватором и процедурой восстановления: они могут кодировать нулевые диапазоны иначе.
Оценить восстановление заранее
Проведите тест восстановления на целевом типе тома. Запишите логический размер, занятые блоки и свободное место до/после. Учитывайте, что дальнейшая запись в пустые диапазоны увеличит реальное потребление. Нельзя планировать том ровно под сегодняшний du, если образ завтра может заполниться.
В программе Linux и Bash для DevOps-инженеров есть работа с дисками, резервным копированием и проверкой восстановления. Откройте программу, чтобы оценивать копию по возможности вернуть сервис в работу, включая требования к месту.
Ещё по теме
Продолжить на практике
- Linux и Bash для DevOps-инженеров ↗
Linux для работы с серверами: процессы, права, systemd, сеть, диски и логи. Автоматизируйте повседневные задачи на Bash и разберите типичные сбои сервиса — от занятого порта до переполненного диска.
