feat(tplus): 新增同步暂存与任务管理迁移和环境配置
This commit is contained in:
1 parent
823d9f02ec
commit
78bef43c06
29 files changed
+1326
-5
No files matched your search
@@ -0,0 +1,87 @@
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$BackupFileName,
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$DatabaseName,
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$DataLogicalName,
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$LogLogicalName,
|
||||
[string]$ContainerName = "ys-tplus-sqlserver-dev",
|
||||
[string]$BackupRoot = "D:\work\app\tplus-sqlserver\backup",
|
||||
[string]$DataRoot = "D:\work\app\tplus-sqlserver\data",
|
||||
[string]$LogRoot = "D:\work\app\tplus-sqlserver\log",
|
||||
[Parameter(Mandatory = $true)]
|
||||
[SecureString]$SaPassword
|
||||
)
|
||||
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
. (Join-Path $PSScriptRoot "container_sql.ps1")
|
||||
|
||||
if ($DatabaseName -notmatch '^[A-Za-z_][A-Za-z0-9_]{0,127}$') {
|
||||
throw "恢复数据库名只能使用字母、数字和下划线。"
|
||||
}
|
||||
if ([IO.Path]::GetFileName($BackupFileName) -ne $BackupFileName) {
|
||||
throw "备份文件名不能包含目录。"
|
||||
}
|
||||
foreach ($path in @($BackupRoot, $DataRoot, $LogRoot)) {
|
||||
if (-not [IO.Path]::GetFullPath($path).StartsWith("D:\", [StringComparison]::OrdinalIgnoreCase)) {
|
||||
throw "恢复目录必须位于 D 盘。"
|
||||
}
|
||||
}
|
||||
$mounts = docker inspect $ContainerName --format '{{json .Mounts}}' | ConvertFrom-Json
|
||||
if ($LASTEXITCODE -ne 0) { throw "无法读取 SQL Server 容器挂载。" }
|
||||
foreach ($pair in @(
|
||||
@{ Target="/var/opt/mssql/data"; Source=$DataRoot },
|
||||
@{ Target="/var/opt/mssql/log"; Source=$LogRoot },
|
||||
@{ Target="/var/opt/mssql/backup"; Source=$BackupRoot }
|
||||
)) {
|
||||
$mount = @($mounts | Where-Object { $_.Destination -eq $pair.Target })
|
||||
if ($mount.Count -ne 1 -or $mount[0].Type -ne "bind") {
|
||||
throw "目标目录未明确绑定到宿主机 D 盘:$($pair.Target)"
|
||||
}
|
||||
if ([IO.Path]::GetFullPath($mount[0].Source) -ine [IO.Path]::GetFullPath($pair.Source)) {
|
||||
throw "实际挂载与恢复目录配置不一致:$($pair.Target)"
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($path in @($BackupRoot, $DataRoot, $LogRoot)) {
|
||||
if (-not (Test-Path -LiteralPath $path)) {
|
||||
New-Item -ItemType Directory -Path $path -Force | Out-Null
|
||||
}
|
||||
}
|
||||
|
||||
$backupPath = Join-Path $BackupRoot $BackupFileName
|
||||
if (-not (Test-Path -LiteralPath $backupPath)) {
|
||||
throw "找不到备份文件:$backupPath"
|
||||
}
|
||||
|
||||
$containerBackupPath = "/var/opt/mssql/backup/$BackupFileName"
|
||||
$dataPath = "/var/opt/mssql/data/$DatabaseName.mdf"
|
||||
$logPath = "/var/opt/mssql/log/$DatabaseName`_log.ldf"
|
||||
$safeDatabaseIdentifier = $DatabaseName.Replace("]", "]]" )
|
||||
$safeDatabaseLiteral = $DatabaseName.Replace("'", "''")
|
||||
$safeDataLogicalName = $DataLogicalName.Replace("'", "''")
|
||||
$safeLogLogicalName = $LogLogicalName.Replace("'", "''")
|
||||
$safeBackupPath = $containerBackupPath.Replace("'", "''")
|
||||
$sql = @"
|
||||
RESTORE VERIFYONLY FROM DISK = N'$safeBackupPath';
|
||||
IF DB_ID(N'$safeDatabaseLiteral') IS NOT NULL
|
||||
BEGIN
|
||||
THROW 51000, 'Target database exists; refusing to overwrite.', 1;
|
||||
END;
|
||||
RESTORE DATABASE [$safeDatabaseIdentifier]
|
||||
FROM DISK = N'$safeBackupPath'
|
||||
WITH MOVE N'$safeDataLogicalName' TO N'$dataPath',
|
||||
MOVE N'$safeLogLogicalName' TO N'$logPath',
|
||||
RECOVERY, STATS = 5;
|
||||
ALTER DATABASE [$safeDatabaseIdentifier] SET READ_ONLY;
|
||||
DBCC CHECKDB (N'$safeDatabaseLiteral') WITH NO_INFOMSGS;
|
||||
"@
|
||||
|
||||
Write-Host "正在校验并恢复备份(密码不会输出)……"
|
||||
Invoke-TPlusContainerSql -ContainerName $ContainerName -Sql $sql -SaPassword $SaPassword
|
||||
Write-Host "恢复完成:$DatabaseName;数据库文件位于 D 盘绑定目录。"
|
||||
Reference in new issue
Block a user