Инкрементальный бэкап через rsync: полное руководство с hardlink-снапшотами
Как настроить ежедневные инкрементальные бэкапы с экономией дискового пространства и возможностью восстановления на любую дату
Введение
Резервное копирование — обязательная часть администрирования любого сервера или рабочей станции. Однако полные бэкапы каждый день быстро съедают дисковое пространство. Решение — инкрементальные бэкапы, которые сохраняют только изменения, но при этом позволяют восстановить данные на любую дату. В Linux классический инструмент для этого — rsync с опцией --link-dest. В этом руководстве мы разберём, как настроить систему ежедневных инкрементальных бэкапов, которая создаёт полные снапшоты, но занимает место только под реальные изменения.
Как работает инкрементальный бэкап в rsync
Идея проста: при первом запуске rsync копирует все файлы в папку с меткой даты (например, backup-2025-01-01). При следующем запуске он сравнивает исходные файлы с предыдущим снапшотом и копирует только новые или изменённые файлы в новую папку. Для неизменённых файлов создаются жёсткие ссылки (hardlinks) на файлы из предыдущего снапшота. В результате каждый снапшот выглядит как полная копия, но физически занимает место только за изменённые данные.
Ключевая опция — --link-dest=DIR. Она указывает rsync, с какой директорией сравнивать и куда создавать hardlinks для идентичных файлов.
Требования и подготовка
Вам понадобится:
Linux-система с установленным
rsync(обычно уже есть, но можно установить черезapt install rsyncилиyum install rsync).Достаточно свободного места на целевом диске для первого полного бэкапа.
Права на чтение исходных данных и запись в целевую директорию.
Желательно отдельный диск или сетевое хранилище для бэкапов.
Проверьте версию rsync: rsync --version. Опция --link-dest поддерживается начиная с версии 2.6.0.
Шаг 1: Создайте структуру каталогов
Выберите место для хранения бэкапов. Например, /mnt/backup. Внутри создайте две папки:
current— символическая ссылка на последний успешный снапшот (удобно для быстрого доступа).snapshots— здесь будут храниться снапшоты с датами.
mkdir -p /mnt/backup/snapshots
ln -s /mnt/backup/snapshots/$(date +%Y-%m-%d) /mnt/backup/current # позже обновимНа практике ссылку current лучше обновлять после каждого бэкапа.
Шаг 2: Напишите скрипт бэкапа
Создайте файл, например /usr/local/bin/backup.sh, со следующим содержимым:
#!/bin/bash
# Настройки
SOURCE="/home/user/data/" # исходная папка (слеш в конце важен)
BACKUP_ROOT="/mnt/backup/snapshots"
DATE=$(date +%Y-%m-%d_%H-%M-%S)
DEST="$BACKUP_ROOT/$DATE"
LATEST_LINK="$BACKUP_ROOT/latest"
# Определяем предыдущий снапшот
if [ -L "$LATEST_LINK" ]; then
PREV=$(readlink -f "$LATEST_LINK")
else
PREV=""
fi
# Создаём новый снапшот
mkdir -p "$DEST"
if [ -n "$PREV" ] && [ -d "$PREV" ]; then
rsync -aAXH --delete --link-dest="$PREV" "$SOURCE" "$DEST/"
else
rsync -aAXH --delete "$SOURCE" "$DEST/"
fi
# Обновляем симлинк latest
ln -sfn "$DEST" "$LATEST_LINK"
# Удаляем старые снапшоты (оставляем 30 дней)
find "$BACKUP_ROOT" -maxdepth 1 -type d -name '20*' -mtime +30 -exec rm -rf {} \;Разберём ключи rsync:
-a— архивный режим (рекурсия, сохранение прав, владельцев, времён).-A— сохранение ACL.-X— сохранение расширенных атрибутов.-H— сохранение жёстких ссылок (важно для корректной работы--link-dest).--delete— удалять файлы в приёмнике, которых нет в источнике (чтобы снапшот точно отражал состояние).--link-dest— создавать жёсткие ссылки на идентичные файлы из предыдущего снапшота.
Сделайте скрипт исполняемым: chmod +x /usr/local/bin/backup.sh.
Шаг 3: Запустите первый бэкап вручную
Выполните скрипт:
/usr/local/bin/backup.shПервый запуск создаст полную копию. Проверьте, что данные скопировались:
ls -la /mnt/backup/snapshots/latest/
du -sh /mnt/backup/snapshots/*Обратите внимание: первый снапшот займёт полный объём данных.
Шаг 4: Проверьте работу hardlinks
Запустите скрипт второй раз (или измените пару файлов в источнике). Затем посмотрите размер снапшотов:
du -sh /mnt/backup/snapshots/*Второй снапшот должен занимать значительно меньше места, чем первый, если изменения были небольшими. Убедитесь, что hardlinks созданы:
ls -li /mnt/backup/snapshots/2025-01-01_12-00-00/file.txt
ls -li /mnt/backup/snapshots/2025-01-02_12-00-00/file.txtОдинаковые inode (первое число) означают, что файлы ссылаются на одни и те же данные на диске.
Шаг 5: Настройте автоматический запуск через cron
Откройте crontab для root или пользователя, у которого есть права:
crontab -eДобавьте строку для ежедневного запуска в 2:00 ночи:
0 2 * * * /usr/local/bin/backup.sh > /var/log/backup.log 2>&1Сохраните и выйдите. Проверьте, что задание добавлено: crontab -l.
Шаг 6: Настройте ротацию старых снапшотов
В скрипте уже есть команда find, удаляющая снапшоты старше 30 дней. Вы можете изменить срок, поменяв -mtime +30 на нужное количество дней. Альтернативно можно использовать более гибкие схемы (например, хранить ежедневные за 7 дней, еженедельные за 4 недели, ежемесячные за 12 месяцев), но это требует отдельного скрипта.
Шаг 7: Бэкап на удалённый сервер по SSH
Если вы хотите хранить бэкапы на другом сервере, используйте rsync через SSH. Измените строку вызова rsync в скрипте:
rsync -aAXH --delete --link-dest="$PREV" -e ssh "$SOURCE" user@remote:/path/to/backup/snapshots/$DATE/Важно: --link-dest работает и на удалённой стороне, если rsync там поддерживает hardlinks. Убедитесь, что на удалённом сервере достаточно места и настроен беспарольный вход по SSH-ключу.
Шаг 8: Исключение ненужных файлов
Чтобы не копировать кэши, временные файлы и мусор, создайте файл исключений, например /etc/rsync-exclude.txt:
*.tmp
*.cache
/home/user/.cache/
/var/tmp/И добавьте в rsync опцию --exclude-from=/etc/rsync-exclude.txt.
Шаг 9: Проверка целостности бэкапа
Периодически проверяйте, что бэкапы создаются и данные читаемы. Можно запускать rsync --dry-run для сравнения источника и последнего снапшота:
rsync -aAXH --delete --dry-run --link-dest=/mnt/backup/snapshots/latest /home/user/data/ /mnt/backup/snapshots/test/Также полезно раз в месяц восстанавливать несколько файлов из случайного снапшота и проверять их содержимое.
Шаг 10: Восстановление данных
Восстановить файлы очень просто: скопируйте их из нужного снапшота. Например, чтобы вернуть файл important.txt из бэкапа за 1 января 2025 года:
cp /mnt/backup/snapshots/2025-01-01_02-00-00/important.txt /home/user/data/Если нужно восстановить всю папку, используйте rsync в обратном направлении:
rsync -aAXH /mnt/backup/snapshots/2025-01-01_02-00-00/ /home/user/data/Будьте осторожны с опцией --delete при восстановлении, чтобы не удалить лишнее.
Типичные ошибки
1. Забыли слеш в конце источника. Если указать /home/user/data без слеша, rsync создаст внутри приёмника папку data. С слешем /home/user/data/ скопируется содержимое папки. 2. Не используется `-H`. Без этого флага hardlinks внутри исходных данных могут быть разорваны, а --link-dest может работать неоптимально. 3. Неправильные права. Если бэкап запускается от пользователя без прав на чтение некоторых файлов, они будут пропущены. Запускайте от root или настройте sudo. 4. Игнорирование `--delete`. Без этой опции в снапшоте будут накапливаться удалённые файлы, и он перестанет отражать реальное состояние. 5. Отсутствие ротации. Без удаления старых снапшотов диск переполнится. 6. Бэкап на тот же диск. Если диск выйдет из строя, вы потеряете и данные, и бэкапы. Храните копии на отдельном носителе. 7. Не проверяете бэкапы. Регулярно тестируйте восстановление.
FAQ
Вопрос: Можно ли использовать `--link-dest` с удалённым сервером? Да, если на удалённой стороне rsync поддерживает hardlinks и файловая система их поддерживает (ext4, xfs и т.п.).
Вопрос: Что будет, если предыдущий снапшот повреждён? Rsync просто создаст новый полный бэкап, так как не сможет найти файлы для ссылок. Это безопасно, но займёт больше места.
Вопрос: Как быть с открытыми файлами? Rsync может скопировать файл в момент изменения, что приведёт к несогласованности. Для баз данных используйте дампы или снапшоты LVM.
Вопрос: Можно ли сжимать бэкапы? Да, можно добавить -z для сжатия при передаче по сети, но на диске данные хранятся как есть. Для экономии места используйте файловую систему с прозрачным сжатием (например, btrfs или zfs).
Вопрос: Как ускорить бэкап? Используйте --numeric-ids, чтобы не тратить время на сопоставление имён пользователей и групп, и исключите ненужные файлы.
Итог
Настройка инкрементального бэкапа через rsync с --link-dest — это надёжный и экономичный способ защитить данные. Вы получаете полные снапшоты на каждую дату, которые занимают место только за изменения. Скрипт легко автоматизируется через cron, а восстановление сводится к копированию файлов из нужной папки. Не забывайте проверять бэкапы и хранить их на отдельном носителе — и ваши данные будут в безопасности.
Читайте также
Комментарии
Комментарии доступны только зарегистрированным пользователям. Войти
- Пока нет комментариев. Будьте первым.



