#!/bin/bash # ERPNext Database Cleanup Script # Prevents database bloat by cleaning old logs and versions # Run monthly via cron or manually with interactive prompts set -euo pipefail # Configuration SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_DIR="$(dirname "$SCRIPT_DIR")" # Default retention policies DEFAULT_COMMUNICATION_RETENTION=180 DEFAULT_VERSION_RETENTION=90 DEFAULT_JOB_LOG_RETENTION=30 DEFAULT_ERROR_LOG_RETENTION=90 # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # Logging functions log_info() { echo -e "${GREEN}[INFO]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } # Function to display help show_help() { cat << EOF ERPNext Database Cleanup Script DESCRIPTION: Prevents database bloat by cleaning old communications, versions, logs, and deleted documents. Supports both interactive and automated modes with configurable retention policies. USAGE: $0 [OPTIONS] [SITE] ARGUMENTS: SITE ERPNext site name (default: erp.localhost) OPTIONS: --comm-retention DAYS Retention days for communications/emails (default: $DEFAULT_COMMUNICATION_RETENTION) --version-retention DAYS Retention days for edit history (default: $DEFAULT_VERSION_RETENTION) --job-retention DAYS Retention days for job logs (default: $DEFAULT_JOB_LOG_RETENTION) --error-retention DAYS Retention days for error logs (default: $DEFAULT_ERROR_LOG_RETENTION) --dry-run Show what would be cleaned without actually doing it -h, --help Show this help message -v, --version Show script version EXAMPLES: # Interactive mode with default site $0 # Interactive mode for specific site $0 erp.production.com # Automated mode with custom retention $0 erp.production.com --comm-retention 365 --version-retention 180 # Dry run to see what would be cleaned $0 --dry-run # Conservative cleanup (keep more data) $0 --comm-retention 365 --version-retention 180 --job-retention 90 --error-retention 180 RETENTION POLICIES: Communications: Email and notification history Versions: Document edit history and audit trail Job Logs: Background job execution logs Error Logs: System error and exception logs NOTES: - All retention periods are in days - Tables are optimized after cleanup to reclaim space - Safe mode is temporarily disabled during cleanup - Run monthly or as needed to prevent database bloat EOF } # Function to show version show_version() { echo "ERPNext Database Cleanup Script v1.0.0" echo "For ERPNext v15+ with MariaDB" } # Function to validate site exists validate_site() { local site="$1" local result=1 log_info "Validating site: $site" # Run docker command and capture result docker compose -f "$PROJECT_DIR/production.yaml" -p erpnext-production exec -T backend \ bench --site "$site" mariadb -e "SELECT 1;" >/dev/null 2>&1 result=$? if [[ $result -eq 0 ]]; then log_info "✓ Site '$site' exists and is accessible" return 0 else log_error "✗ Site '$site' does not exist or is not accessible" log_error "Available sites:" # List sites safely local sites_output sites_output=$(docker compose -f "$PROJECT_DIR/production.yaml" -p erpnext-production exec -T backend \ ls sites/ 2>/dev/null | grep -v -E '\.(json|txt)$' | sed 's/^/ - /' 2>/dev/null || echo " - Unable to list sites") echo "$sites_output" >&2 return 1 fi } # Function to get database size get_db_size() { local size size=$(docker compose -f "$PROJECT_DIR/production.yaml" -p erpnext-production exec -T backend \ bench --site "$SITE" mariadb -N -e " SELECT ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) FROM information_schema.tables WHERE table_schema = DATABASE();" 2>/dev/null | tr -d '\r\n') echo "$size" } # Function to count records that would be deleted count_records_to_delete() { local table_name="$1" local table_query="$2" local retention_days="$3" docker compose -f "$PROJECT_DIR/production.yaml" -p erpnext-production exec -T backend \ bench --site "$SITE" mariadb -N -e " SET SQL_SAFE_UPDATES = 0; SELECT COUNT(*) FROM $table_query WHERE modified < DATE_SUB(NOW(), INTERVAL $retention_days DAY);" 2>/dev/null | tr -d '\r\n' } # Function to perform cleanup perform_cleanup() { log_info "Running cleanup operations..." docker compose -f "$PROJECT_DIR/production.yaml" -p erpnext-production exec -T backend \ bench --site "$SITE" mariadb </dev/null || echo "0") PERCENT=$(echo "scale=2; ($SAVED / $SIZE_BEFORE) * 100" | bc 2>/dev/null || echo "0.00") log_info "✓ Cleanup complete!" log_info " Space recovered: ${SAVED} MB (${PERCENT}%)" exit 0