| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- #Requires -Version 5.1
- <#
- .SYNOPSIS
- 还原 MES Cloud 全量备份(gzip)
- .EXAMPLE
- powershell -ExecutionPolicy Bypass -File .\restore-db.ps1
- powershell -ExecutionPolicy Bypass -File .\restore-db.ps1 -BackupFile "E:\MES_DB_Backup\mes_cloud_20260821.sql.gz"
- #>
- param(
- [string]$BackupFile,
- [switch]$Force
- )
- $ErrorActionPreference = "Stop"
- . (Join-Path $PSScriptRoot "db-config.ps1")
- $dbCfg = Read-MesDbConfig
- $DbHost = [string]$dbCfg.host
- $DbPort = [int]$dbCfg.port
- $DbName = [string]$dbCfg.database
- $DbUser = [string]$dbCfg.user
- $DbPassword = [string]$dbCfg.password
- $BackupRoot = "E:\MES_DB_Backup"
- $CnfFile = Join-Path $env:TEMP ("mes_restore_{0}.cnf" -f $PID)
- function Find-MysqlTool {
- param([string]$Name)
- $cmd = Get-Command $Name -ErrorAction SilentlyContinue
- if ($cmd -and $cmd.Source) { return $cmd.Source }
- $binRoots = @(
- "C:\Program Files\MySQL",
- "C:\Program Files (x86)\MySQL",
- "C:\mysql",
- "D:\MySQL",
- "E:\MySQL",
- "C:\Program Files\MariaDB"
- )
- foreach ($root in $binRoots) {
- if (-not (Test-Path $root)) { continue }
- $hit = Get-ChildItem -Path $root -Filter ($Name + ".exe") -Recurse -ErrorAction SilentlyContinue |
- Where-Object { $_.Directory.Name -eq "bin" } |
- Select-Object -First 1
- if ($hit) { return $hit.FullName }
- }
- return $null
- }
- try {
- if (-not $BackupFile) {
- $latest = Get-ChildItem -Path $BackupRoot -File -Filter "mes_cloud_*.sql.gz" -ErrorAction SilentlyContinue |
- Sort-Object LastWriteTime -Descending |
- Select-Object -First 1
- if (-not $latest) { throw "找不到备份文件,目录: $BackupRoot" }
- $BackupFile = $latest.FullName
- }
- if (-not (Test-Path $BackupFile)) {
- throw "找不到备份文件: $BackupFile"
- }
- if (-not $Force) {
- Write-Host "即将把备份还原到 ${DbHost}:${DbPort} / $DbName"
- Write-Host "备份文件: $BackupFile"
- Write-Host "现有数据会被覆盖。"
- $ans = Read-Host "确认还原请输入 YES"
- if ($ans -ne "YES") {
- Write-Host "已取消"
- exit 0
- }
- }
- $mysql = Find-MysqlTool "mysql"
- if (-not $mysql) { throw "找不到 mysql.exe,请安装 MySQL 客户端并把 bin 目录加入 PATH" }
- Write-MesMysqlCnf -Config $dbCfg -CnfPath $CnfFile
- $isGzip = $false
- $fsHead = [System.IO.File]::OpenRead($BackupFile)
- try {
- $b0 = $fsHead.ReadByte()
- $b1 = $fsHead.ReadByte()
- $isGzip = ($b0 -eq 0x1F -and $b1 -eq 0x8B)
- } finally {
- $fsHead.Dispose()
- }
- Write-Host $(if ($isGzip) { "正在还原(gzip 压缩包)..." } else { "正在还原(SQL 文本,文件较大时请耐心等待)..." })
- $psi = New-Object System.Diagnostics.ProcessStartInfo
- $psi.FileName = $mysql
- $psi.Arguments = ('"--defaults-extra-file={0}" "--max-allowed-packet=1G" "--default-character-set=utf8mb4"' -f $CnfFile)
- $psi.UseShellExecute = $false
- $psi.RedirectStandardInput = $true
- $psi.RedirectStandardError = $true
- $psi.CreateNoWindow = $true
- $proc = New-Object System.Diagnostics.Process
- $proc.StartInfo = $psi
- if (-not $proc.Start()) { throw "无法启动 mysql" }
- $fs = [System.IO.File]::OpenRead($BackupFile)
- $gz = $null
- try {
- $inStream = $fs
- if ($isGzip) {
- $gz = New-Object System.IO.Compression.GZipStream($fs, [System.IO.Compression.CompressionMode]::Decompress)
- $inStream = $gz
- }
- $inStream.CopyTo($proc.StandardInput.BaseStream)
- $proc.StandardInput.Close()
- } finally {
- if ($gz) { $gz.Dispose() }
- $fs.Dispose()
- }
- $err = $proc.StandardError.ReadToEnd()
- $proc.WaitForExit()
- if ($proc.ExitCode -ne 0) {
- throw ("还原失败: {0}" -f $err)
- }
- Write-Host "还原完成"
- exit 0
- } catch {
- Write-Host ("还原失败: {0}" -f $_.Exception.Message) -ForegroundColor Red
- exit 1
- } finally {
- if (Test-Path $CnfFile) { Remove-Item $CnfFile -Force -ErrorAction SilentlyContinue }
- }
|