203 lines
6.5 KiB
PowerShell
203 lines
6.5 KiB
PowerShell
# PostgreSQL 数据导入脚本(Windows PowerShell)
|
||
# 使用方法:.\import-backup.ps1 -BackupFile "backup.sql"
|
||
|
||
param(
|
||
[Parameter(Mandatory=$true)]
|
||
[string]$BackupFile,
|
||
[string]$ServerIP = "192.168.58.20",
|
||
[string]$ServerUser = "root",
|
||
[string]$DBHost = "192.168.58.20",
|
||
[string]$DBUser = "gongxiangpan",
|
||
[string]$DBPass = "gongxiangpan123",
|
||
[string]$DBName = "lobechat",
|
||
[switch]$SkipConfirm
|
||
)
|
||
|
||
Write-Host "=========================================="
|
||
Write-Host " PostgreSQL 数据导入工具"
|
||
Write-Host "=========================================="
|
||
Write-Host ""
|
||
|
||
# 检查本地文件是否存在
|
||
if (!(Test-Path $BackupFile)) {
|
||
Write-Host "❌ 错误: 文件不存在: $BackupFile"
|
||
exit 1
|
||
}
|
||
|
||
$FileInfo = Get-Item $BackupFile
|
||
$FileSize = "{0:N2} MB" -f ($FileInfo.Length / 1MB)
|
||
|
||
Write-Host "📁 备份文件: $BackupFile"
|
||
Write-Host "📊 文件大小: $FileSize"
|
||
Write-Host ""
|
||
|
||
# 生成远程文件路径
|
||
$RemoteFile = "/tmp/import_$(Get-Date -Format 'yyyyMMdd_HHmmss').sql"
|
||
$Timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
|
||
|
||
Write-Host "[1/7] 上传备份文件到服务器..."
|
||
Write-Host " 从: $BackupFile"
|
||
Write-Host " 到: ${ServerUser}@${ServerIP}:${RemoteFile}"
|
||
|
||
scp $BackupFile "${ServerUser}@${ServerIP}:${RemoteFile}"
|
||
|
||
if ($LASTEXITCODE -ne 0) {
|
||
Write-Host "❌ 上传失败"
|
||
exit 1
|
||
}
|
||
Write-Host "✅ 上传成功"
|
||
|
||
Write-Host ""
|
||
Write-Host "[2/7] 解压文件(如果需要)..."
|
||
if ($BackupFile -match "\.gz$") {
|
||
$UnzipCmd = "ssh ${ServerUser}@${ServerIP} 'gunzip $RemoteFile && echo SUCCESS'"
|
||
$Result = Invoke-Expression $UnzipCmd
|
||
if ($Result -match "SUCCESS") {
|
||
$RemoteFile = $RemoteFile -replace "\.gz$", ""
|
||
Write-Host "✅ 解压完成"
|
||
} else {
|
||
Write-Host "❌ 解压失败"
|
||
exit 1
|
||
}
|
||
} else {
|
||
Write-Host "✅ 无需解压"
|
||
}
|
||
|
||
Write-Host ""
|
||
Write-Host "[3/7] 测试数据库连接..."
|
||
$TestCmd = "ssh ${ServerUser}@${ServerIP} 'PGPASSWORD=$DBPass psql -h $DBHost -U $DBUser -d $DBName -c `"SELECT 1`" > /dev/null 2>&1 && echo SUCCESS || echo FAILED'"
|
||
$TestResult = Invoke-Expression $TestCmd
|
||
|
||
if ($TestResult -match "FAILED") {
|
||
Write-Host "❌ 数据库连接失败"
|
||
Write-Host ""
|
||
Write-Host "请检查:"
|
||
Write-Host " - 数据库服务器: $DBHost"
|
||
Write-Host " - 用户名: $DBUser"
|
||
Write-Host " - 密码: $DBPass"
|
||
Write-Host " - 数据库: $DBName"
|
||
exit 1
|
||
}
|
||
Write-Host "✅ 数据库连接成功"
|
||
|
||
Write-Host ""
|
||
Write-Host "[4/7] 创建安全备份..."
|
||
$SafetyBackup = "/tmp/safety_backup_$Timestamp.sql"
|
||
$BackupCmd = "ssh ${ServerUser}@${ServerIP} 'PGPASSWORD=$DBPass pg_dump -h $DBHost -U $DBUser -d $DBName > $SafetyBackup 2>/dev/null && gzip $SafetyBackup && echo SUCCESS'"
|
||
$BackupResult = Invoke-Expression $BackupCmd
|
||
|
||
if ($BackupResult -match "SUCCESS") {
|
||
Write-Host "✅ 安全备份已创建: ${SafetyBackup}.gz"
|
||
} else {
|
||
Write-Host "⚠️ 安全备份创建失败(继续导入)"
|
||
}
|
||
|
||
Write-Host ""
|
||
Write-Host "[5/7] 检查导入文件..."
|
||
$LineCountCmd = "ssh ${ServerUser}@${ServerIP} 'wc -l < $RemoteFile'"
|
||
$LineCount = Invoke-Expression $LineCountCmd
|
||
Write-Host "✅ 文件行数: $LineCount"
|
||
|
||
Write-Host ""
|
||
Write-Host "文件预览(前5行):"
|
||
$PreviewCmd = "ssh ${ServerUser}@${ServerIP} 'head -5 $RemoteFile'"
|
||
$Preview = Invoke-Expression $PreviewCmd
|
||
$Preview | ForEach-Object { Write-Host " $_" }
|
||
Write-Host " ..."
|
||
Write-Host ""
|
||
|
||
# 确认导入
|
||
if (!$SkipConfirm) {
|
||
$Confirm = Read-Host "⚠️ 确认要导入吗?这将覆盖现有数据!(yes/no)"
|
||
if ($Confirm -ne "yes") {
|
||
Write-Host "❌ 导入已取消"
|
||
# 清理远程文件
|
||
ssh "${ServerUser}@${ServerIP}" "rm -f $RemoteFile"
|
||
exit 0
|
||
}
|
||
}
|
||
|
||
Write-Host ""
|
||
Write-Host "[6/7] 开始导入数据..."
|
||
Write-Host "⏳ 这可能需要几分钟,请耐心等待..."
|
||
Write-Host ""
|
||
|
||
$StartTime = Get-Date
|
||
|
||
# 导入数据
|
||
$ImportCmd = "ssh ${ServerUser}@${ServerIP} 'PGPASSWORD=$DBPass psql -h $DBHost -U $DBUser -d $DBName -f $RemoteFile 2>&1 | tee /tmp/import.log && echo IMPORT_SUCCESS'"
|
||
$ImportResult = Invoke-Expression $ImportCmd
|
||
|
||
$EndTime = Get-Date
|
||
$Duration = ($EndTime - $StartTime).TotalSeconds
|
||
|
||
if ($ImportResult -match "IMPORT_SUCCESS") {
|
||
Write-Host ""
|
||
Write-Host "✅ 导入成功"
|
||
Write-Host "⏱️ 耗时: $([math]::Round($Duration, 2)) 秒"
|
||
} else {
|
||
Write-Host ""
|
||
Write-Host "❌ 导入失败"
|
||
Write-Host ""
|
||
Write-Host "错误日志已保存到服务器: /tmp/import.log"
|
||
Write-Host ""
|
||
Write-Host "如需恢复,使用安全备份:"
|
||
Write-Host " ssh ${ServerUser}@${ServerIP}"
|
||
Write-Host " gunzip -c ${SafetyBackup}.gz | PGPASSWORD=$DBPass psql -h $DBHost -U $DBUser -d $DBName"
|
||
exit 1
|
||
}
|
||
|
||
Write-Host ""
|
||
Write-Host "[7/7] 验证导入结果..."
|
||
|
||
# 检查表数量
|
||
$TableCountCmd = "ssh ${ServerUser}@${ServerIP} `"PGPASSWORD=$DBPass psql -h $DBHost -U $DBUser -d $DBName -t -c 'SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = ''public'';' | xargs`""
|
||
$TableCount = Invoke-Expression $TableCountCmd
|
||
Write-Host "✅ 表数量: $TableCount"
|
||
|
||
# 检查主要表的记录数
|
||
Write-Host ""
|
||
Write-Host "主要表记录数:"
|
||
$Tables = @("users", "materials", "categories", "scenes")
|
||
foreach ($Table in $Tables) {
|
||
$CountCmd = "ssh ${ServerUser}@${ServerIP} `"PGPASSWORD=$DBPass psql -h $DBHost -U $DBUser -d $DBName -t -c 'SELECT COUNT(*) FROM $Table' 2>/dev/null | xargs`""
|
||
$Count = Invoke-Expression $CountCmd 2>$null
|
||
if ($Count) {
|
||
Write-Host " - $Table`: $Count 条记录"
|
||
}
|
||
}
|
||
|
||
Write-Host ""
|
||
Write-Host "[清理] 删除远程临时文件..."
|
||
ssh "${ServerUser}@${ServerIP}" "rm -f $RemoteFile"
|
||
Write-Host "✅ 清理完成"
|
||
|
||
Write-Host ""
|
||
Write-Host "=========================================="
|
||
Write-Host " ✅ 导入完成!"
|
||
Write-Host "=========================================="
|
||
Write-Host ""
|
||
Write-Host "📊 导入统计:"
|
||
Write-Host " 文件: $BackupFile"
|
||
Write-Host " 大小: $FileSize"
|
||
Write-Host " 耗时: $([math]::Round($Duration, 2)) 秒"
|
||
Write-Host " 表数: $TableCount"
|
||
Write-Host ""
|
||
Write-Host "🔐 安全备份: ${SafetyBackup}.gz"
|
||
Write-Host " (如需恢复旧数据,使用此备份)"
|
||
Write-Host ""
|
||
Write-Host "📝 导入日志: /tmp/import.log (在服务器上)"
|
||
Write-Host ""
|
||
|
||
# 下载导入日志
|
||
$LogFile = ".\import_log_$Timestamp.txt"
|
||
Write-Host "📥 下载导入日志到本地..."
|
||
scp "${ServerUser}@${ServerIP}:/tmp/import.log" $LogFile 2>$null
|
||
if ($LASTEXITCODE -eq 0) {
|
||
Write-Host "✅ 日志已保存: $LogFile"
|
||
}
|
||
Write-Host ""
|
||
|
||
|
||
|