#!/bin/bash # MySQL清理和重新安装脚本 # 作者: emotion-museum # 日期: 2025-07-21 # 功能: 清理现有MySQL组件,保留数据文件,重新安装MySQL set -e REMOTE_HOST="root@47.111.10.27" MYSQL_DATA_DIR="/data/programs/mysql" MYSQL_ROOT_PASSWORD="EmotionMuseum2025*#" # 颜色输出 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' log_info() { echo -e "${BLUE}[INFO]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1" } log_success() { echo -e "${GREEN}[SUCCESS]${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" } # 检查SSH连接 check_connection() { log_info "检查远程服务器连接..." if ssh -o ConnectTimeout=10 "$REMOTE_HOST" "echo 'SSH连接成功'" > /dev/null 2>&1; then log_success "远程服务器连接正常" else log_error "无法连接到远程服务器: $REMOTE_HOST" exit 1 fi } # 备份数据文件 backup_data_files() { log_info "备份MySQL数据文件..." ssh "$REMOTE_HOST" " echo '📦 备份数据文件...' BACKUP_DIR=\"/data/backups/mysql_data_\$(date +%Y%m%d_%H%M%S)\" mkdir -p \"\$BACKUP_DIR\" # 备份数据目录 if [ -d '$MYSQL_DATA_DIR' ]; then cp -r $MYSQL_DATA_DIR \"\$BACKUP_DIR/\" echo \"✅ 数据文件已备份到: \$BACKUP_DIR\" else echo '⚠️ 数据目录不存在: $MYSQL_DATA_DIR' fi # 导出数据库(如果Docker容器还在运行) if docker ps | grep -q emotion-mysql; then echo '📤 导出数据库...' docker exec emotion-mysql mysqldump -u root -p'$MYSQL_ROOT_PASSWORD' --all-databases --routines --triggers > \"\$BACKUP_DIR/all_databases.sql\" || echo '数据库导出失败' fi " log_success "数据文件备份完成" } # 停止并清理Docker MySQL cleanup_docker_mysql() { log_info "停止并清理Docker MySQL..." ssh "$REMOTE_HOST" " echo '🛑 停止Docker MySQL容器...' docker stop emotion-mysql 2>/dev/null || echo 'MySQL容器已停止' docker rm emotion-mysql 2>/dev/null || echo 'MySQL容器已删除' echo '🗑️ 删除MySQL Docker镜像...' docker rmi mysql:8.0 2>/dev/null || echo 'MySQL镜像不存在或被其他容器使用' echo '✅ Docker MySQL清理完成' " log_success "Docker MySQL清理完成" } # 清理现有MySQL组件 cleanup_existing_mysql() { log_info "清理现有MySQL组件..." ssh "$REMOTE_HOST" " echo '🧹 停止现有MySQL服务...' systemctl stop mysqld 2>/dev/null || echo 'mysqld服务未运行' systemctl stop mysql 2>/dev/null || echo 'mysql服务未运行' echo '🗑️ 卸载现有MySQL和MariaDB包...' # 卸载MySQL相关包(保留数据) yum remove -y mysql-community-server mysql-community-client mysql-community-common mysql-community-libs 2>/dev/null || echo 'MySQL社区版包不存在' yum remove -y mysql-server mysql-client mysql-common mysql-libs 2>/dev/null || echo 'MySQL包不存在' yum remove -y bt-mysql80 2>/dev/null || echo 'bt-mysql80包不存在' # 卸载MariaDB包 yum remove -y mariadb mariadb-server mariadb-libs mariadb-common mariadb-connector-c 2>/dev/null || echo 'MariaDB包不存在' echo '🗑️ 清理配置文件...' # 备份并清理配置文件 if [ -d '/etc/mysql' ]; then mv /etc/mysql /etc/mysql.bak.\$(date +%Y%m%d_%H%M%S) 2>/dev/null || true fi if [ -d '/etc/my.cnf.d' ]; then mv /etc/my.cnf.d /etc/my.cnf.d.bak.\$(date +%Y%m%d_%H%M%S) 2>/dev/null || true fi if [ -f '/etc/my.cnf' ]; then mv /etc/my.cnf /etc/my.cnf.bak.\$(date +%Y%m%d_%H%M%S) 2>/dev/null || true fi echo '🗑️ 清理日志文件...' rm -rf /var/log/mysql* 2>/dev/null || true rm -rf /var/log/mysqld* 2>/dev/null || true echo '🗑️ 清理运行时文件...' rm -rf /var/run/mysqld* 2>/dev/null || true rm -rf /tmp/mysql* 2>/dev/null || true echo '✅ 现有MySQL组件清理完成' " log_success "现有MySQL组件清理完成" } # 下载并安装MySQL仓库 install_mysql_repo() { log_info "下载并安装MySQL仓库..." ssh "$REMOTE_HOST" " echo '📥 下载MySQL仓库配置包...' cd /tmp wget -O mysql80-community-release-el8-3.noarch.rpm https://repo.huaweicloud.com/mysql/Downloads/mysql-8.0/mysql80-community-release-el8-3.noarch.rpm if [ -f 'mysql80-community-release-el8-3.noarch.rpm' ]; then echo '✅ MySQL仓库配置包下载成功' ls -la mysql80-community-release-el8-3.noarch.rpm else echo '❌ MySQL仓库配置包下载失败' exit 1 fi echo '📦 安装MySQL仓库配置...' yum localinstall -y mysql80-community-release-el8-3.noarch.rpm echo '🔄 更新yum缓存...' yum clean all yum makecache echo '✅ MySQL仓库安装完成' " log_success "MySQL仓库安装完成" } # 安装MySQL服务器 install_mysql_server() { log_info "安装MySQL服务器..." ssh "$REMOTE_HOST" " echo '📦 安装MySQL社区服务器...' yum install -y mysql-community-server mysql-community-client # 检查安装结果 if command -v mysql >/dev/null 2>&1 && command -v mysqld >/dev/null 2>&1; then echo '✅ MySQL服务器安装成功' mysql --version mysqld --version else echo '❌ MySQL服务器安装失败' exit 1 fi " log_success "MySQL服务器安装完成" } # 配置MySQL使用现有数据 configure_mysql_with_existing_data() { log_info "配置MySQL使用现有数据..." ssh "$REMOTE_HOST" " echo '⚙️ 创建MySQL配置文件...' cat > /etc/my.cnf << 'EOF' [mysqld] # 数据目录 datadir = /data/programs/mysql socket = /var/lib/mysql/mysql.sock # 网络配置 bind-address = 0.0.0.0 port = 3306 # 字符集配置 character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci # 认证插件 default-authentication-plugin = mysql_native_password # 日志配置 log-error = /var/log/mysqld.log pid-file = /var/run/mysqld/mysqld.pid # 性能配置 max_connections = 200 innodb_buffer_pool_size = 512M # 安全配置 skip-name-resolve # 二进制日志 log-bin = mysql-bin binlog_format = ROW expire_logs_days = 7 [mysql] default-character-set = utf8mb4 [client] default-character-set = utf8mb4 socket = /var/lib/mysql/mysql.sock EOF echo '📁 配置数据目录权限...' # 创建mysql用户(如果不存在) id mysql >/dev/null 2>&1 || useradd -r -s /bin/false mysql # 设置数据目录权限 chown -R mysql:mysql $MYSQL_DATA_DIR chmod -R 750 $MYSQL_DATA_DIR # 创建必要的目录 mkdir -p /var/lib/mysql mkdir -p /var/run/mysqld mkdir -p /var/log chown mysql:mysql /var/lib/mysql chown mysql:mysql /var/run/mysqld touch /var/log/mysqld.log chown mysql:mysql /var/log/mysqld.log echo '✅ MySQL配置完成' " log_success "MySQL配置完成" } # 启动MySQL服务 start_mysql_service() { log_info "启动MySQL服务..." ssh "$REMOTE_HOST" " echo '🚀 启动MySQL服务...' systemctl start mysqld systemctl enable mysqld # 等待MySQL启动 sleep 10 # 检查MySQL状态 if systemctl is-active --quiet mysqld; then echo '✅ MySQL服务启动成功' else echo '❌ MySQL服务启动失败' systemctl status mysqld tail -20 /var/log/mysqld.log exit 1 fi echo '🔍 检查端口监听...' if netstat -tlnp | grep :3306 > /dev/null; then echo '✅ MySQL端口3306正在监听' else echo '⚠️ MySQL端口3306未监听' fi " log_success "MySQL服务启动完成" } # 验证数据完整性 verify_data_integrity() { log_info "验证数据完整性..." ssh "$REMOTE_HOST" " echo '🔍 尝试连接MySQL...' # 由于使用现有数据,root密码应该已经设置 if mysql -u root -p'$MYSQL_ROOT_PASSWORD' -e 'SELECT VERSION();' > /dev/null 2>&1; then echo '✅ MySQL连接成功,密码正确' else echo '⚠️ 使用现有密码连接失败,可能需要重置密码' # 获取临时密码(如果有) TEMP_PASSWORD=\$(grep 'temporary password' /var/log/mysqld.log | tail -1 | awk '{print \$NF}' 2>/dev/null || echo '') if [ -n \"\$TEMP_PASSWORD\" ]; then echo \"发现临时密码,尝试重置...\" mysql -u root -p\"\$TEMP_PASSWORD\" --connect-expired-password << 'EOSQL' ALTER USER 'root'@'localhost' IDENTIFIED BY '$MYSQL_ROOT_PASSWORD'; FLUSH PRIVILEGES; EOSQL echo '✅ 密码重置完成' else echo '⚠️ 未找到临时密码,可能需要手动处理' fi fi echo '🔍 检查数据库列表...' mysql -u root -p'$MYSQL_ROOT_PASSWORD' -e 'SHOW DATABASES;' || echo '数据库列表查询失败' echo '🔍 检查emotion_museum数据库...' mysql -u root -p'$MYSQL_ROOT_PASSWORD' -e 'USE emotion_museum; SHOW TABLES;' || echo 'emotion_museum数据库检查失败' " log_success "数据完整性验证完成" } # 检查最终状态 check_final_status() { log_info "检查最终状态..." ssh "$REMOTE_HOST" " echo '📊 MySQL服务状态:' echo '==================' # 检查服务状态 echo -n 'MySQL服务: ' if systemctl is-active --quiet mysqld; then echo '✅ 运行中' else echo '❌ 未运行' fi # 检查端口监听 echo -n 'MySQL端口(3306): ' if netstat -tlnp | grep :3306 | grep -v docker > /dev/null; then echo '✅ 监听中' else echo '❌ 未监听' fi # 检查进程 echo -n 'MySQL进程: ' if pgrep -f mysqld > /dev/null; then echo '✅ 运行中' else echo '❌ 未运行' fi echo '' echo '🔍 数据目录:' ls -la $MYSQL_DATA_DIR | head -5 echo '' echo '🔍 配置文件:' ls -la /etc/my.cnf 2>/dev/null || echo '配置文件不存在' " log_success "状态检查完成" } # 主函数 main() { log_info "🚀 开始MySQL清理和重新安装..." echo "⚠️ 此操作将:" echo " 1. 备份现有MySQL数据文件" echo " 2. 停止并清理Docker MySQL" echo " 3. 清理现有MySQL/MariaDB组件" echo " 4. 下载并安装MySQL 8.0仓库" echo " 5. 安装MySQL社区服务器" echo " 6. 配置MySQL使用现有数据" echo " 7. 启动MySQL服务" echo "" echo "⚠️ 数据文件将被保留,但配置文件将被重置" echo "" echo "是否继续?(y/N)" read -r confirm if [[ ! "$confirm" =~ ^[Yy]$ ]]; then log_warning "操作已取消" exit 0 fi check_connection backup_data_files cleanup_docker_mysql cleanup_existing_mysql install_mysql_repo install_mysql_server configure_mysql_with_existing_data start_mysql_service verify_data_integrity check_final_status log_success "🎉 MySQL重新安装完成!" echo "" echo "📋 安装结果:" echo " ✅ MySQL 8.0社区版已安装" echo " ✅ 现有数据文件已保留" echo " ✅ 服务正常运行" echo "" echo "📋 连接信息:" echo " 主机: localhost 或 47.111.10.27" echo " 端口: 3306" echo " 用户: root" echo " 密码: $MYSQL_ROOT_PASSWORD" echo " 数据库: emotion_museum" echo "" echo "🔧 下一步:" echo " 1. 测试应用连接" echo " 2. 重启微服务: cd backend && ./deploy-remote.sh" } # 执行主函数 main "$@"