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