Резервное копирование баз программы «1С: Предприятие» различных версий
Возникла следующая задача: есть сервер на Alt Linux на нем установлены различные варианты 1С.
Все базы можно свести к 3 вариантам:
- файловые версии баз причем как 7-ки так и 8-ки (тут все просто, копируем папки)
- базы 7-ки, хранящиеся в PostgreSQL (тут нужен дамп базы, но иногда желательно и папку с конфигурацией, отчетами и т.д. тоже копировать)
- клиент-серверная 8-ка с хранением в PostgreSQL (тут в принципе хватит просто дампа базы)
Конечно у 1С есть свои средства резервного копирования, но все таки ИМХО было быстрее написать единый скрипт, чем копаться сначала в 7-ке, потом в 8-ке, чтобы в итоге это все работало. Поэтому решено написать свой скрипт, который будет все это копировать и выстроит приемлимую структуру копий.
Для бэкапа всего этого зоопарка была выбрана следующая структура хранения данных:
Папка с копиями — версия программы — имя базы — архив от определенного числа.
Также, на всякий случай, ежемесячно откладывать в отдельную папку по резервной копии.
В итоге работы появился bash-скрипт, о котором речь и пойдет под катом.
Решено использовать файл конфигурации, в котором описаны базы в следующем виде:
Имя базы: путь относительно общего каталога с базами: тип базы: имя
базы в PostgreSQL
В принципе, я думаю тут все ясно, остановлюсь только на 3-х моментах:
В результате получается файл содержащий примерно следующее
Base1:cat1/base1:f
Base2:cat2/base2:s:base_2
#Base3:base3:f
Base4::8:Base4
Для удобства я этот файлик скрыл и кинул в домашнюю папку пользователя, от которого будет запускаться скрипт.
Перейдем теперь к самому скрипту. Он разбит на 3 части:
- Ввод переменных
- Копирование во временную папку
- Архивирование и перенос в папку с бэкапами
В принципе, я думаю комментариев в нем достаточно да и сам он не особо сложен.
#!/bin/bash # Переменные pathtmp='путь к временной папке' pathfrom='путь к папке с базами' pathto='путь к папке с бэкапами' format=$(date +%Y%m%d) # дата в виде годмесяцчисло cfg="путь к конфигу" # Параметры подключения к Postgre (если необходимо) dbhost='адрес сервера' dbuser='имя_пользователя' dbpass='пароль' # функция чтения переменных из строчки set_conf_var () { mark=0 #маркер, определяющий тип резервного копирования if [ "$1" != "" ] # отделяем закомментированые базы then folderto=$(head -${cont} $cfg | tail -1|cut -f1 -d:) folderfrom=$(head -${cont} $cfg | tail -1|cut -f2 -d:) type=$(head -${cont} $cfg | tail -1|cut -f3 -d:) mark=1 else mark=0 fi if [ "$type" == "s" ] then sql_base=$(head -${cont} $cfg | tail -1|cut -f4 -d:) ver='77' # переменная с версией программы 1С mark=3 #Это условие нужно для того чтобы раз в неделю и в начале месяца к дампу добавлялась папка с конфигурацией if [ "$(date +%a)" == 'Thu' ]||[ "$(date +%a)" == 'Чтв' ]||[ "$(date +%d)" == '01' ]; then mark=2; fi fi if [ "$type" == "8" ]; then sql_base=$(head -${cont} $cfg | tail -1|cut -f4 -d:);mark=3; ver='82'; fi # тут мы определяем какая именно из файловых версий лежит 7-ая или 8-ая версия if [ "$type" == "f" ] then v77=$(ls "${pathfrom}${folderfrom}/" | grep -ic 1cv7.md) v82=$(ls "${pathfrom}${folderfrom}/" | grep -ic 1cv8.1cd) if [ $v77 -ge 1 ]; then ver='77'; else if [ $v82 -ge 1 ]; then ver='82'; fi; fi echo $v77, $v82, $1 fi } # функция копирования исходных данных во временную папку copy_src () { # копируем только файлы if [ $1 -eq 1 ] then rsync -r "${pathfrom}${folderfrom}/" $format fi #копируем файлы и делаем дамп if [ $1 -eq 2 ] then rsync -r "${pathfrom}${folderfrom}/" $format export PGPASSWORD=${dbpass} pg_dump -h $dbhost -U $dbuser -c $sql_base>"${format}/base_dump.sql" export PGPASSWORD= fi # только дамп базы if [ $1 -eq 3 ] then export PGPASSWORD=${dbpass} pg_dump -h $dbhost -U $dbuser -c $sql_base>"${format}/base_dump.sql" export PGPASSWORD= fi } # Проверка на наличие конфига if [ -f $cfg ]; then : ; else echo "Нет файла конфигурации" exit 0; fi # Подсчет общего количества баз (использовал для отладки, можно закомментить или использовать в логах) cont=1 cfg_all=$(cat "$cfg"|grep -c ".") cfg_comment=$(cat "$cfg" |grep -c \#) echo $cfg_all,$cfg_comment let $[bases_cont=$cfg_all - $cfg_comment] echo "Всего: $bases_cont баз(ы)" # Подготовка папок для бэкапа # создаем (если нет) папку 1cbackup if [ -d "${pathtmp}/1cbackup" ]; then : ; else mkdir "${pathtmp}/1cbackup"; fi # читаем построчно файл конфигурации until [ $cont -gt $cfg_all ] do string=$(head -${cont} $cfg | tail -1|cut -f1 -d\#) set_conf_var "$string" if [ $mark -ne 0 ] then cd ${pathtmp}/1cbackup/ # в одной временной директории создается еще одна, сделано на всякий случай, если вдруг пойдет что то не так собирать файлы придется не по всему темпу а в одной папке (лично мне так удобней) mkdir $format copy_src "$mark" # проверяем существует ли папка для бэкапа if [ -d "${pathto}${ver}/${folderto}" ]; then : ; else mkdir "${pathto}/${ver}/${folderto}"; fi cd $format # проверка на начало месяца, в начале месяца откладываем отдельно if [ "$(date +%d)" == '01' ] then tar -czf "${pathto}${ver}/${folderto}/monthly/${format}.tar.gz" * else tar -czf "${pathto}${ver}/${folderto}/${format}.tar.gz" * fi # удаляем следы cd .. rm -r ${format} fi let $[cont=$cont+1] done
Вот такой скрипт. В конце хотел бы отметить для чего я складываю месячные бэкапы отдельно.
Пока не написал но вообще планирую прикрутить циклическую очистку, чтобы допустим было всего 30 копий а каждая следующая затирала самую старую, поэтому месячные и откладываю (а вдруг).