Software

Скрипт для бэкапа баз 1С

Нет, все-таки не можешь. Но зато есть куча способов бэкапить базы 1С. Как известно, админы делятся на тех кто ещё не делает бэкапы и кто уже делает. Я принципиально не хотел переводить рабочие базы на новый сервер, пока там не будет настроено разномастное, автоматическое резервное копирование.

Исходные данные:

  • Ubuntu Server
  • PostgreSQL
  • Сервер 1С
  • Apache

Автономный сервер 1С

Первое с чем я начал разбираться, когда речь зашла о бэкапах - как делать бэкапы клиент-серверной базы в DT формате? Что самое смешное, фирма 1С не рекомендует использовать этот формат для резервного копирования. Причина: архивная база выгруженная в DT может не загрузиться обратно. Я с таким сталкивался крайне редко, но действительно, пару раз такое было. Зачем же мне понадобились DT? Отвечаю: нужно быть готовым к тому, что может отказать любой элемент сети. В том числе, если новый линуксовый сервер по какой-то причине упадет целиком и нужно будет время на его ремонт – работать как-то надо. В этом случае хорошо бы иметь базы в формате DT под рукой, чтобы быстро развернуть их в старом добром файл-серверном варианте на старом сервере и продолжить работу.

И вот тут пришел на помощь "Автономный сервер 1С". Глобально, скажу честно, так и не понял зачем он нужен в прикладном смысле. Точнее – принял к сведению зачем его разработали, но не придумал такой жизненной ситуации, когда бы это пригодилось. Почитать можно тут: https://its.1c.ru/db/v8320doc#bookmark:adm:TI000000894

У этого автономного сервера есть очень классная консольная утилита и она может выгружать базы в DT без монопольного режима. Это очень удобно, потому что не нужно связываться со скриптами, которые выбивают зависших в базе пользователей. Просто выгружаешь базу "на горячую" и не паришься.

Автономный сервер "стучится" в базу на уровне СУБД. И логин и пароль нужно указывать от пользователя PostgreSQL, а не от базы 1С. Скрипт выгрузки базы "на горячую" выглядит вот так:

backup_1=${dtDir}${base1}_sql_${DATE}
/opt/1cv8/x86_64/${platform}/ibcmd infobase dump --dbms=PostgreSQL --db-server=localhost --db-user=$usersql --db-pwd=$pgpwd --db-name=$base1 ${backup_1}.dt

usersql - это имя пользователя СУБД

pgpwd - это его пароль

Утилита ibcmd вызывает экземпляр автономного сервера. Это утилита для управления автономным сервером из командной строки. Есть и под Windows и под Linux в папке с установленной платформой. Да да, и из под винды тоже можно выгружать DT "на горячую" - круто.

Выгрузка средствами PostgreSQL

Как писал выше, выгрузка в формате DT удобна, но может подвести в ответственный момент. И тут надо подстраховаться бэкапами в формате самой СУБД. Для этого служит команда pg_dump
Я столкнулся с проблемами авторизации при выгрузке дампа базы. Не мог долго запустить скрипт, получал ошибку, что пользователь не прошел проверку подлинности. В официальной документации PostgreSQL написано о двух вариантах авторизации. Либо мы прямо в скрипте загоняем в специальную переменную пароль (но это небезопасно, т.к. пароль лежит в открытом доступе). Либо создаем в домашнем каталоге пользователя (от имени которого работает сервис PostgreSQL) специальный файл с паролем. Но ни тот ни другой вариант у меня не сработал. Почему? Так и осталось для меня загадкой.

На помощь пришел мой коллега линуксоид, который опять выручил советом. Совет был следующий: вообще отключить в конфигурационном файле PostgreSQL проверку. Но сделать это только для локальный подключений. Т.е. при запросах с хоста.

Для этого меняем на "trust" конфигурационный файл так как на скриншоте: /var/lib/pgpro/1c-12/data/pg_hba.conf

После этого PostgreSQL будет "верить" всем пользователям, которые подключаются к базе с хоста и не будет вообще спрашивать пароль. На мой вопрос: "Серег, а это не считается дыркой в безопасности?" мой коллега опять поразил меня нестандартным мышлением линуксоида: "дыркой в чем? ты же разрешаешь для localhost т.е. trust соединения с адреса 127.0.0.1 если на твой хост проникли - то считай и так всё...".

Важно! Когда мы меняем авторизацию таким образом, почему-то перестает работать вход в консоль psql без указания параметра -h. Поэтому вход будет выглядеть так:

psql -h localhost -U postgres

Ключ -h localhost также нужно обязательно указывать при вызове команды pg_dump
В итоге скрипт получился максимально простой:

pg_dump -h localhost -U ${UserPostgreSQL} -c ${base1} | gzip > ${backup_1}.gz

base1 - имя базы

UserPostgreSQL - имя пользователя PostgreSQL

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

Бэкапы бэкапов

Два вида бэкапов – это конечно, хорошо. Но что, если накроется диск с бэкапами или придет вирус-шифровальщик. Опасно хранить все на одном диске. Поэтому я добавил в скрипт команды по копированию архивов на другие машины. Т.е. бэкап во-первых создается на соседнем диске той машины, где крутится PostgreSQL, во-вторых эти архивы копируются на другую машину, на другой диск. В-третьих на этой другой машине (NAS Synology) срабатывает ещё один скрипт (о котором речь в другой статье), который прячет архивы в закрытую папку, к которой нет доступа с других машин. Т.е. папка не сетевая.

#Copy to LAN Dir (Synology)
cp -f ${dtDir}*.gz ${lanDir}
cp -f ${dtDir}*.dt ${lanDir}
#Move to local
mv ${dtDir}*.gz ${localDir}
mv ${dtDir}*.dt ${localDir}
find ${localDir}/*.* -type f -mtime +$OldFiles -exec rm {} \;

Последняя строчка - удаление архивов старше OldFiles дней.

Бэкапы бэкапов бэкапов

Этого мне показалось мало, поэтому на третьей виндовой машине я сделал ещё один скрипт, который копирует созданные бэкапы ещё на один диск, синхронизированный с облаком. Это уже bat под Windows, который запускается регламентным заданием по расписанию.

::Временный архив
set FTPServer=\\СЕТЕВОЙ_ПУТЬ_К_ПАПКЕ_ГДЕ_ЛЕЖАТ_АРХИВЫ
::Локальный архив
set DestPath= ЛОКАЛЬНАЯ_ПАПКА_НА_МАШИНЕ_С_КОТОРОЙ_ЗАПУСКАЕТСЯ_СКРИПТ
::Облачный архив
set CloudServer= ЛОКАЛЬНАЯ_ПАПКА_КОТОРАЯ_СИНХОНИЗИРОВАНА_С_ОБЛАКОМ
set archiv_pwd=ПАРОЛЬ_ДЛЯ_АРХИВАЦИИ
::Определение даты и времени
set timestr=%date:~6,4%_%date:~3,2%_%date:~0,2%
set day=%DATE:~0,2%
set month=%DATE:~3,2%
set year=%DATE:~6,4%
set hour=%TIME:~0,2%
set minute=%TIME:~3,2%
set dat=%year%_%month%_%day%

::Копирование архива в трех форматах на третий сервер
copy "%FTPServer%\*.zip" %DestPath%
copy "%FTPServer%\*.gz" %DestPath%
copy "%FTPServer%\*.dt" %DestPath%

::Создание ежедневного архива
:start_dt
IF NOT EXIST %FTPServer%\*.dt (goto start_gz) ELSE del "%CloudServer%\Actual_DT*" & ping -n 10 127.0.0.1 > NUL & "E:\Program Files\7za.exe" a "%CloudServer%\Actual_DT.zip" -mx1 -v1900m -p%archiv_pwd% -ssw -sccWIN %FTPServer%\*.dt
:start_gz
IF NOT EXIST %FTPServer%\*.gz (goto exit) ELSE del "%CloudServer%\Actual_GZ*" & ping -n 10 127.0.0.1 > NUL & "E:\Program Files\7za.exe" a "%CloudServer%\Actual_GZ.zip" -mx1 -v1900m -p%archiv_pwd% -ssw -sccWIN %FTPServer%\*.gz

:exit
::Удаление старых
Forfiles -p %DestPath% -s -m *.* -d -30 -c "cmd /c del /q @path"

Автоматический мониторинг бэкапов бэкапов бэкапов

И вишенка на торте – нужно мониторить, что скрипты отработали вовремя и бэкапы создаются каждый день. Пришел к выводу, что наиболее удобно это можно сделать в системе Zabbix. Открыл данную систему для себя недавно и впал в полнейший восторг. Особая гордость за то, что это очередная open-source система мирового уровня, которую разработал русский программист Алексей Владышев.

Выражение триггера Zabbix получилось такое:

(now()-last(/ИМЯ_СЕРВЕРА/vfs.file.time["ПУТЬ_К_ПАПКЕ_КОТОРАЯ_СИНХРОНИЗИРУЕТСЯ_С_ОБЛАКОМ\Actual_GZ.zip.001",modify]))>97200

Проверка, что архивы не старше 27 часов. Т.е. сутки + запас на время бэкапирования.