Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » MSFT SQL Server - Резервное копирование и восстановление БД MS SQL средствами PowerShell

Ответить
Настройки темы
MSFT SQL Server - Резервное копирование и восстановление БД MS SQL средствами PowerShell

Новый участник


Сообщения: 10
Благодарности: 0

Профиль | Отправить PM | Цитировать


Изменения
Автор: maximallist
Дата: 24-01-2025
Вложения
Тип файла: zip Скрипты.zip
(3.0 Kb, 1 просмотров)
Приветствую вас, уважаемые форумчане! Прошу вашей помощи в решении проблемы работы скриптов PS.

Вводные данные:
Имеется "боевой" сервер MS SQL 2022, совмещенный с ролью сервера 1С8.
Все нижеописанные действия проводятся на одном сервере.
Для экономии дискового пространства (а оно ограничено), тестовая база для бэкапов одна, а кол-во баз на текущий момент 3, далее может быть и больше.
Скрипты выполняются по расписанию в планировщике Windows.

Для реализации бэкапов БД 1С8 написаны скрипты на PowerShell (PS), в которых реализована следующая логика работы (упрощённо):
  1. Из исходной "боевой" скульной БД выгружается полный сжатый бэкап (.bak) с помощью оснастки PS "Backup-SqlDatabase";
  2. Полученный бэкап восстанавливается в тестовую скульную БД с помощью оснастки PS "Restore-SqlDatabase";
  3. После восстановления, файл бэкапа (.bak) удаляется;
  4. Далее идет подключение к базе 1С8 в режиме конфигуратора, в которую на скуле был восстановлен бэкап, и производится выгрузка дампа БД 1С8 в формате .dt
Код скрипта PowerShell №1

Код: Выделить весь код
# Load SQL Server cmdlets
Import-Module SqlServer

# Set variables SQL Server
$ServerInstance = "1C8SQLERP\SQL1C8ERP"
$DatabaseNameSource = "doc_prod"
$DatabaseNameDestination = "forbackup"
$BackupDir = "F:\BackUp"
$StartTime = (Get-Date)
$Timestamp = Get-Date -Format "yyyyMMdd"
$BackupFile = "${BackupDir}\${DatabaseNameSource}_${Timestamp}.bak"

Write-Host "Job Started in $StartTime" -ForegroundColor Yellow

# Create backup and archive directories if they don't exist
if (!(Test-Path $BackupDir)) {
    New-Item -ItemType Directory -Path $BackupDir
}

# Backup the SQL Server database
Backup-SqlDatabase -ServerInstance $ServerInstance -Database $DatabaseNameSource -BackupFile $BackupFile -CompressionOption On -CopyOnly
Write-Host "Database backup completed successfully." -ForegroundColor Green

# Restore the SQL Server database
Restore-SqlDatabase -ServerInstance $ServerInstance -Database $DatabaseNameDestination -BackupFile $BackupFile -ReplaceDatabase
Write-Host "Database restore completed successfully." -ForegroundColor Green

# Remove the original backup file
Remove-Item $BackupFile
Write-Host "Original backup file removed." -ForegroundColor Green

# Set variables 1C8
$PatchBackup = "\\data3\BackUP\1CBases\DO\" + $DatabaseNameSource + "_" + $Timestamp + "_" + ".dt"
$1cexe = '"C:\Program Files\1cv8\common\1cestart.exe"'
$BaseServer = "/S1C8SQLERP\" + $DatabaseNameDestination
$AdminLogin = '"/NBackUP"'
$Pswd = "/P123456"
$UC = "sudo"
$Argument = " ENTERPRISE $BaseServer $AdminLogin $Pswd /DisableStartupMessages"
$ArgumentBackup = "DESIGNER $BaseServer $AdminLogin $Pswd /UC $UC /DumpIB" + $PatchBackup

# Backup 1C8 Base
Start-Process $1cexe $ArgumentBackup
# Loop for checking the created dt file
While($true)
{
    if (Test-Path $PatchBackup) 
    {
    $EndTime = (Get-Date)
    $TotalTime = $EndTime-$StartTime
    Write-Host "Database 1C8 backup completed successfully." -ForegroundColor Green
    Write-Host "Job Finished in $EndTime" -ForegroundColor Yellow
    Write-Host "Total time:" -ForegroundColor Red
    '{0:mm} min {0:ss} sec' -f $TotalTime
    exit
    }
    Start-Sleep -Seconds 10
}

Код скрипта PowerShell №2
Код: Выделить весь код
# Load SQL Server cmdlets
Import-Module SqlServer

# Set variables SQL Server
$ServerInstance = "1C8SQLERP\SQL1C8ERP"
$DatabaseNameSource = "doc3_prod"
$DatabaseNameDestination = "forbackup"
$BackupDir = "F:\BackUp"
$StartTime = (Get-Date)
$Timestamp = Get-Date -Format "yyyyMMdd"
$BackupFile = "${BackupDir}\${DatabaseNameSource}_${Timestamp}.bak"

Write-Host "Job Started in $StartTime" -ForegroundColor Yellow

# Create backup and archive directories if they don't exist
if (!(Test-Path $BackupDir)) {
    New-Item -ItemType Directory -Path $BackupDir
}

# Backup the SQL Server database
Backup-SqlDatabase -ServerInstance $ServerInstance -Database $DatabaseNameSource -BackupFile $BackupFile -CompressionOption On -CopyOnly
Write-Host "Database backup completed successfully." -ForegroundColor Green

# Restore the SQL Server database
Restore-SqlDatabase -ServerInstance $ServerInstance -Database $DatabaseNameDestination -BackupFile $BackupFile -ReplaceDatabase
Write-Host "Database restore completed successfully." -ForegroundColor Green

# Remove the original backup file
Remove-Item $BackupFile
Write-Host "Original backup file removed." -ForegroundColor Green

# Set variables 1C8
$PatchBackup = "\\data3\BackUP\1CBases\DO\" + $DatabaseNameSource + "_" + $Timestamp + "_" + ".dt"
$1cexe = '"C:\Program Files\1cv8\common\1cestart.exe"'
$BaseServer = "/S1C8SQLERP\" + $DatabaseNameDestination
$AdminLogin = '"/NBackUP"'
$Pswd = "/P123456"
$UC = "sudo"
$Argument = " ENTERPRISE $BaseServer $AdminLogin $Pswd /DisableStartupMessages"
$ArgumentBackup = "DESIGNER $BaseServer $AdminLogin $Pswd /UC $UC /DumpIB" + $PatchBackup

# Backup 1C8 Base
Start-Process $1cexe $ArgumentBackup
# Loop for checking the created dt file
While($true)
{
    if (Test-Path $PatchBackup) 
    {
    $EndTime = (Get-Date)
    $TotalTime = $EndTime-$StartTime
    Write-Host "Database 1C8 backup completed successfully." -ForegroundColor Green
    Write-Host "Job Finished in $EndTime" -ForegroundColor Yellow
    Write-Host "Total time:" -ForegroundColor Red
    '{0:mm} min {0:ss} sec' -f $TotalTime
    exit
    }
    Start-Sleep -Seconds 10
}

Код скрипта PowerShell №3
Код: Выделить весь код
# Load SQL Server cmdlets
Import-Module SqlServer

# Set variables SQL Server
$ServerInstance = "1C8SQLERP\SQL1C8ERP"
$DatabaseNameSource = "erp_prod"
$DatabaseNameDestination = "forbackup"
$BackupDir = "F:\BackUp"
$StartTime = (Get-Date)
$Timestamp = Get-Date -Format "yyyyMMdd"
$BackupFile = "${BackupDir}\${DatabaseNameSource}_${Timestamp}.bak"

Write-Host "Job Started in $StartTime" -ForegroundColor Yellow

# Create backup and archive directories if they don't exist
if (!(Test-Path $BackupDir)) {
    New-Item -ItemType Directory -Path $BackupDir
}

# Backup the SQL Server database
Backup-SqlDatabase -ServerInstance $ServerInstance -Database $DatabaseNameSource -BackupFile $BackupFile -CompressionOption On -CopyOnly
Write-Host "Database backup completed successfully." -ForegroundColor Green

# Restore the SQL Server database
Restore-SqlDatabase -ServerInstance $ServerInstance -Database $DatabaseNameDestination -BackupFile $BackupFile -ReplaceDatabase
Write-Host "Database restore completed successfully." -ForegroundColor Green

# Remove the original backup file
Remove-Item $BackupFile
Write-Host "Original backup file removed." -ForegroundColor Green

# Set variables 1C8
$PatchBackup = "\\data3\BackUP\1CBases\ERP\" + $DatabaseNameSource + "__" + $Timestamp + ".dt"
$1cexe = '"C:\Program Files\1cv8\common\1cestart.exe"'
$BaseServer = "/S1C8SQLERP\" + $DatabaseNameDestination
$AdminLogin = '"/NBackUP"'
$Pswd = "/P123456"
$UC = "sudo"
$Argument = " ENTERPRISE $BaseServer $AdminLogin $Pswd /DisableStartupMessages"
$ArgumentBackup = "DESIGNER $BaseServer $AdminLogin $Pswd /UC $UC /DumpIB" + $PatchBackup

# Backup 1C8 Base
Start-Process $1cexe $ArgumentBackup
# Loop for checking the created dt file
While($true)
{
    if (Test-Path $PatchBackup) 
    {
    $EndTime = (Get-Date)
    $TotalTime = $EndTime-$StartTime
    Write-Host "Database 1C8 backup completed successfully." -ForegroundColor Green
    Write-Host "Job Finished in $EndTime" -ForegroundColor Yellow
    Write-Host "Total time:" -ForegroundColor Red
    '{0:mm} min {0:ss} sec' -f $TotalTime
    exit
    }
    Start-Sleep -Seconds 10
}

Проблема в следующем:
Размер .dt при выполнении скрипта с очередностью 2 и далее (т.е. выполняемый после окончания работы первого), совпадает с размером первого выгруженного .dt,
подозреваю что ошибка возникает на этапе восстановления скульной БД (лишний или недостающий аргумент в оснастке PS "Restore-SqlDatabase").
Соответственно создается некорректный бэкап 2-ой БД с содержимым 1-ой БД.

Отправлено: 07:43, 24-01-2025

 

Deadooshka


Сообщения: 2517
Благодарности: 692

Профиль | Отправить PM | Цитировать


у вас везде $DatabaseNameDestination = "forbackup". Так и должно быть? $DatabaseNameSource при этом разный.

Отправлено: 11:22, 24-01-2025 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Новый участник


Сообщения: 10
Благодарности: 0

Профиль | Отправить PM | Цитировать


Цитата Sham:
у вас везде $DatabaseNameDestination = "forbackup". Так и должно быть? $DatabaseNameSource при этом разный. »
Цитата maximallist:
Для экономии дискового пространства (а оно ограничено), тестовая база для бэкапов одна, а кол-во баз на текущий момент 3, далее может быть и больше. »
Да, всё верно.

Отправлено: 11:36, 24-01-2025 | #3


Deadooshka


Сообщения: 2517
Благодарности: 692

Профиль | Отправить PM | Цитировать


Тестовая база блокируется на время работы 1cestart.exe? Насколько вижу, выбран неудачный способ ожидания завершения работы 1cestart.exe. Скрипт завершается по факту появления dt-файла, а не по факту окончания работы софта. Сам файл появился, скрипт завершается, но заполнение файла ещё может быть не окончено. Т.е. я бы убрал асинхронный start-process с While($true) {...}, заменив его обычным синхронным вызовом команды. У start-process есть флаг -wait, можно его добавить для синхронности.
Это сообщение посчитали полезным следующие участники:

Отправлено: 16:01, 24-01-2025 | #4


Новый участник


Сообщения: 10
Благодарности: 0

Профиль | Отправить PM | Цитировать


Цитата maximallist:
Скрытый текст
# Backup 1C8 Base
Start-Process $1cexe $ArgumentBackup
# Loop for checking the created dt file
While($true)
{
if (Test-Path $PatchBackup)
{
$EndTime = (Get-Date)
$TotalTime = $EndTime-$StartTime
Write-Host "Database 1C8 backup completed successfully." -ForegroundColor Green
Write-Host "Job Finished in $EndTime" -ForegroundColor Yellow
Write-Host "Total time:" -ForegroundColor Red
'{0:mm} min {0:ss} sec' -f $TotalTime
exit
}
Start-Sleep -Seconds 10
}
»
Благодарю за ответ, подскажите, правильно я понял, что нужно добавить в кусок кода флаг -wait:
Часть кода скрипта №1
Код: Выделить весь код
Start-Process $1cexe $ArgumentBackup -wait
# Loop for checking the created dt file
While($true)
{
 if (Test-Path $PatchBackup) 
 {
 $EndTime = (Get-Date)
 $TotalTime = $EndTime-$StartTime
 Write-Host "Database 1C8 backup completed successfully." -ForegroundColor Green
 Write-Host "Job Finished in $EndTime" -ForegroundColor Yellow
 Write-Host "Total time:" -ForegroundColor Red
 '{0:mm} min {0:ss} sec' -f $TotalTime
 exit
 }
 Start-Sleep -Seconds 10

Отправлено: 06:53, 27-01-2025 | #5


Deadooshka


Сообщения: 2517
Благодарности: 692

Профиль | Отправить PM | Цитировать


Цитата maximallist:
While($true)
{ »
Если по каким-то причинам dt-файл не создастся, то этот цикл никогда не закончится и скрипт зависнет. While($true){} лучше убрать и оставить только if (Test-Path $PatchBackup) { .... } else { Write-Host 'Database 1C8 backup failed.' } (добавив else {...} для сообщения).

Отправлено: 14:51, 27-01-2025 | #6


Новый участник


Сообщения: 10
Благодарности: 0

Профиль | Отправить PM | Цитировать


Sham, верно я понял, что код итогового скрипта будет выглядеть так:
Часть кода скрипта
Код: Выделить весь код
Start-Process $1cexe $ArgumentBackup -wait
if (Test-Path $PatchBackup) 
 {
 $EndTime = (Get-Date)
 $TotalTime = $EndTime-$StartTime
 Write-Host "Database 1C8 backup completed successfully! :-)" -ForegroundColor Green
 Write-Host "Job Finished in $EndTime" -ForegroundColor Yellow
 Write-Host "Total time:" -ForegroundColor Red
 '{0:mm} min {0:ss} sec' -f $TotalTime
 exit
 }
else
 {
 Write-Host "Database 1C8 backup failed! :-("
 }
Start-Sleep -Seconds 10


И нужен ли здесь командлет Start-Sleep?

Отправлено: 13:23, 28-01-2025 | #7


Deadooshka


Сообщения: 2517
Благодарности: 692

Профиль | Отправить PM | Цитировать


Цитата maximallist:
нужен ли здесь командлет Start-Sleep? »
Это практический вопрос. Если скрипты отрабатывают корректно без паузы, то не нужна, а если возникают ошибки доступа, то лучше притормозить перед выполнением следующего скрипта.

Отправлено: 07:42, 29-01-2025 | #8



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » MSFT SQL Server - Резервное копирование и восстановление БД MS SQL средствами PowerShell

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
Разное - Резервное копирование средствами CMD Lucich Скриптовые языки администрирования Windows 3 10-03-2020 14:21
PowerShell - Удаление-Копирование-Восстановление MS SQL DB AZABAZA Скриптовые языки администрирования Windows 9 04-05-2015 14:46
MSFT SQL Server - [решено] Резервное копирование MS SQL Server на сетевой ресурс Shiirx Программирование и базы данных 13 26-02-2012 12:46
PowerShell - Резервное копирование средствами PowerShell. Помогите, пжлст, в нескольких моментах snake-as Скриптовые языки администрирования Windows 2 03-02-2012 11:04
MSFT SQL Server - Резервное копирование 1Cv7.7+MS SQL 2000 sp4 FATruden Программирование и базы данных 2 12-01-2011 17:17




 
Переход