#!/bin/bash
# PostgreSQL多版本一键安装脚本(支持12+)
# ---------------------- 全局配置 ----------------------
set -euo pipefail
exec > >(tee "/var/log/pg_install.log") 2>&1
# ---------------------- 参数初始化 ----------------------
PG_VERSION=${1:-15}                     # 默认安装版本
PG_PORT=5785                            # 数据库端口
PG_PASSWORD="Postgres@123"              # 数据库密码
PG_DATA="/pgdb/data"                    # 数据目录
PG_HOME="/pgdb/pgsql"                   # 安装目录
PG_USER="postgres"                      # 运行用户
CPU_CORES=$(grep -c ^processor /proc/cpuinfo)  # CPU核心数
MEM_GB=$(free -g | awk '/Mem:/ {print $2}')    # 内存总量(GB)
# ---------------------- 环境检查 ----------------------
check_environment() {
    # 检查root权限
    [[ $EUID -ne 0 ]] && echo "必须使用root用户执行" && exit 1
    
    # 检查系统版本
    if ! grep -qE 'CentOS Linux 7|8' /etc/redhat-release; then
        echo "仅支持CentOS 7/8系统"
        exit 1
    fi
}
# ---------------------- 系统优化 ----------------------
optimize_system() {
    # 内核参数优化
    cat > /etc/sysctl.d/99-postgres.conf << EOF
# PostgreSQL优化
kernel.shmmax = $(($MEM_GB*1024*1024*1024))
kernel.shmall = $((MEM_GB*1024*1024/4))
fs.file-max = 655360
vm.overcommit_memory = 2
vm.overcommit_ratio = 95
EOF
    sysctl -p /etc/sysctl.d/99-postgres.conf
    # 资源限制优化
    cat > /etc/security/limits.d/postgres.conf << EOF
${PG_USER} soft nofile 65536
${PG_USER} hard nofile 65536
${PG_USER} soft nproc 16384
${PG_USER} hard nproc 16384
EOF
    # SELinux和防火墙
    sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
    setenforce 0
    systemctl stop firewalld
    systemctl disable firewalld
}
# ---------------------- 安装依赖 ----------------------
install_dependencies() {
    yum install -y epel-release
    yum groups mark install "Development Tools"
    yum groupinstall -y "Development Tools"
    yum install -y readline-devel zlib-devel \
        libicu-devel libxslt-devel openssl-devel \
        pam-devel libxml2-devel python3-devel \
        lz4 lz4-devel systemtap-sdt-devel
}
# ---------------------- 用户和目录 ----------------------
setup_environment() {
    # 创建用户
    if ! id ${PG_USER} &>/dev/null; then
        groupadd ${PG_USER}
        useradd -g ${PG_USER} -m ${PG_USER}
        echo "${PG_USER}:${PG_PASSWORD}" | chpasswd
    fi
    # 创建目录
    mkdir -p ${PG_HOME} ${PG_DATA} /pgdb/{archive,backup,scripts}
    chown -R ${PG_USER}:${PG_USER} /pgdb
}
# ---------------------- 源码安装 ----------------------
install_postgres() {
    local pg_url=""
    case ${PG_VERSION} in
        12) pg_url="https://ftp.postgresql.org/pub/source/v12.16/postgresql-12.16.tar.gz" ;;
        13) pg_url="https://ftp.postgresql.org/pub/source/v13.12/postgresql-13.12.tar.gz" ;;
        14) pg_url="https://ftp.postgresql.org/pub/source/v14.9/postgresql-14.9.tar.gz" ;;
        15) pg_url="https://ftp.postgresql.org/pub/source/v15.4/postgresql-15.4.tar.gz" ;;
        *) echo "不支持的版本: ${PG_VERSION}"; exit 1 ;;
    esac
    # 下载并解压
    wget ${pg_url} -P /tmp
    tar xzf /tmp/postgresql-*.tar.gz -C /tmp
    cd /tmp/postgresql-*/
    # 智能编译配置
    ./configure --prefix=${PG_HOME} \
        --with-pgport=${PG_PORT} \
        --with-openssl \
        --with-libxml \
        --with-lz4 \
        --with-icu \
        --with-python \
        --with-pam \
        --with-systemd \
        --enable-nls \
        --enable-debug
    make -j${CPU_CORES} world
    make install-world
    # 清理
    rm -rf /tmp/postgresql-*
}
# ---------------------- 数据库初始化 ----------------------
init_database() {
    su - ${PG_USER} -c "${PG_HOME}/bin/initdb -D ${PG_DATA} \
        --locale=en_US.UTF-8 --encoding=UTF8 \
        --username=${PG_USER} --pwfile=<(echo ${PG_PASSWORD})"
    # 自动生成配置文件
    cat >> ${PG_DATA}/postgresql.conf << EOF
# 智能内存配置
shared_buffers = $((MEM_GB/4))GB
work_mem = $((MEM_GB*1024/16))MB
maintenance_work_mem = $((MEM_GB*1024/8))MB
effective_cache_size = $((MEM_GB*3/4))GB
# 并行配置
max_parallel_workers_per_gather = $((CPU_CORES/2))
max_parallel_workers = ${CPU_CORES}
# 日志配置
log_destination = 'csvlog'
logging_collector = on
log_filename = 'postgresql-%Y-%m-%d.log'
log_rotation_age = 1d
EOF
    # 访问控制
    echo "host all all 0.0.0.0/0 scram-sha-256" >> ${PG_DATA}/pg_hba.conf
}
# ---------------------- 服务管理 ----------------------
setup_service() {
    cat > /etc/systemd/system/postgresql.service << EOF
[Unit]
Description=PostgreSQL ${PG_VERSION} database server
After=network.target
[Service]
Type=notify
User=${PG_USER}
Group=${PG_USER}
Environment=PGPORT=${PG_PORT}
Environment=PGDATA=${PG_DATA}
OOMScoreAdjust=-1000
ExecStart=${PG_HOME}/bin/postgres -D ${PG_DATA}
ExecReload=${PG_HOME}/bin/pg_ctl reload -D ${PG_DATA}
TimeoutSec=300
[Install]
WantedBy=multi-user.target
EOF
    systemctl daemon-reload
    systemctl enable --now postgresql
}
# ---------------------- 主流程 ----------------------
main() {
    check_environment
    optimize_system
    install_dependencies
    setup_environment
    install_postgres
    init_database
    setup_service
    
    echo "安装完成!"
    echo "连接信息:"
    echo "  Host: $(hostname -I | awk '{print $1}')"
    echo "  Port: ${PG_PORT}"
    echo "  User: ${PG_USER}"
    echo "  Password: ${PG_PASSWORD}"
}
main