一、脚本清单与定位¶
1.1 目录中的主要文件¶
mysql_single_instance_5.6-8.0_install_uninstall.sh:单实例版本管理脚本。mysql_multi_instance_5.6-8.0_install_uninstall.sh:多实例版本管理脚本。脚本说明.txt:给出了多实例和单实例的登录命令示例。
1.2 这组脚本的共同价值¶
- 同一套目录支持多版本切换。
- 自动完成解压、初始化、配置文件生成和 systemd 服务注册。
- 安装失败时会输出日志,便于定位问题。
二、单实例脚本整理¶
2.1 安装流程¶
precheck
install_mysql "8.0" "mysql-8.0"
cat > /etc/my.cnf <<EOF
[mysql]
socket=/tmp/mysql.sock
[mysqld]
user=mysql
port=3306
socket=/tmp/mysql.sock
basedir=/usr/local/mysql
datadir=/data/mysql/data
server_id=1
EOF
2.2 脚本里值得保留的细节¶
- 通过
systemctl is-active阻止重复安装。 - 通过等待 socket 文件出现来确认实例真的启动完成。
- 根据 5.6、5.7、8.0 的差异切换不同的初始化和改密方式。
三、多实例脚本整理¶
3.1 多实例的核心变量¶
service_name="mysqld${port}"
base_dir="/usr/local/mysql${version_suffix}"
data_dir="/data/${port}/data"
socket_path="/tmp/mysql${port}.sock"
3.2 多实例的典型配置方式¶
cat > "${data_dir}/my.cnf" <<EOF
[mysql]
socket=${socket_path}
[mysqld]
user=mysql
port=${port}
socket=${socket_path}
basedir=${base_dir}
datadir=${data_dir}
server_id=${port}
EOF
3.3 目录说明文件中给出的登录方式¶
mysql5.6 -uroot -p<your-password> -S /tmp/mysql3356.sock
mysql5.7 -uroot -p<your-password> -S /tmp/mysql3357.sock
mysql8.0 -uroot -p<your-password> -S /tmp/mysql3306.sock
mysql -uroot -p<your-password>
四、发布前的整理建议¶
4.1 需要补充的说明¶
- 安装包需要提前放到
/usr/local,这一点建议写成“环境准备”章节。 userdel -r mysql这类卸载动作要写明风险,避免误删共享用户。- 默认密码不要直接发布,建议改成交互输入或环境变量。
五、完整脚本¶
以下为本文对应的完整脚本,便于直接复制复用。
5.1 mysql_single_instance_5.6-8.0_install_uninstall.sh¶
#!/bin/bash
##############################################################
# File Name: install_uninstall_mysql.sh
# Version: V1.2
# Author: zq
# Organization: www.zhang-qing.com
# Desc: 单实例MySQL版本管理脚本(支持5.6/5.7/8.0切换)
##############################################################
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m'
# 全局常量
MYSQL_BASE_DIR="/usr/local/mysql"
MYSQL_DATA_DIR="/data/mysql/data"
SOCKET_PATH="/tmp/mysql.sock"
SERVICE_NAME="mysqld"
# 预检查函数
precheck() {
# 检查是否已存在运行中的实例
if systemctl is-active "${SERVICE_NAME}" &>/dev/null; then
echo -e "${RED}发现正在运行的MySQL服务,请先卸载当前版本!${NC}"
return 1
fi
# 检查残留文件
if [ -L "${MYSQL_BASE_DIR}" ] || [ -d "${MYSQL_DATA_DIR}" ]; then
echo -e "${RED}发现残留的MySQL文件,请先清理!${NC}"
return 1
fi
return 0
}
# 安装函数
install_mysql() {
local version=$1
local package_prefix=$2
echo -e "${YELLOW}开始安装MySQL ${version}...${NC}"
# 预检查
if ! precheck; then
return 1
fi
# 步骤1:检查安装包
local pkg_file=$(ls /usr/local/${package_prefix}* 2>/dev/null | head -1)
if [ -z "${pkg_file}" ]; then
echo -e "${RED}未找到${package_prefix}开头的安装包${NC}"
return 1
fi
# 步骤2:解压并创建软链接
echo "解压安装包并创建软链接..."
tar -xf "${pkg_file}" -C /usr/local
local extracted_dir=$(tar tf "${pkg_file}" | head -1 | cut -d/ -f1)
ln -sfn "/usr/local/${extracted_dir}" "${MYSQL_BASE_DIR}"
# 步骤3:创建用户和目录
echo "初始化系统环境..."
id mysql &>/dev/null || useradd -r -s /sbin/nologin mysql
mkdir -p "${MYSQL_DATA_DIR}" "/data/mysql/logs"
chown -R mysql:mysql /data
# 步骤4:初始化数据库
echo "执行数据库初始化..."
case $version in
8*)
"${MYSQL_BASE_DIR}/bin/mysqld" --initialize-insecure --user=mysql \
--basedir="${MYSQL_BASE_DIR}" --datadir="${MYSQL_DATA_DIR}" >/dev/null 2>&1
password_cmd="ALTER USER root@'localhost' IDENTIFIED BY '123456';"
;;
5.7*)
"${MYSQL_BASE_DIR}/bin/mysqld" --initialize-insecure --user=mysql \
--basedir="${MYSQL_BASE_DIR}" --datadir="${MYSQL_DATA_DIR}" >/dev/null 2>&1
password_cmd="UPDATE mysql.user SET authentication_string=PASSWORD('123456') WHERE user='root';"
;;
5.6*)
"${MYSQL_BASE_DIR}/scripts/mysql_install_db" --user=mysql \
--basedir="${MYSQL_BASE_DIR}" --datadir="${MYSQL_DATA_DIR}" >/dev/null 2>&1
password_cmd="SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123456');"
;;
esac
# 步骤5:创建配置文件
echo "生成配置文件..."
cat > /etc/my.cnf <<EOF
[mysql]
socket=${SOCKET_PATH}
[mysqld]
user=mysql
port=3306
socket=${SOCKET_PATH}
basedir=${MYSQL_BASE_DIR}
datadir=${MYSQL_DATA_DIR}
server_id=1
EOF
# 步骤6:配置systemd服务
echo "设置系统服务..."
cat > /usr/lib/systemd/system/${SERVICE_NAME}.service <<EOF
[Unit]
Description=MySQL Server
After=network.target
[Service]
User=mysql
Group=mysql
ExecStart=${MYSQL_BASE_DIR}/bin/mysqld --defaults-file=/etc/my.cnf
ExecStop=${MYSQL_BASE_DIR}/bin/mysqladmin shutdown
LimitNOFILE=5000
[Install]
WantedBy=multi-user.target
EOF
# 步骤7:启动服务
systemctl daemon-reload
if ! systemctl start mysqld; then
echo -e "${RED}服务启动失败!${NC}"
journalctl -u mysqld -n 20 --no-pager
return 1
fi
# 新增socket文件等待逻辑
echo -n "等待MySQL启动..."
local timeout=30
while [ ! -S "${SOCKET_PATH}" ] && [ $timeout -gt 0 ]; do
sleep 1
echo -n "."
timeout=$((timeout-1))
done
echo
if [ ! -S "${SOCKET_PATH}" ]; then
echo -e "${RED}错误:等待socket文件超时(${SOCKET_PATH})${NC}"
journalctl -u mysqld -n 20 --no-pager
return 1
fi
# 步骤8:设置root密码
echo "配置root账户..."
local retries=3
for ((i=1; i<=retries; i++)); do
if "${MYSQL_BASE_DIR}/bin/mysql" -uroot -S "${SOCKET_PATH}" --connect-timeout=10 <<EOF
${password_cmd};
FLUSH PRIVILEGES;
EOF
then
break
fi
if [ $i -eq $retries ]; then
echo -e "${RED}密码设置失败!请手动执行:${NC}"
echo "mysql -uroot -S ${SOCKET_PATH}"
return 1
fi
sleep 2
done
# 创建快捷命令
ln -sf "${MYSQL_BASE_DIR}/bin/mysql" /usr/local/bin/mysql
echo -e "${GREEN}MySQL ${version} 安装成功!${NC}"
}
# 卸载函数
uninstall_mysql() {
echo -e "${YELLOW}开始卸载MySQL...${NC}"
systemctl stop "${SERVICE_NAME}" 2>/dev/null
systemctl disable "${SERVICE_NAME}" 2>/dev/null
# 清理文件
rm -rf "${MYSQL_DATA_DIR}" /etc/my.cnf
find /usr/local -maxdepth 1 -type d -name "mysql-*" -exec rm -rf {} +
rm -f "${MYSQL_BASE_DIR}" /usr/local/bin/mysql
# 清理systemd配置
rm -f "/usr/lib/systemd/system/${SERVICE_NAME}.service"
systemctl daemon-reload
echo -e "${GREEN}MySQL 卸载完成!${NC}"
}
# 菜单系统
main_menu() {
while :; do
clear
echo -e "MySQL版本管理菜单"
echo "1. 安装MySQL 8.0"
echo "2. 安装MySQL 5.7"
echo "3. 安装MySQL 5.6"
echo "4. 卸载当前MySQL"
echo "0. 退出"
read -p "请选择: " choice
case $choice in
1) install_mysql "8.0" "mysql-8.0" ;;
2) install_mysql "5.7" "mysql-5.7" ;;
3) install_mysql "5.6" "mysql-5.6" ;;
4) uninstall_mysql ;;
0) exit 0 ;;
*) echo -e "${RED}无效选项!${NC}"; sleep 1 ;;
esac
read -n 1 -p "按任意键继续..."
done
}
# 执行入口
main_menu
5.2 mysql_multi_instance_5.6-8.0_install_uninstall.sh¶
#!/bin/bash
##############################################################
# File Name:install_uninstall_myqsl56_57_8.sh
# Version:V1.0
# Author:zq
# Organization:www.zhang-qing.com
# Desc: 二进制多实例MySQL版本管理脚本(支持5.6/5.7/8.0切换)
##############################################################
# 通用颜色设置
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m'
# 通用确认函数
confirm_operation() {
read -p "是否继续?(y/n): " choice
case "$choice" in
y|Y) return 0 ;;
*) echo "操作已取消"; return 1 ;;
esac
}
# 安装函数
install_mysql() {
local version=$1
local package_prefix=$2
local port=$3
local version_suffix=$4
local service_name="mysqld${port}"
local base_dir="/usr/local/mysql${version_suffix}"
local data_dir="/data/${port}/data"
local socket_path="/tmp/mysql${port}.sock"
echo -e "${YELLOW}开始安装MySQL ${version}...${NC}"
# 步骤1:检查安装包
local pkg_file=$(ls /usr/local/${package_prefix}* 2>/dev/null | head -1)
if [ -z "${pkg_file}" ]; then
echo -e "${RED}未找到${package_prefix}开头的安装包,请上传到/usr/local目录${NC}"
return 1
fi
# 步骤2:解压安装包(保留目录结构)
echo "解压安装包..."
cd /usr/local && tar xf "${pkg_file}"
local extracted_dir=$(tar tf "${pkg_file}" | head -1 | cut -d/ -f1)
# 步骤3:创建软链接
echo "创建软链接:${base_dir} -> ${extracted_dir}"
ln -sf "/usr/local/${extracted_dir}" "${base_dir}"
# 步骤4:创建用户和目录
echo "创建用户和目录..."
id mysql &> /dev/null || useradd -r -s /sbin/nologin mysql
mkdir -p "${data_dir}" "/data/${port}/logs"
chown -R mysql:mysql /data
# 步骤5:初始化数据库
echo "初始化数据库..."
if [ -n "$(ls -A "${data_dir}")" ]; then
echo "发现已有数据,清理目录..."
rm -rf "${data_dir}"/*
fi
case $version in
8*)
"${base_dir}/bin/mysqld" --initialize-insecure --user=mysql \
--basedir="${base_dir}" --datadir="${data_dir}" 2>/dev/null
password_cmd="ALTER USER root@'localhost' IDENTIFIED BY '123456';"
;;
5.7*)
"${base_dir}/bin/mysqld" --initialize-insecure --user=mysql \
--basedir="${base_dir}" --datadir="${data_dir}" 2>/dev/null
password_cmd="UPDATE mysql.user SET authentication_string=PASSWORD('123456') WHERE user='root';"
;;
5.6*)
"${base_dir}/scripts/mysql_install_db" --user=mysql \
--basedir="${base_dir}" --datadir="${data_dir}" 2>/dev/null
password_cmd="SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123456');"
;;
esac
# 步骤6:创建配置文件
echo "创建配置文件..."
cat > "${data_dir}/my.cnf" <<EOF
[mysql]
socket=${socket_path}
[mysqld]
user=mysql
port=${port}
socket=${socket_path}
basedir=${base_dir}
datadir=${data_dir}
server_id=${port}
innodb_fast_shutdown=0
EOF
# 步骤7:创建systemd服务
echo "创建systemd服务..."
cat > "/usr/lib/systemd/system/${service_name}.service" <<EOF
[Unit]
Description=MySQL ${version} Server
After=network.target
[Service]
User=mysql
Group=mysql
ExecStart=${base_dir}/bin/mysqld --defaults-file=${data_dir}/my.cnf
ExecStop=${base_dir}/bin/mysqladmin --defaults-file=${data_dir}/my.cnf shutdown
ExecReload=${base_dir}/bin/mysqladmin --defaults-file=${data_dir}/my.cnf reload
LimitNOFILE=5000
[Install]
WantedBy=multi-user.target
EOF
# 步骤8:启动服务
echo "启动服务..."
systemctl daemon-reload
if ! systemctl restart "${service_name}"; then
echo -e "${RED}服务启动失败,请检查以下日志:${NC}"
journalctl -u "${service_name}" -n 20 --no-pager
return 1
fi
# 新增服务状态检查
if ! systemctl is-active --quiet "${service_name}"; then
echo -e "${RED}服务未处于运行状态,请检查日志${NC}"
return 1
fi
# 新增等待socket文件生成的逻辑(最多等待30秒)
echo "等待MySQL socket文件生成..."
timeout=30
while [ ! -S "${socket_path}" ] && [ $timeout -gt 0 ]; do
sleep 1
timeout=$((timeout-1))
done
if [ ! -S "${socket_path}" ]; then
echo -e "${RED}错误:等待socket文件超时(${socket_path})${NC}"
echo -e "${YELLOW}可能原因:\n1. MySQL启动失败\n2. 配置文件路径错误\n3. 权限问题${NC}"
journalctl -u "${service_name}" -n 20 --no-pager
return 1
fi
# 步骤9:设置密码
echo "设置root密码..."
retry_count=3
for i in $(seq 1 $retry_count); do
if "${base_dir}/bin/mysql" -uroot -S "${socket_path}" --connect-timeout=10 <<EOF
${password_cmd}
FLUSH PRIVILEGES;
EOF
then
break
fi
if [ $i -eq $retry_count ]; then
echo -e "${RED}密码设置失败,请手动执行以下命令:${NC}"
echo "${base_dir}/bin/mysql -uroot -S ${socket_path}"
return 1
fi
done
# 步骤10:创建版本化命令别名
echo "创建全局命令链接..."
ln -sf "${base_dir}/bin/mysql" "/usr/local/bin/mysql${version_suffix}"
ln -sf "${base_dir}/bin/mysqldump" "/usr/local/bin/mysqldump${version_suffix}"
ln -sf "${base_dir}/bin/mysqladmin" "/usr/local/bin/mysqladmin${version_suffix}"
echo -e "${GREEN}MySQL ${version} 安装完成!${NC}"
echo -e "连接信息:\n 命令: mysql${version_suffix}\n Socket: ${socket_path}\n Port: ${port}\n 密码: 123456"
}
# 卸载函数(安全增强版)
uninstall_mysql() {
local port=$1
local service_name="mysqld${port}"
local data_dir="/data/${port}"
echo -e "${YELLOW}开始卸载MySQL...${NC}"
# 确认操作
read -p "确认要卸载MySQL(端口:${port})?此操作不可逆!(y/n): " confirm
[[ "$confirm" != "y" ]] && echo "操作已取消" && return
# 步骤1:停止服务
echo "停止服务..."
systemctl stop "${service_name}" 2>/dev/null
systemctl disable "${service_name}" 2>/dev/null
# 步骤2:删除数据目录
echo "删除数据目录..."
[ -d "${data_dir}" ] && rm -rf "${data_dir}" && echo "删除 ${data_dir}"
# 步骤3:删除用户(安全判断)
if id mysql &>/dev/null; then
if ! userdel -r mysql 2>/dev/null; then
echo -e "${RED}删除mysql用户失败,请手动检查${NC}"
fi
fi
# 步骤4:精确清理文件
echo "清理残留文件..."
find /usr/local -maxdepth 1 -type l -name "mysql*" -delete
find /usr/local -maxdepth 1 -type d -name "mysql-*" -exec rm -rf {} +
rm -f "/usr/lib/systemd/system/${service_name}.service"
systemctl daemon-reload
# 步骤5:删除版本化命令别名
local version_suffix
case $port in
3306) version_suffix="8.0" ;;
3357) version_suffix="5.7" ;;
3356) version_suffix="5.6" ;;
esac
echo "删除命令别名..."
rm -f "/usr/local/bin/mysql${version_suffix}" \
"/usr/local/bin/mysqldump${version_suffix}" \
"/usr/local/bin/mysqladmin${version_suffix}" 2>/dev/null
echo -e "${GREEN}MySQL(端口:${port})卸载完成!${NC}"
}
# 主菜单
main_menu() {
while true; do
clear
echo "======== MySQL管理菜单 ========"
echo "1. 安装MySQL"
echo "2. 卸载MySQL"
echo "0. 退出"
read -p "请输入选择: " main_choice
case $main_choice in
1) install_submenu ;;
2) uninstall_submenu ;;
0) exit 0 ;;
*) echo -e "${RED}无效的选项,请重新输入${NC}"; sleep 1 ;;
esac
done
}
# 安装子菜单
install_submenu() {
while true; do
clear
echo "-------- 安装MySQL版本 --------"
echo "1. MySQL 8.0(端口:3306)"
echo "2. MySQL 5.7(端口:3357)"
echo "3. MySQL 5.6(端口:3356)"
echo "0. 返回主菜单"
read -p "请选择版本: " ver_choice
case $ver_choice in
1) install_mysql "8.0" "mysql-8.0" 3306 "8.0" ;;
2) install_mysql "5.7" "mysql-5.7" 3357 "5.7" ;;
3) install_mysql "5.6" "mysql-5.6" 3356 "5.6" ;;
0) return ;;
*) echo -e "${RED}无效的版本选择${NC}"; sleep 1 ;;
esac
if [ $? -eq 0 ]; then
read -p "按回车键返回菜单..."
break
fi
done
}
# 卸载子菜单
uninstall_submenu() {
while true; do
clear
echo "-------- 卸载MySQL版本 --------"
echo "1. MySQL 8.0(端口:3306)"
echo "2. MySQL 5.7(端口:3357)"
echo "3. MySQL 5.6(端口:3356)"
echo "0. 返回主菜单"
read -p "请选择版本: " ver_choice
case $ver_choice in
1) uninstall_mysql 3306 ;;
2) uninstall_mysql 3357 ;;
3) uninstall_mysql 3356 ;;
0) return ;;
*) echo -e "${RED}无效的版本选择${NC}"; sleep 1 ;;
esac
read -p "按回车键返回菜单..."
done
}
# 脚本入口
main_menu