#!/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