feat: add conditional VACUUM ANALYZE support to weekly monitoring scripts
This commit is contained in:
@@ -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`
|
||||||
@@ -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)
|
||||||
@@ -6,7 +6,8 @@
|
|||||||
Sets up automated weekly performance monitoring via Windows Task Scheduler
|
Sets up automated weekly performance monitoring via Windows Task Scheduler
|
||||||
|
|
||||||
.DESCRIPTION
|
.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
|
.PARAMETER Uninstall
|
||||||
Remove the scheduled task
|
Remove the scheduled task
|
||||||
@@ -17,12 +18,24 @@
|
|||||||
.PARAMETER DayOfWeek
|
.PARAMETER DayOfWeek
|
||||||
Day of week to run (default: Monday)
|
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
|
.EXAMPLE
|
||||||
.\Setup-Weekly-Monitor.ps1
|
.\Setup-Weekly-Monitor.ps1
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
.\Setup-Weekly-Monitor.ps1 -TaskTime "3am" -DayOfWeek Sunday
|
.\Setup-Weekly-Monitor.ps1 -TaskTime "3am" -DayOfWeek Sunday
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
.\Setup-Weekly-Monitor.ps1 -EnableAutoVacuumAnalyze -DeadTupleThreshold 10000 -DeadTuplePercentThreshold 20
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
.\Setup-Weekly-Monitor.ps1 -Uninstall
|
.\Setup-Weekly-Monitor.ps1 -Uninstall
|
||||||
#>
|
#>
|
||||||
@@ -37,7 +50,18 @@ param (
|
|||||||
|
|
||||||
[Parameter()]
|
[Parameter()]
|
||||||
[ValidateSet('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday')]
|
[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"
|
$ErrorActionPreference = "Stop"
|
||||||
@@ -104,6 +128,11 @@ Write-ColorOutput "Configuration:" -Color Cyan
|
|||||||
Write-ColorOutput " Task Name: $TaskName" -Color White
|
Write-ColorOutput " Task Name: $TaskName" -Color White
|
||||||
Write-ColorOutput " Script: $MonitorScript" -Color White
|
Write-ColorOutput " Script: $MonitorScript" -Color White
|
||||||
Write-ColorOutput " Schedule: Every $DayOfWeek at $TaskTime" -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 ""
|
Write-ColorOutput ""
|
||||||
|
|
||||||
# Remove existing task if present
|
# Remove existing task if present
|
||||||
@@ -116,9 +145,14 @@ if ($existingTask) {
|
|||||||
# Create scheduled task action
|
# Create scheduled task action
|
||||||
Write-ColorOutput "Creating scheduled task..." -Color Cyan
|
Write-ColorOutput "Creating scheduled task..." -Color Cyan
|
||||||
|
|
||||||
|
$scriptArguments = "-NoProfile -ExecutionPolicy Bypass -File `"$MonitorScript`""
|
||||||
|
if ($EnableAutoVacuumAnalyze) {
|
||||||
|
$scriptArguments += " -AutoVacuumAnalyze -DeadTupleThreshold $DeadTupleThreshold -DeadTuplePercentThreshold $DeadTuplePercentThreshold"
|
||||||
|
}
|
||||||
|
|
||||||
$action = New-ScheduledTaskAction `
|
$action = New-ScheduledTaskAction `
|
||||||
-Execute "PowerShell.exe" `
|
-Execute "PowerShell.exe" `
|
||||||
-Argument "-NoProfile -ExecutionPolicy Bypass -File `"$MonitorScript`""
|
-Argument $scriptArguments
|
||||||
|
|
||||||
# Create trigger
|
# Create trigger
|
||||||
$trigger = New-ScheduledTaskTrigger `
|
$trigger = New-ScheduledTaskTrigger `
|
||||||
|
|||||||
@@ -10,7 +10,8 @@
|
|||||||
2. Analyzes slow queries
|
2. Analyzes slow queries
|
||||||
3. Tracks index usage over time
|
3. Tracks index usage over time
|
||||||
4. Generates weekly performance reports
|
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
|
.PARAMETER OutputDirectory
|
||||||
Directory to save reports (default: reports/weekly)
|
Directory to save reports (default: reports/weekly)
|
||||||
@@ -27,6 +28,9 @@
|
|||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
.\Weekly-Performance-Monitor.ps1 -OutputDirectory "C:\Reports\Jellyfin" -CompareWithPrevious
|
.\Weekly-Performance-Monitor.ps1 -OutputDirectory "C:\Reports\Jellyfin" -CompareWithPrevious
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
.\Weekly-Performance-Monitor.ps1 -AutoVacuumAnalyze -DeadTupleThreshold 10000 -DeadTuplePercentThreshold 20
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
# Schedule weekly via Task Scheduler
|
# Schedule weekly via Task Scheduler
|
||||||
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-File C:\Path\To\Weekly-Performance-Monitor.ps1"
|
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-File C:\Path\To\Weekly-Performance-Monitor.ps1"
|
||||||
@@ -47,7 +51,18 @@ param (
|
|||||||
[switch]$EmailReport,
|
[switch]$EmailReport,
|
||||||
|
|
||||||
[Parameter()]
|
[Parameter()]
|
||||||
[switch]$CompareWithPrevious
|
[switch]$CompareWithPrevious,
|
||||||
|
|
||||||
|
[Parameter()]
|
||||||
|
[switch]$AutoVacuumAnalyze,
|
||||||
|
|
||||||
|
[Parameter()]
|
||||||
|
[ValidateRange(1, [int]::MaxValue)]
|
||||||
|
[int]$DeadTupleThreshold = 10000,
|
||||||
|
|
||||||
|
[Parameter()]
|
||||||
|
[ValidateRange(0.01, 100.0)]
|
||||||
|
[double]$DeadTuplePercentThreshold = 20.0
|
||||||
)
|
)
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
@@ -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, tablename) 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 {
|
function Compare-WithPrevious {
|
||||||
param(
|
param(
|
||||||
[string]$CurrentReport,
|
[string]$CurrentReport,
|
||||||
@@ -361,6 +437,17 @@ Get-IndexUsageStats -OutputFile $indexUsageFile | Out-Null
|
|||||||
$tableSizesFile = Join-Path $reportDir "table_sizes_$timestamp.txt"
|
$tableSizesFile = Join-Path $reportDir "table_sizes_$timestamp.txt"
|
||||||
Get-TableSizeStats -OutputFile $tableSizesFile | Out-Null
|
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
|
# Compare with previous week if requested
|
||||||
if ($CompareWithPrevious) {
|
if ($CompareWithPrevious) {
|
||||||
Compare-WithPrevious -CurrentReport $diagnosticsFile -OutputDirectory $reportDir
|
Compare-WithPrevious -CurrentReport $diagnosticsFile -OutputDirectory $reportDir
|
||||||
|
|||||||
Reference in New Issue
Block a user