lmrc-postgres 0.3.16

PostgreSQL management library for the LMRC Stack - comprehensive library for managing PostgreSQL installations on remote servers via SSH
Documentation
//! Example: Configuration Validation and Auto-Tuning
//!
//! This example demonstrates:
//! 1. Memory size validation
//! 2. CIDR notation validation
//! 3. Conflicting settings detection
//! 4. Resource limits validation
//! 5. Auto-tuning based on system resources
//!
//! Run with:
//! ```bash
//! cargo run --example validation_and_tuning
//! ```

use lmrc_postgres::{
    PostgresConfig, WorkloadType, auto_tune, check_conflicting_settings, validate_comprehensive,
    validate_resource_limits,
};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Initialize logging
    tracing_subscriber::fmt()
        .with_max_level(tracing::Level::INFO)
        .init();

    println!("=== PostgreSQL Configuration Validation & Auto-Tuning ===\n");

    // Example 1: Valid configuration
    println!("Example 1: Valid Configuration");
    println!("--------------------------------");
    let config = PostgresConfig::builder()
        .version("15")
        .database_name("myapp")
        .username("appuser")
        .password("secure_password")
        .listen_addresses("0.0.0.0/0")
        .port(5432)
        .max_connections(100)
        .shared_buffers("256MB")
        .effective_cache_size("1GB")
        .work_mem("4MB")
        .maintenance_work_mem("64MB")
        .wal_buffers("16MB")
        .checkpoint_completion_target(0.9)
        .build()?;

    println!("✓ Configuration built successfully");
    println!("  Version: {}", config.version);
    println!("  Max connections: {:?}", config.max_connections);
    println!("  Shared buffers: {:?}", config.shared_buffers);
    println!();

    // Run comprehensive validation
    match validate_comprehensive(&config) {
        Ok(warnings) => {
            println!("✓ Configuration is valid");
            if !warnings.is_empty() {
                println!("  Warnings:");
                for warning in warnings {
                    println!("{}", warning);
                }
            }
        }
        Err(e) => {
            println!("✗ Configuration validation failed: {}", e);
        }
    }
    println!();

    // Example 2: Invalid memory size format
    println!("Example 2: Invalid Memory Size Format");
    println!("--------------------------------------");
    let result = PostgresConfig::builder()
        .version("15")
        .database_name("myapp")
        .username("appuser")
        .password("secure_password")
        .shared_buffers("256XB") // Invalid unit
        .build();

    match result {
        Ok(_) => println!("✗ Should have failed validation"),
        Err(e) => println!("✓ Correctly rejected: {}", e),
    }
    println!();

    // Example 3: Invalid CIDR notation
    println!("Example 3: Invalid CIDR Notation");
    println!("----------------------------------");
    let result = PostgresConfig::builder()
        .version("15")
        .database_name("myapp")
        .username("appuser")
        .password("secure_password")
        .listen_addresses("999.999.999.999") // Invalid IP
        .build();

    match result {
        Ok(_) => println!("✗ Should have failed validation"),
        Err(e) => println!("✓ Correctly rejected: {}", e),
    }
    println!();

    // Example 4: Conflicting settings detection
    println!("Example 4: Conflicting Settings Detection");
    println!("-------------------------------------------");
    let config = PostgresConfig::builder()
        .version("15")
        .database_name("myapp")
        .username("appuser")
        .password("secure_password")
        .max_connections(1000) // Very high
        .work_mem("100MB") // Large per-connection memory
        .shared_buffers("32GB") // Extremely large
        .effective_cache_size("1GB") // Smaller than shared_buffers (conflict!)
        .maintenance_work_mem("4GB") // Very large
        .build()?;

    let warnings = check_conflicting_settings(&config)?;
    println!("Detected {} potential issues:", warnings.len());
    for warning in warnings {
        println!("{}", warning);
    }
    println!();

    // Example 5: Resource limits validation
    println!("Example 5: Resource Limits Validation");
    println!("---------------------------------------");
    let config = PostgresConfig::builder()
        .version("15")
        .database_name("myapp")
        .username("appuser")
        .password("secure_password")
        .max_connections(5) // Very low
        .build()?;

    let warnings = validate_resource_limits(&config)?;
    println!("Resource limit warnings:");
    for warning in warnings {
        println!("{}", warning);
    }
    println!();

    // Example 6: Auto-tuning for different workloads
    println!("Example 6: Auto-Tuning Based on System Resources");
    println!("--------------------------------------------------");

    let total_ram_mb = 16384; // 16GB RAM
    let cpu_cores = 8;

    println!(
        "System: {}GB RAM, {} CPU cores\n",
        total_ram_mb / 1024,
        cpu_cores
    );

    // Web application workload
    println!("A. Web Application Workload:");
    let web_tuned = auto_tune(total_ram_mb, cpu_cores, WorkloadType::Web);
    println!("  Recommended settings:");
    for (key, value) in &web_tuned {
        println!("    {} = {}", key, value);
    }
    println!();

    // Data warehouse workload
    println!("B. Data Warehouse Workload:");
    let dw_tuned = auto_tune(total_ram_mb, cpu_cores, WorkloadType::DataWarehouse);
    println!("  Recommended settings:");
    for (key, value) in &dw_tuned {
        println!("    {} = {}", key, value);
    }
    println!();

    // OLTP workload
    println!("C. OLTP Workload:");
    let oltp_tuned = auto_tune(total_ram_mb, cpu_cores, WorkloadType::Oltp);
    println!("  Recommended settings:");
    for (key, value) in &oltp_tuned {
        println!("    {} = {}", key, value);
    }
    println!();

    // Mixed workload
    println!("D. Mixed Workload:");
    let mixed_tuned = auto_tune(total_ram_mb, cpu_cores, WorkloadType::Mixed);
    println!("  Recommended settings:");
    for (key, value) in &mixed_tuned {
        println!("    {} = {}", key, value);
    }
    println!();

    // Example 7: Building config with auto-tuned values
    println!("Example 7: Building Configuration with Auto-Tuned Values");
    println!("----------------------------------------------------------");
    let tuned = auto_tune(8192, 4, WorkloadType::Web); // 8GB RAM, 4 cores

    let config = PostgresConfig::builder()
        .version("15")
        .database_name("webapp_db")
        .username("webapp_user")
        .password("secure_password")
        .listen_addresses("0.0.0.0/0")
        .port(5432)
        .max_connections(tuned.get("max_connections").unwrap().parse().unwrap())
        .shared_buffers(tuned.get("shared_buffers").unwrap())
        .effective_cache_size(tuned.get("effective_cache_size").unwrap())
        .work_mem(tuned.get("work_mem").unwrap())
        .maintenance_work_mem(tuned.get("maintenance_work_mem").unwrap())
        .wal_buffers(tuned.get("wal_buffers").unwrap())
        .checkpoint_completion_target(
            tuned
                .get("checkpoint_completion_target")
                .unwrap()
                .parse()
                .unwrap(),
        )
        .build()?;

    println!("✓ Auto-tuned configuration created successfully");
    println!("  Max connections: {:?}", config.max_connections);
    println!("  Shared buffers: {:?}", config.shared_buffers);
    println!("  Effective cache size: {:?}", config.effective_cache_size);
    println!("  Work mem: {:?}", config.work_mem);
    println!();

    // Validate the auto-tuned configuration
    match validate_comprehensive(&config) {
        Ok(warnings) => {
            println!("✓ Auto-tuned configuration is valid");
            if !warnings.is_empty() {
                println!(
                    "  Warnings: {} (auto-tuning produces optimized but conservative settings)",
                    warnings.len()
                );
            }
        }
        Err(e) => {
            println!("✗ Validation failed: {}", e);
        }
    }

    println!("\n=== Validation & Auto-Tuning Complete ===");
    Ok(())
}