Redis脚本
#!/bin/bash
# ====== 配置变量 ======
REDIS_VERSION="7.4.2"
REDIS_PORT="63790"
REDIS_USER="redis"
REDIS_GROUP="redis"
REDIS_HOME="/usr/local/redis"
REDIS_DATA_DIR="/var/lib/redis"
REDIS_LOG_DIR="/var/log/redis"
REDIS_RUN_DIR="/var/run/redis"
# ====== 颜色输出函数 ======
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
log_info() {
echo -e "${GREEN}[INFO]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1" >&2
}
# ====== 检查并安装依赖 ======
install_dependencies() {
log_info "开始安装依赖包..."
# 检查并安装tar
if ! command -v tar &> /dev/null; then
yum -y install tar
log_info "已安装tar"
else
log_info "tar已安装"
fi
# 检查并安装gcc
if ! command -v gcc &> /dev/null; then
yum -y install gcc
log_info "已安装gcc"
else
log_info "gcc已安装"
fi
# 检查gcc是否安装成功
if ! command -v gcc &> /dev/null; then
log_error "GCC安装失败,请检查YUM源配置"
exit 1
fi
}
# ====== 配置系统参数 ======
configure_system() {
log_info "配置系统参数..."
# 配置内存过度分配
if ! grep -q "vm.overcommit_memory = 1" /etc/sysctl.conf; then
echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf
sysctl -p
log_info "已配置内存过度分配策略"
fi
# 配置透明大页 (需要重启生效)
if [ ! -f /etc/rc.d/rc.local ]; then
echo '#!/bin/bash' > /etc/rc.d/rc.local
fi
chmod +x /etc/rc.d/rc.local
if ! grep -q "transparent_hugepage" /etc/rc.d/rc.local; then
echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.d/rc.local
log_info "已配置透明大页禁用(重启后生效)"
fi
}
# ====== 创建Redis用户和组 ======
create_redis_user() {
log_info "创建Redis用户和组..."
if ! getent group ${REDIS_GROUP} > /dev/null; then
groupadd -r ${REDIS_GROUP}
log_info "已创建Redis组: ${REDIS_GROUP}"
fi
if ! id -u ${REDIS_USER} > /dev/null 2>&1; then
useradd -r -g ${REDIS_GROUP} -s /sbin/nologin ${REDIS_USER}
log_info "已创建Redis用户: ${REDIS_USER}"
fi
}
# ====== 安装Redis ======
install_redis() {
log_info "开始安装Redis ${REDIS_VERSION}..."
# 检查Redis源码包是否存在
if [ ! -f "/usr/local/src/redis-${REDIS_VERSION}.tar.gz" ]; then
log_error "Redis源码包不存在: /usr/local/src/redis-${REDIS_VERSION}.tar.gz"
exit 1
fi
# 解压Redis源码
tar -zxf "/usr/local/src/redis-${REDIS_VERSION}.tar.gz" -C /usr/local
if [ $? -ne 0 ]; then
log_error "解压Redis源码包失败"
exit 1
fi
# 重命名目录
mv "/usr/local/redis-${REDIS_VERSION}" "${REDIS_HOME}"
# 编译安装Redis
cd "${REDIS_HOME}"
make MALLOC=libc
if [ $? -ne 0 ]; then
log_error "Redis编译失败"
exit 1
fi
cd "${REDIS_HOME}/src"
make install PREFIX="${REDIS_HOME}"
if [ $? -ne 0 ]; then
log_error "Redis安装失败"
exit 1
fi
log_info "Redis ${REDIS_VERSION} 安装成功"
}
# ====== 配置Redis ======
configure_redis() {
log_info "配置Redis..."
# 创建数据和日志目录
mkdir -p ${REDIS_DATA_DIR} ${REDIS_LOG_DIR} ${REDIS_RUN_DIR}
chown -R ${REDIS_USER}:${REDIS_GROUP} ${REDIS_DATA_DIR} ${REDIS_LOG_DIR} ${REDIS_RUN_DIR}
chmod -R 755 ${REDIS_DATA_DIR} ${REDIS_LOG_DIR} ${REDIS_RUN_DIR}
# 修改Redis配置文件
if [ -f "${REDIS_HOME}/redis.conf" ]; then
# 备份原始配置文件
cp "${REDIS_HOME}/redis.conf" "${REDIS_HOME}/redis.conf.bak"
# 应用配置修改
sed -i 's/^bind 127.0.0.1/bind 0.0.0.0/g' "${REDIS_HOME}/redis.conf" # 开放对外链接
sed -i 's/daemonize no/daemonize yes/' "${REDIS_HOME}/redis.conf" # 守护进程方式启动
sed -i 's/protected-mode yes/protected-mode no/' "${REDIS_HOME}/redis.conf" # 开放外部访问
sed -i "s/port 6379/port ${REDIS_PORT}/" "${REDIS_HOME}/redis.conf" # 修改端口号
# 添加额外配置
echo "dir ${REDIS_DATA_DIR}" >> "${REDIS_HOME}/redis.conf"
echo "logfile ${REDIS_LOG_DIR}/redis.log" >> "${REDIS_HOME}/redis.conf"
echo "pidfile ${REDIS_RUN_DIR}/redis.pid" >> "${REDIS_HOME}/redis.conf"
# 设置配置文件权限
chown ${REDIS_USER}:${REDIS_GROUP} "${REDIS_HOME}/redis.conf"
chmod 644 "${REDIS_HOME}/redis.conf"
log_info "Redis配置已完成"
else
log_error "Redis配置文件不存在: ${REDIS_HOME}/redis.conf"
exit 1
fi
}
# ====== 创建Systemd服务 ======
create_systemd_service() {
log_info "创建Systemd服务..."
cat > /etc/systemd/system/redis.service << EOF
[Unit]
Description=Redis In-Memory Data Store
Documentation=https://redis.io/documentation
After=network.target
[Service]
Type=forking
User=${REDIS_USER}
Group=${REDIS_GROUP}
PIDFile=${REDIS_RUN_DIR}/redis.pid
ExecStart=${REDIS_HOME}/bin/redis-server ${REDIS_HOME}/redis.conf
ExecStop=${REDIS_HOME}/bin/redis-cli -h 127.0.0.1 -p ${REDIS_PORT} shutdown
Restart=always
RestartSec=3
LimitNOFILE=65535
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
# 重新加载Systemd配置
systemctl daemon-reload
log_info "Systemd服务已创建"
}
# ====== 创建符号链接 ======
create_symlinks() {
log_info "创建符号链接..."
ln -sf "${REDIS_HOME}/bin/redis-cli" /usr/local/sbin/redis-cli
ln -sf "${REDIS_HOME}/bin/redis-server" /usr/local/sbin/redis-server
# 添加到PATH环境变量
if ! grep -q "${REDIS_HOME}/bin" /etc/profile; then
echo "export PATH=\${PATH}:${REDIS_HOME}/bin" >> /etc/profile
source /etc/profile
fi
log_info "符号链接已创建"
}
# ====== 配置防火墙 ======
configure_firewall() {
log_info "配置防火墙..."
if systemctl is-active --quiet firewalld; then
firewall-cmd --permanent --add-port=${REDIS_PORT}/tcp
firewall-cmd --reload
log_info "已放行TCP ${REDIS_PORT}端口"
else
log_warning "firewalld未运行,跳过端口放行"
fi
}
# ====== 启动Redis服务 ======
start_redis_service() {
log_info "启动Redis服务..."
# 设置目录权限
chown -R ${REDIS_USER}:${REDIS_GROUP} ${REDIS_HOME}
# 启动并启用服务
systemctl start redis
systemctl enable redis
# 检查服务状态
sleep 2 # 等待服务启动
if systemctl is-active --quiet redis; then
log_info "Redis服务启动成功"
systemctl status redis --no-pager
else
log_error "Redis服务启动失败"
journalctl -u redis --since "1 minute ago" --no-pager
exit 1
fi
}
# ====== 安装后提示 ======
post_install_info() {
echo ""
log_info "========== Redis 安装完成 =========="
log_info "版本: Redis ${REDIS_VERSION}"
log_info "端口: ${REDIS_PORT}"
log_info "配置文件: ${REDIS_HOME}/redis.conf"
log_info "数据目录: ${REDIS_DATA_DIR}"
log_info "日志文件: ${REDIS_LOG_DIR}/redis.log"
log_info "管理命令:"
log_info " 启动: systemctl start redis"
log_info " 停止: systemctl stop redis"
log_info " 状态: systemctl status redis"
log_info " 连接: redis-cli -p ${REDIS_PORT}"
echo ""
log_warning "注意: 当前配置未设置密码,生产环境请设置requirepass"
log_warning " 修改配置文件: ${REDIS_HOME}/redis.conf"
log_warning " 取消注释: # requirepass foobared 并设置强密码"
echo ""
}
# ====== 主执行流程 ======
main() {
log_info "开始Redis安装流程"
# 检查root权限
if [ "$(id -u)" != "0" ]; then
log_error "此脚本必须使用root权限运行"
exit 1
fi
# 执行安装步骤
install_dependencies
configure_system
create_redis_user
install_redis
configure_redis
create_systemd_service
create_symlinks
configure_firewall
start_redis_service
post_install_info
log_info "Redis安装完成"
}
# 执行主函数
main "$@"
MySQL脚本
#!/bin/bash
# 脚本配置
SCRIPT_NAME="install_mysql-ziqi"
LOG_FILE="/var/log/${SCRIPT_NAME}.log"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 函数:记录日志
log() {
local level=$1
local message=$2
echo -e "${TIMESTAMP} [${level}] ${message}" | tee -a "${LOG_FILE}"
}
# 函数:检查命令执行状态
check_status() {
local exit_code=$1
local success_msg=$2
local error_msg=$3
if [ ${exit_code} -eq 0 ]; then
log "SUCCESS" "${success_msg}"
return 0
else
log "ERROR" "${error_msg} (退出码: ${exit_code})"
return 1
fi
}
# 函数:错误处理
error_exit() {
local error_msg=$1
local exit_code=${2:-1}
log "FATAL" "${error_msg}"
exit ${exit_code}
}
# 函数:清理旧MySQL安装
cleanup_old_mysql() {
log "INFO" "清理旧的MySQL安装..."
# 查找并停止正在运行的MySQL服务
if systemctl is-active --quiet mysqld 2>/dev/null || systemctl is-active --quiet mysql 2>/dev/null; then
systemctl stop mysqld mysql 2>/dev/null
log "INFO" "已停止运行的MySQL服务"
fi
# 查找并移除旧包
old_mysql=$(rpm -qa | grep -E 'mariadb|mysql' | tr '\n' ' ')
if [ -n "${old_mysql}" ]; then
rpm -e --nodeps ${old_mysql} >> "${LOG_FILE}" 2>&1
check_status $? "旧MySQL包移除成功" "旧MySQL包移除失败"
fi
# 移除MySQL相关目录
find / -name "mysql" -type d -not -path "/data*" -exec rm -rf {} + 2>/dev/null || true
log "INFO" "旧MySQL安装清理完成"
}
# 主执行函数
main() {
log "INFO" "开始MySQL安装过程"
# 创建日志目录
mkdir -p "$(dirname "${LOG_FILE}")"
touch "${LOG_FILE}"
chmod 644 "${LOG_FILE}"
# 显示开始信息
echo -e "${GREEN}开始安装MySQL...${NC}"
echo -e "详细日志请查看: ${YELLOW}${LOG_FILE}${NC}"
# 修改环境
log "INFO" "修改SELinux设置..."
setenforce 0 >> "${LOG_FILE}" 2>&1
check_status $? "SELinux临时禁用成功" "SELinux临时禁用失败"
sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config >> "${LOG_FILE}" 2>&1
check_status $? "SELinux永久禁用成功" "SELinux永久禁用失败"
# 清理旧MySQL安装
cleanup_old_mysql
# 定义路径变量
mysql_path_b=/data/mysql
mysql_path=/data/mysql/mysql
mysql_path_data=$mysql_path_b/data
# 安装依赖
log "INFO" "安装必要依赖..."
yum -y install libaio >> "${LOG_FILE}" 2>&1
check_status $? "libaio安装成功" "libaio安装失败" || error_exit "无法安装libaio"
yum -y install tar >> "${LOG_FILE}" 2>&1
check_status $? "tar安装成功" "tar安装失败" || error_exit "无法安装tar"
# 创建用户和组
log "INFO" "创建MySQL用户和组..."
groupadd mysql >> "${LOG_FILE}" 2>&1
check_status $? "MySQL用户组创建成功" "MySQL用户组创建失败" || error_exit "无法创建MySQL用户组"
useradd -g mysql -s /sbin/nologin mysql >> "${LOG_FILE}" 2>&1
check_status $? "MySQL用户创建成功" "MySQL用户创建失败" || error_exit "无法创建MySQL用户"
# 创建目录
log "INFO" "创建MySQL目录..."
mkdir -p $mysql_path_data >> "${LOG_FILE}" 2>&1
check_status $? "MySQL目录创建成功" "MySQL目录创建失败" || error_exit "无法创建MySQL目录"
# 解压MySQL
log "INFO" "解压MySQL安装包..."
tar -xvf /usr/local/src/mysql-8.0.4* -C $mysql_path_b >> "${LOG_FILE}" 2>&1
check_status $? "MySQL解压成功" "MySQL解压失败" || error_exit "无法解压MySQL安装包"
# 重命名目录
mv $mysql_path_b/mysql-8.0.4* $mysql_path_b/mysql >> "${LOG_FILE}" 2>&1
check_status $? "MySQL目录重命名成功" "MySQL目录重命名失败"
# 设置权限
chown -R mysql:mysql $mysql_path_data $mysql_path_b >> "${LOG_FILE}" 2>&1
check_status $? "目录权限设置成功" "目录权限设置失败"
chmod 755 $mysql_path_data $mysql_path_b >> "${LOG_FILE}" 2>&1
check_status $? "目录权限修改成功" "目录权限修改失败"
# 创建符号链接
ln -s $mysql_path/bin/mysql /usr/bin/mysql >> "${LOG_FILE}" 2>&1
check_status $? "MySQL符号链接创建成功" "MySQL符号链接创建失败"
# 添加PATH环境变量
echo "export PATH=${PATH}:$mysql_path/bin" >>/etc/profile
source /etc/profile >> "${LOG_FILE}" 2>&1
check_status $? "PATH环境变量更新成功" "PATH环境变量更新失败"
# 移除旧配置文件
rm -fr /etc/my.cnf >> "${LOG_FILE}" 2>&1
check_status $? "旧配置文件移除成功" "旧配置文件移除失败"
# 创建新配置文件
log "INFO" "创建MySQL配置文件..."
cat > /etc/my.cnf << EOF
[client]
port = 3306
socket = $mysql_path_data/mysql.sock
default-character-set = utf8mb4
[mysql]
disable-auto-rehash
default-character-set = utf8mb4
connect-timeout = 10
[mysqld]
user = mysql
server-id = 3306
port = 3306
socket = $mysql_path_data/mysql.sock
pid-file = $mysql_path_data/mysql.pid
basedir = $mysql_path_b
datadir = $mysql_path_data/data
autocommit = 1
plugin_dir = $mysql_path/lib/plugin
default_authentication_plugin = mysql_native_password
character-set-server = utf8mb4
explicit_defaults_for_timestamp = true
lower_case_table_names = 1
back_log = 103
max_connections = 10000
max_connect_errors = 100000
table_open_cache = 512
external-locking = FALSE
max_allowed_packet = 32M
sort_buffer_size = 2M
join_buffer_size = 2M
thread_cache_size = 51
transaction_isolation = READ-COMMITTED
tmp_table_size = 96M
max_heap_table_size = 96M
###***logs
long_query_time = 10
slow_query_log = 1
slow_query_log_file = $mysql_path_data/slow.log
log_error_verbosity = 3
log-error = $mysql_path_data/mysql.err
log_output = FILE
max_binlog_size = 1G
log-bin = $mysql_path_data/mysql-bin
# innodb storage engine parameters
innodb_buffer_pool_size = 500M
innodb_data_file_path = ibdata1:100M:autoextend:max:5G
innodb_temp_data_file_path = ibtemp1:100M:autoextend:max:10G
innodb_log_buffer_size = 16M
innodb_log_file_size = 256M
innodb_log_files_in_group = 2
innodb_lock_wait_timeout = 50
innodb_file_per_table = 1
EOF
check_status $? "MySQL配置文件创建成功" "MySQL配置文件创建失败" || error_exit "无法创建MySQL配置文件"
# 创建必要的文件
touch $mysql_path/mysql.pid
touch $mysql_path/mysql_err.log
chown -R mysql:mysql $mysql_path_b
# 初始化MySQL
log "INFO" "初始化MySQL..."
mysqld --defaults-file=/etc/my.cnf --initialize-insecure >> "${LOG_FILE}" 2>&1
check_status $? "MySQL初始化成功" "MySQL初始化失败" || error_exit "无法初始化MySQL"
# 创建systemd服务
log "INFO" "创建systemd服务..."
cat > /etc/systemd/system/mysql.service << EOF
[Unit]
Description=MySQL Server 8.0
After=network.target
[Service]
User=mysql
Group=mysql
ExecStart=$mysql_path/bin/mysqld --defaults-file=/etc/my.cnf
LimitNOFILE = 65535
PIDFile=$mysql_path/mysql.pid
ExecStop=$mysql_path/mysqladmin shutdown
[Install]
WantedBy=multi-user.target
EOF
check_status $? "systemd服务文件创建成功" "systemd服务文件创建失败" || error_exit "无法创建systemd服务文件"
chmod 644 /etc/systemd/system/mysql.service >> "${LOG_FILE}" 2>&1
check_status $? "服务文件权限设置成功" "服务文件权限设置失败"
systemctl daemon-reload >> "${LOG_FILE}" 2>&1
check_status $? "systemd重载成功" "systemd重载失败"
# 启动MySQL服务
log "INFO" "启动MySQL服务..."
systemctl start mysql >> "${LOG_FILE}" 2>&1
check_status $? "MySQL服务启动成功" "MySQL服务启动失败" || error_exit "无法启动MySQL服务"
systemctl enable mysql >> "${LOG_FILE}" 2>&1
check_status $? "MySQL服务启用自启成功" "MySQL服务启用自启失败"
# 配置防火墙
log "INFO" "配置防火墙..."
firewall-cmd --zone=public --add-port=3306/tcp --permanent >> "${LOG_FILE}" 2>&1
check_status $? "防火墙端口添加成功" "防火墙端口添加失败"
firewall-cmd --reload >> "${LOG_FILE}" 2>&1
check_status $? "防火墙重载成功" "防火墙重载失败"
# 等待MySQL完全启动
log "INFO" "等待MySQL完全启动..."
sleep 5
# 设置root密码和远程访问
log "INFO" "设置MySQL root密码和远程访问..."
$mysql_path/bin/mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'shangben@123';" >> "${LOG_FILE}" 2>&1
check_status $? "Root密码设置成功" "Root密码设置失败"
$mysql_path/bin/mysql -u root -pshangben@123 -e "UPDATE mysql.user SET host = '%' WHERE user = 'root' AND host = 'localhost';" >> "${LOG_FILE}" 2>&1
check_status $? "远程访问设置成功" "远程访问设置失败"
$mysql_path/bin/mysql -u root -pshangben@123 -e "FLUSH PRIVILEGES;" >> "${LOG_FILE}" 2>&1
check_status $? "权限刷新成功" "权限刷新失败"
# 验证安装
log "INFO" "验证MySQL安装..."
systemctl status mysql >> "${LOG_FILE}" 2>&1
check_status $? "MySQL服务状态检查成功" "MySQL服务状态检查失败"
# 显示安装摘要
log "SUCCESS" "===== MySQL安装完成 ====="
log "INFO" "安装路径: $mysql_path"
log "INFO" "数据目录: $mysql_path_data"
log "INFO" "配置文件: /etc/my.cnf"
log "INFO" "Root密码: shangben@123"
log "INFO" "服务状态: $(systemctl is-active mysql)"
log "INFO" "日志文件: $LOG_FILE"
log "INFO" "连接命令: mysql -u root -p -h 127.0.0.1"
log "SUCCESS" "=========================="
echo -e "${GREEN}MySQL安装完成!${NC}"
echo -e "Root密码: ${YELLOW}shangben@123${NC}"
echo -e "连接命令: ${YELLOW}mysql -u root -p -h 127.0.0.1${NC}"
echo -e "详细日志请查看: ${YELLOW}${LOG_FILE}${NC}"
}
# 执行主函数
main "$@"
MongoDB脚本
#!/bin/bash
# ====== 变量定义 ======
MONGO_VERSION="6.0.20"
MONGO_PKG="mongodb-linux-x86_64-rhel90-$MONGO_VERSION"
ARCHIVE="$MONGO_PKG.tgz"
INSTALL_DIR="/opt/mongodb"
DATA_DIR="/data/db"
LOG_DIR="/var/log/mongodb"
RUN_DIR="/var/run/mongodb"
MONGO_USER="mongodb"
MONGO_GROUP="mongodb"
AUTH_ENABLED="disabled" # 默认禁用认证,便于初始配置
# ====== 颜色定义 ======
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# ====== 函数定义 ======
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
check_command() {
if ! command -v $1 &> /dev/null; then
log_error "$1 命令未找到,请安装后再运行脚本"
exit 1
fi
}
# ====== 前置检查 ======
check_command tar
check_command curl
# 检查是否以root用户运行
if [ "$EUID" -ne 0 ]; then
log_error "请以root用户运行此脚本"
exit 1
fi
# ====== 检查本地安装包是否存在 ======
if [ ! -f "$ARCHIVE" ]; then
log_warn "安装包 $ARCHIVE 不存在,尝试下载..."
DOWNLOAD_URL="https://fastdl.mongodb.org/linux/$ARCHIVE"
if curl -O --fail "$DOWNLOAD_URL"; then
log_info "下载成功: $ARCHIVE"
else
log_error "下载失败,请手动将 $ARCHIVE 放在当前目录后重试"
exit 1
fi
fi
# ====== 创建 mongodb 用户和组 ======
if ! id "$MONGO_USER" &>/dev/null; then
log_info "创建 mongodb 用户和组..."
groupadd -r $MONGO_GROUP
useradd -r -g $MONGO_GROUP -s /sbin/nologin $MONGO_USER
fi
# ====== 安装依赖 ======
log_info "安装依赖包..."
if command -v dnf &> /dev/null; then
dnf install -y libcurl openssl xz-libs || { log_error "安装依赖失败"; exit 1; }
elif command -v yum &> /dev/null; then
yum install -y libcurl openssl xz-libs || { log_error "安装依赖失败"; exit 1; }
else
log_warn "未找到dnf或yum包管理器,跳过依赖安装"
fi
# ====== 创建目录结构 ======
log_info "创建目录..."
mkdir -p $INSTALL_DIR $DATA_DIR $LOG_DIR $RUN_DIR
chown -R $MONGO_USER:$MONGO_GROUP $INSTALL_DIR $DATA_DIR $LOG_DIR $RUN_DIR
chmod -R 755 $INSTALL_DIR $DATA_DIR $LOG_DIR $RUN_DIR
# ====== 检查端口是否被占用 ======
log_info "检查端口 27017 是否被占用..."
if netstat -tuln | grep -q ":27017"; then
log_warn "端口 27017 已被占用,尝试终止占用进程..."
PID=$(lsof -ti:27017)
if [ ! -z "$PID" ]; then
kill -9 $PID
sleep 2
fi
fi
# ====== 解压 MongoDB 安装包 ======
log_info "解压 MongoDB 安装包..."
if ! tar -xzf "$ARCHIVE"; then
log_error "解压失败"
exit 1
fi
# 清理可能的旧安装
rm -rf $INSTALL_DIR/*
cp -r $MONGO_PKG/* $INSTALL_DIR/
chown -R $MONGO_USER:$MONGO_GROUP $INSTALL_DIR
# 清理临时文件
rm -rf $MONGO_PKG
# ====== 配置环境变量 ======
log_info "配置环境变量..."
if ! grep -q "mongodb" /etc/profile; then
echo "export PATH=\$PATH:$INSTALL_DIR/bin" >> /etc/profile
source /etc/profile
fi
# ====== 写入配置文件 ======
log_info "写入 mongod.conf 配置..."
cat <<EOF > $INSTALL_DIR/mongod.conf
systemLog:
destination: file
path: $LOG_DIR/mongod.log
logAppend: true
storage:
dbPath: $DATA_DIR
journal:
enabled: true
net:
bindIp: 0.0.0.0
port: 27017
processManagement:
fork: true
pidFilePath: $RUN_DIR/mongod.pid
security:
authorization: $AUTH_ENABLED
EOF
# ====== 创建 systemd 服务文件 ======
log_info "配置 systemd 服务..."
cat <<EOF > /etc/systemd/system/mongodb.service
[Unit]
Description=MongoDB Database Server
Documentation=https://docs.mongodb.org/manual
After=network.target
[Service]
User=$MONGO_USER
Group=$MONGO_GROUP
ExecStart=$INSTALL_DIR/bin/mongod --config=$INSTALL_DIR/mongod.conf
ExecReload=/bin/kill -s HUP \$MAINPID
ExecStop=$INSTALL_DIR/bin/mongod --shutdown --config=$INSTALL_DIR/mongod.conf
Restart=always
RestartSec=10
StartLimitInterval=60
StartLimitBurst=5
LimitNOFILE=64000
LimitNPROC=64000
Environment="MONGODB_CONFIG=$INSTALL_DIR/mongod.conf"
Environment="MONGODB_HOME=$INSTALL_DIR"
Environment="MONGODB_DATA=$DATA_DIR"
Environment="MONGODB_LOG=$LOG_DIR"
RuntimeDirectory=mongodb
RuntimeDirectoryMode=0755
PIDFile=$RUN_DIR/mongod.pid
Type=forking
[Install]
WantedBy=multi-user.target
EOF
# ====== 设置SELinux上下文 ======
if command -v semanage &> /dev/null && command -v restorecon &> /dev/null; then
log_info "配置SELinux上下文..."
semanage fcontext -a -t mongod_var_lib_t "$DATA_DIR(/.*)?" 2>/dev/null || true
semanage fcontext -a -t mongod_log_t "$LOG_DIR(/.*)?" 2>/dev/null || true
semanage fcontext -a -t mongod_var_run_t "$RUN_DIR(/.*)?" 2>/dev/null || true
restorecon -Rv $DATA_DIR $LOG_DIR $RUN_DIR 2>/dev/null || true
fi
# ====== 检查SELinux状态 ======
if command -v getenforce &> /dev/null && [ "$(getenforce)" = "Enforcing" ]; then
log_warn "SELinux处于强制模式,可能需要额外配置"
log_warn "如需临时禁用SELinux,可运行: setenforce 0"
fi
# ====== 启动服务 ======
log_info "启动 MongoDB 服务..."
systemctl daemon-reload
systemctl enable mongodb
# 尝试直接启动MongoDB进程进行测试
log_info "测试启动MongoDB进程..."
sudo -u $MONGO_USER $INSTALL_DIR/bin/mongod --config $INSTALL_DIR/mongod.conf --fork
sleep 3
# 检查MongoDB进程是否运行
if pgrep -f "mongod" > /dev/null; then
log_info "MongoDB 进程启动成功,正在停止测试进程..."
pkill -f "mongod"
sleep 2
else
log_error "MongoDB 进程启动失败,查看日志获取详细信息:"
tail -n 20 $LOG_DIR/mongod.log 2>/dev/null || echo "无法访问日志文件"
exit 1
fi
# 正式启动服务
if systemctl start mongodb; then
sleep 5
# 检查服务状态
if systemctl is-active --quiet mongodb; then
log_info "MongoDB 服务启动成功"
else
log_error "MongoDB 服务启动失败"
journalctl -u mongodb -n 20 --no-pager
log_error "详细日志:"
tail -n 30 $LOG_DIR/mongod.log 2>/dev/null || echo "无法访问日志文件"
exit 1
fi
else
log_error "启动MongoDB服务失败"
journalctl -u mongodb -n 20 --no-pager
log_error "详细日志:"
tail -n 30 $LOG_DIR/mongod.log 2>/dev/null || echo "无法访问日志文件"
exit 1
fi
# ====== 放行防火墙端口 ======
log_info "配置防火墙放行 MongoDB 端口..."
if command -v firewall-cmd &> /dev/null && systemctl is-active --quiet firewalld; then
firewall-cmd --add-port=27017/tcp --permanent
firewall-cmd --reload
log_info "已放行 TCP 27017 端口"
else
log_warn "firewalld 未运行,跳过端口放行"
fi
# ====== 显示最终状态 ======
log_info "MongoDB 服务状态:"
systemctl status mongodb --no-pager -l
log_info "MongoDB 安装完成!"
log_info "安装目录: $INSTALL_DIR"
log_info "数据目录: $DATA_DIR"
log_info "日志目录: $LOG_DIR"
log_info "配置文件: $INSTALL_DIR/mongod.conf"
if [ "$AUTH_ENABLED" = "enabled" ]; then
log_info "认证已启用,管理员账号: admin, 密码: admin123"
else
log_info "认证已禁用,无需账号密码即可连接"
fi
log_info "连接命令: $INSTALL_DIR/bin/mongo"
PostgreSQL脚本
#!/bin/bash
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # 无颜色
# 函数:打印带颜色的消息
print_status() {
echo -e "${BLUE}[INFO]${NC} $1"
}
print_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 函数:检查命令执行结果
check_result() {
if [ $? -eq 0 ]; then
print_success "$1"
else
print_error "$2"
exit 1
fi
}
# 脚本开始
echo -e "${GREEN}"
echo "================================================"
echo " PostgreSQL 17.4 安装脚本"
echo "================================================"
echo -e "${NC}"
# 检查是否以root权限运行
if [ "$EUID" -ne 0 ]; then
print_error "请使用sudo或以root用户运行此脚本"
exit 1
fi
print_status "开始安装 PostgreSQL 17.4..."
# 安装必要依赖
print_status "安装必要依赖包..."
dnf install -y wget tar
check_result "依赖包安装成功" "依赖包安装失败"
# 清理旧数据目录
print_status "清理旧数据目录..."
if [ -d "/opt/pgsql/data" ]; then
rm -rf /opt/pgsql/data
check_result "旧数据目录清理成功" "旧数据目录清理失败"
else
print_warning "旧数据目录不存在,跳过清理"
fi
# 创建 postgres 用户和组
print_status "创建 postgres 用户和组..."
groupadd postgres 2>/dev/null || true
useradd -r -g postgres postgres 2>/dev/null || true
check_result "用户和组创建成功" "用户和组创建失败"
# 下载 PostgreSQL 17.4 源码
print_status "下载 PostgreSQL 17.4 源码..."
if [ ! -f "postgresql-17.4.tar.gz" ]; then
wget https://ftp.postgresql.org/pub/source/v17.4/postgresql-17.4.tar.gz
check_result "源码下载成功" "源码下载失败"
else
print_warning "源码文件已存在,跳过下载"
fi
# 解压源码包
print_status "解压源码包..."
tar -xvzf postgresql-17.4.tar.gz
check_result "源码解压成功" "源码解压失败"
cd postgresql-17.4 || exit 1
# 安装编译依赖
print_status "安装编译依赖..."
dnf groupinstall -y "Development Tools"
dnf install -y readline-devel zlib-devel libicu-devel perl
check_result "编译依赖安装成功" "编译依赖安装失败"
# 配置编译选项
print_status "配置编译选项..."
./configure --prefix=/usr/local/pgsql
check_result "配置成功" "配置失败"
# 编译并安装
print_status "编译 PostgreSQL (这可能需要一段时间)..."
make -j$(nproc)
check_result "编译成功" "编译失败"
print_status "安装 PostgreSQL..."
make install
check_result "安装成功" "安装失败"
# 创建数据目录并设置权限
print_status "创建数据目录并设置权限..."
mkdir -p /opt/pgsql/data
chown -R postgres:postgres /opt/pgsql
check_result "数据目录创建和权限设置成功" "数据目录创建和权限设置失败"
# 初始化数据库
print_status "初始化数据库..."
sudo -u postgres /usr/local/pgsql/bin/initdb -D /opt/pgsql/data
check_result "数据库初始化成功" "数据库初始化失败"
# 设置全局环境变量
print_status "设置环境变量..."
echo 'export PATH=/usr/local/pgsql/bin:$PATH' | tee /etc/profile.d/pgsql.sh
source /etc/profile.d/pgsql.sh
check_result "环境变量设置成功" "环境变量设置失败"
# 修改配置文件允许远程访问
print_status "配置远程访问..."
sudo -u postgres sed -i "s/#listen_addresses = 'localhost'/listen_addresses = '*'/g" /opt/pgsql/data/postgresql.conf
echo "host all all 0.0.0.0/0 md5" | sudo -u postgres tee -a /opt/pgsql/data/pg_hba.conf
check_result "远程访问配置成功" "远程访问配置失败"
# 创建 systemd 服务文件
print_status "创建 systemd 服务..."
tee /etc/systemd/system/postgresql.service > /dev/null <<EOF
[Unit]
Description=PostgreSQL database server
Documentation=man:postgres(1)
After=network.target
[Service]
Type=forking
User=postgres
Group=postgres
ExecStart=/usr/local/pgsql/bin/pg_ctl start -D /opt/pgsql/data -l /opt/pgsql/data/logfile
ExecStop=/usr/local/pgsql/bin/pg_ctl stop -D /opt/pgsql/data
ExecReload=/usr/local/pgsql/bin/pg_ctl reload -D /opt/pgsql/data
PIDFile=/opt/pgsql/data/postmaster.pid
[Install]
WantedBy=multi-user.target
EOF
check_result "systemd服务创建成功" "systemd服务创建失败"
# 重载服务配置并启动
print_status "启动PostgreSQL服务..."
systemctl daemon-reload
systemctl enable postgresql
systemctl restart postgresql
check_result "服务启动成功" "服务启动失败"
# 等待服务启动后设置密码
print_status "设置postgres用户密码..."
for i in {1..5}; do
if sudo -u postgres /usr/local/pgsql/bin/psql -c "ALTER USER postgres WITH PASSWORD 'shangben@123';" 2>/dev/null; then
print_success "密码设置成功"
break
fi
if [ $i -eq 5 ]; then
print_error "密码设置失败,请手动执行: ALTER USER postgres WITH PASSWORD 'shangben@123';"
else
print_warning "密码设置尝试失败 ($i/5),重试中..."
sleep 2
fi
done
# 验证安装
echo -e "\n${GREEN}"
echo "================================================"
echo " 安装完成,正在进行最终验证"
echo "================================================"
echo -e "${NC}"
print_status "检查服务状态..."
systemctl status postgresql --no-pager
echo -e "\n"
print_status "检查数据库连接..."
sudo -u postgres /usr/local/pgsql/bin/psql -c "\l"
echo -e "\n${GREEN}"
echo "================================================"
echo " PostgreSQL 17.4 安装成功完成!"
echo " 连接信息:"
echo " - 用户名: postgres"
echo " - 密码: shangben@123"
echo " - 端口: 5432"
echo "================================================"
echo -e "${NC}"