9 Commits

11 changed files with 379 additions and 67 deletions
+1 -1
View File
@@ -42,7 +42,7 @@ Properties/PublishProfiles/
# Ignore schema directories (database schema dumps)
**/schema/
schema/
[Rr]eports/
# Ignore .idea IDE directory
**/.idea/
.idea/
+67
View File
@@ -0,0 +1,67 @@
# Dead Tuple Auto-Vacuum Guide
## What was added
The weekly PostgreSQL monitoring workflow now supports **conditional `VACUUM ANALYZE`** based on dead tuple thresholds.
This was added to:
- `scripts\Weekly-Performance-Monitor.ps1`
- `scripts\Setup-Weekly-Monitor.ps1`
When enabled, the monitor checks `pg_stat_user_tables` and runs:
```sql
VACUUM (ANALYZE, VERBOSE) schema.table_name;
```
only for tables that exceed both configured thresholds.
## New monitor parameters
`scripts\Weekly-Performance-Monitor.ps1` now supports:
- `-AutoVacuumAnalyze`
Enables conditional vacuum/analyze.
- `-DeadTupleThreshold <int>`
Minimum dead tuples required (default: `10000`).
- `-DeadTuplePercentThreshold <double>`
Minimum dead tuple percentage required (default: `20.0`).
## How to run manually
```powershell
.\scripts\Weekly-Performance-Monitor.ps1 -AutoVacuumAnalyze
```
Example with custom thresholds:
```powershell
.\scripts\Weekly-Performance-Monitor.ps1 -AutoVacuumAnalyze -DeadTupleThreshold 15000 -DeadTuplePercentThreshold 25
```
## How to enable in the scheduled task
`scripts\Setup-Weekly-Monitor.ps1` now supports:
- `-EnableAutoVacuumAnalyze`
- `-DeadTupleThreshold <int>`
- `-DeadTuplePercentThreshold <double>`
Create or update the weekly task with auto-vacuum enabled:
```powershell
.\scripts\Setup-Weekly-Monitor.ps1 -EnableAutoVacuumAnalyze -DeadTupleThreshold 10000 -DeadTuplePercentThreshold 20
```
The setup script passes these options to the weekly monitor when the scheduled task runs.
## Notes
- Conditional vacuum is **opt-in** and disabled unless you pass the enable flag.
- Threshold checks are currently scoped to these schemas:
- `library`
- `users`
- `authentication`
- `displaypreferences`
- `activitylog`
+174
View File
@@ -0,0 +1,174 @@
# Master Documentation Index
This file is a generated master index of markdown documentation under `docs/`, with a consolidated summary of major change themes represented in the documentation corpus.
## Change Summary (Derived from Documentation Content)
Total markdown files indexed: **151**
| Theme | Files mentioning theme | Summary |
|---|---:|---|
| PostgreSQL and database migration | 130 | Migration work, provider updates, backup/restore, and PostgreSQL-first deployment guidance. |
| Performance and query optimization | 111 | Index strategy, diagnostics, slow-query remediation, and maintenance automation. |
| Startup and configuration | 136 | Startup.json behavior, OS/path handling, and runtime configuration fixes. |
| Build and installer workflow | 93 | Build stabilization, installer updates, and SQL file publish packaging fixes. |
| Async and runtime behavior | 80 | Async conversion progress, runtime safety, and auth/websocket handling updates. |
| Schema and data model changes | 103 | Schema conversion notes, entity/table alignment, and constraint compatibility changes. |
### Overall Change Narrative
The documented work shows a strong PostgreSQL-focused modernization effort across the project, including migration from SQLite paths, schema alignment, and operational hardening. Performance tuning is a major thread (indexes, diagnostics, query fixes), with complementary updates to startup/config behavior and packaging workflows. The docs also capture broad async conversion progress and stability fixes in runtime and data access paths. Recent additions include conditional dead-tuple-based `VACUUM ANALYZE` automation in the weekly monitoring workflow.
## Table of Contents
- [🚀 Add Supplementary Indexes to jellyfin_testsdata](ADD_INDEXES_GUIDE.md)
- [Repository Async Conversion Checklist](ASYNC_CONVERSION_CHECKLIST.md)
- [Repository Async Conversion Priority List](ASYNC_CONVERSION_PRIORITY.md)
- [Jellyfin Async Migration Plan](ASYNC_MIGRATION_PLAN.md)
- [✅ Auto-Apply Performance Indexes - Implementation Complete!](AUTO_APPLY_INDEXES_COMPLETE.md)
- [Auto-Generated Startup Configuration](AUTO_GENERATED_STARTUP_CONFIG.md)
- [Summary: Auto-Generated startup.json Configuration](AUTO_GENERATION_SUMMARY.md)
- [Automatic Database Creation - Implementation Summary](AUTOMATIC_DATABASE_CREATION_SUMMARY.md)
- [Automatic Database Creation - PostgreSQL](AUTOMATIC_DATABASE_CREATION.md)
- [BASEITEM_ASYNC_REFERENCE](BASEITEM_ASYNC_REFERENCE.md)
- [BaseItemRepository Async Conversion - Final Status Report](BASEITEM_FINAL_STATUS.md)
- [Build Installer Script - Fixed!](BUILD_INSTALLER_FIXED.md)
- [Build Success Summary - Emby.Naming Project](BUILD_SUCCESS_SUMMARY.md)
- [Build Error Resolution Guide](build-error-resolution.md)
- [Centralized lib Folder Build Configuration](CENTRALIZED_LIB_FOLDER.md)
- [Code Proof: startup.json IS Checked on Startup](CODE_PROOF_STARTUP_JSON.md)
- [Complete Fix Summary: SQLite Removal + EF Core Optimization](COMPLETE_FIX_SUMMARY.md)
- [Complete Session Summary - Jellyfin PostgreSQL Error Fixes](COMPLETE-SESSION-SUMMARY.md)
- [Jellyfin Contributors](CONTRIBUTORS.md)
- [Correlated Subquery Performance Fix](CORRELATED_SUBQUERY_FIX.md)
- [CS0006 Error Fix - SQLite References Removal](CS0006_SQLITE_FIX.md)
- [📊 Database Performance Analysis - Your Results](DATABASE_ANALYSIS_REPORT.md)
- [Database Configuration Guide](DATABASE_CONFIGURATION_GUIDE.md)
- [Database Configuration Guide](DATABASE_CONFIGURATION.md)
- [Database Schema Mismatch - Detailed Entity Mapping](DATABASE_MISMATCH_DETAILED_ENTITY_MAP.md)
- [Visual Schema Mismatch Comparison](DATABASE_MISMATCH_VISUAL_COMPARISON.md)
- [Summary: Multi-Database Configuration with Presets](DATABASE_PRESETS_FEATURE.md)
- [Database Schema Creation - How It Works](DATABASE_SCHEMA_CREATION.md)
- [PostgreSQL Database Schema Mismatch Report](DATABASE_SCHEMA_MISMATCH_REPORT.md)
- [PostgreSQL Database Views](DATABASE_VIEWS.md)
- [PostgreSQL Database Configuration Examples](database-configuration-examples.md)
- [Database Constraint Violation - BaseItemProviders Duplicate Key](database-constraint-violation-baseitem-providers.md)
- [Database Deadlock Handling - Item Deletion](database-deadlock-handling.md)
- [Database Query Optimization Guide](database-query-optimization.md)
- [How to run EFCore migrations](database/jellyfin-database-readme.md)
- [PostgreSQL Backup Configuration](database/postgres-backup-configuration.md)
- [PostgreSQL Database Provider - Migration Guide](database/postgres-migration-guide.md)
- [Jellyfin.Database.Providers.Postgres](database/postgres-provider-readme.md)
- [Dead Tuple Auto-Vacuum Guide](DEAD_TUPLE_AUTOVACUUM_GUIDE.md)
- [✅ Remote Database Diagnostics Complete!](DIAGNOSTICS_COMPLETE_SUMMARY.md)
- [Documentation Organization Complete!](DOCUMENTATION_ORGANIZATION.md)
- [✅ Documentation Reorganization Complete!](DOCUMENTATION_REORGANIZATION.md)
- [EditorConfig Setup for Emby.Naming Project](EDITORCONFIG_SETUP.md)
- [EF Core QuerySplittingBehavior Warning Fix](EF_CORE_QUERY_SPLITTING_FIX.md)
- [EF Core Query Translation Fix](EF_CORE_QUERY_TRANSLATION_FIX.md)
- [EF Core Removal Analysis — pgsql-jellyfin Fork](EF_CORE_REMOVAL_ANALYSIS.md)
- [EF Core Change Tracking Conflict Fix - BaseItemProvider UPSERT](ef-core-tracking-conflict-fix.md)
- [Exception Middleware - Authentication Error Messaging Improvement](exception-middleware-authentication-messaging.md)
- [Database Table Verification and Auto-Creation Feature](FEATURE_DATABASE_TABLE_VERIFICATION.md)
- [Summary: File-Based Startup Configuration](FILE_BASED_CONFIG_SUMMARY.md)
- [File-Based Startup Configuration](FILE_BASED_STARTUP_CONFIG.md)
- [Fix: Empty database.xml on Startup](FIX_EMPTY_DATABASE_XML.md)
- [Check and Fix system.xml MetadataPath on Windows](FIX_SYSTEM_XML_PATHS.md)
- [Generate PostgreSQL Migrations from SQLite](GENERATE_POSTGRESQL_MIGRATIONS.md)
- [Git Commit: OS-Specific startup.json Generation](GIT_COMMIT_OS_STARTUP.md)
- [PublishProfiles Added to .gitignore](GITIGNORE_PUBLISHPROFILES.md)
- [How to Ignore IDE0065 Error Message](HOW_TO_IGNORE_IDE0065.md)
- [🎯 How to Switch Database Connections](HOW_TO_SWITCH_DATABASE.md)
- [✅ Supplementary Index Checker - Implementation Complete!](IMPLEMENTATION_COMPLETE.md)
- [Increasing Database Command Timeout](increase-database-timeout.md)
- [Creating an Installer for Jellyfin](INSTALLER_GUIDE.md)
- [🔍 Jellyfin Setup Installer Analysis](INSTALLER_NEEDS_UPDATE.md)
- [Quick Installer Setup](INSTALLER_QUICK_START.md)
- [✅ Jellyfin Installer Updated!](INSTALLER_UPDATE_COMPLETE.md)
- [✅ ItemValues Indexes Added to performance_indexes.sql](ITEMVALUES_INDEXES_ADDED.md)
- [📊 Fresh Diagnostics Analysis - Remote Database (2026-02-28)](LATEST_DIAGNOSTICS_ANALYSIS.md)
- [Quick Reference: Centralized lib Folder](LIB_FOLDER_QUICK_REF.md)
- [Library Options DB Design](LIBRARY_OPTIONS_DB_DESIGN.md)
- [Library Monitor Delay Configuration](library-monitor-delay-configuration.md)
- [LibraryMonitor Disposal Fix - Summary](LIBRARYMONITOR_DISPOSAL_FIX_SUMMARY.md)
- [ObjectDisposedException in LibraryMonitor Fix](LIBRARYMONITOR_DISPOSAL_FIX.md)
- [Summary: Linux Paths Showing on Windows](LINUX_PATH_ISSUE_SUMMARY.md)
- [Fix Jellyfin Marker Conflict Error](MARKER_CONFLICT_FIX.md)
- [🎉 MediaAttachmentRepository Async Conversion - Complete!](MEDIAATTACHMENT_CONVERSION_COMPLETE.md)
- [Merge Migrations - Instructions](MERGE_MIGRATIONS_GUIDE.md)
- [PostgreSQL Migration Recovery Fix](MIGRATION_RECOVERY_FIX.md)
- [✅ PostgreSQL Migration Successfully Applied!](MIGRATION_SUCCESS_REPORT.md)
- [PostgreSQL Migration Verification Report](MIGRATION_VERIFICATION_REPORT.md)
- [🔧 Fixed: Missing Base Performance Indexes](MISSING_INDEXES_FIXED.md)
- [.NET 11 Migration Summary](NET11_MIGRATION_SUMMARY.md)
- [PostgreSQL "Command Already in Progress" - Fix](NPGSQL_COMMAND_IN_PROGRESS_FIX.md)
- [Option 1 Implementation Complete! ✅](OPTION1_IMPLEMENTATION_COMPLETE.md)
- [OS-Specific startup.json Generation](OS_SPECIFIC_STARTUP_CONFIG.md)
- [🎊 ASYNC MIGRATION PROJECT - OVERALL STATUS](OVERALL_PROJECT_STATUS.md)
- [Jellyfin Path Configuration Guide](PATH_CONFIGURATION_GUIDE.md)
- [Windows Path Fix for Jellyfin PostgreSQL Database](PATH_FIX_GUIDE.md)
- [Database Performance Monitoring - Quick Start Guide](PERFORMANCE_MONITORING_GUIDE.md)
- [Performance Monitoring Setup Complete - Summary](PERFORMANCE_SETUP_COMPLETE.md)
- [Phase 3 BaseItemRepository Async Conversion - Combined Summary](PHASE_3_COMBINED_SUMMARY.md)
- [Phase 3A: Query Operations Async Conversion - Final Summary](PHASE_3A_FINAL_SUMMARY.md)
- [Phase 3b: Item Retrieval Async Conversion - Summary](PHASE_3B_SUMMARY.md)
- [Phase 3C & 3D: Write & Delete Operations Async Conversion - Summary](PHASE_3C_3D_SUMMARY.md)
- [Phase 3E: Aggregations and Statistics Async Conversion - Summary](PHASE_3E_SUMMARY.md)
- [🎉 Phase 1 COMPLETE! All Repositories Async Converted](PHASE1_COMPLETE.md)
- [🎉 Phase 1 Complete! Repository Async Conversion Status](PHASE1_PROGRESS_REPORT.md)
- [🎉 Phase 2 COMPLETE! PeopleRepository Async Converted](PHASE2_COMPLETE.md)
- [🔥 Phase 3 Strategy: BaseItemRepository Async Conversion](PHASE3_STRATEGY.md)
- [🎉 Sub-Phase 3a COMPLETE! BaseItemRepository Query Operations Converted](PHASE3A_COMPLETE.md)
- [🎉 Async Conversion POC - Summary Report](POC_SUMMARY_REPORT.md)
- [PostgreSQL Backup Configuration - Implementation Summary](POSTGRES_BACKUP_IMPLEMENTATION.md)
- [PostgreSQL Backup - Local-Only Implementation Summary](POSTGRES_BACKUP_LOCAL_ONLY_IMPLEMENTATION.md)
- [PostgreSQL Backup Logging - External Tool References](POSTGRES_BACKUP_LOGGING_EXTERNAL_TOOLS.md)
- [PostgreSQL Backup and Restore Analysis](POSTGRESQL_BACKUP_ANALYSIS.md)
- [PostgreSQL Migration Generation - Complete! ✅](POSTGRESQL_MIGRATION_COMPLETE.md)
- [PostgreSQL Migration Generation - Summary](POSTGRESQL_MIGRATION_GENERATED.md)
- [PostgreSQL Troubleshooting Guide](POSTGRESQL_TROUBLESHOOTING.md)
- [PostgreSQL UUID Aggregate Fix](postgresql-uuid-aggregate-fix.md)
- [✅ PowerShell Script Fixed!](POWERSHELL_SCRIPT_FIXED.md)
- [🎉 JELLYFIN ASYNC CONVERSION - PROJECT COMPLETE! 🎉](PROJECT_COMPLETION.md)
- [Query Grouping Performance - Current Status and Workarounds](query-grouping-current-status.md)
- [Query Grouping Optimization - Final Solution](query-grouping-final-solution.md)
- [Query Optimization Journey - Complete Story](query-optimization-complete-story.md)
- [⚡ Quick Action Plan - Based on Your Diagnostics](QUICK_ACTION_PLAN.md)
- [🚀 Quick Reference: Publish Jellyfin with SQL Files](QUICK_PUBLISH_REFERENCE.md)
- [Quick Reference: Auto-Migration & Index Checker](QUICK_REFERENCE.md)
- [Quick Start: PostgreSQL with Jellyfin](QUICKSTART_POSTGRESQL.md)
- [Summary: EditorConfig Configuration for Emby.Naming Project](README_EDITORCONFIG_CHANGES.md)
- [Comprehensive README.md Generated!](README_GENERATION.md)
- [README.md Update Summary](README_UPDATE_SUMMARY.md)
- [Jellyfin with PostgreSQL Support](README-POSTGRESQL.md)
- [Jellyfin with PostgreSQL Support](README.md)
- [README.original](README.original.md)
- [✅ Remote Database Analysis - Quick Summary](REMOTE_ANALYSIS_SUMMARY.md)
- [📊 Remote Database Analysis - Updated](REMOTE_DATABASE_ANALYSIS.md)
- [Remote PostgreSQL Backup Support](remote-postgresql-backup-support.md)
- [SQL Column Conversion Reference - All Tables](SCHEMA_COLUMN_CONVERSION_REFERENCE.md)
- [SQL Schema Conversion Guide - PascalCase to snake_case](SCHEMA_CONVERSION_GUIDE.md)
- [Quick Connect and Add Supplementary Indexes](scripts/CONNECT_AND_UPDATE.md)
- [Complete Session Summary - All Tasks Accomplished](SESSION_SUMMARY.md)
- [✅ SQL Files Not Included in Publish - Solution](SQL_FILES_PUBLISH_FIX.md)
- [✅ SQL Files Publish Issue - FIXED!](SQL_PUBLISH_ISSUE_RESOLVED.md)
- [SQLite-Specific Migration Filtering - Fix Summary](SQLITE_MIGRATION_FILTERING_FIX.md)
- [Removing SQLite from PostgreSQL-Only Deployment](SQLITE_REMOVAL_PLAN.md)
- [SQLite Migration Filtering Fix](sqlite-migration-filtering-fix.md)
- [🎯 Jellyfin Database Async Migration](STAKEHOLDER_PRESENTATION.md)
- [🎯 READY TO RUN - Add Supplementary Indexes](START_HERE.md)
- [Comparison: Before vs After](STARTUP_CONFIG_COMPARISON.md)
- [Startup Configuration Update Summary](STARTUP_CONFIG_UPDATE.md)
- [Fixing startup.json - OS-Specific Defaults Not Applied](STARTUP_JSON_FIX.md)
- [Startup.json Configuration Fix - Marker Conflict Resolution](STARTUP_JSON_MARKER_FIX.md)
- [How startup.json is Loaded and Used on Startup](STARTUP_JSON_VERIFICATION.md)
- [Visual Guide: startup.json Auto-Generation](STARTUP_JSON_VISUAL_GUIDE.md)
- [Fix: startup.json Still Has Wrong WebDir](STARTUP_JSON_WEBDIR_FIX.md)
- [SyncPlay Authorization Error Handling Improvement](syncplay-authorization-error-handling.md)
- [Summary: Path Configuration Enhancement](TEMP_DIR_CONFIGURATION_FEATURE.md)
- [Troubleshooting: EF Core Pending Model Changes Warning](TROUBLESHOOTING_EF_PENDING_CHANGES.md)
- [Version Update to 11.0.0-PostgreSQL PREVIEW](VERSION_UPDATE_11.0.0_PREVIEW.md)
- [✅ WebDir Path Issue - FULLY FIXED](WEBDIR_ISSUE_COMPLETE_FIX.md)
- [WebSocket Authentication Guide](WEBSOCKET_AUTHENTICATION.md)
- [WebSocket "Token is required" Error - Not a Bug!](WEBSOCKET_TOKEN_REQUIRED_ERROR.md)
- [📊 Weekly Index Usage Tracking](WEEKLY_TRACKING.md)
Binary file not shown.
Binary file not shown.
@@ -1,50 +0,0 @@
================================================================================
JELLYFIN DATABASE WEEKLY PERFORMANCE SUMMARY
================================================================================
Report Date: 2026-03-05 08:00:21
Database: jellyfin_testdata at 192.168.129.248
Week Number: 10
================================================================================
REPORTS GENERATED:
* diagnostics_2026-03-05_080020.txt : Full diagnostic report
* query_analysis_2026-03-05_080020.txt : Slow query analysis
* index_usage_2026-03-05_080020.txt : Index usage statistics
* table_sizes_2026-03-05_080020.txt : Table size and bloat info
* summary_2026-03-05_080020.txt : This summary
================================================================================
QUICK HEALTH CHECK:
================================================================================
To view critical issues check diagnostics file for:
* Section 5: TABLES WITH HIGH SEQUENTIAL SCANS
* Section 8: UNUSED OR RARELY USED INDEXES
* Section 10: SLOWEST QUERIES
To identify slow queries check query_analysis file for:
* Section 2: TOP 20 SLOWEST QUERIES (by max execution time)
* Section 5: BASEITEMS TABLE QUERIES ANALYSIS
================================================================================
RECOMMENDED ACTIONS:
================================================================================
* Review slow queries taking longer than 10 seconds
* Check if new indexes are being utilized
* Look for tables with many sequential scans
* Monitor cache hit ratio (should be above 95 percent)
* Check for tables with high dead tuples percentage (need VACUUM)
================================================================================
AUTOMATION SETUP:
================================================================================
To schedule this script weekly via Task Scheduler run Setup-Weekly-Monitor.ps1
as Administrator. This will create a scheduled task to run every Monday at 6am.
To disable the scheduled task run Setup-Weekly-Monitor.ps1 with -Uninstall flag.
================================================================================
NEXT REPORT: 03/05/2026 08:00:21.AddDays(7).ToString("yyyy-MM-dd")
================================================================================
+37 -3
View File
@@ -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 `
+97 -10
View File
@@ -10,7 +10,8 @@
2. Analyzes slow queries
3. Tracks index usage over time
4. Generates weekly performance reports
5. 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)
@@ -27,6 +28,9 @@
.EXAMPLE
.\Weekly-Performance-Monitor.ps1 -OutputDirectory "C:\Reports\Jellyfin" -CompareWithPrevious
.EXAMPLE
.\Weekly-Performance-Monitor.ps1 -AutoVacuumAnalyze -DeadTupleThreshold 10000 -DeadTuplePercentThreshold 20
.EXAMPLE
# Schedule weekly via Task Scheduler
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-File C:\Path\To\Weekly-Performance-Monitor.ps1"
@@ -47,7 +51,18 @@ param (
[switch]$EmailReport,
[Parameter()]
[switch]$CompareWithPrevious
[switch]$CompareWithPrevious,
[Parameter()]
[switch]$AutoVacuumAnalyze,
[Parameter()]
[ValidateRange(1, [int]::MaxValue)]
[int]$DeadTupleThreshold = 100,
[Parameter()]
[ValidateRange(0.01, 100.0)]
[double]$DeadTuplePercentThreshold = 0.02
)
# ============================================================================
@@ -154,15 +169,15 @@ function Get-IndexUsageStats {
$query = @"
SELECT
schemaname,
tablename,
indexname,
relname AS tablename,
indexrelname,
idx_scan,
idx_tup_read,
idx_tup_fetch,
pg_size_pretty(pg_relation_size(indexrelid)) AS index_size
FROM pg_stat_user_indexes
WHERE schemaname IN ('library', 'users', 'authentication', 'displaypreferences', 'activitylog')
ORDER BY schemaname, tablename, idx_scan DESC;
ORDER BY schemaname, relname, idx_scan DESC;
"@
try {
@@ -189,16 +204,16 @@ function Get-TableSizeStats {
$query = @"
SELECT
schemaname,
tablename,
pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS total_size,
pg_size_pretty(pg_relation_size(schemaname||'.'||tablename)) AS table_size,
pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename) - pg_relation_size(schemaname||'.'||tablename)) AS index_size,
relname,
pg_size_pretty(pg_total_relation_size(schemaname||'.'||relname)) AS total_size,
pg_size_pretty(pg_relation_size(schemaname||'.'||relname)) AS table_size,
pg_size_pretty(pg_total_relation_size(schemaname||'.'||relname) - pg_relation_size(schemaname||'.'||relname)) AS index_size,
n_live_tup AS row_count,
n_dead_tup AS dead_rows,
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')
ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;
ORDER BY pg_total_relation_size(schemaname||'.'||relname) DESC;
"@
try {
@@ -217,6 +232,67 @@ ORDER BY pg_total_relation_size(schemaname||'.'||tablename) 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,
@@ -361,6 +437,17 @@ Get-IndexUsageStats -OutputFile $indexUsageFile | Out-Null
$tableSizesFile = Join-Path $reportDir "table_sizes_$timestamp.txt"
Get-TableSizeStats -OutputFile $tableSizesFile | Out-Null
# Optionally vacuum/analyze tables that exceed dead tuple thresholds
if ($AutoVacuumAnalyze) {
$vacuumSuccess = Invoke-ConditionalVacuumAnalyze `
-MinDeadTuples $DeadTupleThreshold `
-MinDeadPercent $DeadTuplePercentThreshold
if (-not $vacuumSuccess) {
Write-ColorOutput "[WARN] Conditional VACUUM ANALYZE encountered errors" -Color Yellow
}
}
# Compare with previous week if requested
if ($CompareWithPrevious) {
Compare-WithPrevious -CurrentReport $diagnosticsFile -OutputDirectory $reportDir
+3 -3
View File
@@ -4,9 +4,9 @@
# Database connection settings
$PSQL_PATH = "C:\Program Files\PostgreSQL\18\bin\psql.exe"
$DB_USER = "jellyfin"
$DB_NAME = "jellyfin" # ← Change this to switch databases
$DB_HOST = "192.168.129.163"
$DB_PORT = "5432"
$DB_NAME = "jellyfin_test2" # ← Change this to switch databases
$DB_HOST = "192.168.129.253"
$DB_PORT = "6432"
# Export for use in other scripts
$global:PSQL_PATH = $PSQL_PATH