Суть рассматриваемого вопроса изложена в заголовке, повествование разобьем на три части. Отдельно внизу будут приведены тексты скриптов.
1) Предисловие
Вопрос необходимости резервного копирования в автоматическом режиме не подлежит сомнению ни у корифеев, ни у новичков. В статье рассмотрим резервное копирование средствами 1С (что имеет ряд преимуществ перед копированием средствами СУБД). При этом будут применены средства пакетного запуска платформы 1С, powershell и планировщик задач Windows.
Задачи обновления информационных давно автоматизированы, но только для типовых конфигураций, либо тех, что используют библиотеку стандартных подсистем. В моем случае мы работаем со старенькой Альфа-Авто редакции 4, которая распространяется на 12 серверов. Изменения вносятся примерно два раза в неделю, поэтому выгода от автоматизации налицо.
В обоих случаях мы имеем следующие исходные данные:
- Операционная система Windows Server (версии от 2008 до 2012);
- Клиент-серверный вариант платформы 1С 8.3 (с обязательно установленным компонентом COM-соединение).
Разумеется, у нас есть учетные данные ОС и 1С с административными правами.
Для обновления конфигурации так же понадобится ftp-сервер.
Чтобы не раздувать статью, рекомендую прочесть про powershell и про планировщик Windows отдельно.
2) Резервное копирование
После прочтения указанных ссылок мы уже знаем, что надо сделать, чтобы запустить скрипт powershell, поэтому сразу перейду к делу.
Сделать резервную копию информационной базы в пакетном режиме очень просто, надо только «выгнать» всех пользователей. Делать мы это будем, подключившись COM-объектом к базе данных. Это в нашем примере делает функция ExitAll. В тело функции зашито, что она вызывается на том сервере, на котором, собственно, установлен кластер серверов 1С. Вызовите эту функция безо всяких параметров в своем скрипте на сервере — и ВСЕ пользователи из ВСЕХ баз кластера вылетят.
Приношу свои извинения человеку, чьим кодом я воспользовался при написании этой процедуры — авторство восстановить не удалось.
После этого следует вызвать функцию BackUpBase с параметром — имя информационной базы. У меня во всех ИБ есть служебный администратор с одинаковыми учетными данными, поэтому я их просто захардкодил. При необходимости можно их параметризовать, либо обойтись аутентификацией ОС.
Итоговый скрипт сохраняем в файл.
В планировщике задач создаем «Простую задачу», имя, разумеется, на ваше усмотрение.
У меня работает ежедневно, но и тут хозяин — барин. Запускать лучше всего ночью, когда никто не работает, например, в 3:00. Действие для задачи — «Запустить программу». Сама программа у нас «powershell.exe». А вот ее аргументы —
-File "D:\1C_automatization\ExitAllUsersAndBackup.ps1" -ExecutionPolicy RemoteSigned
где ExitAllUsersAndBackup.ps1 — как раз наш сохраненный скрипт.
-ExecutionPolicy RemoteSigned — ключ, который разрешает выполнение пакетных скриптов powershell, если в системе они глобально не разрешены. Работает через раз (возможно, не хватает компетенции чтобы разобраться, но закономерности не нашёл). В случаях, когда не работает с этим ключом, приходится разрешать выполнение скриптов для всего сервера.
Для этого Win+R, powershell.exe,
Set-ExecutionPolicy RemoteSigned
и подтверждаем действие.
Время работы с данными скриптами — более трех месяцев. Перебои были, но связаны с отключением электричества и прочими внешними факторами.
3) Обновление конфигурации
После того, как все пользователи вышли (или выгнаны, как в предыдущем случае), можно обновлять конфигурацию. Наличие регламентных заданий может помешать обновлению, так как с момента отключения всех пользователей и открытия конфигуратора для загрузки конфигурации вполне может начать работу какое-то задание. Поэтому расписание следует обдумать.
Конфигурацию мы храним на ftp-сервере, на который помещаем ее вручную. Файл конфигурации называется GK.cf, в приведенном примере обновляется одна единственная конфигурация. Потенциально можно так же обновлять и несколько различных конфигураций.
На ftp рядом с GK.cf помещаем файл с названием flag.txt. Наличие этого файла сигнализирует о том, что обновляться надо. Можно проверять наличие самого фйла GK.cf, но мы используем флаг так же для других целей.
Скрипт работает следующим образом:
- Удаляет GK.cf и flag.txt, если таковые есть в рабочем каталоге (у пользователя, от имени которого будет запускаться планировщик, должно быть право на запись в этот каталог);
- Предпринимается попытка скачать файл флага;
- Если такой файл скачать получилось — скачиваем .cf;
- Собственно, обновление функцией UpdateCf.
В отличии от предыдущего случая, параметры запуска 1С переданы не массивом, а в привычном по командной строке режиме.
Надежность этого скрипта чуть меньше. Обновление проходит до конца на 100% в тех случаях, когда меняется структура метаданных. В других случаях бывает, как я предупреждал ранее, появление активного пользователя. В результате конфигурация загружена в базу, но конфигурация базы данных не обновлена (снова прошу прощения за подобную кривоватую терминологию перед людьми, не связанными с 1С). В остальном — полет нормальный.
Скрипт резервного копирования
# параметры общие ++
$BAKUPDIR="D:\1C_automatization\BACKUP\"
$CEXE="C:\Program Files (x86)\1cv8\common\1cestart.exe"
# параметры общие --
function ExitAll{
# Сценарий разрывает все сессии пользователей во всех ИБ на выбранном кластере сервера приложений 1С
# Если часть сессий остается активными после этого, то он останавливает все рабочие процессы кластера
# Параметры запуска сценария: адрес сервера, основной порт кластера
#$SrvAddr = "tcp://y001-ap-01:1640"
$SrvAddr = "tcp://127.0.0.1"
########################################
$V83Com = New-Object -COMObject "V83.COMConnector"
# Подключение к агенту сервера
$ServerAgent = $V83Com.ConnectAgent($SrvAddr)
$ClusterFound = $FALSE
#Получим массив кластеров сервера
$Clasters = $ServerAgent.GetClusters()
foreach ($Claster in $Clasters){
# Аутентификация к выбранному кластеру
# если у пользователя, под которым будет выполняться сценарий нет прав на кластер,
# можно прописать ниже имя пользователя и пароль администратора кластера
$ServerAgent.Authenticate($Claster,"","")
#получаем список сессий кластера и прерываем их
$Sessions = $ServerAgent.GetSessions($Claster)
write-host "Разрывается" $Sessions.Count "сессий..."
foreach ($Session in $Sessions){
$ServerAgent.TerminateSession($Claster,$Session)}
if (($Sessions.Count -eq 0)){
continue}
# Если часть сессий осталась активной можно остановить рабочие процессы
# Они перезапустятся автоматически главным менеджером кластера, но без "зависших" сессий
# Получаем список рабочих процессов кластера
$WorkingProcesses = $ServerAgent.GetWorkingProcesses($Claster)
foreach ($WorkingProcess in $WorkingProcesses){
if ($WorkingProcess.Running -eq 1){
write-host "Останавливаем процесс с PID =" $WorkingProcess.PID
#!!!здесь хорошо бы проверить что компьютер с которого запущен сценарий это выбранный в параметрах запуска сервер приложений 1С
Stop-Process $WorkingProcess.PID -Force}}
}
$V83Com = ""
}
function BackUpBase($IbName){
#Сформируем текущие дату и время
$NOWDATETIME = Get-Date -UFormat "%Y_%m_%d_%H-%M"
#Укажем, куда копировать (можно так же параметризовать, чтобы разные базы копировались в разные каталоги)
$TARGETDIR = $BAKUPDIR
#Сформируем имя файла резервной копии
$BAKFN=$TARGETDIR + $IbName + "_" + $NOWDATETIME + ".dt"
#Сформируем массив параметров
$PARAMS = ("DESIGNER","/UseHwLicenses+","/S","127.0.0.1\$IbName","/N","ИМЯАДМИНА1С","/P","ПАРОЛЬАДМИНА1С","/DumpIB",$BAKFN)
#Собственно, поехали
&$CEXE $PARAMS
}
#Выгонем всех
ExitAll
#Вот эти базы будут скопированы
BackUpBase RingAlpha
BackUpBase MazdaAlpha
BackUpBase RingAcc
BackUpBase RingZup
BackUpBase MazdaHRM
BackUpBase MazdaAcc
BackUpBase RingAcc48
BackUpBase RingHRM48
BackUpBase RingAccNorth
BackUpBase RingHRMNorth
Скрипт обновления конфигурации
function Download_File ($si_UserName, $si_Password, $si_Source_Path, $si_Target_Path){
$oi_Credentials = New-Object System.Net.NetworkCredential($si_UserName,$si_Password)
$oi_Web_Client = New-Object System.Net.WebClient
$oi_Web_Client.Credentials = $oi_Credentials
$oi_Web_Client.DownloadFile($si_Source_Path, $si_Target_Path)
while($oi_Web_Client.IsBusy){}
}
Clear-Host;
$curDir = $MyInvocation.MyCommand.Definition | split-path -parent
$curDir = $curDir + "\"
$server = "111.222.33.4" #FTP сайт
$flagfoldername = "/1C/flag.txt" #удаленная папка с флаг-файлом
$flagurl = "ftp://$server$flagfoldername" #url для закачки флага
$cffoldername = "/1C/GK.cf" #удаленная папка с файлом кофигурации
$cfurl = "ftp://$server$cffoldername" #url для закачки файла конфигурации
$login = "MYFTPUSER" #ftp-логин
$password = "MYFTPPWD" #ftp-пароль
$flagfile = $curDir + "flag.txt"
$cffile = $curDir + "GK.cf" #файл с конфигурацией на локальном диске
$SERVERNAME="127.0.0.1"
$CEXE="C:\Program Files (x86)\1cv8\common\1cestart.exe"
$ADMINNAME="1CUSER"
$ADMINPASS="1CPWD"
function UpdateCf($IBNameLocal){
&$CEXE 'DESIGNER' '/S' $SERVERNAME'\'$IBNameLocal '/N' $ADMINNAME '/P' $ADMINPASS '/LoadCfg' $cffile '/UpdateDBCfg' '-Server'
}
function FileExist($fpath){
$isfile = Test-Path $fpath
return ($isfile -eq "True")
}
#собственно, начало выполнения скрипта
if (FileExist $flagfile){
Remove-Item $flagfile
}
if (FileExist $cffile){
Remove-Item $cffile
}
Download_File $login $password $flagurl $flagfile
if (FileExist $flagfile){
Download_File $login $password $cfurl $cffile
if (FileExist $cffile){#стартуем обновление
UpdateCf "MazdaAlpha"
UpdateCf "RingAlpha"
}
}
Благодарю за внимание. Готов к конструктивной критике.
Комментарии (24)
Igorjan
18.01.2018 17:47А чем неудобен бэкап средствами сервера БД?
bolshoyfedya Автор
18.01.2018 21:39Всегда под рукой копия, которую можно развернуть в файловый вариант или на другом сервере с другой СУБД. Как минимум для «разбора полетов» и экспериментов, которые неудобно проводить на рабочей базе.
Психологически спокойнее, так сказать.
Больше, думаю, ничем.Gamm
19.01.2018 09:57Проблема только в том, что выгрузка в DT не является средством резервного копирования.
Не всегда можно восстановить базу из данного файла.
Это также официальная позиция 1С — бекап делать средствами субд или копированием файла 1CD, для файловой базы.
osipov_dv
18.01.2018 17:53Писал подобный скрипт, после того как 1с программисты отказались рассматривать продукты аналогичные тому что в первом комменте. У меня были следующие отличия от вашего:
1) базы находились на MS SQL и бэкапились его средствами (запуск invoke-sqlcommand вроде бы)
2) скрипт выполнялся каждые 5 минут, сканируя определенную сетевую шару на предмет файлов заданий (.update), в которых были указаны пути к базам и пути по unc к файлам конфигураций (обошлись без ftp)
3) по завершению файл-задание менял имя на .done или .error и высылал на почту (адрес получателя был в файле задания отдельной строкой) отчет о том как прошла процедура, и на каком шаге какая ошибка произошла
4) из-за особенностей платформы 8.3 и конфигураций (там не была реализована функция выхода всех пользователей), выгонялось через интерфейс кластера 1с + ставился запрет на фоновые задания и вход пользователей (пароль) до завершения процедуры обновления.
возможно что-то было еще, я это писал больше двух лет назад, и оставил в компании которую на тот момент покидал :) (то был дембельский аккорд)
Если интересно, попробую поднять старые исходники и показать интересующие места.osipov_dv
18.01.2018 17:57ах, да — сама идея такого скрипта была следующая: есть куча разработчиков, которые делают конфигурацию и не имеют прав ее применять (административных и юридически). И есть больше 10 серверов 1с с более чем 30 баз, которые надо обновлять в наименее критичное для бизнеса время (нет такого понятия как люди не работают с базами). Обновления идут часто и человек занимающийся ручным обновлением хочет спать, за результат обновления (качество работы 1с кода) он не отвечает :)
bolshoyfedya Автор
18.01.2018 21:41Думаю, было бы интересно добавить
запрет на фоновые задания и вход пользователей (пароль) до завершения процедуры обновления
особенно отследить момент завершения процесса обновления.osipov_dv
19.01.2018 08:58у меня он лежит на github, размещал для своих нужд, но расшарить не жалко. Все равно полноценную статью я писать не осилю:
github.com/OsipovDV/1c_update
еще одно важное отличие от вашего — у меня в файле задании говорится когда и во сколько обновлять. То есть какое-то жалкое подобие планировщика :)
hamnsk
18.01.2018 18:01Очень плохая идея, выгнать всех! А если идет массовое перепроведение документов? А если что то бухгалтера считать запустили? А если регламентные задания работают? Так что идея бекапить базу минуя сиквел сервер это плахая идея, база бекапиться только там и там же восстанавливается, при этом так же бекапяться и транзакшен логи. А про ком объект отдельная тема, любой админ 1ски знает, что иногда сервер DCOM перестает работать, ну просто вот так и ве это лечиться только перезагрузкой сервера целиком, что не всегда приемлемо. И вот в этом случае ваш скрипт уже сразу сломается. Далее вы грузите свой бекап на ftp, а если обрыв сессии? Докачка есть? Как показала практика бекап через фтп это не то что не безопасно это еще и не надежно, темболее хранить пароли в файле. Для этого как минимум можно их зашифровать и читать вообще с другого файла. Но лучшее решение это использовать Backula у нее есть клиент под винду, и проблема с фтп автоматом отпадет. В общем и целом, решение ваше это скорей попытка попробовать как можно, но не решение как нужно. Итак чтобы обеспечить точную доставку целого бекапа и последующее его восстановление нам надо:
1. Настроить Планы обслуживания на сервере БД, в том числе и бекап базы с проверкой, а так же бекап лога транзакций
2. Настроить Бакулу для забора этого бекапа, в определенное время
3. Переодически тестировать восстановление из бекапа
Только так.bolshoyfedya Автор
18.01.2018 21:511.Бэкап на ftp не грузится. Бэкап забирается по расписанию NASом с сервера.
2.COM-объект использую уже почти 4 года для выполнения целого ряда задач. За все время его «отвалы» проходили только после обновлений платформы и, реже, Windows. Обновления ОС ставятся по расписанию, после них уже составлен план для тестирования сервера. Платформу вообще вручную обновляем.
3.Как минимум две базы сразу разворачиваются из резервных копий в другие ИБ. В случае «несрабатывания» этого пункта получаем оповещение от пользователей в 9-00, и тут уже резервный вариант с копирование средствами СУБД. Пожалуйста, не спрашивайте, зачем такой извращенный способ.
По поводу того, что может быть прерван длительный процесс какой-либо обработки я с вами соглашусь. Но в моей практике такое было один раз и то сам виноват.hamnsk
19.01.2018 14:521. ФТП сама по себе плохая идея, тут важен контроль закачки, если докачка не поддерживается то без разницы как оно сделано
2. Есть проекты, когда 1с достаточно хорошо нагружена и имеет в онлайне больше 100 пользователей сразу, там есть вещи которые отваливают СОМ+, темболее сама Майкрософт давно признала, что это плохая технология и не рекомендует ее использовать, но что 1С до рекомендаций какой то Майкрософт
3. Не спрашиваю, средствами БД это все равно лучше и правильней, есть только одно НО, если тестировщик или разработчик сидит в конфигураторе или что то делает с базой вы ее никак не накатите, даже средствами SQL, будет просто обломс
По поводу длительных процессов, ну видимо вы не так активно используете 1с, бывает ее нагибают и в хвост и в гриву, когда 1с это основная система.
kol_dm_ukk
18.01.2018 21:56Выгрузка в DT будет эффективна только для баз небольшого размера. Очень неэффективно рубить сессии не глядя кто и что делает — возможно кто-то задержался на работе или работает удаленно, а вы ему вырубили длительную операцию. Я использовал в течении 7 лет Vritas (ранее Symantec) Backup Exec с агентом для приложений — в результате эффективное копирование, шифрование, тестирование копии и прочие плюшки, включая мониторинг заданий.
Автоматическое обновление баз в продуктиве для смелых парней!
dimatl
19.01.2018 02:17Масштабно, делаю тоже самое, но в меньшее количество строк, одна перезапускает сервер, чтобы все не выключенные компы отвалились, вторая делает бекап в папку синхронизируемую с яндекс-диском. Наверно это не очень корректно, и без защиты от шифровальщиков, но я пока с проблемами такого подхода не сталкивался.
grumegargler
19.01.2018 06:271. Резервное копирование средствами 1С, не является средством резервного копирования (https://its.1c.ru/db/v8311doc#bookmark:cs:TI000000136)
2. Чтобы обеспечить монопольный доступ, нужно не думать, как планировать задания (обновление индекса, например, может происходить каждый 15секунд), а ставить ключ блокировки сеансов.
altervision
19.01.2018 08:44Такими темпами может оказаться, что проще развернуть 1С в виртуальной среде и делать резервные копии самих виртуалок целиком.
osipov_dv
19.01.2018 08:59базы хранятся в SQL, а это не всегда тот же сервер. Так базы данных не резервируют, ибо велик шанс нарушить целостность базы.
Sergey-S-Kovalev
19.01.2018 08:48Захардкоженные логин и пароль это просто прекрасно.
Вы там хотя бы маломальскую авторизацию для этого прикрутите от AD или от локальной учетки хотя бы.osipov_dv
19.01.2018 09:01в моей версии логины вообще не захардкожены, авторизация AD от этой учетки запускается задание в шедулере, в 1с выданы права на АД учетку (в 1с это реализовано через зад). можете найти выше в комментах ссылку на гитхаб
EvilBeaver
19.01.2018 09:51А зачем убивать рабочие процессы 1С? Какой-то мегахаотичный скрипт. Да еще и на живую сеансы грохает… Лучше взять наработки 1с-комьюнити.Тот же обновлятор или скрипты "деплойки" по ссылкам выше привели.
vitaly71
19.01.2018 10:18Как уже было сказано, регламентно бекапить в dt идея не очень, но если уж так, то тогда, например —
rem Выключение службы, затем пауза на 30 секунд, затем включение службы, затем пауза на 30 секунд.
sc stop «1C:Enterprise 8.3 Server Agent»
ping -n 30 localhost
sc start «1C:Enterprise 8.3 Server Agent»
ping -n 30 localhost
rem Резервное копирование баз.
«C:\Program Files (x86)\1cv8\common\1cestart.exe» CONFIG /S«ts-2\BaseName» /N«User» /P«Password» /DumpIB"\\host\directory\%date:~-10%-basename.dt"bolshoyfedya Автор
19.01.2018 10:19За 30 секунд после запуска агента как раз фоновое задание может быть запущено.
deaddy64
19.01.2018 10:20Делать копию важных баз 1С с помощью механизма выгрузки информационной базы — моветон.
Цитата из официальной документации:
Выгрузка информационной базы данных в файл
Не рекомендуется использовать данный способ для создания резервной копии информационной базы по следующим причинам:
? может возникнуть ситуация, при которой файл выгрузки будет невозможно загрузить, если в информационной базе, из которой производилась выгрузка, существовали ошибки;
? длительное время создания;
? необходимость монопольного доступа к базе данных;
? высокие требования к оперативной памяти.
Если база sql, то копии нужно делать средствами sql сервера. Если база файловая, то только копия файлов БД. Это касается критических данных. Для тестирования и разработки наверно пойдёт и ваш метод.
Diversus
Знание скриптов — это хорошо, но все же готовый инструмент будет лучшим решением.
Обратите внимание на Обновлятор 1С.
Обновляет он лучше Вашего скрипта: он завершает все активные сеансы и блокирует работу с ИБ, обновляет, запускает конфигурацию в режиме предприятия и выполняет регламентные операции при обновлении и это в автоматическом режиме и может обновлять сразу на несколько релизов. Это что касается обновления.
Что касается резервного копирования, то он умеет не только делать бэкап, но и допустим защищать его от шифровальщиков, или делать дополнительно бэкап в облако.
Бесплатная версия очень функциональна, а если заплатите 900 руб, то получите полнофункциональную версию.
Очень рекомендую.