#!/usr/bin/env bash set -euo pipefail MARIADB_MEMORY_PERCENT=25 MIN_BUFFER_POOL_MB=256 MAX_CONNECTIONS_MIN=80 MAX_CONNECTIONS_MAX=300 usage() { cat <<'EOF' Usage: my-cnf-gen.sh [--output PATH] Generates a conservative MariaDB 10.6 my.cnf for DirectAdmin servers. The InnoDB buffer pool is sized to about 25% RAM so other DA services such as web, exim, dovecot, redis and spam filtering keep enough memory. EOF } read_mem_total_mb() { local mem_bytes if [[ -n "${MYSQL_GEN_MEM_MB:-}" ]]; then printf '%s\n' "$MYSQL_GEN_MEM_MB" return 0 fi if [[ -r /proc/meminfo ]]; then awk '/^MemTotal:/ { printf "%d\n", int($2 / 1024) }' /proc/meminfo return 0 fi mem_bytes="$(sysctl -n hw.memsize 2>/dev/null || true)" if [[ -n "$mem_bytes" ]]; then printf '%d\n' "$((mem_bytes / 1024 / 1024))" return 0 fi echo "Unable to detect total memory" >&2 exit 1 } read_cpu_cores() { local cores cores="" if [[ -n "${MYSQL_GEN_CPU_CORES:-}" ]]; then printf '%s\n' "$MYSQL_GEN_CPU_CORES" return 0 fi if [[ -r /proc/cpuinfo ]]; then cores="$(grep -c '^processor[[:space:]]*:' /proc/cpuinfo 2>/dev/null || true)" fi if [[ -z "$cores" || "$cores" -lt 1 ]]; then cores="$(getconf _NPROCESSORS_ONLN 2>/dev/null || true)" fi if [[ -z "$cores" || "$cores" -lt 1 ]]; then cores=1 fi printf '%s\n' "$cores" } round_down_mb() { local value_mb="$1" local step_mb="$2" local rounded rounded=$((value_mb / step_mb * step_mb)) if (( rounded < step_mb )); then rounded="$step_mb" fi printf '%s\n' "$rounded" } format_size() { local value_mb="$1" if (( value_mb >= 1024 && value_mb % 1024 == 0 )); then printf '%sG\n' "$((value_mb / 1024))" else printf '%sM\n' "$value_mb" fi } calc_buffer_pool_mb() { local mem_mb="$1" local pool_mb pool_mb=$((mem_mb * MARIADB_MEMORY_PERCENT / 100)) if (( pool_mb < MIN_BUFFER_POOL_MB )); then pool_mb="$MIN_BUFFER_POOL_MB" fi round_down_mb "$pool_mb" 128 } calc_buffer_pool_instances() { local pool_mb="$1" local cores="$2" local instances=1 if (( pool_mb >= 8192 && cores >= 4 )); then instances=4 elif (( pool_mb >= 4096 && cores >= 2 )); then instances=2 fi printf '%s\n' "$instances" } calc_max_connections() { local mem_mb="$1" local cores="$2" local connections connections=$((mem_mb / 128)) if (( connections < MAX_CONNECTIONS_MIN )); then connections="$MAX_CONNECTIONS_MIN" fi if (( connections > MAX_CONNECTIONS_MAX )); then connections="$MAX_CONNECTIONS_MAX" fi if (( cores <= 2 && connections > 120 )); then connections=120 fi printf '%s\n' "$connections" } calc_log_file_mb() { local pool_mb="$1" local log_mb log_mb=$((pool_mb / 4)) if (( log_mb < 128 )); then log_mb=128 elif (( log_mb > 1024 )); then log_mb=1024 fi round_down_mb "$log_mb" 128 } generate_config() { local mem_mb="$1" local cores="$2" local pool_mb="$3" local pool_instances="$4" local max_connections="$5" local log_file_mb="$6" local io_capacity="$7" local io_capacity_max="$8" cat <&2; exit 1; } output="$1" ;; --help|-h) usage exit 0 ;; *) echo "Unknown argument: $1" >&2 usage >&2 exit 1 ;; esac shift done mem_mb="$(read_mem_total_mb)" cores="$(read_cpu_cores)" pool_mb="$(calc_buffer_pool_mb "$mem_mb")" pool_instances="$(calc_buffer_pool_instances "$pool_mb" "$cores")" max_connections="$(calc_max_connections "$mem_mb" "$cores")" log_file_mb="$(calc_log_file_mb "$pool_mb")" io_capacity=$((cores * 100)) if (( io_capacity < 200 )); then io_capacity=200 elif (( io_capacity > 800 )); then io_capacity=800 fi io_capacity_max=$((io_capacity * 2)) if [[ -n "$output" ]]; then generate_config "$mem_mb" "$cores" "$pool_mb" "$pool_instances" "$max_connections" "$log_file_mb" "$io_capacity" "$io_capacity_max" > "$output" else generate_config "$mem_mb" "$cores" "$pool_mb" "$pool_instances" "$max_connections" "$log_file_mb" "$io_capacity" "$io_capacity_max" fi } main "$@"