Как я организовал бэкапы баз 1С
Автор: clovus
Поделюсь своим решением, как я организовал бэкапы баз 1С. Основное требование к решению (за исключением работоспособности) - использование штатного ПО, которое уже есть в репозитории/ничего дополнительно не устанавливать. Имитация закрытого контура.
Итак, условия: windows server на котором работает 1с и на нем же PostgreSQL и некое файловое хранилище, к которому есть доступ исключительно по ftp.
Из утилит, которыми можно решать задачу, под рукой оказалась rsync
.
Бэкап базы 1С будем делать штатной программой от 1С. Однозначного мнения нет, чем лучше бэкапить - средствами СУБД или этой программой, есть у каждого варианта свои преимущества и недостатки. В нашем варианте используем именно ПО от 1С.
Чтобы делать это с помощью планировщика, делаем простой .bat для windows сервера, имя файла отражает дату его создания.
set datetemp=%date:~-10%
"C:\Program Files\1cv8\8.3.24.1819\bin\ibcmd.exe" infobase dump --db-server=localhost --dbms=PostgreSQL --db-name=название_бд --db-user=имя_пользователя_бд --db-pwd=пароль_пользователя_бд --user=имя_пользователя_в_1С --password=пароль_пользователя_1С "C:\путь_для_бэкапа\имя_файла_"%datetemp%".dt"
Бэкапы базы сохраняются локально. Теперь надо их оттуда забрать и бережно перенести на файловое хранилище.
Для этих целей хорошо подойдет rsync
. Поднимать сервер rsync не хотелось, поэтому пошел по пути набора команд.
Формат будущей команды выглядит так:
rsync -av ~/bases_1s/bgu ~/backup/
Rsync
(ключа а = в архивном режиме, его обычно достаточно для целей бэкапа, ключ v добавит подробностей) скопирует папку bgu
из ~/bases_1s
и положит их в ~/backup/
.
Обращайте внимание на слэши в конце пути - играют роль в вопросе перенести папку целиком или же ее содержимое, без создания одноименной папки в точке назначения.
ЧИТАТЬ ПЕРВЫМ В ТЕЛЕГРАМВсе хорошо, но rsync работает, если хотя бы один путь локальный, а у нас два удаленных хоста. Выход есть. Примонтируем папку с бэкапами по SMB.
Строка в /etc/fstab
выглядит у меня так:
//192.168.0.2/название_папки_на_сервере_win /home/user/bases_1s cifs credentials=/home/user/.smbcreds,noauto,users,iocharset=utf8,uid=500,gid=500 0 0
В .smbcreds
лежит логин с паролем пользователя windows сервера, noauto=не монтировать при запуске.
Далее, возникла засада в виде того, что если доступ есть по ftp
, то rsync бессилен
, ftp
- протокол и rsync
тоже протокол и надо выбрать.
В этой ситуации поможет замечательная curlftpfs
. Утилита позволяет монтировать удаленные ftp
папки в локальную файловую систему.
Установим ее и добавим своего пользователя в группу fuse (чтобы работать без повышения привилегий):
apt-get install curlftpfs
usermod -aG fuse имя_пользователя.
Создаем файлик с кредами, создаем папку куда будем монтировать и подключаемся (все от своего пользователя):
echo 'machine 192.168.0.18
login фтп_юзер
password пароль' > .netrc
Кроме работы rsync
есть еще реализация резервного копирования посредством cp
. Оставил пока как есть, в планах единообразить и прикрутить отчет о выполнении.
На данном этапе скрипт выглядит примерно так:
#!/bin/bash
#монтируем папку, если она не смонтирована, если неуспешно, выход
mount | grep "bases_1s" || mount ~/bases_1s
mount | grep "bases_1s" || { echo "не смонтировано, отмена"; exit 1; }
#аналогично, с файловыми хранилищем
mount | grep "ftp" || curlftpfs 192.168.0.18:/folder ~/ftp -o rw, uid=500, gid=500
mount | grep "ftp" || { echo "не смонтировано, отмена"; exit 1; }
mkdir /tmp/rs 2>/dev/null
rsync -av --temp-dir=/tmp/rs --size-only /home/user/backup/bgu/bgu* /home/user/ftp/bgu_office/
mount | grep "mount_kassa" || mount ~/mount_kassa
mount | grep "mount_kassa" || { echo "не смонтировано, отмена"; exit 1; }
#получаем самый свежий файл
file_copy=$(ls ~/mount_kassa/rosn* -t | head -1)
#считаем количество файлов бэкапов
count_files=$(ls ~/mount_kassa/rosn* | wc -l)
cp $file_copy ~/ftp/kassa-adm/
status_copy=$?
#после проверки успешности копии удаляем самый старый файл, при этом
#общее количество файлов должно быть больше 10.
if [[ $status_copy -eq 0 ]]; then
echo "скопирован $file_copy"
fi
if [[ $count_files -gt 10 ]] && [[ $status_copy -eq 0 ]]; then
file_remove=$(ls ~/mount_kassa/rosn* -t | tail -1)
echo "будет удален $file_remove"
rm $file_remove
fi
umount ~/mount_kassa
Стоит еще пояснить о ключе --temp-dir=/tmp/rs
в команде rsync. Он нужен чтобы обойти ограничение “ftp файловой системы”, которая не поддерживает создание временных файлов.