#!/bin/bash # Docker环境数据库检查脚本 # 用法: ./scripts/check-docker-db.sh set -e # 颜色定义 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} $1" } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } # 检查Docker是否运行 check_docker() { log_info "检查Docker状态..." if ! docker info > /dev/null 2>&1; then log_error "Docker未运行,请启动Docker服务" exit 1 fi log_success "Docker运行正常" } # 检查Docker Compose文件 check_compose_file() { local compose_file="docker-compose.test.yml" if [[ ! -f "$compose_file" ]]; then log_error "Docker Compose文件不存在: $compose_file" exit 1 fi log_success "找到Docker Compose文件: $compose_file" } # 启动测试环境 start_test_environment() { log_info "启动Docker测试环境..." # 检查容器是否已运行 if docker-compose -f docker-compose.test.yml ps mysql-test | grep -q "Up"; then log_info "MySQL容器已在运行" else log_info "启动MySQL容器..." docker-compose -f docker-compose.test.yml up -d mysql-test # 等待MySQL启动 log_info "等待MySQL启动..." local max_attempts=30 local attempt=0 while [[ $attempt -lt $max_attempts ]]; do if docker-compose -f docker-compose.test.yml exec -T mysql-test mysqladmin ping -h localhost --silent; then log_success "MySQL启动成功" break fi attempt=$((attempt + 1)) echo -n "." sleep 2 done if [[ $attempt -eq $max_attempts ]]; then log_error "MySQL启动超时" docker-compose -f docker-compose.test.yml logs mysql-test exit 1 fi fi } # 检查MySQL容器状态 check_mysql_container() { log_info "检查MySQL容器状态..." local container_status=$(docker-compose -f docker-compose.test.yml ps mysql-test | grep -E "mysql-test.*Up") if [[ -z "$container_status" ]]; then log_error "MySQL容器未运行" return 1 fi log_success "MySQL容器运行正常" echo "$container_status" } # 检查MySQL连接 check_mysql_connection() { log_info "检查MySQL连接..." # 测试连接 if docker-compose -f docker-compose.test.yml exec -T mysql-test mysql -u test -ptest -e "SELECT 1" > /dev/null 2>&1; then log_success "MySQL连接成功" return 0 else log_error "MySQL连接失败" return 1 fi } # 检查数据库是否存在 check_database_exists() { log_info "检查数据库是否存在..." local databases=$(docker-compose -f docker-compose.test.yml exec -T mysql-test mysql -u test -ptest -e "SHOW DATABASES LIKE 'fendx_test'" 2>/dev/null) if echo "$databases" | grep -q "fendx_test"; then log_success "数据库 'fendx_test' 存在" return 0 else log_warning "数据库 'fendx_test' 不存在" return 1 fi } # 创建数据库 create_database() { log_info "创建数据库..." if docker-compose -f docker-compose.test.yml exec -T mysql-test mysql -u test -ptest -e "CREATE DATABASE IF NOT EXISTS fendx_test CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"; then log_success "数据库创建成功" return 0 else log_error "数据库创建失败" return 1 fi } # 检查表结构 check_tables() { log_info "检查数据库表..." local tables=$(docker-compose -f docker-compose.test.yml exec -T mysql-test mysql -u test -ptest fendx_test -e "SHOW TABLES" 2>/dev/null) if [[ -z "$tables" ]]; then log_warning "数据库中没有表" echo "💡 建议运行迁移命令:" echo " docker-compose -f docker-compose.test.yml exec app php bin/console migrate:run" return 1 fi log_success "数据库表列表:" echo "$tables" | tail -n +2 | while read -r table; do if [[ -n "$table" ]]; then local count=$(docker-compose -f docker-compose.test.yml exec -T mysql-test mysql -u test -ptest fendx_test -e "SELECT COUNT(*) FROM \`$table\`" 2>/dev/null | tail -n 1) echo " - $table ($count 条记录)" fi done } # 检查用户数据 check_user_data() { log_info "检查用户数据..." local user_count=$(docker-compose -f docker-compose.test.yml exec -T mysql-test mysql -u test -ptest fendx_test -e "SELECT COUNT(*) FROM users" 2>/dev/null | tail -n 1 2>/dev/null) if [[ -z "$user_count" ]]; then log_warning "用户表不存在" return 1 fi echo "👥 用户数据:" echo " - 总用户数: $user_count" if [[ "$user_count" -gt 0 ]]; then echo " - 最近注册用户:" docker-compose -f docker-compose.test.yml exec -T mysql-test mysql -u test -ptest fendx_test -e "SELECT username, email, created_at FROM users ORDER BY created_at DESC LIMIT 3" 2>/dev/null | tail -n +2 | while read -r line; do if [[ -n "$line" ]]; then echo " * $line" fi done fi } # 运行数据库迁移 run_migrations() { log_info "运行数据库迁移..." if docker-compose -f docker-compose.test.yml exec -T app php bin/console migrate:run; then log_success "数据库迁移完成" return 0 else log_error "数据库迁移失败" return 1 fi } # 填充测试数据 seed_test_data() { log_info "填充测试数据..." if docker-compose -f docker-compose.test.yml exec -T app php bin/console migrate:seed; then log_success "测试数据填充完成" return 0 else log_error "测试数据填充失败" return 1 fi } # 显示MySQL日志 show_mysql_logs() { log_info "显示MySQL日志..." docker-compose -f docker-compose.test.yml logs --tail=20 mysql-test } # 重启MySQL服务 restart_mysql() { log_info "重启MySQL服务..." docker-compose -f docker-compose.test.yml restart mysql-test # 等待重启完成 sleep 10 if check_mysql_connection; then log_success "MySQL重启成功" else log_error "MySQL重启失败" return 1 fi } # 完整检查 full_check() { log_info "开始完整数据库检查..." echo "==================================================" # 检查Docker check_docker # 检查Compose文件 check_compose_file # 启动环境 start_test_environment # 检查容器状态 check_mysql_container # 检查连接 if ! check_mysql_connection; then log_error "数据库连接失败,尝试重启MySQL..." restart_mysql fi echo "--------------------------------------------------" # 检查数据库 if ! check_database_exists; then create_database fi # 检查表 check_tables # 检查用户数据 check_user_data echo "==================================================" log_success "数据库检查完成" } # 修复数据库 fix_database() { log_info "开始修复数据库..." # 确保环境运行 start_test_environment # 创建数据库 if ! check_database_exists; then create_database fi # 运行迁移 run_migrations # 填充数据 seed_test_data log_success "数据库修复完成" } # 显示帮助 show_help() { cat << EOF Docker环境数据库检查工具 用法: $0 [选项] 选项: check 检查数据库状态 (默认) fix 修复数据库问题 migrate 运行数据库迁移 seed 填充测试数据 logs 显示MySQL日志 restart 重启MySQL服务 help 显示帮助信息 示例: $0 # 检查数据库 $0 check # 检查数据库 $0 fix # 修复数据库 $0 migrate # 运行迁移 $0 seed # 填充数据 $0 logs # 查看日志 EOF } # 主函数 main() { local action="${1:-check}" case "$action" in "check") full_check ;; "fix") fix_database ;; "migrate") start_test_environment run_migrations ;; "seed") start_test_environment seed_test_data ;; "logs") show_mysql_logs ;; "restart") restart_mysql ;; "help"|"-h"|"--help") show_help ;; *) log_error "未知选项: $action" show_help exit 1 ;; esac } # 运行主函数 main "$@"