本文主要介绍如何快速在自己的linux服务器上安装各个版本的PostgreSQL,主旨在于快速开始一个新版本的PostgreSQL环境。用来进行测试和学习。本次测试环境为debian11。
已挂载/data盘1.parted -s /dev/sdb mklabel msdos mkpart primary 0% 100% && partprobe 2.mkfs.ext4 /dev/sdb13.mkdir -p /data && mount /dev/sdb1 /data4.echo "/dev/sdb1 /data ext4 defaults 0 0" >> /etc/fstab已配置apt包管理工具cp /etc/apt/sources.list /etc/apt/sources.list.bakcat > /etc/apt/sources.list << EOFdeb http://deb.debian.org/debian bullseye main contrib non-freedeb http://deb.debian.org/debian bullseye-updates main contrib non-freedeb http://deb.debian.org/debian bullseye-backports main contrib non-freedeb http://security.debian.org/debian-security bullseye-security main contrib non-freeEOFapt update#!/bin/bash# PostgreSQL 版本自动安装脚本 (支持断点续跑)# 使用方法: ./add_pg_version_1.1.sh <版本号> [起始步骤]# 示例: ./add_pg_version_1.1.sh 17.3 # 从第1步开始# 示例: ./add_pg_version_1.1.sh 17.3 7 # 从第7步开始# 示例: ./add_pg_version_1.1.sh --list # 列出所有可安装版本 (14+)# 示例: ./add_pg_version_1.1.sh --delete 17.3 # 删除指定版本set -eERROR_DIR="/data/soft/postgres/errors"mkdir -p "$ERROR_DIR"# ========== 列出可安装版本 ==========if [ "${1}" = "--list" ]; then echo "正在获取 PostgreSQL 可安装版本列表 (14+)..." echo "========================================" VERSION_LIST=$(curl -s https://ftp.postgresql.org/pub/source/ 2>/dev/null | \ grep -oP 'v1[4-9]\.[0-9]+|v[2-9][0-9]\.[0-9]+' | \ sed 's/^v//' | \ sort -t. -k1,1n -k2,2n | \ uniq) if [ -z "$VERSION_LIST" ]; then echo "无法获取版本列表,请检查网络连接" exit 1 fi echo "可用版本 (14+):" echo "----------------------------------------" echo "$VERSION_LIST" | while read ver; do VER_NO_DOT=$(echo "$ver" | tr -d '.') VER_LEN=${#VER_NO_DOT} if [ "$VER_LEN" -eq 4 ]; then PORT="5${VER_NO_DOT}" else PORT="54${VER_NO_DOT}" fi printf " %-10s 端口: %s\n" "$ver" "$PORT" done echo "========================================" echo "安装示例: $0 17.3" exit 0fi# ========== 删除指定版本 ==========if [ "${1}" = "--delete" ]; then if [ -z "${2}" ]; then echo "错误: 请指定要删除的版本号" echo "使用方法: $0 --delete <版本号>" echo "示例: $0 --delete 17.3" exit 1 fi DEL_VERSION=$2 DEL_DATA_DIR="/data/pgdata/pgdata${DEL_VERSION}" DEL_INSTALL_DIR="/usr/local/pgsql/pgsql${DEL_VERSION}" echo "========================================" echo "开始删除 PostgreSQL ${DEL_VERSION}" echo "========================================" # 检查数据目录是否存在 if [ ! -d "$DEL_DATA_DIR" ]; then echo "数据目录不存在: ${DEL_DATA_DIR}" echo "版本 ${DEL_VERSION} 未安装或已删除" exit 1 fi echo "[1/3] 查找并停止 PostgreSQL ${DEL_VERSION} 进程..." # 查找该数据目录对应的 postgres 主进程 (排除 grep 自身) PG_PIDS=$(ps -ef | grep "${DEL_DATA_DIR}" | grep -v grep | awk '{print $2}') if [ -n "$PG_PIDS" ]; then echo "找到以下相关进程:" ps -ef | grep "${DEL_DATA_DIR}" | grep -v grep echo "" echo "正在停止进程..." for pid in $PG_PIDS; do kill $pid 2>/dev/null && echo " 已终止进程 PID: $pid" || echo " 无法终止进程 PID: $pid (可能已退出)" done # 等待进程退出 sleep 2 # 再次检查,若仍在运行则强制杀掉 REMAIN_PIDS=$(ps -ef | grep "${DEL_DATA_DIR}" | grep -v grep | awk '{print $2}') if [ -n "$REMAIN_PIDS" ]; then echo "进程仍在运行,强制终止..." for pid in $REMAIN_PIDS; do kill -9 $pid 2>/dev/null && echo " 已强制终止进程 PID: $pid" || echo " 无法强制终止进程 PID: $pid" done sleep 1 fi echo "所有进程已停止" else echo "未发现运行中的 PostgreSQL ${DEL_VERSION} 进程" fi echo "[2/3] 删除数据目录..." if [ -d "$DEL_DATA_DIR" ]; then rm -rf "$DEL_DATA_DIR" echo " 已删除: ${DEL_DATA_DIR}" fi echo "[3/3] 删除安装目录..." if [ -d "$DEL_INSTALL_DIR" ]; then rm -rf "$DEL_INSTALL_DIR" echo " 已删除: ${DEL_INSTALL_DIR}" fi echo "" echo "========================================" echo "PostgreSQL ${DEL_VERSION} 已完全删除" echo "========================================" exit 0fi# ========== 检查参数 ==========if [ $# -lt 1 ] || [ $# -gt 2 ]; then echo "使用方法: $0 <版本号> [起始步骤]" echo "示例: $0 17.3 # 从第1步开始" echo "示例: $0 17.3 7 # 从第7步开始" echo "示例: $0 --list # 列出所有可安装版本 (14+)" echo "示例: $0 --delete 17.3 # 删除指定版本" exit 1fiPG_VERSION=$1START_STEP=${2:-1} # 默认从第1步开始# 验证起始步骤是否有效if [ "$START_STEP" -lt 1 ] || [ "$START_STEP" -gt 10 ]; then echo "错误: 起始步骤必须是 1-10 之间的数字" exit 1fiPG_USER="postgres"PG_BASE_DIR="/usr/local/pgsql"PG_VERSION_DIR="${PG_BASE_DIR}/pgsql${PG_VERSION}"PG_DATA_DIR="/data/pgdata/pgdata${PG_VERSION}"PG_SOFT_DIR="/data/soft/postgres"# 解析版本号获取端口号# 规则: 4位补5,3位补54 (例如 17.3 -> 173 -> 54173, 12.15 -> 1215 -> 51215)PG_VERSION_NO_DOT=$(echo $PG_VERSION | tr -d '.')VERSION_LENGTH=${#PG_VERSION_NO_DOT}if [ $VERSION_LENGTH -eq 4 ]; then PG_PORT="5${PG_VERSION_NO_DOT}"else PG_PORT="54${PG_VERSION_NO_DOT}"fiPG_TARBALL="postgresql-${PG_VERSION}.tar.gz"PG_DOWNLOAD_PATH="${PG_SOFT_DIR}/${PG_TARBALL}"PG_SRC_DIR="/data/soft/postgres/postgresql-${PG_VERSION}"# 检测是否以 root 身份运行IS_ROOT=falseif [ "$(id -u)" -eq 0 ]; then IS_ROOT=true echo "检测到 root 用户运行,涉及编译安装的步骤将自动切换到 postgres 用户执行"fi# 封装: 以 postgres 用户执行命令run_as_postgres() { if [ "$IS_ROOT" = true ]; then su - $PG_USER -c "$*" else eval "$*" fi}# 封装: 安装 apt 包 (已存在则跳过,stdout -> /dev/null, stderr -> 错误文件)install_apt_pkg() { local pkg=$1 local error_file="${ERROR_DIR}/apt_${pkg}.err" if dpkg -l "$pkg" 2>/dev/null | grep -q "^ii"; then echo " [已安装] $pkg,跳过" else echo " [安装中] $pkg..." if apt install -y "$pkg" >/dev/null 2>"$error_file"; then echo " [完成] $pkg" rm -f "$error_file" else echo " [失败] $pkg,错误信息见: $error_file" fi fi}echo "========================================"echo "开始安装 PostgreSQL ${PG_VERSION}"echo "起始步骤: ${START_STEP}"echo "========================================"echo "安装目录: ${PG_VERSION_DIR}"echo "数据目录: ${PG_DATA_DIR}"echo "端口: ${PG_PORT}"echo "错误日志目录: ${ERROR_DIR}"echo "========================================"# ========== 步骤 1: 检查并配置 /data 盘 ==========if [ "$START_STEP" -le 1 ]; then echo "[1/10] 检查 /data 盘配置..." if ! mountpoint -q /data; then echo "警告: /data 目录未挂载,请先按照 CLAUDE.md 配置磁盘挂载" read -p "是否继续? (y/n) " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then exit 1 fi fielse echo "[1/10] 跳过"fi# ========== 步骤 2: 检查 postgres 用户 ==========if [ "$START_STEP" -le 2 ]; then echo "[2/10] 检查 postgres 用户..." if ! id -u $PG_USER >/dev/null 2>&1; then echo "创建 postgres 用户..." groupadd postgres || true useradd -m -d /home/postgres -s /bin/bash -g postgres postgres || true echo -e "Cql@3673@\nCql@3673@" | passwd postgres # 配置 sudo 权限 echo "配置 sudo 权限..." if ! grep -q "^postgres.*NOPASSWD" /etc/sudoers; then sh -c 'echo "postgres ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers' fi else echo "postgres 用户已存在" fielse echo "[2/10] 跳过"fi# ========== 步骤 3: 授权目录 ==========if [ "$START_STEP" -le 3 ]; then echo "[3/10] 授权目录..." mkdir -p $PG_BASE_DIR chown -R $PG_USER:$PG_USER $PG_BASE_DIR/ chown -R $PG_USER:$PG_USER /dataelse echo "[3/10] 跳过"fi# ========== 步骤 4: 下载 PostgreSQL 安装包 ==========if [ "$START_STEP" -le 4 ]; then echo "[4/10] 下载 PostgreSQL ${PG_VERSION} 安装包..." mkdir -p $PG_SOFT_DIR if [ -f "$PG_DOWNLOAD_PATH" ]; then echo "安装包已存在: $PG_DOWNLOAD_PATH" else echo "正在下载..." wget -P $PG_SOFT_DIR/ https://ftp.postgresql.org/pub/source/v${PG_VERSION}/postgresql-${PG_VERSION}.tar.gz fi chown -R $PG_USER:$PG_USER $PG_SOFT_DIRelse echo "[4/10] 跳过"fi# ========== 步骤 5: 创建目录结构 ==========if [ "$START_STEP" -le 5 ]; then echo "[5/10] 创建目录结构..." mkdir -p $PG_VERSION_DIR mkdir -p $PG_DATA_DIR chown -R $PG_USER:$PG_USER $PG_VERSION_DIR chown -R $PG_USER:$PG_USER $PG_DATA_DIRelse echo "[5/10] 跳过"fi# ========== 步骤 6: 解压并编译安装 ==========if [ "$START_STEP" -le 6 ]; then echo "[6/10] 解压并编译安装..." # 安装依赖 (root 执行) echo "安装依赖..." apt update >/dev/null 2>"${ERROR_DIR}/apt_update.err" || true install_apt_pkg libxml2 install_apt_pkg libxml2-dev install_apt_pkg libreadline-dev install_apt_pkg libperl-dev install_apt_pkg python3-dev install_apt_pkg build-essential install_apt_pkg flex install_apt_pkg bison # 解压 (postgres 用户执行) echo "解压源码..." if run_as_postgres "[ -d ${PG_SRC_DIR} ]"; then echo "源码目录已存在,跳过解压" else EXTRACT_ERROR="${ERROR_DIR}/tar_extract.err" run_as_postgres "cd ${PG_SOFT_DIR} && tar -zxf ${PG_TARBALL} 2>${EXTRACT_ERROR}" if [ $? -eq 0 ]; then echo "解压完成" rm -f "$EXTRACT_ERROR" else echo "解压失败,错误信息见: ${EXTRACT_ERROR}" exit 1 fi fi # 配置并编译 (postgres 用户执行) echo "配置..." run_as_postgres "cd ${PG_SRC_DIR} && ./configure --prefix=${PG_VERSION_DIR} --enable-debug --enable-cassert --with-libxml --with-perl --with-python >/dev/null 2>${ERROR_DIR}/configure.err" echo "编译安装 (这可能需要一些时间)..." run_as_postgres "cd ${PG_SRC_DIR} && make -j 4 >/dev/null 2>${ERROR_DIR}/make.err" run_as_postgres "cd ${PG_SRC_DIR} && make install >/dev/null 2>${ERROR_DIR}/make_install.err"else echo "[6/10] 跳过"fi# ========== 步骤 7: 初始化数据库 ==========if [ "$START_STEP" -le 7 ]; then echo "[7/10] 初始化数据库..." if [ -d "$PG_DATA_DIR" ] && [ "$(ls -A $PG_DATA_DIR)" ]; then echo "数据目录已存在且不为空,跳过初始化" else export PATH=${PG_VERSION_DIR}/bin:$PATH run_as_postgres "export PATH=${PG_VERSION_DIR}/bin:\$PATH && initdb -D ${PG_DATA_DIR} -U postgres" fielse echo "[7/10] 跳过"fi# ========== 步骤 8: 修改 postgresql.conf ==========if [ "$START_STEP" -le 8 ]; then echo "[8/10] 修改配置文件..." CONF_FILE="${PG_DATA_DIR}/postgresql.conf" # 检查是否已配置 if grep -q "listen_addresses = '\*'" "$CONF_FILE"; then echo "配置已存在,跳过修改" else echo "listen_addresses = '*'port=${PG_PORT} # 端口规则: 3位补54, 4位补5 (如17.3->54173, 12.15->51215)log_destination = 'csvlog'logging_collector = onlog_filename = 'postgresql-%Y-%m-%d.log'" >> $CONF_FILE fielse echo "[8/10] 跳过"fi# ========== 步骤 9: 修改 pg_hba.conf ==========if [ "$START_STEP" -le 9 ]; then echo "[9/10] 修改 pg_hba.conf..." HBA_FILE="${PG_DATA_DIR}/pg_hba.conf" # 检查是否已配置 if grep -q "192.168.101.0/24" "$HBA_FILE"; then echo "pg_hba.conf 已配置,跳过修改" else # 在说明的下层添加配置 sed -i "/^# TYPE/a host all all 192.168.101.0/24 md5\nhost replication replica 192.168.101.0/24 trust" $HBA_FILE fielse echo "[9/10] 跳过"fi# ========== 步骤 10: 修改 postgres 用户 .bashrc ==========if [ "$START_STEP" -le 10 ]; then echo "[10/10] 修改 postgres 用户 .bashrc..." BASHRC="/home/postgres/.bashrc" # 确保 .bashrc 存在 if [ ! -f "$BASHRC" ]; then run_as_postgres "touch $BASHRC" fi PATH_LINE="export PATH=${PG_VERSION_DIR}/bin:\$PATH" LD_LINE="export LD_LIBRARY_PATH=${PG_VERSION_DIR}/lib:\$LD_LIBRARY_PATH" # 清理旧的 PG 相关 PATH 和 LD_LIBRARY_PATH 配置(包括 export export 等异常格式) sed -i '/^export[[:space:]]*export[[:space:]]*PATH=/d' "$BASHRC" sed -i '/^export[[:space:]]*export[[:space:]]*LD_LIBRARY_PATH=/d' "$BASHRC" sed -i '/^export[[:space:]]*PATH=.*\/pgsql/d' "$BASHRC" sed -i '/^export[[:space:]]*LD_LIBRARY_PATH=.*\/pgsql/d' "$BASHRC" # 追加新配置 echo "$PATH_LINE" >> "$BASHRC" echo "$LD_LINE" >> "$BASHRC" echo " 已配置 PATH 和 LD_LIBRARY_PATH" source $BASHRC chown postgres:postgres "$BASHRC"else echo "[10/10] 跳过"fiecho ""echo "========================================"echo "PostgreSQL ${PG_VERSION} 安装完成!"echo "========================================"echo "安装目录: ${PG_VERSION_DIR}"echo "数据目录: ${PG_DATA_DIR}"echo "端口: ${PG_PORT}"echo ""echo "启动数据库:"echo " pg_ctl -D ${PG_DATA_DIR} start"echo ""echo "连接数据库:"echo " psql -p ${PG_PORT} -U postgres"echo ""###查看可安装的pg版本./add_pg_version_1.1.sh --list正在获取 PostgreSQL 可安装版本列表 (14+)...========================================可用版本 (14+):---------------------------------------- 14.0 端口: 54140 14.1 端口: 54141 14.2 端口: 54142 14.3 端口: 54143 14.4 端口: 54144 14.5 端口: 54145 14.6 端口: 54146 14.7 端口: 54147 14.8 端口: 54148 14.9 端口: 54149 14.10 端口: 51410 14.11 端口: 51411 14.12 端口: 51412 14.13 端口: 51413 14.14 端口: 51414 14.15 端口: 51415 14.16 端口: 51416 14.17 端口: 51417 14.18 端口: 51418 14.19 端口: 51419 14.20 端口: 51420 14.21 端口: 51421 14.22 端口: 51422 15.0 端口: 54150 15.1 端口: 54151 15.2 端口: 54152 15.3 端口: 54153 15.4 端口: 54154 15.5 端口: 54155 15.6 端口: 54156 15.7 端口: 54157 15.8 端口: 54158 15.9 端口: 54159 15.10 端口: 51510 15.11 端口: 51511 15.12 端口: 51512 15.13 端口: 51513 15.14 端口: 51514 15.15 端口: 51515 15.16 端口: 51516 15.17 端口: 51517 16.0 端口: 54160 16.1 端口: 54161 16.2 端口: 54162 16.3 端口: 54163 16.4 端口: 54164 16.5 端口: 54165 16.6 端口: 54166 16.7 端口: 54167 16.8 端口: 54168 16.9 端口: 54169 16.10 端口: 51610 16.11 端口: 51611 16.12 端口: 51612 16.13 端口: 51613 17.0 端口: 54170 17.1 端口: 54171 17.2 端口: 54172 17.3 端口: 54173 17.4 端口: 54174 17.5 端口: 54175 17.6 端口: 54176 17.7 端口: 54177 17.8 端口: 54178 17.9 端口: 54179 18.0 端口: 54180 18.1 端口: 54181 18.2 端口: 54182 18.3 端口: 54183###安装新的pg版本./add_pg_version_1.1.sh 17.3检测到 root 用户运行,涉及编译安装的步骤将自动切换到 postgres 用户执行========================================开始安装 PostgreSQL 17.3起始步骤: 1========================================安装目录: /usr/local/pgsql/pgsql17.3数据目录: /data/pgdata/pgdata17.3端口: 54173错误日志目录: /data/soft/postgres/errors========================================[1/10] 检查 /data 盘配置...[2/10] 检查 postgres 用户...创建 postgres 用户...useradd: Not copying any file from skel directory into it.New password: Retype new password: passwd: password updated successfully配置 sudo 权限...[3/10] 授权目录...[4/10] 下载 PostgreSQL 17.3 安装包...安装包已存在: /data/soft/postgres/postgresql-17.3.tar.gz[5/10] 创建目录结构...[6/10] 解压并编译安装...安装依赖... [已安装] libxml2,跳过 [已安装] libxml2-dev,跳过 [已安装] libreadline-dev,跳过 [已安装] libperl-dev,跳过 [已安装] python3-dev,跳过 [已安装] build-essential,跳过 [已安装] flex,跳过 [已安装] bison,跳过解压源码...源码目录已存在,跳过解压配置...编译安装 (这可能需要一些时间)...[7/10] 初始化数据库...[8/10] 修改配置文件...[9/10] 修改 pg_hba.conf...[10/10] 修改 postgres 用户 .bashrc... 已配置 PATH 和 LD_LIBRARY_PATH========================================PostgreSQL 17.3 安装完成!========================================安装目录: /usr/local/pgsql/pgsql17.3数据目录: /data/pgdata/pgdata17.3端口: 54173启动数据库: pg_ctl -D /data/pgdata/pgdata17.3 start连接数据库: psql -p 54173 -U postgres###删除已安装的pg版本root@testai:/data/testai/add_pg_version# ps -ef|grep "postgres -D"postgres 3347 1 0 11:06 ? 00:00:00 /usr/local/pgsql/pgsql18.3/bin/postgres -D /data/pgdata/pgdata18.3postgres 62568 1 0 17:18 ? 00:00:00 /usr/local/pgsql/pgsql17.3/bin/postgres -D /data/pgdata/pgdata17.3root@testai:/data/testai/add_pg_version# ./add_pg_version_1.1.sh --delete 17.3========================================开始删除 PostgreSQL 17.3========================================[1/3] 查找并停止 PostgreSQL 17.3 进程...找到以下相关进程:postgres 62568 1 0 17:18 ? 00:00:00 /usr/local/pgsql/pgsql17.3/bin/postgres -D /data/pgdata/pgdata17.3正在停止进程... 已终止进程 PID: 62568所有进程已停止[2/3] 删除数据目录... 已删除: /data/pgdata/pgdata17.3[3/3] 删除安装目录... 已删除: /usr/local/pgsql/pgsql17.3========================================PostgreSQL 17.3 已完全删除========================================root@testai:/data/testai/add_pg_version# ps -ef|grep "postgres -D"postgres 3347 1 0 11:06 ? 00:00:00 /usr/local/pgsql/pgsql18.3/bin/postgres -D /data/pgdata/pgdata18.3root 62836 24304 0 17:25 pts/2 00:00:00 grep postgres -Droot@testai:/data/testai/add_pg_version# ./add_pg_version_1.1.sh --delete 18.3========================================开始删除 PostgreSQL 18.3========================================[1/3] 查找并停止 PostgreSQL 18.3 进程...找到以下相关进程:postgres 3347 1 0 11:06 ? 00:00:00 /usr/local/pgsql/pgsql18.3/bin/postgres -D /data/pgdata/pgdata18.3正在停止进程... 已终止进程 PID: 3347所有进程已停止[2/3] 删除数据目录... 已删除: /data/pgdata/pgdata18.3[3/3] 删除安装目录... 已删除: /usr/local/pgsql/pgsql18.3========================================PostgreSQL 18.3 已完全删除