anxin-ruoyi/docker/scripts/diagnose-database-connection.sh
2026-01-08 20:47:24 +08:00

245 lines
7.5 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# 数据库连接诊断脚本
# 用于诊断和修复数据库连接池问题
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_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 检查数据库服务状态
check_database_service() {
log_info "检查数据库服务状态..."
if docker ps --filter "name=anxin-mysql-prod" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep anxin-mysql-prod; then
log_success "✓ MySQL容器正在运行"
# 检查健康状态
local health=$(docker inspect anxin-mysql-prod --format='{{.State.Health.Status}}' 2>/dev/null || echo "unknown")
log_info "MySQL健康状态: $health"
if [[ "$health" == "healthy" ]]; then
log_success "✓ MySQL容器健康检查通过"
else
log_warn "MySQL容器健康检查未通过"
fi
else
log_error "✗ MySQL容器未运行"
return 1
fi
}
# 测试数据库连接
test_database_connection() {
log_info "测试数据库连接..."
if [[ -f "environments/.env.production" ]]; then
source environments/.env.production
# 测试root连接
log_info "测试root用户连接..."
if docker exec anxin-mysql-prod mysql -uroot -p"$MYSQL_ROOT_PASSWORD" -e "SELECT 1;" 2>/dev/null; then
log_success "✓ root用户连接成功"
else
log_error "✗ root用户连接失败"
fi
# 测试应用用户连接
log_info "测试应用用户连接..."
if docker exec anxin-mysql-prod mysql -u"$DB_USER" -p"$DB_PASSWORD" -e "SELECT 1;" "$DB_NAME" 2>/dev/null; then
log_success "✓ 应用用户连接成功"
else
log_error "✗ 应用用户连接失败"
fi
# 检查数据库是否存在
log_info "检查数据库是否存在..."
if docker exec anxin-mysql-prod mysql -uroot -p"$MYSQL_ROOT_PASSWORD" -e "SHOW DATABASES;" | grep -q "$DB_NAME"; then
log_success "✓ 数据库 $DB_NAME 存在"
else
log_error "✗ 数据库 $DB_NAME 不存在"
fi
fi
}
# 检查后端服务连接配置
check_backend_connection_config() {
log_info "检查后端服务连接配置..."
if docker ps --filter "name=anxin-backend-prod" --format "{{.Names}}" | grep -q "anxin-backend-prod"; then
log_success "✓ 后端容器正在运行"
# 检查环境变量
echo "数据库连接环境变量:"
docker exec anxin-backend-prod env | grep -E "^DB_" | while read line; do
if [[ $line == *"PASSWORD"* ]]; then
echo " ${line%%=*}=[HIDDEN]"
else
echo " $line"
fi
done
# 检查网络连通性
log_info "测试容器间网络连通性..."
if docker exec anxin-backend-prod nc -z anxin-mysql 3306 2>/dev/null; then
log_success "✓ 后端容器可以连接到MySQL容器"
else
log_error "✗ 后端容器无法连接到MySQL容器"
fi
else
log_error "✗ 后端容器未运行"
fi
}
# 检查应用日志中的连接错误
check_connection_errors() {
log_info "检查应用日志中的连接错误..."
echo "最近的数据库连接错误:"
echo "----------------------------------------"
./deploy.sh logs backend -e production --tail 100 | grep -i -E "(connection|datasource|mysql|jdbc)" | tail -10 || echo "未找到相关日志"
echo "----------------------------------------"
# 检查是否有连接池相关错误
if ./deploy.sh logs backend -e production --tail 200 | grep -i "DataSourceClosedException"; then
log_error "发现数据源关闭异常"
fi
if ./deploy.sh logs backend -e production --tail 200 | grep -i "CannotGetJdbcConnectionException"; then
log_error "发现JDBC连接获取异常"
fi
}
# 修复数据库连接问题
fix_database_connection() {
log_info "尝试修复数据库连接问题..."
# 1. 重启MySQL服务
log_info "重启MySQL服务..."
./deploy.sh restart mysql -e production
sleep 10
# 2. 等待MySQL完全启动
log_info "等待MySQL服务完全启动..."
local max_attempts=30
local attempt=1
while [ $attempt -le $max_attempts ]; do
if docker exec anxin-mysql-prod mysqladmin ping -h localhost -u root -p"$MYSQL_ROOT_PASSWORD" 2>/dev/null; then
log_success "MySQL服务已就绪"
break
fi
echo "等待MySQL服务... (尝试 $attempt/$max_attempts)"
sleep 2
attempt=$((attempt + 1))
done
if [ $attempt -gt $max_attempts ]; then
log_error "MySQL服务启动超时"
return 1
fi
# 3. 重启后端服务
log_info "重启后端服务..."
./deploy.sh restart backend -e production
sleep 15
# 4. 检查修复结果
log_info "检查修复结果..."
if ./deploy.sh logs backend -e production --tail 20 | grep -i "started.*in"; then
log_success "✓ 后端服务启动成功"
else
log_warn "后端服务启动状态未知,请检查日志"
fi
}
# 显示修复建议
show_fix_suggestions() {
log_info "修复建议:"
echo "========================================"
echo "如果问题仍然存在,请尝试以下步骤:"
echo ""
echo "1. 完全重启所有服务:"
echo " ./deploy.sh down -e production"
echo " ./deploy.sh up -e production"
echo ""
echo "2. 检查数据库用户权限:"
echo " docker exec anxin-mysql-prod mysql -uroot -p"
echo " SHOW GRANTS FOR 'anxin_prod'@'%';"
echo ""
echo "3. 检查数据库配置:"
echo " docker exec anxin-mysql-prod mysql -uroot -p -e \"SHOW VARIABLES LIKE 'max_connections';\""
echo ""
echo "4. 如果是连接池配置问题检查application-docker.yml中的Druid配置"
echo ""
echo "5. 监控资源使用情况:"
echo " docker stats anxin-mysql-prod anxin-backend-prod"
echo "========================================"
}
# 主函数
main() {
local action=${1:-"diagnose"}
log_info "数据库连接诊断工具"
echo "========================================"
case $action in
"diagnose")
check_database_service
echo ""
test_database_connection
echo ""
check_backend_connection_config
echo ""
check_connection_errors
echo ""
show_fix_suggestions
;;
"fix")
if [[ -f "environments/.env.production" ]]; then
source environments/.env.production
fix_database_connection
echo ""
main "diagnose"
else
log_error "未找到环境配置文件"
fi
;;
*)
echo "用法: $0 [diagnose|fix]"
echo " diagnose - 诊断数据库连接问题(默认)"
echo " fix - 尝试修复数据库连接问题"
exit 1
;;
esac
echo "========================================"
log_success "操作完成!"
}
# 如果脚本被直接执行
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi