升级之前,必须做好数据库备份,虚拟机快照
bash
#!/bin/bash
# ============================================================
# 升级之前,必须做好数据库备份,虚拟机快照
# ============================================================
BACKUP_BASE="/backup"
BACKUP_DIR="${BACKUP_BASE}/mysql_config_$(date +%Y%m%d_%H%M%S)"
LOG_FILE="/var/log/mysql_maintenance.log"
CONFIG_PATHS=(
"/etc/my.cnf"
"/etc/mysql/my.cnf"
"/etc/mysql/mysql.conf.d"
"/etc/mysql/conf.d"
"/etc/my.cnf.d"
)
WORK_DIR="/opt/mysql_install"
MYSQL_TAR="mysql-5.7.44-1.el7.x86_64.rpm-bundle.tar"
MYSQL_URL="https://downloads.mysql.com/archives/get/p/23/file/$MYSQL_TAR"
# 设置新密码为固定值
NEW_PASS="123456"
# MySQL 固定导入命令(放前面)
MYSQL_IMPORT_CMD='mysql -uroot -p"123456" mysql < /data/mysql_dump/mysql_20260920.sql'
# ============================================================
# 01bak.sh 逻辑开始
# ============================================================
set -e # 遇到错误立即退出
# ---------- 日志函数 ----------
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}
# ---------- 创建备份目录 ----------
mkdir -p "$BACKUP_DIR"
log "备份目录已创建: $BACKUP_DIR"
# ============================================================
# 3. 备份 MySQL 配置文件
# ============================================================
log "开始备份 MySQL 配置文件..."
for path in "${CONFIG_PATHS[@]}"; do
if [ -e "$path" ]; then
cp -a "$path" "$BACKUP_DIR/"
log "已备份: $path"
fi
done
# 额外备份整个 /etc/mysql 目录(如果存在)
if [ -d "/etc/mysql" ]; then
cp -a /etc/mysql "$BACKUP_DIR/"
log "已备份整个 /etc/mysql 目录"
fi
log "MySQL 配置文件备份完成,位置: $BACKUP_DIR"
# ============================================================
# 4. 停止 MySQL 服务(未检测到服务则跳过,不退出)
# ============================================================
log "正在检测 MySQL 服务名..."
MYSQL_SERVICE=""
if systemctl list-units --full -all 2>/dev/null | grep -q 'mysqld.service'; then
MYSQL_SERVICE="mysqld"
elif systemctl list-units --full -all 2>/dev/null | grep -q 'mysql.service'; then
MYSQL_SERVICE="mysql"
elif systemctl list-units --full -all 2>/dev/null | grep -q 'mariadb.service'; then
MYSQL_SERVICE="mariadb"
else
if service mysql status &>/dev/null; then
MYSQL_SERVICE="mysql"
elif service mysqld status &>/dev/null; then
MYSQL_SERVICE="mysqld"
elif service mariadb status &>/dev/null; then
MYSQL_SERVICE="mariadb"
fi
fi
if [ -z "$MYSQL_SERVICE" ]; then
log "警告: 未找到 MySQL 服务,跳过停止服务与禁用开机自启步骤,继续执行后续安装。"
else
log "检测到 MySQL 服务名为: $MYSQL_SERVICE"
log "正在停止 MySQL 服务..."
if systemctl is-active --quiet "$MYSQL_SERVICE" 2>/dev/null; then
systemctl stop "$MYSQL_SERVICE"
log "MySQL 服务已停止 (systemctl)"
elif service "$MYSQL_SERVICE" status &>/dev/null; then
service "$MYSQL_SERVICE" stop
log "MySQL 服务已停止 (service)"
else
log "MySQL 服务当前未运行或无法停止"
fi
# 验证停止状态
if systemctl is-active --quiet "$MYSQL_SERVICE" 2>/dev/null || service "$MYSQL_SERVICE" status &>/dev/null; then
log "警告: MySQL 服务可能仍在运行,请手动检查!"
else
log "MySQL 服务已成功停止"
fi
fi
# ============================================================
# 5. 关闭 MySQL 开机自动(未检测到服务则跳过)
# ============================================================
log "正在关闭 MySQL 开机自启..."
if [ -z "$MYSQL_SERVICE" ]; then
log "未检测到 MySQL 服务,跳过禁用开机自启步骤"
else
if systemctl list-unit-files 2>/dev/null | grep -q "^${MYSQL_SERVICE}.service"; then
systemctl disable "$MYSQL_SERVICE"
log "已禁用 $MYSQL_SERVICE 开机自启 (systemctl)"
elif command -v chkconfig &>/dev/null && chkconfig --list "$MYSQL_SERVICE" &>/dev/null; then
chkconfig "$MYSQL_SERVICE" off
log "已禁用 $MYSQL_SERVICE 开机自启 (chkconfig)"
elif command -v update-rc.d &>/dev/null; then
update-rc.d "$MYSQL_SERVICE" disable
log "已禁用 $MYSQL_SERVICE 开机自启 (update-rc.d)"
else
log "警告: 无法自动禁用开机自启,请手动检查"
fi
fi
log "01bak.sh 部分执行完成"
# ============================================================
# 02sj.sh 逻辑开始
# ============================================================
# 检查是否以 root 权限运行
if [ "$EUID" -ne 0 ]; then
echo "请以 root 权限运行此脚本。"
exit 1
fi
# 创建工作目录
mkdir -p $WORK_DIR
cd $WORK_DIR || exit
# 检查 tar 文件是否存在,不存在则下载
if [ ! -f "$WORK_DIR/$MYSQL_TAR" ]; then
echo "[信息] 正在下载 MySQL RPM 包..."
wget -O $WORK_DIR/$MYSQL_TAR $MYSQL_URL
if [ $? -ne 0 ]; then
echo "❌ 下载失败,请检查网络连接或 URL 是否有效。"
exit 1
fi
else
echo "✅ 已找到 $MYSQL_TAR,跳过下载步骤。"
fi
echo "[信息] 正在解压 tar 文件..."
tar -xvf $MYSQL_TAR
# 导入 MySQL GPG 密钥(离线环境可跳过,忽略失败)
echo "[信息] 正在导入 MySQL GPG 密钥..."
if ! rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022 2>/dev/null; then
echo "⚠️ GPG 密钥导入失败(可能无外网),跳过,继续本地 RPM 安装。"
fi
# 卸载 mariadb-libs
echo "[信息] 检查并卸载 mariadb-libs..."
if rpm -qa | grep -qw mariadb-libs; then
echo "发现 mariadb-libs,正在卸载..."
yum remove -y mariadb-libs
else
echo "未发现 mariadb-libs,跳过卸载步骤。"
fi
# 安装依赖项
echo "[信息] 安装依赖:libaio、perl、net-tools、perl-Data-Dumper、perl-JSON ..."
yum install -y libaio perl net-tools perl-Data-Dumper perl-JSON
# 安装 MySQL 基础包(跳过签名校验,避免离线环境报错)
echo "[信息] 正在安装 MySQL 5.7 的基础 RPM 包..."
for pkg in mysql-community-common mysql-community-libs mysql-community-client mysql-community-server; do
rpm_file=$(ls ${pkg}-*.rpm)
echo "正在安装 $rpm_file ..."
rpm -ivh --nodigest --nosignature $rpm_file
done
# 初始化数据库
echo "[信息] 初始化 MySQL 数据库..."
mysqld --initialize --user=mysql
# 获取临时密码(可选)------ 加 || true 防止 grep 未匹配时因 set -e 退出
TEMP_PASS=$(grep 'temporary password' /var/log/mysqld.log | awk '{print $NF}' || true)
if [ -n "$TEMP_PASS" ]; then
echo "[信息] MySQL 初始临时密码为:$TEMP_PASS"
else
echo "警告: 未找到初始临时密码,请确认是否已正确初始化数据库或手动设置root密码。"
fi
# 启动 MySQL 服务
echo "⚙️ 启动 MySQL 服务..."
systemctl enable mysqld
systemctl start mysqld
# 检查状态(加 || true 防止 status 返回非零导致 set -e 退出)
systemctl status mysqld || true
# 自动登录 MySQL 并修改 root 密码及授权 root@%
if [ -n "$TEMP_PASS" ]; then
echo "[信息] 正在修改 MySQL root 用户的密码为 $NEW_PASS 并授权 root@% ..."
mysql --connect-expired-password -u root -p"$TEMP_PASS" << EOF
ALTER USER 'root'@'localhost' IDENTIFIED BY '$NEW_PASS';
CREATE USER IF NOT EXISTS 'root'@'%' IDENTIFIED BY '$NEW_PASS';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
EOF
if [ $? -eq 0 ]; then
echo "✅ 成功修改 MySQL root 用户的密码并授权 root@%。"
else
echo "❌ 修改 MySQL root 用户的密码或授权失败。请检查 MySQL 日志获取更多信息。"
exit 1
fi
else
echo "由于没有获取到临时密码,无法自动修改 MySQL root 用户的密码或授权,请手动进行修改和授权。"
fi
# 开启3306端口
echo "[信息] 正在开启防火墙中的3306端口..."
if systemctl is-active --quiet firewalld; then
firewall-cmd --zone=public --add-port=3306/tcp --permanent
firewall-cmd --reload
echo "✅ 防火墙中的3306端口已开启。"
else
echo "警告: firewalld 服务未运行,无法自动开启3306端口。请手动配置防火墙。"
fi
echo "✅ MySQL 5.7 安装完成!"
echo "你可以使用以下命令从其他主机登录 MySQL:"
echo "mysql -h your_server_ip -u root -p"
# ============================================================
# 03导入.txt 逻辑开始
# ============================================================
echo "[信息] 执行 MySQL 固定导入命令..."
eval "$MYSQL_IMPORT_CMD"