diff --git a/production/scripts/cleanup-database.sh b/production/scripts/cleanup-database.sh new file mode 100755 index 00000000..c4d17e5f --- /dev/null +++ b/production/scripts/cleanup-database.sh @@ -0,0 +1,434 @@ +#!/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 \ No newline at end of file