130 lines
4.2 KiB
PowerShell
130 lines
4.2 KiB
PowerShell
# Start PostgreSQL with data directory = project/data/postgres (no Docker required)
|
|
param([string]$Root = '')
|
|
|
|
. "$PSScriptRoot\db-local.ps1"
|
|
|
|
function Start-PostgresWithWait {
|
|
param(
|
|
[string]$PgBin,
|
|
[string]$PgData,
|
|
[int]$Port,
|
|
[int]$TimeoutSec = 120
|
|
)
|
|
|
|
$postgres = Join-Path $PgBin 'postgres.exe'
|
|
if (-not (Test-Path $postgres)) {
|
|
Write-Host ' [ERROR] postgres.exe not found'
|
|
return $false
|
|
}
|
|
|
|
Write-Host ' Launching postgres...'
|
|
[Console]::Out.Flush()
|
|
|
|
# pg_ctl stdout/stderr를 PowerShell 파이프·캡처하면 Windows에서 영구 블로킹될 수 있음 → postgres 직접 기동
|
|
Start-Process -FilePath $postgres -ArgumentList @('-D', $PgData, '-p', "$Port") -WindowStyle Hidden | Out-Null
|
|
|
|
for ($i = 1; $i -le $TimeoutSec; $i++) {
|
|
if (Test-DbPortOpen -Port $Port) {
|
|
Write-Host " PostgreSQL ready (${i}s)"
|
|
return $true
|
|
}
|
|
if ($i -eq 1 -or $i % 5 -eq 0) {
|
|
Write-Host " ... waiting for port $Port ($i/${TimeoutSec}s)"
|
|
[Console]::Out.Flush()
|
|
}
|
|
Start-Sleep -Seconds 1
|
|
}
|
|
return $false
|
|
}
|
|
|
|
if (-not $Root) { $Root = Get-ProjectRoot -FromScript $PSScriptRoot }
|
|
|
|
$pgBin = Find-PgBin
|
|
if (-not $pgBin) {
|
|
Write-Host '[ERROR] PostgreSQL not found. Install PostgreSQL 16 or Docker Desktop.'
|
|
return 1
|
|
}
|
|
|
|
$pgData = Get-PgDataDir -Root $Root
|
|
New-Item -ItemType Directory -Force -Path $pgData | Out-Null
|
|
|
|
$initdb = Join-Path $pgBin 'initdb.exe'
|
|
$pgCtl = Join-Path $pgBin 'pg_ctl.exe'
|
|
$logFile = Get-PgCtlLogPath -Root $Root
|
|
$hasData = Test-Path (Join-Path $pgData 'PG_VERSION')
|
|
|
|
if ($hasData) {
|
|
Write-Host ' Existing DB found: data\postgres (keeping your data)'
|
|
} else {
|
|
Write-Host ' No DB yet - will create data\postgres'
|
|
}
|
|
|
|
Ensure-BackendEnv -Root $Root
|
|
Set-PostgresPort -PgData $pgData -Port $LocalDbPort
|
|
Clear-StalePostmasterLock -PgData $pgData
|
|
|
|
if (Test-DbPortOpen -Port $LocalDbPort) {
|
|
Write-Host " PostgreSQL already running on port $LocalDbPort"
|
|
return 0
|
|
}
|
|
|
|
# pid file only, process dead -> stop cleanly before restart
|
|
if (Test-Path (Join-Path $pgData 'postmaster.pid')) {
|
|
Write-Host ' Cleaning up previous postgres instance...'
|
|
[Console]::Out.Flush()
|
|
$stopArgs = @('-D', $pgData, 'stop', '-m', 'fast', '-W', '-t', '5')
|
|
$null = Start-Process -FilePath $pgCtl -ArgumentList $stopArgs -WindowStyle Hidden -Wait
|
|
Start-Sleep -Seconds 1
|
|
Clear-StalePostmasterLock -PgData $pgData
|
|
}
|
|
|
|
if (-not $hasData) {
|
|
Write-Host ' Local DB init (data\postgres)...'
|
|
$migrated = $false
|
|
try {
|
|
$migrated = & "$PSScriptRoot\migrate-legacy-db.ps1" -Root $Root -PgBin $pgBin -PgData $pgData -Port $LocalDbPort
|
|
} catch {
|
|
Write-Warning $_.Exception.Message
|
|
if (Test-Path $pgData) {
|
|
Get-ChildItem $pgData -Force -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
|
|
}
|
|
New-Item -ItemType Directory -Force -Path $pgData | Out-Null
|
|
}
|
|
|
|
if (-not $migrated) {
|
|
& $initdb -D $pgData -U $LocalDbUser -E UTF8 --locale=C -A trust
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Host '[ERROR] initdb failed'
|
|
return 1
|
|
}
|
|
Set-PostgresPort -PgData $pgData -Port $LocalDbPort
|
|
Clear-StalePostmasterLock -PgData $pgData
|
|
|
|
Write-Host ' Starting PostgreSQL (new database)...'
|
|
if (-not (Start-PostgresWithWait -PgBin $pgBin -PgData $pgData -Port $LocalDbPort)) {
|
|
Write-Host '[ERROR] PostgreSQL did not start — see data\pg_ctl.log'
|
|
return 1
|
|
}
|
|
|
|
try {
|
|
Invoke-Psql -PgBin $pgBin -Port $LocalDbPort -Sql "ALTER USER $LocalDbUser WITH PASSWORD '$LocalDbPassword';"
|
|
Invoke-Psql -PgBin $pgBin -Port $LocalDbPort -Sql "CREATE DATABASE $LocalDbName OWNER $LocalDbUser;"
|
|
} catch {
|
|
Write-Host "[ERROR] $($_.Exception.Message)"
|
|
return 1
|
|
}
|
|
return 0
|
|
}
|
|
}
|
|
|
|
Write-Host ' Starting PostgreSQL (recovery after move may take 1-2 min)...'
|
|
if (-not (Start-PostgresWithWait -PgBin $pgBin -PgData $pgData -Port $LocalDbPort)) {
|
|
Write-Host '[ERROR] PostgreSQL did not start — see data\pg_ctl.log'
|
|
Write-Host ' 1) 서버종료.bat db 2) 5초 대기 3) 서버시작.bat'
|
|
Write-Host ' PC 종료 전 서버종료.bat db 로 DB 정상 종료 권장'
|
|
Write-Host ' OneDrive/백신에서 data\postgres 제외'
|
|
return 1
|
|
}
|
|
|
|
return 0
|