package linuxmodules import ( "rubric/utils" ) var BackupModule = Module{ Key: "backup", Aliases: []string{"bk", "tar", "бэкап"}, Title: "Резервное копирование", Description: "Темы 38–40: tar, инкрементальные бэкапы, rsync, VDO", Run: showBackup, } func showBackup() { utils.Header("Linux — Резервное копирование") // ─── 38. tar ────────────────────────────────────────────────── utils.Section("38. Создание бэкапов с tar") utils.Println("tar — основной инструмент архивирования в Linux.") utils.Println(utils.ColorBold + "\nОсновные флаги tar:" + utils.ColorReset) utils.Code(`c — create (создать архив) x — extract (извлечь) t — list (показать содержимое) v — verbose (подробный вывод) f — file (имя файла архива) z — gzip (сжатие gzip, .tar.gz / .tgz) j — bzip2 (сжатие bzip2, .tar.bz2) J — xz (сжатие xz, .tar.xz) p — preserve permissions (сохранить права) C — change directory (распаковать в указанную папку)`) utils.Println(utils.ColorBold + "Создание архива:" + utils.ColorReset) utils.Code(`# Создать архив: tar -cvf archive.tar /path/to/dir # без сжатия tar -czvf archive.tar.gz /etc/ # с gzip tar -cjvf archive.tar.bz2 /var/www/ # с bzip2 tar -cJvf archive.tar.xz /home/alice/ # с xz (медленнее, лучше) # Создать с меткой даты: tar -czvf backup_$(date +%Y%m%d_%H%M).tar.gz /etc/ # Исключить директории: tar -czvf backup.tar.gz /home/ \ --exclude=/home/.cache \ --exclude='/home/*/.local' # Архивировать только изменённые файлы: tar -czvf backup.tar.gz --newer "2024-01-01" /home/`) utils.Println(utils.ColorBold + "Извлечение архива:" + utils.ColorReset) utils.Code(`# Извлечь в текущую директорию: tar -xvf archive.tar tar -xzvf archive.tar.gz # Извлечь в указанную директорию: tar -xzvf archive.tar.gz -C /tmp/restore/ # Извлечь только конкретные файлы: tar -xzvf archive.tar.gz etc/nginx/nginx.conf # Просмотр содержимого без распаковки: tar -tzvf archive.tar.gz tar -tzvf archive.tar.gz | grep nginx`) utils.Println(utils.ColorBold + "rsync — синхронизация файлов:" + utils.ColorReset) utils.Code(`# Базовый синтаксис: rsync [опции] источник назначение # Опции: -a — архивный режим (-rlptgoD: рекурсия, права, время...) -v — verbose -z — сжатие при передаче -P — прогресс + продолжение -n — dry-run (симуляция без изменений) --delete — удалять файлы которых нет в источнике -e ssh — использовать SSH # Локальная синхронизация: rsync -av /source/ /dest/ # / после source — содержимое (без самой папки) rsync -av /source /dest/ # без / — копирует саму папку # По сети через SSH: rsync -avzP /home/alice/ user@server:/backup/alice/ rsync -avzP user@server:/data/ /local/backup/ # Зеркало (с удалением лишнего): rsync -av --delete /source/ /mirror/ # Бэкап с сохранением удалённых файлов: rsync -av --backup --backup-dir=/backup/old-$(date +%Y%m%d) \ --delete /source/ /mirror/`) // ─── 39. Инкрементальные бэкапы ─────────────────────────────── utils.Section("39. Инкрементальные бэкапы с tar") utils.Println("Инкрементальный бэкап — сохраняет только изменения с момента последнего бэкапа.") utils.Code(`# tar поддерживает инкрементальные бэкапы через snapshot-файл. # Snapshot хранит список файлов и время последнего изменения. # Полный бэкап (level 0): tar -czvf backup_full_$(date +%Y%m%d).tar.gz \ --listed-incremental=/var/backup/snapshot.snar \ /home/ # Инкрементальный бэкап (только изменения): tar -czvf backup_incr_$(date +%Y%m%d_%H%M).tar.gz \ --listed-incremental=/var/backup/snapshot.snar \ /home/ # Восстановление: сначала полный, затем все инкрементальные по порядку: tar -xzvf backup_full_20240101.tar.gz \ --listed-incremental=/dev/null -C /restore/ tar -xzvf backup_incr_20240102.tar.gz \ --listed-incremental=/dev/null -C /restore/ # Просмотр инкрементального архива: tar -tzvf backup_incr.tar.gz --listed-incremental=/dev/null`) utils.Println(utils.ColorBold + "Скрипт автоматического бэкапа:" + utils.ColorReset) utils.Code(`#!/bin/bash set -euo pipefail BACKUP_DIR="/backup" SOURCE="/home /etc /var/www" SNAPSHOT="/var/backup/snapshot.snar" DATE=$(date +%Y%m%d_%H%M) LOG="/var/log/backup.log" log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG"; } log "Начало бэкапа" # Полный бэкап по воскресеньям, инкрементальный остальные дни: if [ "$(date +%u)" -eq 7 ]; then cp "$SNAPSHOT" "${SNAPSHOT}.prev" 2>/dev/null || true ARCHIVE="$BACKUP_DIR/full_$DATE.tar.gz" tar -czvf "$ARCHIVE" --listed-incremental="$SNAPSHOT" $SOURCE log "Полный бэкап: $ARCHIVE" else ARCHIVE="$BACKUP_DIR/incr_$DATE.tar.gz" tar -czvf "$ARCHIVE" --listed-incremental="$SNAPSHOT" $SOURCE log "Инкрементальный бэкап: $ARCHIVE" fi # Удалить старые бэкапы (оставить за 30 дней): find "$BACKUP_DIR" -name "*.tar.gz" -mtime +30 -delete log "Старые бэкапы очищены. Готово."`) // ─── 40. VDO ────────────────────────────────────────────────── utils.Section("40. Дедупликация с VDO (Virtual Data Optimizer)") utils.Println("VDO — технология RHEL для дедупликации и сжатия данных на блочном уровне.") utils.Println("Уменьшает занимаемое место на диске без изменения работы приложений.") utils.Code(`# VDO доступен в RHEL/CentOS. Установка: dnf install vdo kmod-kvdo # Создать VDO-устройство поверх блочного (/dev/sdb): vdo create --name=vdo_data \ --device=/dev/sdb \ --vdoLogicalSize=100G # виртуальный размер (больше физического) # Посмотреть VDO-устройства: vdo list vdo status --name=vdo_data # Создать ФС на VDO: mkfs.ext4 -E nodiscard /dev/mapper/vdo_data mount /dev/mapper/vdo_data /mnt/data # Статистика экономии: vdostats --human-readable # Показывает: физический размер / использовано / коэффициент сжатия # VDO в /etc/fstab: /dev/mapper/vdo_data /mnt/data ext4 defaults,x-systemd.requires=vdo.service 0 2 # Запустить/остановить: vdo start --name=vdo_data vdo stop --name=vdo_data # Удалить VDO: vdo remove --name=vdo_data --force`) utils.Note("VDO хорошо работает для виртуализации, контейнеров и бэкапов — там много одинаковых данных.") utils.Note("LVM 2.3+ поддерживает VDO напрямую через lvcreate --type vdo.") utils.Footer() }