#!/bin/bash # MySQL从Docker迁移到直接部署脚本 # 作者: emotion-museum # 日期: 2025-07-21 # 功能: 将Docker部署的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_mysql_data() { log_info "备份当前MySQL数据..." ssh "$REMOTE_HOST" " echo '📦 创建数据备份...' BACKUP_DIR=\"/data/backups/mysql_\$(date +%Y%m%d_%H%M%S)\" mkdir -p \"\$BACKUP_DIR\" # 备份数据目录 cp -r $MYSQL_DATA_DIR \"\$BACKUP_DIR/\" # 导出数据库 echo '📤 导出数据库...' docker exec emotion-mysql mysqldump -u root -p'$MYSQL_ROOT_PASSWORD' --all-databases --routines --triggers > \"\$BACKUP_DIR/all_databases.sql\" if [ -f \"\$BACKUP_DIR/all_databases.sql\" ]; then echo \"✅ 数据备份完成: \$BACKUP_DIR\" else echo '❌ 数据备份失败' exit 1 fi " log_success "MySQL数据备份完成" } # 安装MySQL服务器 install_mysql_server() { log_info "安装MySQL服务器..." ssh "$REMOTE_HOST" " echo '📦 安装MySQL服务器...' # 检查系统类型并安装MySQL if command -v yum >/dev/null 2>&1; then echo '使用yum安装MySQL...' yum update -y yum install -y mysql-server mysql elif command -v dnf >/dev/null 2>&1; then echo '使用dnf安装MySQL...' dnf update -y dnf install -y mysql-server mysql elif command -v apt >/dev/null 2>&1; then echo '使用apt安装MySQL...' apt update DEBIAN_FRONTEND=noninteractive apt install -y mysql-server mysql-client else echo '❌ 不支持的包管理器' exit 1 fi # 检查安装结果 if command -v mysql >/dev/null 2>&1; then echo '✅ MySQL服务器安装成功' mysql --version else echo '❌ MySQL服务器安装失败' exit 1 fi " log_success "MySQL服务器安装完成" } # 停止Docker MySQL并配置直接部署 migrate_mysql() { log_info "迁移MySQL到直接部署..." ssh "$REMOTE_HOST" " echo '🛑 停止Docker MySQL容器...' docker stop emotion-mysql echo '🔧 停止系统MySQL服务...' systemctl stop mysql || service mysql stop echo '📁 配置数据目录权限...' # 更改数据目录所有者为mysql用户 chown -R mysql:mysql $MYSQL_DATA_DIR chmod -R 750 $MYSQL_DATA_DIR echo '⚙️ 配置MySQL...' # 创建MySQL配置文件 cat > /etc/mysql/mysql.conf.d/emotion-museum.cnf << 'EOF' [mysqld] # 数据目录 datadir = /data/programs/mysql # 网络配置 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/mysql/error.log slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow.log long_query_time = 2 # 性能配置 max_connections = 200 innodb_buffer_pool_size = 512M innodb_log_file_size = 128M # 安全配置 skip-name-resolve sql_mode = STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO # 二进制日志 log-bin = mysql-bin binlog_format = ROW expire_logs_days = 7 EOF echo '🚀 启动MySQL服务...' # 启动MySQL服务(兼容不同系统) if command -v systemctl >/dev/null 2>&1; then echo '使用systemctl启动MySQL...' systemctl start mysqld || systemctl start mysql systemctl enable mysqld || systemctl enable mysql # 等待MySQL启动 sleep 10 # 检查MySQL状态 if systemctl is-active --quiet mysqld || systemctl is-active --quiet mysql; then echo '✅ MySQL服务启动成功' else echo '❌ MySQL服务启动失败' systemctl status mysqld || systemctl status mysql exit 1 fi else echo '使用service启动MySQL...' service mysqld start || service mysql start chkconfig mysqld on || chkconfig mysql on || true # 等待MySQL启动 sleep 10 # 检查MySQL状态 if pgrep -f mysqld > /dev/null; then echo '✅ MySQL服务启动成功' else echo '❌ MySQL服务启动失败' service mysqld status || service mysql status exit 1 fi fi echo '🔐 配置root密码...' # 重置root密码 mysql -u root << 'EOSQL' ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '$MYSQL_ROOT_PASSWORD'; CREATE USER IF NOT EXISTS 'root'@'%' IDENTIFIED WITH mysql_native_password BY '$MYSQL_ROOT_PASSWORD'; GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION; FLUSH PRIVILEGES; EOSQL echo '✅ MySQL配置完成' " log_success "MySQL迁移完成" } # 验证数据完整性 verify_data_integrity() { log_info "验证数据完整性..." ssh "$REMOTE_HOST" " echo '🔍 检查数据库连接...' if mysql -u root -p'$MYSQL_ROOT_PASSWORD' -e 'SELECT VERSION();' > /dev/null 2>&1; then echo '✅ MySQL连接正常' else echo '❌ MySQL连接失败' exit 1 fi echo '🔍 检查数据库列表...' mysql -u root -p'$MYSQL_ROOT_PASSWORD' -e 'SHOW DATABASES;' echo '🔍 检查emotion_museum数据库...' if mysql -u root -p'$MYSQL_ROOT_PASSWORD' -e 'USE emotion_museum; SHOW TABLES;' > /dev/null 2>&1; then echo '✅ emotion_museum数据库存在' mysql -u root -p'$MYSQL_ROOT_PASSWORD' -e 'USE emotion_museum; SHOW TABLES;' else echo '❌ emotion_museum数据库不存在' exit 1 fi echo '🔍 检查用户表数据...' mysql -u root -p'$MYSQL_ROOT_PASSWORD' -e 'USE emotion_museum; SELECT COUNT(*) as user_count FROM user;' || echo '用户表检查失败' " log_success "数据完整性验证完成" } # 清理Docker容器和镜像 cleanup_docker() { log_info "清理Docker容器和镜像..." ssh "$REMOTE_HOST" " echo '🗑️ 删除MySQL Docker容器...' docker rm emotion-mysql 2>/dev/null || echo 'MySQL容器已删除' echo '🗑️删除MySQL Docker镜像...' docker rmi mysql:8.0 2>/dev/null || echo 'MySQL镜像不存在或被其他容器使用' echo '✅ Docker清理完成' " log_success "Docker清理完成" } # 检查最终状态 check_final_status() { log_info "检查最终状态..." ssh "$REMOTE_HOST" " echo '📊 MySQL服务状态:' echo '==================' # 检查服务状态 echo -n 'MySQL服务: ' if systemctl is-active --quiet mysql; 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 '✅ 运行中' ps aux | grep mysqld | grep -v grep | head -1 else echo '❌ 未运行' fi echo '' echo '🔍 数据目录权限:' ls -la $MYSQL_DATA_DIR | head -5 echo '' echo '🔍 配置文件:' ls -la /etc/mysql/mysql.conf.d/emotion-museum.cnf 2>/dev/null || echo '配置文件不存在' " log_success "状态检查完成" } # 主函数 main() { log_info "🚀 开始MySQL从Docker迁移到直接部署..." echo "⚠️ 此操作将:" echo " 1. 备份当前MySQL数据" echo " 2. 停止Docker MySQL容器" echo " 3. 安装系统MySQL服务器" echo " 4. 迁移数据到直接部署" echo " 5. 清理Docker容器和镜像" echo "" echo "是否继续?(y/N)" read -r confirm if [[ ! "$confirm" =~ ^[Yy]$ ]]; then log_warning "操作已取消" exit 0 fi check_connection backup_mysql_data install_mysql_server migrate_mysql verify_data_integrity cleanup_docker check_final_status log_success "🎉 MySQL迁移完成!" echo "" echo "📋 迁移结果:" echo " ✅ MySQL已从Docker迁移到直接部署" 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 "$@"