All checks were successful
CI/CD / Test (push) Successful in 2m58s
CI/CD / Lint (push) Successful in 1m11s
CI/CD / Integration Tests (push) Successful in 53s
CI/CD / Native Engine Tests (push) Successful in 49s
CI/CD / Build Binary (push) Successful in 46s
CI/CD / Test Release Build (push) Successful in 1m23s
CI/CD / Release Binaries (push) Successful in 10m17s
- Remove compress/gzip import from internal/backup/engine.go - Use pgzip.NewReader for parallel decompression in archive verification - All restore paths now consistently use pgzip for parallel gzip operations Bump version to 5.4.1
157 lines
5.0 KiB
Go
157 lines
5.0 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// RestoreProfile defines resource settings for restore operations
|
|
type RestoreProfile struct {
|
|
Name string
|
|
ParallelDBs int // Number of databases to restore in parallel
|
|
Jobs int // Parallel decompression jobs
|
|
DisableProgress bool // Disable progress indicators to reduce overhead
|
|
MemoryConservative bool // Use memory-conservative settings
|
|
}
|
|
|
|
// GetRestoreProfile returns the profile settings for a given profile name
|
|
func GetRestoreProfile(profileName string) (*RestoreProfile, error) {
|
|
profileName = strings.ToLower(strings.TrimSpace(profileName))
|
|
|
|
switch profileName {
|
|
case "conservative":
|
|
return &RestoreProfile{
|
|
Name: "conservative",
|
|
ParallelDBs: 1, // Single-threaded restore
|
|
Jobs: 1, // Single-threaded decompression
|
|
DisableProgress: false,
|
|
MemoryConservative: true,
|
|
}, nil
|
|
|
|
case "balanced", "":
|
|
return &RestoreProfile{
|
|
Name: "balanced",
|
|
ParallelDBs: 0, // Use config default or auto-detect
|
|
Jobs: 0, // Use config default or auto-detect
|
|
DisableProgress: false,
|
|
MemoryConservative: false,
|
|
}, nil
|
|
|
|
case "aggressive", "performance":
|
|
return &RestoreProfile{
|
|
Name: "aggressive",
|
|
ParallelDBs: -1, // Auto-detect based on resources
|
|
Jobs: -1, // Auto-detect based on CPU
|
|
DisableProgress: false,
|
|
MemoryConservative: false,
|
|
}, nil
|
|
|
|
case "potato":
|
|
// Easter egg: same as conservative but with a fun name
|
|
return &RestoreProfile{
|
|
Name: "potato",
|
|
ParallelDBs: 1,
|
|
Jobs: 1,
|
|
DisableProgress: false,
|
|
MemoryConservative: true,
|
|
}, nil
|
|
|
|
case "turbo":
|
|
// TURBO MODE: Maximum parallelism for fastest restore
|
|
// Matches native pg_restore -j8 performance
|
|
return &RestoreProfile{
|
|
Name: "turbo",
|
|
ParallelDBs: 4, // 4 DBs in parallel (balanced I/O)
|
|
Jobs: 8, // pg_restore --jobs=8
|
|
DisableProgress: false,
|
|
MemoryConservative: false,
|
|
}, nil
|
|
|
|
case "max-performance", "maxperformance", "max":
|
|
// Maximum performance for high-end servers
|
|
// Use for dedicated restore operations where speed is critical
|
|
return &RestoreProfile{
|
|
Name: "max-performance",
|
|
ParallelDBs: 8, // 8 DBs in parallel
|
|
Jobs: 16, // pg_restore --jobs=16
|
|
DisableProgress: true, // Reduce TUI overhead
|
|
MemoryConservative: false,
|
|
}, nil
|
|
|
|
default:
|
|
return nil, fmt.Errorf("unknown profile: %s (valid: conservative, balanced, aggressive, turbo, max-performance)", profileName)
|
|
}
|
|
}
|
|
|
|
// ApplyProfile applies profile settings to config, respecting explicit user overrides
|
|
func ApplyProfile(cfg *Config, profileName string, explicitJobs, explicitParallelDBs int) error {
|
|
profile, err := GetRestoreProfile(profileName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Show profile being used
|
|
if cfg.Debug {
|
|
fmt.Printf("Using restore profile: %s\n", profile.Name)
|
|
if profile.MemoryConservative {
|
|
fmt.Println("Memory-conservative mode enabled")
|
|
}
|
|
}
|
|
|
|
// Apply profile settings only if not explicitly overridden
|
|
if explicitJobs == 0 && profile.Jobs > 0 {
|
|
cfg.Jobs = profile.Jobs
|
|
}
|
|
|
|
if explicitParallelDBs == 0 && profile.ParallelDBs != 0 {
|
|
cfg.ClusterParallelism = profile.ParallelDBs
|
|
}
|
|
|
|
// Store profile name
|
|
cfg.ResourceProfile = profile.Name
|
|
|
|
// Conservative profile implies large DB mode settings
|
|
if profile.MemoryConservative {
|
|
cfg.LargeDBMode = true
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetProfileDescription returns a human-readable description of the profile
|
|
func GetProfileDescription(profileName string) string {
|
|
profile, err := GetRestoreProfile(profileName)
|
|
if err != nil {
|
|
return "Unknown profile"
|
|
}
|
|
|
|
switch profile.Name {
|
|
case "conservative":
|
|
return "Conservative: --jobs=1, single-threaded, minimal memory usage. Best for resource-constrained servers."
|
|
case "potato":
|
|
return "Potato Mode: Same as conservative, for servers running on a potato 🥔"
|
|
case "balanced":
|
|
return "Balanced: Auto-detect resources, moderate parallelism. Good default for most scenarios."
|
|
case "aggressive":
|
|
return "Aggressive: Maximum parallelism, all available resources. Best for dedicated database servers."
|
|
case "turbo":
|
|
return "Turbo: --jobs=8, 4 parallel DBs. Matches pg_restore -j8 speed. Great for production restores."
|
|
case "max-performance":
|
|
return "Max-Performance: --jobs=16, 8 parallel DBs, TUI disabled. For dedicated restore operations."
|
|
default:
|
|
return profile.Name
|
|
}
|
|
}
|
|
|
|
// ListProfiles returns a list of all available profiles with descriptions
|
|
func ListProfiles() map[string]string {
|
|
return map[string]string{
|
|
"conservative": GetProfileDescription("conservative"),
|
|
"balanced": GetProfileDescription("balanced"),
|
|
"turbo": GetProfileDescription("turbo"),
|
|
"max-performance": GetProfileDescription("max-performance"),
|
|
"aggressive": GetProfileDescription("aggressive"),
|
|
"potato": GetProfileDescription("potato"),
|
|
}
|
|
}
|