Merge branch 'main' of https://gitea.wpjones.com/wjones/pgsql-jellyfin
This commit is contained in:
@@ -6,7 +6,8 @@
|
||||
Sets up automated weekly performance monitoring via Windows Task Scheduler
|
||||
|
||||
.DESCRIPTION
|
||||
Creates a scheduled task to run Weekly-Performance-Monitor.ps1 every Monday at 6 AM
|
||||
Creates a scheduled task to run Weekly-Performance-Monitor.ps1 every Monday at 6 AM.
|
||||
Can optionally enable conditional VACUUM ANALYZE based on dead tuple thresholds.
|
||||
|
||||
.PARAMETER Uninstall
|
||||
Remove the scheduled task
|
||||
@@ -17,12 +18,24 @@
|
||||
.PARAMETER DayOfWeek
|
||||
Day of week to run (default: Monday)
|
||||
|
||||
.PARAMETER EnableAutoVacuumAnalyze
|
||||
Enable conditional VACUUM ANALYZE for tables above dead tuple thresholds
|
||||
|
||||
.PARAMETER DeadTupleThreshold
|
||||
Minimum dead tuples before VACUUM ANALYZE runs (default: 10000)
|
||||
|
||||
.PARAMETER DeadTuplePercentThreshold
|
||||
Minimum dead tuple percentage before VACUUM ANALYZE runs (default: 20)
|
||||
|
||||
.EXAMPLE
|
||||
.\Setup-Weekly-Monitor.ps1
|
||||
|
||||
.EXAMPLE
|
||||
.\Setup-Weekly-Monitor.ps1 -TaskTime "3am" -DayOfWeek Sunday
|
||||
|
||||
.EXAMPLE
|
||||
.\Setup-Weekly-Monitor.ps1 -EnableAutoVacuumAnalyze -DeadTupleThreshold 10000 -DeadTuplePercentThreshold 20
|
||||
|
||||
.EXAMPLE
|
||||
.\Setup-Weekly-Monitor.ps1 -Uninstall
|
||||
#>
|
||||
@@ -37,7 +50,18 @@ param (
|
||||
|
||||
[Parameter()]
|
||||
[ValidateSet('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday')]
|
||||
[string]$DayOfWeek = 'Monday'
|
||||
[string]$DayOfWeek = 'Monday',
|
||||
|
||||
[Parameter()]
|
||||
[switch]$EnableAutoVacuumAnalyze,
|
||||
|
||||
[Parameter()]
|
||||
[ValidateRange(1, [int]::MaxValue)]
|
||||
[int]$DeadTupleThreshold = 10000,
|
||||
|
||||
[Parameter()]
|
||||
[ValidateRange(0.01, 100.0)]
|
||||
[double]$DeadTuplePercentThreshold = 20.0
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
@@ -104,6 +128,11 @@ Write-ColorOutput "Configuration:" -Color Cyan
|
||||
Write-ColorOutput " Task Name: $TaskName" -Color White
|
||||
Write-ColorOutput " Script: $MonitorScript" -Color White
|
||||
Write-ColorOutput " Schedule: Every $DayOfWeek at $TaskTime" -Color White
|
||||
if ($EnableAutoVacuumAnalyze) {
|
||||
Write-ColorOutput " Auto VACUUM ANALYZE: Enabled (dead tuples >= $DeadTupleThreshold, dead percent >= $DeadTuplePercentThreshold)" -Color White
|
||||
} else {
|
||||
Write-ColorOutput " Auto VACUUM ANALYZE: Disabled" -Color White
|
||||
}
|
||||
Write-ColorOutput ""
|
||||
|
||||
# Remove existing task if present
|
||||
@@ -116,9 +145,14 @@ if ($existingTask) {
|
||||
# Create scheduled task action
|
||||
Write-ColorOutput "Creating scheduled task..." -Color Cyan
|
||||
|
||||
$scriptArguments = "-NoProfile -ExecutionPolicy Bypass -File `"$MonitorScript`""
|
||||
if ($EnableAutoVacuumAnalyze) {
|
||||
$scriptArguments += " -AutoVacuumAnalyze -DeadTupleThreshold $DeadTupleThreshold -DeadTuplePercentThreshold $DeadTuplePercentThreshold"
|
||||
}
|
||||
|
||||
$action = New-ScheduledTaskAction `
|
||||
-Execute "PowerShell.exe" `
|
||||
-Argument "-NoProfile -ExecutionPolicy Bypass -File `"$MonitorScript`""
|
||||
-Argument $scriptArguments
|
||||
|
||||
# Create trigger
|
||||
$trigger = New-ScheduledTaskTrigger `
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
4. Generates weekly performance reports
|
||||
5. Optionally runs VACUUM ANALYZE on tables with high dead tuples
|
||||
6. Can be scheduled via Task Scheduler
|
||||
5. Optionally runs VACUUM ANALYZE on tables with high dead tuples
|
||||
6. Can be scheduled via Task Scheduler
|
||||
|
||||
.PARAMETER OutputDirectory
|
||||
Directory to save reports (default: reports/weekly)
|
||||
@@ -51,18 +53,7 @@ param (
|
||||
[switch]$EmailReport,
|
||||
|
||||
[Parameter()]
|
||||
[switch]$CompareWithPrevious,
|
||||
|
||||
[Parameter()]
|
||||
[switch]$AutoVacuumAnalyze,
|
||||
|
||||
[Parameter()]
|
||||
[ValidateRange(1, [int]::MaxValue)]
|
||||
[int]$DeadTupleThreshold = 100,
|
||||
|
||||
[Parameter()]
|
||||
[ValidateRange(0.01, 100.0)]
|
||||
[double]$DeadTuplePercentThreshold = 0.01
|
||||
[switch]$CompareWithPrevious
|
||||
)
|
||||
|
||||
# ============================================================================
|
||||
@@ -232,67 +223,6 @@ ORDER BY pg_total_relation_size(schemaname||'.'||relname) DESC;
|
||||
}
|
||||
}
|
||||
|
||||
function Invoke-ConditionalVacuumAnalyze {
|
||||
param(
|
||||
[int]$MinDeadTuples,
|
||||
[double]$MinDeadPercent
|
||||
)
|
||||
|
||||
Write-ColorOutput "`nChecking for tables that need VACUUM ANALYZE..." -Color Cyan
|
||||
Write-ColorOutput "Thresholds: dead tuples >= $MinDeadTuples and dead percent >= $MinDeadPercent" -Color Gray
|
||||
|
||||
$tableQuery = @"
|
||||
SELECT
|
||||
format('%I.%I', schemaname, relname) AS qualified_table,
|
||||
n_dead_tup,
|
||||
ROUND(100.0 * n_dead_tup / NULLIF(n_live_tup, 0), 2) AS dead_pct
|
||||
FROM pg_stat_user_tables
|
||||
WHERE schemaname IN ('library', 'users', 'authentication', 'displaypreferences', 'activitylog')
|
||||
AND n_live_tup > 0
|
||||
AND n_dead_tup >= $MinDeadTuples
|
||||
AND (100.0 * n_dead_tup / NULLIF(n_live_tup, 0)) >= $MinDeadPercent
|
||||
ORDER BY n_dead_tup DESC;
|
||||
"@
|
||||
|
||||
try {
|
||||
$tables = & $PSQL_PATH -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME -t -A -F "|" -c $tableQuery 2>&1
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-ColorOutput "[ERROR] Failed to evaluate dead tuple thresholds: $tables" -Color Red
|
||||
return $false
|
||||
}
|
||||
|
||||
$tableLines = @($tables | Where-Object { -not [string]::IsNullOrWhiteSpace($_) })
|
||||
if ($tableLines.Count -eq 0) {
|
||||
Write-ColorOutput "[OK] No tables exceeded dead tuple thresholds" -Color Green
|
||||
return $true
|
||||
}
|
||||
|
||||
Write-ColorOutput "Found $($tableLines.Count) table(s) requiring VACUUM ANALYZE" -Color Yellow
|
||||
|
||||
foreach ($line in $tableLines) {
|
||||
$parts = $line -split "\|", 3
|
||||
$qualifiedTable = $parts[0].Trim()
|
||||
$deadTuples = if ($parts.Count -ge 2) { $parts[1].Trim() } else { "unknown" }
|
||||
$deadPercent = if ($parts.Count -ge 3) { $parts[2].Trim() } else { "unknown" }
|
||||
|
||||
Write-ColorOutput "Running VACUUM ANALYZE on $qualifiedTable (dead tuples: $deadTuples, dead percent: $deadPercent)" -Color Cyan
|
||||
|
||||
$vacuumResult = & $PSQL_PATH -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME -c "VACUUM (ANALYZE, VERBOSE) $qualifiedTable;" 2>&1
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-ColorOutput "[ERROR] VACUUM ANALYZE failed for ${qualifiedTable}: $vacuumResult" -Color Red
|
||||
return $false
|
||||
}
|
||||
|
||||
Write-ColorOutput "[OK] VACUUM ANALYZE completed for $qualifiedTable" -Color Green
|
||||
}
|
||||
|
||||
return $true
|
||||
} catch {
|
||||
Write-ColorOutput "[ERROR] Conditional VACUUM ANALYZE failed: $_" -Color Red
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
function Compare-WithPrevious {
|
||||
param(
|
||||
[string]$CurrentReport,
|
||||
|
||||
Reference in New Issue
Block a user