Варианты бекапа: Самописка, rsync, dd и Amanda

Сегодня я хотел бы поговорить о различных вариантах бекапа. Очень часто новички ищут готовые варианты бекапов для своих частных случаев вместо понимания и приведения их к стандартизации.

Конечно, если необходимо бекапить что-то простое, то незачем тратить время на изучение сложных систем резеврного копирования — зачастую собственно написанный скрипт бекапа работает более просто и прозрачен для понимания.

Написание скрипта бекапа требует как минимум базового знакомства с утилитами Unix систем, такими как:

  • find
  • gzip
  • timestamp
  • if — fi
  • for do — done

Их рассмотрение выходит за рамки этой заметки, и я подразумеваю, что у читающего есть базовые понятия об их работе.

Для того, чтоб понять как создать скрипт бекапа, предлагаю рассмореть самый примитивный скрипт, который работает на принципе «Что бекапим, куда сохраняем, как долго храним».

  1. #!/bin/bash
  2. #backup.sh
  3. timestamp=`date “+%Y-%m-%d-%H-%M”`
  4. backupFS=”/etc /var/lib/mysql /usr/local/etc”
  5. backupTO=/var/backup5
  6. KeepTime=7
  7. if [ -d $backupTO ]; then
  8. find $backupTO -maxdepth 1 -name \*.tar.gz -mtime +${KeepTime} -exec rm -f {} \;
  9. for i in $backupFS
  10. do
  11. j=`expr ${i//\//-}`
  12. tar -zcvf $backupTO/`hostname`.${timestamp}.${j}.tar.gz $i
  13. echo “$i is done”
  14. done
  15. else
  16. echo “backup directory is missing...exiting”
  17. exit 1
  18. fi

Выполняем команду chmod +x <имя этого скрипта>, другими словами делаем его исполняемым.
В рабочем скрипте цифр быть не должно. Я добавил их для удобства объяснения строк кода.

  1. Любой скрипт в Linux начинается с этой последовательности, которая называется sha-bang. По сути исполняемый файл может быть просто перечислением набора команд, но если планируется что-то сложнее, где предстоит работа с переменными то sha-bang стоит поместить в файл. В этом случае будет создан процесс, в котором мы можем хранить временные данные;
  2. Все строки в файле начинающиеся с символа #, кроме первой строки – комментарии. Здесь я просто указал название нашего скрипта как многие делают;
  3. В переменную timestamp мы сохраняем результат выполнения команды date в нужном нам формате: год-месяц-день-час-минута. Значение переменной будет фигурировать в конечном имени файла;
  4. В переменной backupFS мы будем сохранять список каталогов для бекапа. Каталоги указываем через пробел а весь их список берем в двойные кавычки;
  5. Переменная backupTO содержит каталог, куда мы будем делать бекапы;
  6. В переменной KeepTime мы храним срок хранения бекапов. Файлы старше 7 дней мы будем удалять. Место на диске все таки не резиновое;
  7. В дело вступает команда test. Прежде чем продолжить дальше имеет смысл проверить существование backup-каталога. Иначе нет смысла продолжать. В скрипте мы не будем его создавать – пусть администратор сам управляет своей файловой системой;
  8. Перед созданием бекапа мы просматриваем backup-каталог и удаляем файлы которые хранятся более 7 дней. Для вычисления сколько архив находится в файловой системе мы использовали атрибут файла mtime. В этом атрибуте сохраняется время последней модификации файла;
  9. Начинаем цикл for и последовательно для каждого каталога в переменной backupFS сделаем ряд действий;
  10. Начинаем новую итерацию цикла for;
  11. В переменную j мы сохраняем результат выполнения регулярного выражения. Нам необходимо удалить символ “/” из путей каталогов в переменной i. Так как создать tar.gz-архив с “/” в имени файла у нас не получится;
  12. Архивируем нужную нам директорию. Имя файла мы генерируем динамически. В имени будет использован результат выполнения команды hostname, То есть мы подставим имя нашего сервера, что весьма полезно при хранение бекапов в централизованном месте, где могут быть бекапыс десятка серверов. Далее в название файла добавляем текущее время в соответствие с форматом переменной timestamp. После добавления времени добавляем название резервируемого каталога с заменой символов “/” на “-”;
  13. Выводим сообщение, что архивация директории завершена. Впрочем для скрипта висящего в cron в этом нет необходимости;
  14. Завершение итерации цикла for;
  15. Это условие выполняется если backup-каталог отсутствует в файловой системе;
  16. Выводим сообщение “backup-каталог отсутствует”;
  17. Выходим из скрипта с ошибкой (код 1). Польза от этого есть когда это анализируется каким-то другим процессом. Но в целях правописания мы это добавим;
  18. Завершение условного оператора и выход из программы.

В соответствие со своими нуждами поправьте список каталогов для бекапа, путь куда их сохранять и количество дней хранения копий. Помещаем скрипт в cron администратора, например на 4 часа утра каждый рабочий день, еще мы добавим и субботу, чтобы захватить данные которые были сделаны в
течение рабочего дня пятницы:

      0 4 * * 1-6 /root/backup.sh

Каталог для бекапа может быть NFS-ресурсом экспортированным на сервер. Так мы простым скриптом решаем важную задачу системного администрирования. Для более сложной инфраструктуры скорее всего
понадобится что-то более функциональное и гибкое.
В своих backup-скриптах больше внимания уделяйте обходу потенциальных ошибок и неадекватного поведения в случае отсутствия места на диске или в случае отсутствия нужных каталогов. Не тратьте время на оптимизацию, смысла в этом не много, ведь узким местом всегда будет процесс копирования/архивирования ваших данных.

Rsync или как скопировать бекап на удаленный сервер

Rsync (Remote Synchronization) — с помошью этой программы происходит копирование файлов между серверами, пришла на замену rcp.

Простой пример, есть два сервера: centos52 — сервер куда будем делать бекап и unixbox — сервер с которого будем делать бекап.

На сервере unixbox создадим пользователя rsync от которого будут запрашиваться файлы для бекапа.
Добавим пользователя rsync и установим ему пароль:

# useradd rsync
# passwd rsync

Добавим его в нужные группы чтобы он мог получить право на чтение если такого еще нет.
Скопируем каталог /etc с сервера unixbox в наш локальный каталог /var/backup:

$ rsync -e ssh -avz --delete-after --force [email protected]:/etc /var/backup/

Вводим пароль и все.

Если хочется процедуру автоматизировать то нужно будет сгенерировать public ключ на сервере centos52 и положить его в файл authorized_keys пользователю rsync на сервере unixbox. Давайте сделаем это:

# ssh-keygen -t rsa
# ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]

Все. Теперь можно поместить выполнение команды в crontab:

# crontab -e
* */4 * * * rsync -e ssh -avz --delete-after --force [email protected]:/etc /var/backup

Каждые 4 часа будем копировать каталог /etc с сервера unixbox в локальный
каталог /var/backup

Пояснения

Внимание: если после /etc нет “/” то будет скопирован сам каталог и его содержимое. Если “/” есть, то будет скопировано только содержимое этого каталога.

  • -e ssh – этим ключем мы показываем что будем использовать ssh, то есть наш трафик будет шифроваться;
  • -a – работа в режиме архивирования, сохраняются права доступа иинформация о владельцах;
  • -v – выводить больше информативной информации;
  • -z – архивировать передаваемые данные;
  • —delete-after – удалять файлы которые отсутствуют в источнике после того как закончится передача файлов по сети. Мы хотим иметь полную копию контента с удаленного сервера. Можете включать эту опцию периодически. Вдруг кто-нибудь случайно удалит файл на удаленном сервере и во времяближайшей синхронизации мы удалим его тоже;
  • —force – не удалять директорию пока в ней есть файлы.

rsyncd или об атавизме

Также есть сервис – rsyncd который работает на порту 873 TCP. При запущенном сервисе строка доступа может выглядеть так:

rsync://[[email protected]]HOST[:PORT]/SRC [DEST]

То есть в начале будет добавлено rsync:// а остальное также как и в примере выше. Аутентификация в rsyncd основана на 128 bit MD4, что очень ненадежно в наше время. К тому же данные передаются в открытом виде, что явно не в пользу этого сервиса, когда есть такие средства как rsync+ssh и scp.
Поэтому подробно рассматривать его не вижу смысла.

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

 #!/bin/bash
 #backup.sh
 LIST=/var/backup/backup.list
 cat ${LIST} | while read res; do
 rsync -e ssh -avz --delete-after --force [email protected]:$res /var/backup
 done

Файл /var/backup/backup.list должен содержать список каталог длякопирования. Примерно так:

/etc
/var/www/cms
/usr/local/etc
/var/billing

Про dd или как сделать полный бекап диска

Стандартная ситуация — на сервере начал умирать диск, появились первые беды, система с трудом встает после ребута. Но переустанавливать все заново очень долго, да и зачем? Гораздо проще сделать полный клон диска или испорченного раздела. И в этом поможет dd.

Программа dd идеально подойдет там где нужно сделать точную копию раздела/слайса диска. Она сектор за сектором копирует данные из источника (параметр if ) в пункт назначения, если так можно выразиться (параметр of ).
Чтобы понять как просто пользоваться программой давайте сделаем это на практике.

# dd if=/dev/hda of=/dev/hdb conv=noerror,sync

Команда выше сделает точную копию раздела /dev/hda в разделе /dev/hdb.
То есть мы «отзеркалировали» /dev/hda. После conv= мы можем указать ряд параметров:

  • noerror — продолжать копирование не обращая внимание на bad-блоки и прочие ошибки
  • sync — поврежденные или отсутствующие данные во входном буфере на выходе будут заменены на нули. Опция замедляет работу команды dd, но для более корректного образа стоит воспользоваться ею.
# dd if=/dev/hda3 of=/var/backup/hda3.img

Этой командой мы записали раздел /dev/hda3 в бинарный файл hda3.img. Теперь его можно перенести на другой сервер и развернуть в точную копию/dev/hda3. Только учтите один минус dd — программа копирует данные по секторам и ей все равно есть на этом участке диска данные или нет, будет
воссоздана точная копия и размер будет точно такой же! То есть если раздел /dev/hda3 имеет объем в 5 Гб а занят на нем только 1 то файл hda3.img будет весить 5 Гб.
Восстановить раздел из образа также просто как и создать:

# dd if=/var/backup/hda3.img of=/dev/hda3

Ну и напоследок сделаем копию нашей MBR (Master Boot Record). MBR – это первый сектор на жестком диске содержащий таблицу разделов и запись, с какого раздела загружаться. Иногда требуется восстановить MBR из резерва.

# dd if=/dev/hda1 of=/var/backup/mbr.dump bs=512 count=1

Команде dd мы просто передали параметры bs и count, этим указав какой
объем данных мы хотим скопировать.

  • bs — block size, размера блока который мы хотим скопировать
  • count — количество bs

Мы ведь уже знаем, что MBR находится в первых 512 байтах (1-й сектор).
Теперь восстановим MBR из резервной копии

# dd if=/var/backup/mbr.dump of=/dev/hda1 bs=512 count=1

Размер сектора можно узнать так:

# fdisk -l /dev/hda1

Amanda — Advanced Maryland Automatic Network Disk Archiver

Amanda – это клиент/серверная система создания резервных копий. Хороший выбор для средних и крупных предприятий. Что тут говорить, сама корпорация Xerox использует Amanda в своей ИТ инфраструктуре.
Изначально Amanda была создана для работы с ленточными накопителями но сейчас активно используется при бекапе на HDD. Такая концепция получила название “виртуальные ленты” (vtapes). Amanda не испытывает проблем при работе в гетерогенных сетях (в сетях, которые используют
разные платформы и операционные системы).

Некоторые термины:

  • level 0 – полный бекап
  • level 1 – инкрементальный бекап
  • level n – инкрементальный бекап с момента предыдущего инкрементального
  • бекапа (level n-1)
  • Disklist Entry (DLE) – каждая запись в файле disklist
  • dumpcycle – Промежуток времени в течение которого делается level 0
  • backup каждой из DLE (обычно 1 неделя)
  • runspercycle – сколько раз Amanda будет запущена в течение dumpcycle
  • tapecycle – сколько лент будет использовано в системе резервного копирования

Мы рассмотрим версию Amanda на CentOS 5

Настройка Amanda Server

Описание

  • fasttech – так назовем наш проект про резервному копированию
  • centos52 – Amanda Server
  • unixbox – Amanda Client
  • /var/backup – каталог для резервных копий

Задача
Будем делать бекап каталога /etc сервера unixbox. Один раз в неделю будем делать полный бекап, остальные – инкрементальный.
Начинаем установку

yum -y install amanda-server.i386

Создаем каталог для нового проекта и копируем файл amanda.conf из проекта по умолчанию.

mkdir /etc/amanda/fasttech
cp /etc/amanda/DailySet1/amanda.conf /etc/amanda/fasttech/

Редактируем файл /etc/amanda/fasttech/amanda.conf

 org «Dedic.ru»
 mailto «root»
 dumpuser «amanda»
 dumporder «sssS»
 taperalgo first
 displayunit «m»
 dumpcycle 5
 runspercycle 5
 tapecycle 10
 tpchanger «chg-disk» # /usr/lib/amanda/chg-disk
 tapedev «file:/var/backup»
 tapetype DISK
 labelstr «fasttech-.*»
 infofile «/etc/amanda/fasttech/curinfo»
 logdir «/etc/amanda/fasttech»
 indexdir «/etc/amanda/fasttech/index»
 define tapetype DISK {
 length 500000 MB
 }
 define dumptype comp-tar {
 program «GNUTAR»
 compress fast
 index yes

}

Создаем структуру каталогов и файлов которые потребуются во время работы.

# mkdir /etc/amanda/fasttech/{curinfo,index}

Создаем два пустых файла

# touch /etc/amanda/fasttech/{tapelist,disklist}

Нашему проекту назначаем правильного владельца

# chown -R amanda:disk /etc/amanda/fasttech/

В файл disklist помещаем систему с которой будем делать бекап и директорию

# echo "unixbox /etc comp-tar" > /etc/amanda/fasttech/disklist

Разрешаем пользователю root с сервера unixbox получать с нас бекап.

# echo "unixbox root" > `grep amanda /etc/passwd | cut -d: -f6`/.amandahosts

Создаем директорию для временных файлов

# mkdir -p /var/backup/holding

В цикле создаем директории для наших будущих виртуальных лент

# for i in 1 2 3 4 5; do mkdir /var/backup/slot$i; done

Делаем символическую ссылку первой ленты на каталог data

# ln -s /var/backup/slot1 /var/backup/data

Устанавливаем права на backup-директорию

# chown -R amanda:disk /var/backup/

Создаем каталог amanda

# mkdir -p /usr/adm/amanda

Устанавливаем правильного владельца на директорию

# chown -R amanda:disk /usr/adm/amanda

Переходим на учетную запись amanda

# su - amanda

В свой файл настроек добавляем каталог /usr/sbin в переменную PATH. Тогда не нужно будет писать полный путь к программам расположенным в этом каталоге, достаточно только указать их название.

$ echo «export PATH=$PATH:/usr/sbin» >> .bash_profile

Проверяем статус “лент”

 $ ammt -t file:/var/backup/ status
 file:/var/backup/ status: ONLINE

Переходим в бекап-директорию

$ cd /var/backup

Помечаем директории и виртуальную ленту

$ for i in 1 2 3 4 5; do amlabel fasttech fasttech-$i slot $i; done

Сбрасываем счетчик лент

$ amtape fasttech reset

Проверим корректность нашего amanda.conf

$ amcheck -s fasttech
 Amanda Tape Server Host Check
 -----------------------------
 slot 3: read label `fasttech-3’, date `X’
 NOTE: skipping tape-writable test
 Tape fasttech-3 label ok
 WARNING: tapecycle (5) <= runspercycle (5).
 Server check took 0.070 seconds
 (brought to you by Amanda 2.5.0p2)

Если серьезных ошибок не замечено то продолжаем дальше. Запускаем сервис.

В файле /etc/xinetd.d/amandaidx меняем disable=yes на disable=no

# /etc/init.d/xinetd restart

Проверяем, начала ли работать наша служба

 # netstat -lp | grep :amanda
 0     0 *:amandaidx             *:*          LISTEN     3403/xinetd  tcp

Сервер готов.

Amanda client

# yum -y install amanda-client

Разрешаем серверу centos52 получать с нас бекап.

# echo «centos52 amanda» > `grep amanda /etc/passwd | cut -d: -f6`/.amandahosts

Запускаем сервис

В файле /etc/xinetd.d/amanda меняем disable=yes на disable=no
# /etc/init.d/xinetd restart
# netstat -lp | grep :amanda
udp        0 0 *:amanda                    *:*                4850/xinetd

Клиент готов.

Backuping

Бекапы делаем от пользователя amanda

# su - amanda

Делаем бекап каталога /etc с сервера unixbox (ну или что там у вас в /etc/amanda/fasttech/disklist)

$ amdump fasttech

Проверим, получилось ли у нас…

$ amadmin fasttech info unixbox /etc
 Current info for unixbox /etc:
 Stats: dump rates (kps), Full: 968.0, -1.0, -1.0
 Incremental: -1.0, -1.0, -1.0
 compressed size, Full: 26.0%,-100.0%,-100.0%
 Incremental: -100.0%,-100.0%,-100.0%
 Dumps: lev datestmp tape           file origK compK secs
 0 20090214 fasttech-3         1 11190 2906 3

Как видим бекап был успешно сделан. Поскольку мы делали первый раз бекап каталога /etc то был сделан полный дамп (Dumps: 0)

Сделав бекап еще раз, мы увидим что на этот раз получена инкрементальная
копия (Dumps: 1)

$ amadmin fasttech info unixbox /etc
 Current info for unixbox /etc:
 Stats: dump rates (kps), Full: 968.0, -1.0, -1.0
 Incremental: 2891.0, -1.0, -1.0
 compressed size, Full: 26.0%,-100.0%,-100.0%
 Incremental: 26.1%,-100.0%,-100.0%
 Dumps: lev datestmp tape           file origK compK secs
 0 20090214 fasttech-3         1 11190 2906 3
 1 20090214 fasttech-4         1 11080 2891 1

Restoring

su - amanda

Выясняем на каких лентах есть нужный нам каталог.

$ amadmin fasttech info unixbox /etc
Current info for unixbox /etc:
 Stats: dump rates (kps), Full: 968.0, -1.0, -1.0
 Incremental: 2891.0, -1.0, -1.0
 compressed size, Full: 26.0%,-100.0%,-100.0%
 Incremental: 26.1%,-100.0%,-100.0%
 Dumps: lev datestmp tape           file origK compK secs
 0 20090214 fasttech-3         1 11190 2906 3
 1 20090214 fasttech-4         1 11080 2891 1

Если версий этого файла много то можно использовать такую команду

$ amadmin fasttech find unixbox /etc
 Scanning /var/backup/holding...
 Scanning /var/backup/holding...
 date     host disk lv tape or file file part status
 2009-02-14 unixbox /etc 0 fasttech-3      1 -- OK
 2009-02-14 unixbox /etc 1 fasttech-4      1 -- OK

К примеру нам нужен файл shells из каталога /etc c ленты fasttech-3

Вставляем нужную ленту

$ amtape fasttech slot 3

Получаем нужный архив с этой ленты в наш текущий каталог

$ amrestore file:/var/backup/ unixbox "/etc"

Полученный файл — это tar-архив. Теперь возьмем из него файл shells.

$ tar xvf unixbox._etc.20090214.0 ./shells

Файл shells отправляем на сервер unixbox и замещаем им поврежденный.

Точно также работаем с целыми наборами каталогов. Если команде amrestore не передавать в качестве аргумента нужный нам каталог то мы получим все резервируемые каталоги с сервера. Дальше дело техники.

Чтобы делать бекап в 4 утра каждый будний день, пользователю amanda в crontab (crontab -e) помещаем такую строку:

0 4 * * 1-6 /usr/sbin/amdump fasttech

Полезное

Эта команда попросит Amanda сделать полный бекап каталога /etc с сервера unixbox в следующий раз:

amadmin fasttech force unixbox /etc

Команда перемотает виртуальную ленту на начало

ammt -t file:/var/backup rewind

Конфигурационный файл /etc/amanda/fasttech/amanda.conf

  • org               Название компании;
  • mailto            Кому отправлять почтовые отчеты;
  • dumpuser          Логин используемый для бекапов;
  • dumporder         Приоритет дампера: s – маленький размер, S – большой размер.
  • taperalgo         Алгоритм для выбора какой дамп записывать на ленту;
  • displayunit       В каких еденицах отображать цифры, используем мегабайты;
  • dumpcycle         Число дней в backup-цикле;
  • runspercycle      Тоже самое что и dumpcycle;
  • tpchanger         Название устройства по смене лент;
  • tapecycle         Число лент которое Amanda использует в порядке ротации, должно быть больше чем в dumpcycle, обычно это количество лент dumpcycle*2;
  • tapedev           Тип ленточного устройства;
  • tapetype          Тип ленточного устройства ассоциированного с tapedev;
  • labelstr          Метка которая будет наноситься на ленты;
  • infofile, logdir, indexdir Опции задают расположение log-файлов, индексных файлов (содержащих образ бекап-директорий);
  • define tapetype   Задает бекап-устройство, в моем примере это диск на 500 Гб;
  • define dumptype   Здесь задаются backup-опции.

Подводим итоги

Принцип работы Amanda понять не сложно. Есть сервер с запущенной службой через xinetd и есть клиенты с запущенным сервисом ожидающим подключения от сервера. В файле .amandahosts на клиенте мы разрешаем каким серверам можно получать с нас бекап. В файле disklist на сервере мы перечисляем список серверов и каталогов которые мы хотим резервировать с них.

Как я писал выше, изначально Amanda была создана для работы с ленточными накопителями и это дает о себе знать. Нам нужно создать набор каталогов и пометить их как лента. Как будто мы работаем с набором лент ленточного накопителя. При каждом запуске резервного копирования ленты последовательно будут меняться в “виртуальном лотке”.