当前位置: 首页 > news >正文

MySQL一键升级脚本(5.7-8.0)

在这里插入图片描述
在这里插入图片描述

脚本内容:

#!/bin/bash
# Description: This script is designed to upgrade MySQL 5.7 to MySQL 8.0 (Binary Package Installation)
# Date: 2025-10-22
# ========================================================================
# Precautions before use:
# 1. Test in non-production environment first
# 2. Ensure complete database backup (data directory + logical backup)
# 3. Check application compatibility with MySQL 8.0
# 4. Execute as root user
# ========================================================================
# How to use:
# 1. chmod +x upgrade_mysql80_binary.sh
# 2. ./upgrade_mysql80_binary.sh
# ========================================================================set -e# ==============================================
# 请根据实际环境修改以下配置(二进制包安装相关路径)
# ==============================================
MYSQL_57_BASE_DIR="/usr/local/mysql"  # 5.7二进制安装根目录
MYSQL_DATA_DIR="/data/mysql"  # 数据目录(通常在安装目录下)
MYSQL_80_TAR_PATH="/opt/mysql-8.0.42-linux-glibc2.17-x86_64.tar.xz"  # 8.0二进制包路径
MYSQL_80_BASE_DIR="/usr/local/mysql-8.0"  # 8.0安装目录
MYSQL_SOFT_LINK="/usr/local/mysql"  # 软链接路径(指向当前版本)
MYSQL_CONF="/etc/my.cnf"  # 配置文件路径
MYSQL_USER="mysql"  # 运行MySQL的系统用户
MYSQL_GROUP="mysql"  # 运行MySQL的系统组
MYSQL_ROOT_USER="root"  # 数据库root用户
# ==============================================# 其他关键配置
BACKUP_DIR="/var/backups/mysql_upgrade"
LOG_FILE="/var/log/mysql_upgrade_$(date +%Y%m%d%H%M).log"
SERVICE_SCRIPT="${MYSQL_SOFT_LINK}/support-files/mysql.server"  # 二进制包自带的服务脚本# 颜色代码
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m'  # No Color# 步骤0:初始化日志
exec > >(tee -a "$LOG_FILE") 2>&1
echo -e "${YELLOW}[0/13] 开始MySQL二进制包升级流程 $(date)${NC}"# 确认继续操作
confirm_continue() {read -p "$1 (y/n)? " choicecase "$choice" iny|Y) echo -e "${GREEN} 继续执行...${NC}";;*)   echo -e "${YELLOW} 操作已取消${NC}"; exit 1;;esac
}# 获取MySQL root密码
get_mysql_password() {if [ -z "$MYSQL_ROOT_PASS" ]; thenread -s -p "输入MySQL root密码: " MYSQL_ROOT_PASSechofi
}# 验证二进制包文件
verify_80_tar() {if [ ! -f "$MYSQL_80_TAR_PATH" ]; thenecho -e "${RED} 错误:MySQL 8.0二进制包不存在($MYSQL_80_TAR_PATH${NC}"exit 1fi
# 验证文件格式(是否为tar.xz)if ! file "$MYSQL_80_TAR_PATH" | grep -q "XZ compressed data"; thenecho -e "${RED} 错误:文件不是有效的xz压缩包($MYSQL_80_TAR_PATH${NC}"exit 1
fi
}# 步骤1: 验证当前用户(必须为root)
echo -e "${YELLOW}[1/13] 验证执行用户${NC}"
if [ "$(id -u)" -ne 0 ]; thenecho -e "${RED} 错误:此脚本必须以root权限运行!${NC}"exit 1
fi
echo -e "${GREEN} 执行用户验证通过${NC}"# 步骤2: 验证当前MySQL版本(必须为5.7)
echo -e "${YELLOW}[2/13] 检查当前MySQL版本${NC}"
MYSQL_57_BIN="${MYSQL_57_BASE_DIR}/bin/mysql"
if [ ! -f "$MYSQL_57_BIN" ]; thenecho -e "${RED} 错误:未找到MySQL 5.7二进制文件($MYSQL_57_BIN${NC}"exit 1
fi
CURRENT_VERSION=$("$MYSQL_57_BIN" -V 2>&1 | awk '{print $5}' | tr -d ,)
if [[ ! "$CURRENT_VERSION" =~ 5\.7 ]]; thenecho -e "${RED} 错误:当前MySQL版本($CURRENT_VERSION)不是5.7,终止升级!${NC}"exit 1
fi
echo -e "${GREEN} 当前版本验证通过: $CURRENT_VERSION${NC}"# 步骤3: 完整数据库备份(逻辑备份+数据目录备份)
echo -e "${YELLOW}[3/13] 执行全量备份${NC}"
mkdir -p "$BACKUP_DIR"
get_mysql_password# 逻辑备份(使用5.7的mysqldump)
echo -e "${YELLOW} 执行逻辑备份(全库+存储过程+事件)...${NC}"
MYSQLDUMP_57="${MYSQL_57_BASE_DIR}/bin/mysqldump"
"$MYSQLDUMP_57" -u"$MYSQL_ROOT_USER" -p"$MYSQL_ROOT_PASS" \--all-databases --routines --events --single-transaction > \"$BACKUP_DIR/full_backup_$(date +%F).sql"
if [ $? -eq 0 ]; thenecho -e "${GREEN} 逻辑备份成功: $BACKUP_DIR/full_backup_$(date +%F).sql${NC}"
elseecho -e "${RED} 错误:逻辑备份失败!${NC}"exit 1
fi# 数据目录备份(物理备份)
echo -e "${YELLOW} 执行数据目录备份...${NC}"
DATA_BACKUP_DIR="${BACKUP_DIR}/mysql_data_57_$(date +%s)"
cp -a "$MYSQL_DATA_DIR" "$DATA_BACKUP_DIR"
echo -e "${GREEN} 数据目录备份成功: $DATA_BACKUP_DIR${NC}"# 步骤4: 停止MySQL 5.7服务
echo -e "${YELLOW}[4/13] 停止MySQL 5.7服务${NC}"
if [ -f "$SERVICE_SCRIPT" ]; then# 执行停止命令"$SERVICE_SCRIPT" stop# 等待2秒,确保进程有足够时间退出(解决短暂延迟问题)sleep 2# 验证是否停止成功:优先检查PID文件(服务正常停止会删除PID文件)# 从服务脚本中提取PID文件路径(通常在my.cnf或服务脚本中定义)PID_FILE=$("$SERVICE_SCRIPT" status | grep "PID file" | awk -F'[()]' '{print $2}')# 若服务脚本中未提取到PID文件,使用默认路径(可根据实际环境调整)if [ -z "$PID_FILE" ]; thenPID_FILE="${MYSQL_DATA_DIR}/$(hostname).pid"fi# 检查进程和PID文件双重验证if pgrep -u "$MYSQL_USER" -f "^${MYSQL_57_BASE_DIR}/bin/mysqld$" >/dev/null || [ -f "$PID_FILE" ]; thenecho -e "${RED} 错误:MySQL 5.7服务停止失败,强制终止进程...${NC}"pkill -u "$MYSQL_USER" -f "^${MYSQL_57_BASE_DIR}/bin/mysqld$"# 强制终止后再次检查if pgrep -u "$MYSQL_USER" -f "^${MYSQL_57_BASE_DIR}/bin/mysqld$" >/dev/null; thenecho -e "${RED} 错误:强制终止失败,请手动检查进程!${NC}"exit 1fifiecho -e "${GREEN} MySQL 5.7服务已停止${NC}"
elseecho -e "${RED} 错误:未找到服务脚本($SERVICE_SCRIPT${NC}"exit 1
fi# 步骤5: 备份5.7配置和二进制目录
echo -e "${YELLOW}[5/13] 备份MySQL 5.7安装目录${NC}"
MV_57_DIR="${MYSQL_57_BASE_DIR}_57_backup_$(date +%s)"
mv "$MYSQL_57_BASE_DIR" "$MV_57_DIR"
echo -e "${GREEN} 5.7安装目录已备份至: $MV_57_DIR${NC}"# 步骤6: 安装MySQL 8.0二进制包
echo -e "${YELLOW}[6/13] 安装MySQL 8.0二进制包${NC}"
verify_80_tar# 解压二进制包(用tar xJf简化格式,-C指定目标父目录)
echo -e "${YELLOW} 解压MySQL 8.0二进制包...${NC}"
mkdir -p "$(dirname "$MYSQL_80_BASE_DIR")"
# 执行解压(x=解压,J=xz格式,f=指定文件,C=指定解压到的父目录)
tar xJf "$MYSQL_80_TAR_PATH" -C "$(dirname "$MYSQL_80_BASE_DIR")"# 精准获取解压后的主目录名(tar -tf仅列出压缩包内容,无多余日志)
TAR_EXTRACT_DIR=$(tar -tf "$MYSQL_80_TAR_PATH" | head -1 | cut -d/ -f1)
TAR_EXTRACT_FULL_PATH="$(dirname "$MYSQL_80_BASE_DIR")/$TAR_EXTRACT_DIR"# 验证解压目录存在性,避免空路径错误
if [ ! -d "$TAR_EXTRACT_FULL_PATH" ]; thenecho -e "${RED} 错误:未找到解压后的目录($TAR_EXTRACT_FULL_PATH${NC}"exit 1
fi# 重命名解压目录(统一为配置的MYSQL_80_BASE_DIR路径)
mv "$TAR_EXTRACT_FULL_PATH" "$MYSQL_80_BASE_DIR"# 创建软链接(指向8.0版本)
ln -snf "$MYSQL_80_BASE_DIR" "$MYSQL_SOFT_LINK"
echo -e "${GREEN} 8.0二进制包安装完成,软链接: $MYSQL_SOFT_LINK -> $MYSQL_80_BASE_DIR${NC}"# 步骤7: 调整权限(关键!二进制包依赖mysql用户权限)
echo -e "${YELLOW}[7/13] 配置目录权限${NC}"
# 确保mysql用户组存在
if ! id -u "$MYSQL_USER" >/dev/null 2>&1; thengroupadd "$MYSQL_GROUP"useradd -r -g "$MYSQL_GROUP" "$MYSQL_USER"
fi
# 递归设置权限(数据目录+安装目录)
chown -R "$MYSQL_USER:$MYSQL_GROUP" "$MYSQL_80_BASE_DIR"
chown -R "$MYSQL_USER:$MYSQL_GROUP" "$MYSQL_DATA_DIR"  # 数据目录保留原数据
chmod -R 755 "$MYSQL_80_BASE_DIR"
echo -e "${GREEN} 权限配置完成${NC}"# 步骤8: 调整配置文件(适配8.0兼容参数)
echo -e "${YELLOW}[8/13] 调整my.cnf配置(兼容8.0)${NC}"
# 备份原配置
cp "$MYSQL_CONF" "${MYSQL_CONF}_57_backup"# 添加/修改8.0兼容参数(关键:解决认证插件和语法兼容问题)
# 1. 禁用query_cache(8.0已移除)
sed -i '/query_cache/d' "$MYSQL_CONF"
# 2. 设置默认认证插件为5.7兼容模式(避免应用连接失败)
if ! grep -q "default_authentication_plugin" "$MYSQL_CONF"; thensed -i '/\[mysqld\]/a default_authentication_plugin=mysql_native_password' "$MYSQL_CONF"
elsesed -i 's/default_authentication_plugin=.*/default_authentication_plugin=mysql_native_password/' "$MYSQL_CONF"
fi
# 3. 移除8.0不支持的参数(如sql_mode中的NO_AUTO_CREATE_USER)
sed -i 's/NO_AUTO_CREATE_USER//' "$MYSQL_CONF"echo -e "${GREEN} 配置文件调整完成${NC}"# 步骤9: 启动MySQL 8.0并升级系统表
echo -e "${YELLOW}[9/13] 启动MySQL 8.0并升级系统表${NC}"
# 启动8.0服务(使用二进制包自带的服务脚本)
NEW_SERVICE_SCRIPT="${MYSQL_SOFT_LINK}/support-files/mysql.server"
"$NEW_SERVICE_SCRIPT" start
sleep 5  # 等待服务启动# 验证启动状态
if ! pgrep -f "/usr/local/mysql/bin/mysqld" >/dev/null; thenecho -e "${RED} 错误:MySQL 8.0启动失败,请检查日志(${MYSQL_DATA_DIR}/error.err)${NC}"exit 1
fi# 步骤9.1: 验证服务器自动升级是否成功(核心判断)
echo -e "${YELLOW} 验证数据目录自动升级结果...${NC}"
ERROR_LOG="${MYSQL_DATA_DIR}/mysql.err"
sleep 5  # 等待日志写入# 匹配日志中"从50700升级到80042(或其他8.0.x版本)并完成"的记录,包含关键事件码MY-013381
if grep -q "MY-013381.*Server upgrade from '50700' to '8[0-9]*' completed" "$ERROR_LOG"; thenecho -e "${GREEN} 数据目录自动升级成功(日志验证通过)${NC}"
elseif grep -q "MY-013381.*Server upgrade.*failed" "$ERROR_LOG"; thenecho -e "${RED} 错误:数据目录升级失败,日志详情:${NC}"grep "MY-013381.*upgrade.*failed" "$ERROR_LOG"elseecho -e "${RED} 错误:未在日志中找到升级完成标志,请检查错误日志:$ERROR_LOG ${NC}"# 输出日志中升级相关记录,方便排查echo -e "${YELLOW} 日志中升级相关记录:${NC}"grep -i "upgrade" "$ERROR_LOG"fiexit 1
fi# 步骤10: 重置root密码(处理8.0密码加密方式)
echo -e "${YELLOW}[10/13] 重置root密码(适配8.0加密)${NC}"# 【新增代码】定义MySQL 8.0客户端二进制文件路径(关键修复)
MYSQL_80_BIN="${MYSQL_SOFT_LINK}/bin/mysql"# 可选:手动指定socket路径(若默认路径不匹配,可从my.cnf中查socket参数)
MYSQL_SOCKET=$(grep "socket" "$MYSQL_CONF" | grep -v "#" | awk -F'=' '{gsub(/ /,"",$2);print $2}')# 颜色代码(注:此处颜色代码重复定义,可删除以精简,不影响功能)
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m'MYSQL_ROOT_PASS="123123"# 步骤1:检查并添加免密配置
echo -e "${YELLOW}1/6 检查免密配置(skip-grant-tables)...${NC}"
if ! grep -q "skip-grant-tables" "$MYSQL_CONF"; thensed -i '/\[mysqld\]/a skip-grant-tables' "$MYSQL_CONF"echo -e "${YELLOW}  已添加免密配置${NC}"
elseecho -e "${GREEN}  免密配置已存在${NC}"
fi# 步骤2:重启MySQL服务
echo -e "${YELLOW}2/6 重启MySQL服务...${NC}"
"$NEW_SERVICE_SCRIPT" stop >/dev/null 2>&1
"$NEW_SERVICE_SCRIPT" start
sleep 5# 步骤3:查询实际root用户(获取真实host)
echo -e "${YELLOW}3/6 查询实际root用户...${NC}"
ROOT_USERS=$("$MYSQL_80_BIN" -u"$MYSQL_ROOT_USER" -Nse "SELECT host FROM mysql.user WHERE user='$MYSQL_ROOT_USER';")
if [ -z "$ROOT_USERS" ]; thenecho -e "${RED}  错误:未查询到root用户!${NC}"sed -i '/skip-grant-tables/d' "$MYSQL_CONF""$NEW_SERVICE_SCRIPT" restartexit 1
fi
echo -e "${GREEN}  查询到root用户的host:${NC}"
echo "$ROOT_USERS" | while read -r host; do echo "    - $host"; done# 步骤4:重置root密码(针对所有真实host)
echo -e "${YELLOW}4/6 重置root密码...${NC}"
SQL="FLUSH PRIVILEGES;"
while read -r host; doSQL+="ALTER USER '$MYSQL_ROOT_USER'@'$host' IDENTIFIED WITH mysql_native_password BY '$MYSQL_ROOT_PASS';"
done <<< "$ROOT_USERS"
SQL+="FLUSH PRIVILEGES;""$MYSQL_80_BIN" -u"$MYSQL_ROOT_USER" -e "$SQL" 2>&1
if [ $? -eq 0 ]; thenecho -e "${GREEN}  密码重置成功(新密码:$MYSQL_ROOT_PASS${NC}"
elseecho -e "${RED}  错误:密码重置失败!SQL:$SQL${NC}"sed -i '/skip-grant-tables/d' "$MYSQL_CONF""$NEW_SERVICE_SCRIPT" restartexit 1
fi# 步骤5:移除免密配置并重启
echo -e "${YELLOW}5/6 移除免密配置并重启服务...${NC}"
sed -i '/skip-grant-tables/d' "$MYSQL_CONF"
"$NEW_SERVICE_SCRIPT" stop >/dev/null 2>&1
"$NEW_SERVICE_SCRIPT" start
sleep 5echo -e "${GREEN} root密码重置完成${NC}"# 步骤11: 验证MySQL 8.0版本
echo -e "${YELLOW}[11/13] 验证升级后版本${NC}"
# 用正则匹配提取版本号(匹配Ver后的数字版本,如8.0.42)
NEW_VERSION=$("$MYSQL_80_BIN" -V 2>&1 | grep -oP '(?<=Ver )\d+\.\d+\.\d+')
if [[ "$NEW_VERSION" =~ 8\.0 ]]; thenecho -e "${GREEN} 版本验证通过:$NEW_VERSION${NC}"
elseecho -e "${RED} 错误:升级后版本不是8.0(当前:$NEW_VERSION${NC}"exit 1
fi# 步骤12: 验证数据库可用性
echo -e "${YELLOW}[12/13] 验证数据库连接${NC}"
"$MYSQL_80_BIN" -u"$MYSQL_ROOT_USER" -p"$MYSQL_ROOT_PASS" -e "SELECT VERSION();" >/dev/null
if [ $? -eq 0 ]; thenecho -e "${GREEN} 数据库连接成功,升级后可用${NC}"
elseecho -e "${RED} 错误:无法连接升级后的数据库!${NC}"exit 1
fi# 步骤13: 升级完成提示
echo -e "${YELLOW}[13/13] 升级流程结束${NC}"
echo -e "${GREEN}====================================================${NC}"
echo -e "${GREEN} MySQL 5.7 -> 8.0 二进制包升级成功!${NC}"
echo -e "${GREEN}====================================================${NC}"
echo "关键信息:"
echo "1. 备份文件路径:$BACKUP_DIR"
echo "2. 升级日志:$LOG_FILE"
echo "3. 8.0安装目录:$MYSQL_80_BASE_DIR"
echo "4. 建议操作:"
echo "   - 验证应用连接(注意认证插件兼容性)"
echo "   - 检查错误日志:${MYSQL_DATA_DIR}/error.log"
echo "   - 必要时优化8.0新特性(如innodb_dedicated_server)"
http://www.dtcms.com/a/519355.html

相关文章:

  • 销售网站建设工资多少绿色主色调网站
  • 应用层网络协议深度解析:设计、实战与安全
  • C++:类和对象_bite
  • SQL之键与约束
  • 【vTESTstudio开发教程】--- 如何添加测试用例List
  • SpringBoot-Web开发之内容协商
  • 实现一个JSON工具类自动处理JSON转String
  • 域名注册网站那个好企业服务官网
  • SpringBoot-数据访问之MyBatis与Redis
  • iOS 26 App 运行状况全面解析 多工具协同监控与调试实战指南
  • uts ios插件开发tips
  • 单页营销型网站全国城建中心官方网站
  • 了解sip和rtp是什么
  • MySQL-3-函数应用及多表查询
  • 自然语言处理分享系列-词语和短语的分布式表示及其组合性(二)
  • 网站建设珠海 新盈科技泉州建站模板
  • ISO 8601日期时间标准及其在JavaScript、SQLite与MySQL中的应用解析
  • 利用博客做网站排名南京外贸网站建设案例
  • 使用 VS Code 的 Dev Containers 插件,通过跳板机间接连接docker
  • 衡水城乡建设局网站首页北京网站建设华大
  • 湛江网站建设哪家优惠多常见的网站结构有哪些
  • php网站源码架构seo标题生成器
  • ui设计师与网站编辑有什么关系重庆森林为什么不能看
  • 站长工具成品源码广西贵港建设集团有限公司网站
  • 电子商务网站建设技术解决方案wordpress ios
  • 企业是如何做电子商务网站软件开发培训机构去学
  • 摄影网站策划书wordpress 赞 分享
  • 深圳我的网站深圳市工程交易服务网宝安
  • php制作wap网站开发我国酒店网站建设存在的问题
  • 金坛网站建设企业手机网站建设渠道