rocky9下一键安装postgres16

前置条件,软件安装包:postgresql-16.3.tar.gz 放置于tmp目录下

#!/bin/bash
set -euo pipefail
trap 'echo "执行错误,退出状态: $?" >&2' ERR

# ---------------------------
# 可配置参数区(按需修改)
# ---------------------------
declare -r POSTGRES_USER="postgres"
declare -r POSTGRES_GROUP="postgres"
declare -ri POSTGRES_UID=60000
declare -ri POSTGRES_GID=60000

declare -r POSTGRESQL_DIR="/postgresql"
declare -r PG16_DIR="${POSTGRESQL_DIR}/pg16"
declare -r PGDATA_DIR="${POSTGRESQL_DIR}/pgdata"
declare -r SOFT_DIR="${POSTGRESQL_DIR}/soft"
declare -r POSTGRES_VER="16.3"    --软件版本,可根据个人情况修改
declare -r PG_PORT=5432

# ---------------------------
# 衍生变量(无需修改)
# ---------------------------
declare -r PG_SOURCE_FILE="/tmp/postgresql-${POSTGRES_VER}.tar.gz"   --软件后缀 tar.gz 依照个人情况修改
declare -r PG_SOURCE_DIR="${SOFT_DIR}/postgresql-${POSTGRES_VER}"
declare -r PG_CONF_FILE="${PGDATA_DIR}/postgresql.conf"
declare -r PG_HBA_FILE="${PGDATA_DIR}/pg_hba.conf"
declare -r RANDOM_PASSWORD=$(openssl rand -base64 16 | tr -dc '_A-Za-z0-9')

# ---------------------------
# 功能函数定义
# ---------------------------

clean_previous_installation() {
    echo "正在清理旧安装..."
    # 停止并禁用服务
    if systemctl is-active --quiet postgresql; then
        systemctl stop postgresql
        systemctl disable postgresql
    fi

    # 删除服务文件
    rm -f /etc/systemd/system/postgresql.service

    # 清理目录
    for dir in "${PG16_DIR}" "${PGDATA_DIR}"; do
        if [[ -d "${dir}" ]]; then
            echo "删除目录: ${dir}"
            rm -rf "${dir}"
        fi
    done

    # 删除用户
    if id "${POSTGRES_USER}" &>/dev/null; then
        userdel "${POSTGRES_USER}"
    fi
}

install_dependencies() {
    echo "安装系统依赖..."
    yum install -y \
        readline-devel \
        zlib-devel \
        openssl-devel \
        libicu-devel \
        python3 \
        libxml2-devel \
        libxslt-devel \
        systemd-devel \
        wget \
        sudo \
        tar \
        make \
        gcc \
        gcc-c++
}

setup_user_and_dirs() {
    echo "创建用户和目录..."
    if ! getent group "${POSTGRES_GROUP}" >/dev/null; then
        groupadd -g "${POSTGRES_GID}" "${POSTGRES_GROUP}"
    fi

    if ! id "${POSTGRES_USER}" &>/dev/null; then
        useradd -u "${POSTGRES_UID}" -g "${POSTGRES_GROUP}" "${POSTGRES_USER}" -s /bin/bash
    fi

    mkdir -p "${POSTGRESQL_DIR}" "${SOFT_DIR}"
    chown -R "${POSTGRES_USER}:${POSTGRES_GROUP}" "${POSTGRESQL_DIR}"
    chmod 750 "${POSTGRESQL_DIR}"
}

compile_postgres() {
    echo "编译PostgreSQL..."
    if [[ ! -f "${PG_SOURCE_FILE}" ]]; then
        echo "错误: 源码包不存在 ${PG_SOURCE_FILE}" >&2
        exit 1
    fi

    chown "${POSTGRES_USER}:${POSTGRES_GROUP}" "${PG_SOURCE_FILE}"
    sudo -u "${POSTGRES_USER}" tar xvf "${PG_SOURCE_FILE}" -C "${SOFT_DIR}"

    local cpu_cores
    cpu_cores=$(nproc)

    pushd "${PG_SOURCE_DIR}" >/dev/null
    sudo -u "${POSTGRES_USER}" ./configure \
        --prefix="${PG16_DIR}" \
        --with-systemd \
        --with-openssl \
        --with-libxml \
        --with-libxslt \
        --with-icu

    sudo -u "${POSTGRES_USER}" make -j"${cpu_cores}"
    sudo -u "${POSTGRES_USER}" make install
    sudo -u "${POSTGRES_USER}" make -j"${cpu_cores}" install-world
    popd >/dev/null
}

configure_environment() {
    echo "配置环境变量..."
    local bash_profile="/home/${POSTGRES_USER}/.bash_profile"
    cat >> "${bash_profile}" <<EOF
export LANG=en_US.UTF-8
export PS1="[\u@\h \W]\$ "
export PGPORT=${PG_PORT}
export PGDATA=${PGDATA_DIR}
export PGHOME=${PG14_DIR}
export LD_LIBRARY_PATH=\$PGHOME/lib:/lib64:/usr/lib64:/usr/local/lib64:/lib:/usr/lib:/usr/local/lib:\$LD_LIBRARY_PATH
export PATH=\$PGHOME/bin:\$PATH:.
export DATE=\`date +"%Y%m%d%H%M"\`
export MANPATH=\$PGHOME/share/man:\$MANPATH
export PGHOST=/tmp
export PGUSER=${POSTGRES_USER}
export PGDATABASE=postgres
EOF
    chown "${POSTGRES_USER}:${POSTGRES_GROUP}" "${bash_profile}"
}

init_db() {
    echo "初始化数据库..."
    mkdir -p "${PGDATA_DIR}"
    chown "${POSTGRES_USER}:${POSTGRES_GROUP}" "${PGDATA_DIR}"
    chmod 700 "${PGDATA_DIR}"

    if [[ -n $(ls -A "${PGDATA_DIR}" 2>/dev/null) ]]; then
        read -rp "PGDATA目录非空,是否清空?[y/N] " confirm
        if [[ "${confirm,,}" =~ ^y ]]; then
            rm -rf "${PGDATA_DIR:?}"/*
        else
            echo "使用现有数据库目录"
        fi
    fi

    sudo -u "${POSTGRES_USER}" "${PG16_DIR}/bin/initdb" \
        -D "${PGDATA_DIR}" \
        -E UTF8 \
        --locale=en_US.utf8 \
        -U "${POSTGRES_USER}"
}

configure_postgres() {
    echo "配置PostgreSQL..."
    # 备份原始配置
    cp "${PG_CONF_FILE}" "${PG_CONF_FILE}.bak_$(date +%Y%m%d)"
    cp "${PG_HBA_FILE}" "${PG_HBA_FILE}.bak_$(date +%Y%m%d)"

    # 动态内存配置
    local total_mem=$(free -m | awk '/Mem:/ {print $2}')
    local shared_buffers=$((total_mem / 4))MB
    local work_mem=$((total_mem / 16))MB

    cat >> "${PG_CONF_FILE}" <<EOF
listen_addresses = '*'
port = ${PG_PORT}
unix_socket_directories = '/tmp'
dynamic_shared_memory_type = posix
shared_buffers = ${shared_buffers}
work_mem = ${work_mem}
logging_collector = on
log_directory = 'pg_log'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_truncate_on_rotation = on
EOF

    cat >> "${PG_HBA_FILE}" <<EOF
# TYPE  DATABASE  USER  ADDRESS      METHOD
local   all       all                trust
host    all       all   0.0.0.0/0    md5
EOF
}

setup_systemd() {
    echo "配置systemd服务..."
    cat > /etc/systemd/system/postgresql.service <<EOF
[Unit]
Description=PostgreSQL 16 Database Server
After=network.target

[Service]
Type=notify  
User=${POSTGRES_USER}
Group=${POSTGRES_GROUP}

# 核心环境变量
Environment=PGDATA=${PGDATA_DIR}
Environment=LD_LIBRARY_PATH=${PG16_DIR}/lib  # 添加库路径
Environment=PGPORT=${PG_PORT}

# 进程管理
ExecStart=${PG16_DIR}/bin/postgres -D ${PGDATA_DIR}
ExecReload=/bin/kill -HUP \$MAINPID

# 资源限制
TimeoutSec=300
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

    systemctl daemon-reload
    systemctl enable --now postgresql
}


post_installation() {
    echo "执行安装后配置..."
    # 设置密码
    echo "ALTER USER ${POSTGRES_USER} WITH PASSWORD '${RANDOM_PASSWORD}';" | \
        sudo -u "${POSTGRES_USER}" "${PG16_DIR}/bin/psql" -h /tmp -d postgres

    # 保存密码文件
    echo "PostgreSQL管理员密码: ${RANDOM_PASSWORD}" > /root/postgres_credentials.txt
    chmod 600 /root/postgres_credentials.txt

    # 验证安装
    if ! sudo -u "${POSTGRES_USER}" "${PG16_DIR}/bin/psql" -c "SELECT version();" &>/dev/null; then
        echo "错误: 数据库连接验证失败!" >&2
        exit 1
    fi
}

# ---------------------------
# 主执行流程
# ---------------------------
main() {
    clean_previous_installation
    install_dependencies
    setup_user_and_dirs
    compile_postgres
    configure_environment
    init_db
    configure_postgres
    setup_systemd
    post_installation

    echo -e "\n\033[32m安装成功!\033[0m"
    echo "管理员密码已保存至: /root/postgres_credentials.txt"
    echo "启动命令: systemctl start postgresql"
}

main "$@"

  

安装后输出:

initdb: warning: enabling "trust" authentication for local connections
initdb: hint: You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb.

Success. You can now start the database server using:

    /postgresql/pg16/bin/pg_ctl -D /postgresql/pgdata -l logfile start

配置PostgreSQL...
配置systemd服务...
执行安装后配置...
ALTER ROLE

安装成功!
管理员密码已保存至: /root/postgres_credentials.txt
启动命令: systemctl start postgresql
posted @ 2025-02-10 16:39  小满人生  阅读(64)  评论(0)    收藏  举报