#!/bin/bash # ============================================================================= # SQL Server 2017 Express - Configuración Optimizada para Bajo Consumo de RAM # ============================================================================= # Uso: ./start.db.sh [start|stop|restart|status|optimize|logs] # ============================================================================= set -e CONTAINER_NAME="mssql2017" SA_PASSWORD="Asde71.4Asde71.4" DATA_DIR="/home/andres/mssql/data" LOG_DIR="/home/andres/mssql/log" # Colores RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' log_info() { echo -e "${GREEN}[INFO]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } wait_for_sql() { log_info "Esperando que SQL Server inicie..." for i in {1..30}; do if docker exec $CONTAINER_NAME /opt/mssql-tools/bin/sqlcmd \ -S localhost -U sa -P "$SA_PASSWORD" \ -Q "SELECT 1" &>/dev/null; then log_info "SQL Server listo" return 0 fi sleep 2 done log_error "SQL Server no respondió en 60 segundos" return 1 } apply_optimizations() { log_info "Aplicando optimizaciones de rendimiento y estabilidad..." docker exec $CONTAINER_NAME /opt/mssql-tools/bin/sqlcmd \ -S localhost -U sa -P "$SA_PASSWORD" -Q " -- ============================================= -- OPTIMIZACIONES PARA BAJO CONSUMO + ESTABILIDAD -- ============================================= -- Habilitar opciones avanzadas EXEC sp_configure 'show advanced options', 1; RECONFIGURE; -- MAX SERVER MEMORY: Limitar buffer pool EXEC sp_configure 'max server memory', 384; RECONFIGURE; -- MIN SERVER MEMORY: Permitir liberar bajo presión EXEC sp_configure 'min server memory', 128; RECONFIGURE; -- OPTIMIZE FOR AD HOC: Reduce cache de planes únicos EXEC sp_configure 'optimize for ad hoc workloads', 1; RECONFIGURE; -- MAXDOP: Limitar paralelismo (reduce RAM en operaciones paralelas) EXEC sp_configure 'max degree of parallelism', 2; RECONFIGURE; -- COST THRESHOLD: Solo queries costosas usan paralelismo EXEC sp_configure 'cost threshold for parallelism', 50; RECONFIGURE; -- RECOVERY INTERVAL: Checkpoints frecuentes = recuperación rápida EXEC sp_configure 'recovery interval (min)', 1; RECONFIGURE; -- TRACE FLAGS para estabilidad DBCC TRACEON(3226, -1); -- Suprime logs de backup exitoso DBCC TRACEON(1118, -1); -- Reduce contención tempdb DBCC TRACEON(1117, -1); -- Crecimiento uniforme de archivos PRINT 'Optimizaciones aplicadas correctamente'; " 2>/dev/null log_info "Optimizaciones aplicadas" } start_container() { if docker ps -q -f name=$CONTAINER_NAME | grep -q .; then log_warn "El contenedor ya está corriendo" return 0 fi # Eliminar contenedor existente si está detenido docker rm -f $CONTAINER_NAME 2>/dev/null || true # Crear directorios si no existen mkdir -p "$DATA_DIR" "$LOG_DIR" log_info "Iniciando SQL Server 2017 Express (512MB RAM)..." docker run -d \ --name $CONTAINER_NAME \ --memory="384m" \ --memory-swap="4g" \ --memory-reservation="384m" \ --restart=unless-stopped \ -e "ACCEPT_EULA=Y" \ -e "MSSQL_SA_PASSWORD=$SA_PASSWORD" \ -e "MSSQL_PID=Express" \ -e "MSSQL_MEMORY_LIMIT_MB=340" \ -v "$DATA_DIR:/var/opt/mssql/data" \ -v "$LOG_DIR:/var/opt/mssql/log" \ -p 1433:1433 \ mcr.microsoft.com/mssql/server:2017-latest wait_for_sql apply_optimizations log_info "SQL Server iniciado y optimizado" show_status } stop_container() { log_info "Deteniendo SQL Server..." docker stop $CONTAINER_NAME 2>/dev/null || true log_info "SQL Server detenido" } show_status() { echo "" echo "=== Estado del Contenedor ===" docker ps -a --filter "name=$CONTAINER_NAME" \ --format "table {{.Status}}\t{{.Ports}}" if docker ps -q -f name=$CONTAINER_NAME | grep -q .; then echo "" echo "=== Consumo de Recursos ===" docker stats $CONTAINER_NAME --no-stream \ --format "table {{.MemUsage}}\t{{.MemPerc}}\t{{.CPUPerc}}" echo "" echo "=== Configuración SQL Server ===" docker exec $CONTAINER_NAME /opt/mssql-tools/bin/sqlcmd \ -S localhost -U sa -P "$SA_PASSWORD" -Q " SET NOCOUNT ON; SELECT CAST(name AS VARCHAR(35)) AS Setting, CAST(value_in_use AS VARCHAR(10)) AS Value FROM sys.configurations WHERE name IN ( 'max server memory (MB)', 'min server memory (MB)', 'max degree of parallelism', 'optimize for ad hoc workloads' ) ORDER BY name; " 2>/dev/null fi } show_logs() { docker logs $CONTAINER_NAME --tail 50 -f } # ============================================================================= # MAIN # ============================================================================= case "${1:-start}" in start) start_container ;; stop) stop_container ;; restart) stop_container sleep 2 start_container ;; status) show_status ;; optimize) wait_for_sql && apply_optimizations ;; logs) show_logs ;; *) echo "Uso: $0 {start|stop|restart|status|optimize|logs}" exit 1 ;; esac