Эта публикация — дань уважения и некоторая переработка статьи за авторством jeffpeter68. Тем, кому неинтересны разглагольствования, промотайте чуть ниже. Там вы найдёте готовый скрипт для снятия бэкапов ревит-сервера на файловом уровне(выгрузкой .rvt файлов).

Системный администратор, работающий в компаниях занимающихся архитектурой, рано или поздно начинает превращаться (хотя-бы отчасти) в БИМа. Архитектура сети, хранилищ, их резервное копирование, распределение доступов — все эти стандартные для профессии задачи, в данной области обязательно должны учитывать особенности архитектурной деятельности.

I hope that in the near future Autodesk will buildin a backup/rollback feature

Эта цитата, из статьи 2014го (!!!) года, вызвала у меня, и моих коллег, знакомых с "особенностями" autodesk продуктов, приступ истерического смеха.

Итак, спустя 11лет, автодеском так и не было предложено разумного решения для снятия бэкапов на уровне файлов, для ревит-сервера. Каждый решает их по-своему, интернет полнится различными методами, но большая часть из них неполна, использует излишне усложнённые методы, или вовсе составлена без понимания работы РС.

В чём вообще проблема создания резервных копий РС? "Классический", он же самый простой способ хранения моделей — на файловом сервере. Тут всё просто, модели представлены файлами .rvt, настроить на любом типе хранилища инкрементные и полные бэкапы не представляет сложности. Мы работаем на уровне файлов, и любые способы — от скриптов до использования ПО нам подойдут.

Но РС хранит модели по-другому. Модели на РС представлены директориями вида "ИмяМодели.rvt". Внутри находятся различные служебные директории и файлы, обеспечивающие блокировку для редактирования только отдельных элементов модели, таким образом осуществляя "гит" подход РС к синхронизации данных. Всё это связывается центральным lock файлом и БД. Всё это прекрасно позволяет прекрасно закрывать задачи для которых разрабатывался РС, но превращается в кошмар для системного администратора. Ведь инкрементное снятие копий на файловом уровне приведёт к неконсистентности бэкапов, из-за наличия центральной БД. Полный же бэкап, заставляет восстанавливать его полностью, опять же для консистентности, ведь центральная БД не будет "в курсе" состояния восстановленной модели. Конечно, данное представление может быть не совсем верно, но трудности в снятии бэкапов оно на мой взгляд отражает достаточно верно.

Снимать бэкапы именно директорий можно, но чтобы они получились консистентными, РС необходимо заблокировать на время снятия бэкапа. Что добавляет трудностей, тк нам нужно однозначно знать в автоматическом режиме что сервер блокирован до снятия бэкапа, и что он точно разблокирован после. Ошибки здесь недопустимы, ведь мы однозначно не хотим ходить и руками разблокировать сервер, или получить неконсистентные бэкапы важного проекта.

Эта статься призвана помочь людям, столкнувшимся с данным вопросом, и предоставить готовое решение для бэкапов РС на файловом уровне.

Итак, наша задача — получить выгрузку моделей в виде .rvt файлов с ревит-сервера, для дальнейшего хранения, и в случае необходимости, передачи БИМ-менеджеру. Эту модель он спокойно самостоятельно сможет заменить через админ-панель сервера, и получить предыдущую версию модели.

Данная задача бьётся на более мелкие — получаем список моделей на сервере, передаём список утилите выгрузки, складываем модели в хранилище. По-хорошему, пишем процесс в лог, для дальнейшего мониторинга возможных проблем. Учтите, что список моделей нельзя передать утилите в абсолютном виде — ей необходимы относительные пути, начальной точкой которых является директория projects ревит-сервера.

Перейдем к главному — ниже скрипт, закрывающий все вышеописанные задачи. RevitServerToolCommand поддерживает unc и сетевые пути согласно документации, так-что он применим для сетевых хранилищ "as is".

@echo off
chcp 65001 >nul
setlocal EnableDelayedExpansion

rem ================================================== Configuration ==================================================
set "listfile=R:\BACKUP\rvtprojects-list.txt"
set "basepath=R:\Revit Server 2022\Projects"
set "servername=rvtest"
set "basefolder=R:\BACKUP"
set "toolpath=C:\Program Files\Autodesk\Revit Server 2022\Tools\RevitServerToolCommand\RevitServerTool.exe"

rem ================================================== End of configuration ==================================================

rem Create timestamped backup folder
for /f %%a in ('powershell -command "Get-Date -Format 'yyyy-MM-dd_HH-mm-ss'"') do set "timestamp=%%a"
set "backupfolder=!basefolder!\!timestamp!"
set "logfile=!backupfolder!\backup.log"

echo ===== REVIT SERVER BACKUP PROCESS =====
echo Server: !servername!
echo Projects path: !basepath!
echo Backup folder: !backupfolder!
echo Model list: !listfile!
echo Log file: !logfile!
echo ========================================
echo.

rem Create backup folder
if not exist "!backupfolder!" mkdir "!backupfolder!"

rem Initialize log file
echo Backup started at %date% %time% > "!logfile!"
echo Server: !servername! >> "!logfile!"
echo Projects path: !basepath! >> "!logfile!"
echo ================================== >> "!logfile!"

rem Check if RevitServerTool exists
if not exist "!toolpath!" (
    echo ERROR: RevitServerTool not found: !toolpath!
    echo ERROR: RevitServerTool not found: !toolpath! >> "!logfile!"
    pause
    exit /b
)

rem Check if projects path exists
if not exist "!basepath!" (
    echo ERROR: Projects path not found: !basepath!
    echo ERROR: Projects path not found: !basepath! >> "!logfile!"
    pause
    exit /b
)

rem STEP 1: Generate model list
echo STEP 1: Generating model list...
echo STEP 1: Generating model list... >> "!logfile!"

if exist "%listfile%" del "%listfile%"
for /D /R "%basepath%" %%d in (*.rvt) do (
    set "fullpath=%%d"
    set "relativepath=!fullpath:*%basepath%\=!"
    
    rem Convert to logical path format
    set "logicalpath=!relativepath:\=/!"
    
    echo !logicalpath!>>"%listfile%"
)

rem Check if any models were found
if not exist "!listfile!" (
    echo ERROR: No models found - list file was not created
    echo ERROR: No models found - list file was not created >> "!logfile!"
    pause
    exit /b
)

rem Count models in list
for /f %%c in ('find /c /v "" ^< "!listfile!"') do set "modelcount=%%c"
echo Models found: !modelcount!
echo Models found: !modelcount! >> "!logfile!"
echo.

if !modelcount! equ 0 (
    echo ERROR: No models found in list
    echo ERROR: No models found in list >> "!logfile!"
    pause
    exit /b
)

rem STEP 2: Backup models
echo STEP 2: Starting backup process...
echo STEP 2: Starting backup process... >> "!logfile!"

rem Process each model from the list
set "successcount=0"
set "errorcount=0"

for /f "delims=" %%m in (!listfile!) do (
    set "modelpath=%%m"
    
    rem Extract model name for local file
    for %%f in ("!modelpath!") do set "modelname=%%~nxf"
    
    set "localfile=!backupfolder!\!modelname!"
    
    echo Backing up: !modelpath!
    echo   to: !localfile!
    echo Backing up: !modelpath! >> "!logfile!"
    echo   to: !localfile! >> "!logfile!"
    
    "!toolpath!" createLocalRVT "!modelpath!" -s !servername! -d "!localfile!" -o
    
    if !errorlevel! equ 0 (
        echo   SUCCESS
        echo   SUCCESS >> "!logfile!"
        set /a successcount+=1
    ) else (
        echo   ERROR - Exit code: !errorlevel!
        echo   ERROR - Exit code: !errorlevel! >> "!logfile!"
        set /a errorcount+=1
    )
    echo.
    echo ---------------------------------- >> "!logfile!"
)

echo.
echo ===== BACKUP SUMMARY =====
echo Total models: !modelcount!
echo Successful: !successcount!
echo Failed: !errorcount!
echo Backup folder: !backupfolder!
echo ==========================

echo ===== BACKUP SUMMARY ===== >> "!logfile!"
echo Total models: !modelcount! >> "!logfile!"
echo Successful: !successcount! >> "!logfile!"
echo Failed: !errorcount! >> "!logfile!"
echo Backup completed at %date% %time% >> "!logfile!"

if exist "%listfile%" del "%listfile%"
echo Backup process completed.
pause

На мой взгляд, у данного подхода есть только один минус — довольно ощутимое время снятия бэкапа. В тестовой среде, при расположении дисков ВМ на ссд-массиве, и конфигурации 4 ядра(2,6 ГГц) 4 гб, снятие бэкапа 20ти моделей(вес директорий от 10ти до 150 мб) заняло 30 минут. Могу предположить, что для его уменьшения стоить выдать машине больше вычислительных ресурсов.

Комментарии (0)