# 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 ""