银河麒麟x86架构一键安装oracle19c数据库

#!/bin/bash
set -euo pipefail

# ====================== 常量(不需要用户输入的固定配置) ======================
HOST_NAME="oracle"
ORACLE_SID="orcl"
ORACLE_CHARSET="ZHS16GBK"
BUSINESS_USER="oracle"
ORACLE_BASE="/opt/oracle"
ORACLE_HOME="/opt/oracle/product/19c/dbhome_1"
LISTENER_PORT="1521"
DB_RPM="oracle-database-ee-19c-1.0-1.x86_64.rpm"
INSTALL_FLAG="/root/oracle_stage1.ok"
CONF_FILE="/root/.oracle_install.conf"   # 阶段间传递用户输入,权限 600

# ====================== 日志配置 ======================
LOG_FILE="/var/log/oracle_install_$(date +%Y%m%d_%H%M%S).log"
exec > >(tee -a "${LOG_FILE}") 2>&1
echo "📋 安装日志保存到:${LOG_FILE}"

# ====================== root 检查 ======================
if [ "$(id -u)" != "0" ]; then
    echo "❌ 请用 root 用户执行!"
    exit 1
fi

clear
echo "============================================"
echo "     Oracle 19c 非容器 智能分阶段安装脚本"
echo "============================================"
echo "日志文件:${LOG_FILE}"
echo ""

# ====================== 工具函数 ======================
append_if_absent() {
    local line="$1"
    local file="$2"
    grep -qxF "${line}" "${file}" 2>/dev/null || echo "${line}" >> "${file}"
}

# ====================== 前置环境检查 ======================
check_environment() {
    echo -e "\n=================================================="
    echo "  环境预检"
    echo "=================================================="
    local errors=0

    local mem_kb
    mem_kb=$(grep MemTotal /proc/meminfo | awk '{print $2}')
    if [ "${mem_kb}" -lt 2097152 ]; then
        echo "❌ 内存不足 2GB(当前: $((mem_kb/1024)) MB)"
        errors=$((errors + 1))
    else
        echo "✅ 内存检查通过($((mem_kb/1024)) MB)"
    fi

    local disk_avail
    disk_avail=$(df -BG /opt 2>/dev/null | awk 'NR==2{gsub("G",""); print $4}' || echo 0)
    if [ "${disk_avail}" -lt 20 ]; then
        echo "❌ /opt 剩余空间不足 20GB(当前: ${disk_avail}GB)"
        errors=$((errors + 1))
    else
        echo "✅ 磁盘空间检查通过(/opt 剩余: ${disk_avail}GB)"
    fi

    local swap_kb
    swap_kb=$(grep SwapTotal /proc/meminfo | awk '{print $2}')
    if [ "${swap_kb}" -lt 2097152 ]; then
        echo "⚠️  Swap 不足 2GB(当前: $((swap_kb/1024)) MB),建议增大 Swap"
    else
        echo "✅ Swap 检查通过($((swap_kb/1024)) MB)"
    fi

    if [ "${errors}" -gt 0 ]; then
        echo "❌ 环境检查未通过,请修复以上问题后重试!"
        exit 1
    fi
    echo -e "✅ 环境检查全部通过!\n"
}

# ====================== 智能依赖安装 ======================
install_deps() {
    echo -e "\n=================================================="
    echo "  开始安装 Oracle 系统依赖"
    echo "=================================================="

    local DEPS_LIST="binutils glibc glibc-devel ksh libaio libaio-devel \
    libX11 libXau libXi libXtst libgcc libstdc++ libstdc++-devel libxcb \
    make nfs-utils net-tools smartmontools sysstat unixODBC unixODBC-devel libnsl"

    set +e
    ping -c 2 -W 2 www.baidu.com > /dev/null 2>&1
    if [ $? -eq 0 ]; then
        echo "✅ 网络正常,联网安装依赖..."
        dnf install -y ${DEPS_LIST}
    else
        echo "⚠️  网络不通,离线安装系统依赖..."
        echo "--------------------------------------------------"

        shopt -s nullglob
        local rpm_files=(*.rpm)
        shopt -u nullglob

        if [ ${#rpm_files[@]} -eq 0 ]; then
            echo "❌ 当前目录无任何 .rpm 文件,离线安装失败!"
            exit 1
        fi

        local installed=0
        for rpm_file in "${rpm_files[@]}"; do
            if [[ "${rpm_file}" =~ ^oracle-database- ]]; then
                echo "  ⏭  跳过:${rpm_file}"
                continue
            fi
            echo "  📦 安装:${rpm_file}"
            rpm -Uvh "${rpm_file}" --nodeps --force 2>&1 || true
            installed=$((installed + 1))
        done

        echo "--------------------------------------------------"
        echo "  共处理 ${installed} 个依赖 RPM"
    fi
    set -e
    echo -e "✅ 依赖安装完成!\n"
}

# ====================================================================
#  阶段判断:有 INSTALL_FLAG → 第二阶段;否则 → 第一阶段
# ====================================================================
if [ -f "${INSTALL_FLAG}" ]; then

    # ======================= 重启校验新增 BEGIN =======================
    FLAG_TIME=$(cat "${INSTALL_FLAG}")
    NOW_TIME=$(date +%s)
    UPTIME=$(awk '{print int($1)}' /proc/uptime)
    BOOT_TIME=$((NOW_TIME - UPTIME))

    if [ "${BOOT_TIME}" -lt "${FLAG_TIME}" ]; then
        echo "❌ 检测到还未重启,必须 reboot 后再继续执行!"
        echo "   请执行:reboot 重启服务器,再次运行此脚本"
        exit 1
    fi
    # ======================= 重启校验新增 END =========================

    # ================================================================
    #  第二阶段:从配置文件加载变量,无需用户重复输入
    # ================================================================
    if [ ! -f "${CONF_FILE}" ]; then
        echo "❌ 找不到阶段配置文件 ${CONF_FILE},无法继续!"
        echo "   请重新从第一阶段开始(删除 ${INSTALL_FLAG} 后重新运行脚本)"
        exit 1
    fi

    # 加载第一阶段保存的变量
    # shellcheck source=/dev/null
    source "${CONF_FILE}"

    echo "✅ 检测到重启完成,进入第二阶段安装"
    echo "   IP地址  : ${SERVER_IP}"
    echo "   SID     : ${ORACLE_SID}"
    echo "   业务用户: ${BUSINESS_USER}"
    echo ""
    read -rp "继续安装?(y/n): " ok
    [ "${ok}" != "y" ] && exit 0
    rm -f "${INSTALL_FLAG}"

else

    # ================================================================
    #  第一阶段:收集用户输入 → 保存配置文件 → 系统配置 → 等待重启
    # ================================================================
    echo "🆕 首次安装:第一阶段(环境检查 + 系统配置 + 依赖 + 用户)"
    echo ""

    # ---------- 收集所有需要用户输入的变量 ----------
    read -rp "请输入当前服务器的IP地址: " SERVER_IP
    if [ -z "${SERVER_IP}" ]; then
        echo "❌ IP地址不能为空!"
        exit 1
    fi

    read -rsp "请输入SYS密码(直接回车使用默认值 mhis): " SYS_PASSWORD
    echo
    SYS_PASSWORD="${SYS_PASSWORD:-mhis}"

    read -rsp "请输入业务用户(${BUSINESS_USER})密码(直接回车使用默认值 oracle): " BUSINESS_PASSWORD
    echo
    BUSINESS_PASSWORD="${BUSINESS_PASSWORD:-oracle}"

    read -rsp "请输入 oracle 操作系统用户密码: " ORACLE_OS_PASSWORD
    echo
    if [ -z "${ORACLE_OS_PASSWORD}" ]; then
        echo "❌ oracle 系统用户密码不能为空!"
        exit 1
    fi

    echo ""
    read -rp "开始安装?(y/n): " ok
    [ "${ok}" != "y" ] && exit 0

    # ---------- 持久化到配置文件(仅 root 可读) ----------
    cat > "${CONF_FILE}" << CONF
SERVER_IP="${SERVER_IP}"
SYS_PASSWORD="${SYS_PASSWORD}"
BUSINESS_PASSWORD="${BUSINESS_PASSWORD}"
ORACLE_OS_PASSWORD="${ORACLE_OS_PASSWORD}"
CONF
    chmod 600 "${CONF_FILE}"
    echo "✅ 配置已保存到 ${CONF_FILE}(权限 600,仅 root 可读)"

    # ---------- 环境预检 ----------
    check_environment

    echo ">>> 配置主机名和 hosts"
    grep -qxF "${SERVER_IP} ${HOST_NAME} ${HOST_NAME}.localdomain" /etc/hosts \
        || echo "${SERVER_IP} ${HOST_NAME} ${HOST_NAME}.localdomain" >> /etc/hosts
    hostnamectl set-hostname "${HOST_NAME}"

    install_deps

    echo ">>> 创建 Oracle 用户组"
    getent group oinstall || groupadd -g 54321 oinstall
    getent group dba      || groupadd -g 54322 dba
    getent group oper     || groupadd -g 54323 oper

    echo ">>> 创建 oracle 用户"
    if ! id oracle &>/dev/null; then
        useradd -u 54321 -g oinstall -G dba,oper oracle
    fi

    echo ">>> 设置 oracle 系统用户密码"
    echo "oracle:${ORACLE_OS_PASSWORD}" | chpasswd

    mkdir -p "${ORACLE_HOME}"
    chown -R oracle:oinstall "${ORACLE_BASE}"
    chmod -R 775 "${ORACLE_BASE}"

    # 写入当前时间戳,用于第二阶段验证是否真正重启
    date +%s > "${INSTALL_FLAG}"
    echo -e "\n✅ 第一阶段安装完成!"
    echo "⚠️  请执行:reboot  重启服务器"
    echo "🔄 重启后重新运行本脚本,将自动进入第二阶段"
    exit 0
fi

# ====================================================================
#  第二阶段主体
# ====================================================================
echo ">>> 第二阶段:安装 Oracle 软件 + 创建非容器数据库"

if [ ! -f "${DB_RPM}" ]; then
    echo "❌ 缺少 ${DB_RPM} 安装包,请确认文件在当前目录!"
    exit 1
fi

# ---------- 安装 Oracle RPM ----------
if rpm -q oracle-database-ee-19c &>/dev/null; then
    echo "✅ Oracle 19c RPM 已安装,跳过..."
else
    echo ">>> 安装 Oracle 19c 主程序(此步骤较慢,请耐心等待)..."
    set +e
    rpm -ivh "${DB_RPM}" --nodeps --force --nosignature
    RPM_RC=$?
    set -e
    if [ "${RPM_RC}" -ne 0 ]; then
        echo "❌ Oracle RPM 安装失败(返回码:${RPM_RC}),请检查日志:${LOG_FILE}"
        exit 1
    fi
fi

chown -R oracle:oinstall "${ORACLE_BASE}"

# ---------- 配置环境变量 ----------
echo ">>> 配置 oracle 用户环境变量"
if ! grep -q "ORACLE_BASE" /home/oracle/.bash_profile 2>/dev/null; then
    sudo -u oracle tee -a /home/oracle/.bash_profile > /dev/null << EOF

# Oracle 19c ENV (added by install script)
export ORACLE_BASE=${ORACLE_BASE}
export ORACLE_HOME=${ORACLE_HOME}
export ORACLE_SID=${ORACLE_SID}
export PATH=\${ORACLE_HOME}/bin:\${PATH}
export NLS_LANG=AMERICAN_AMERICA.${ORACLE_CHARSET}
export LANG=C
EOF
    echo "✅ 环境变量写入完成"
else
    echo "✅ 环境变量已存在,跳过..."
fi

# ---------- 配置数据库服务 ----------
SERVICE_NAME="oracledb_${ORACLE_SID}-19c"
INIT_SCRIPT="/etc/init.d/${SERVICE_NAME}"
SYSCONFIG_FILE="/etc/sysconfig/${SERVICE_NAME}.conf"

echo ">>> 配置数据库服务:${SERVICE_NAME}"
if [ ! -f "${INIT_SCRIPT}" ]; then
    cp /etc/init.d/oracledb_ORCLCDB-19c "${INIT_SCRIPT}"
    cp /etc/sysconfig/oracledb_ORCLCDB-19c.conf "${SYSCONFIG_FILE}"
    sed -i "s/export ORACLE_SID=.*/export ORACLE_SID=${ORACLE_SID}/"         "${INIT_SCRIPT}"
    sed -i "s/export CHARSET=.*/export CHARSET=${ORACLE_CHARSET}/"            "${INIT_SCRIPT}"
    sed -i "s/export NUMBER_OF_PDBS=.*/export NUMBER_OF_PDBS=0/"              "${INIT_SCRIPT}"
    sed -i "s/export CREATE_AS_CDB=.*/export CREATE_AS_CDB=false/"            "${INIT_SCRIPT}"
    sed -i "s/export PDB_NAME=.*/export PDB_NAME=ORCLPDB1/"                   "${INIT_SCRIPT}"
    sed -i "s|dbca -silent -createDatabase|dbca -silent -J-Doracle.assistants.dbca.validate.ConfigurationParams=false -createDatabase|" "${INIT_SCRIPT}"
else
    echo "✅ 服务脚本已存在,跳过生成..."
fi

# ---------- 创建数据库 ----------
if grep -q "^${ORACLE_SID}:" /etc/oratab 2>/dev/null; then
    echo "✅ 数据库 ${ORACLE_SID} 已存在(oratab 中有记录),跳过创建..."
else
    echo ">>> 开始创建非容器数据库,耗时 5~10 分钟..."
    /etc/init.d/"${SERVICE_NAME}" configure
fi

# ---------- 配置数据库用户 ----------
echo ">>> 修改 SYS 密码、创建业务用户"
su - oracle -c "
export ORACLE_HOME=${ORACLE_HOME}
export ORACLE_SID=${ORACLE_SID}
export PATH=\${ORACLE_HOME}/bin:\${PATH}

sqlplus -S / as sysdba <<'SQLEOF'
set feedback off;
set echo off;
alter user sys identified by ${SYS_PASSWORD};
declare
  v_count number;
begin
  select count(*) into v_count from dba_users where username = upper('${BUSINESS_USER}');
  if v_count = 0 then
    execute immediate 'create user ${BUSINESS_USER} identified by ${BUSINESS_PASSWORD}';
    execute immediate 'grant dba, connect, resource to ${BUSINESS_USER}';
  else
    execute immediate 'alter user ${BUSINESS_USER} identified by ${BUSINESS_PASSWORD}';
  end if;
end;
/
exit;
SQLEOF
"

# ---------- 配置开机自启 ----------
echo ">>> 配置 dbstart(修复 ORACLE_HOME_LISTNER)"
grep -q 'ORACLE_HOME_LISTNER=\$ORACLE_HOME' "${ORACLE_HOME}/bin/dbstart" \
    || sed -i "s/ORACLE_HOME_LISTNER=\$1/ORACLE_HOME_LISTNER=\$ORACLE_HOME/" "${ORACLE_HOME}/bin/dbstart"

echo ">>> 配置 oratab 自启标志"
sed -i "/^${ORACLE_SID}:/s|:N$|:Y|" /etc/oratab

echo ">>> 配置 rc.local 自启(幂等写入)"
chmod +x /etc/rc.d/rc.local
append_if_absent "su - oracle -c 'lsnrctl start'" /etc/rc.d/rc.local
append_if_absent "su - oracle -c 'dbstart'"       /etc/rc.d/rc.local

# ---------- 配置防火墙 ----------
echo ">>> 配置防火墙(开放 ${LISTENER_PORT} 端口)"
if systemctl is-active --quiet firewalld; then
    firewall-cmd --permanent --add-port="${LISTENER_PORT}/tcp" && \
        firewall-cmd --reload && \
        echo "✅ 防火墙已放行端口 ${LISTENER_PORT}" \
        || echo "⚠️  防火墙配置失败,请手动开放 ${LISTENER_PORT} 端口"
else
    echo "⚠️  firewalld 未运行,跳过(如有其他防火墙请手动开放 ${LISTENER_PORT} 端口)"
fi

# ---------- 启动监听 ----------
echo ">>> 启动监听器"
su - oracle -c "
export ORACLE_HOME=${ORACLE_HOME}
export PATH=\${ORACLE_HOME}/bin:\${PATH}
lsnrctl start || true
"

# ---------- 清理临时配置文件(密码不再需要) ----------
rm -f "${CONF_FILE}"
echo "✅ 临时配置文件已清除"

# ---------- 完成信息 ----------
echo ""
echo "================================================================================"
echo " 🎉 Oracle 19c 非容器数据库 安装成功!"
echo "================================================================================"
echo " 主机IP    : ${SERVER_IP}"
echo " SID       : ${ORACLE_SID}"
echo " 端口      : ${LISTENER_PORT}"
echo " 字符集    : ${ORACLE_CHARSET}"
echo " SYS密码   : ${SYS_PASSWORD}"
echo " 业务用户  : ${BUSINESS_USER} / ${BUSINESS_PASSWORD}"
echo " 安装日志  : ${LOG_FILE}"
echo "================================================================================"
echo " 连接示例(DBA)  : sqlplus sys/${SYS_PASSWORD}@${SERVER_IP}:${LISTENER_PORT}/${ORACLE_SID} as sysdba"
echo " 连接示例(业务) : sqlplus ${BUSINESS_USER}/${BUSINESS_PASSWORD}@${SERVER_IP}:${LISTENER_PORT}/${ORACLE_SID}"
echo "================================================================================"

完整安装包地址:
链接: https://pan.baidu.com/s/1yyGfwdwkA3rdi5JIzJCaRw 提取码: 2kuh 复制这段内容后打开百度网盘手机App,操作更方便哦

更多推荐