fix(deploy-mining): 支持 Docker 环境的数据库操作和迁移
- 添加 run_psql helper 函数自动检测 Docker 或本地 psql - 修改 db_create/db_drop/db_status 使用 docker exec - 修改 db_migrate 支持通过容器运行 prisma migration - 修改 health_check/show_stats 支持 Docker 环境 解决在服务器 Docker 环境中 full-reset 失败的问题。 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
5d880f011e
commit
5c302bfca8
|
|
@ -220,6 +220,29 @@ load_env() {
|
||||||
KAFKA_BROKERS="${KAFKA_BROKERS:-localhost:9092}"
|
KAFKA_BROKERS="${KAFKA_BROKERS:-localhost:9092}"
|
||||||
REDIS_HOST="${REDIS_HOST:-localhost}"
|
REDIS_HOST="${REDIS_HOST:-localhost}"
|
||||||
REDIS_PORT="${REDIS_PORT:-6379}"
|
REDIS_PORT="${REDIS_PORT:-6379}"
|
||||||
|
|
||||||
|
# Docker container names
|
||||||
|
POSTGRES_CONTAINER="${POSTGRES_CONTAINER:-postgres}"
|
||||||
|
KAFKA_CONTAINER="${KAFKA_CONTAINER:-kafka}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ===========================================================================
|
||||||
|
# Helper: Execute psql command (auto-detect Docker or local)
|
||||||
|
# ===========================================================================
|
||||||
|
run_psql() {
|
||||||
|
local db="$1"
|
||||||
|
local sql="$2"
|
||||||
|
|
||||||
|
# Try docker exec first (for production Docker environment)
|
||||||
|
if docker ps --format '{{.Names}}' 2>/dev/null | grep -q "^${POSTGRES_CONTAINER}$"; then
|
||||||
|
docker exec -e PGPASSWORD="$POSTGRES_PASSWORD" "$POSTGRES_CONTAINER" \
|
||||||
|
psql -h localhost -U "$POSTGRES_USER" -d "$db" -c "$sql" 2>/dev/null
|
||||||
|
return $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Fall back to local psql
|
||||||
|
PGPASSWORD="$POSTGRES_PASSWORD" psql -h "$POSTGRES_HOST" -p "$POSTGRES_PORT" -U "$POSTGRES_USER" -d "$db" -c "$sql" 2>/dev/null
|
||||||
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
# ===========================================================================
|
# ===========================================================================
|
||||||
|
|
@ -238,9 +261,11 @@ db_create() {
|
||||||
|
|
||||||
for db in "${dbs_to_create[@]}"; do
|
for db in "${dbs_to_create[@]}"; do
|
||||||
log_step "Creating database: $db"
|
log_step "Creating database: $db"
|
||||||
PGPASSWORD="$POSTGRES_PASSWORD" psql -h "$POSTGRES_HOST" -p "$POSTGRES_PORT" -U "$POSTGRES_USER" -d postgres -c "CREATE DATABASE $db;" 2>/dev/null || {
|
if run_psql "postgres" "CREATE DATABASE $db;"; then
|
||||||
|
log_success "Database $db created"
|
||||||
|
else
|
||||||
log_warn "Database $db already exists or creation failed"
|
log_warn "Database $db already exists or creation failed"
|
||||||
}
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
log_success "Database creation completed"
|
log_success "Database creation completed"
|
||||||
|
|
@ -259,9 +284,11 @@ db_drop() {
|
||||||
|
|
||||||
for db in "${dbs_to_drop[@]}"; do
|
for db in "${dbs_to_drop[@]}"; do
|
||||||
log_step "Dropping database: $db"
|
log_step "Dropping database: $db"
|
||||||
PGPASSWORD="$POSTGRES_PASSWORD" psql -h "$POSTGRES_HOST" -p "$POSTGRES_PORT" -U "$POSTGRES_USER" -d postgres -c "DROP DATABASE IF EXISTS $db WITH (FORCE);" 2>/dev/null || {
|
if run_psql "postgres" "DROP DATABASE IF EXISTS $db WITH (FORCE);"; then
|
||||||
|
log_success "Database $db dropped"
|
||||||
|
else
|
||||||
log_warn "Failed to drop database $db"
|
log_warn "Failed to drop database $db"
|
||||||
}
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
log_success "Database drop completed"
|
log_success "Database drop completed"
|
||||||
|
|
@ -282,9 +309,36 @@ db_migrate() {
|
||||||
service_dir="$SCRIPT_DIR/$service"
|
service_dir="$SCRIPT_DIR/$service"
|
||||||
if [ -d "$service_dir/prisma" ]; then
|
if [ -d "$service_dir/prisma" ]; then
|
||||||
log_step "Migrating: $service"
|
log_step "Migrating: $service"
|
||||||
cd "$service_dir"
|
|
||||||
npx prisma migrate deploy 2>/dev/null || npx prisma db push --accept-data-loss
|
# Check if running in Docker environment (container exists)
|
||||||
cd "$SCRIPT_DIR"
|
local container_name="rwa-${service}"
|
||||||
|
if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "^${container_name}$"; then
|
||||||
|
# Run migration inside the container
|
||||||
|
log_info "Running migration in container: $container_name"
|
||||||
|
docker start "$container_name" 2>/dev/null || true
|
||||||
|
sleep 2
|
||||||
|
docker exec "$container_name" npx prisma migrate deploy 2>/dev/null || \
|
||||||
|
docker exec "$container_name" npx prisma db push --accept-data-loss 2>/dev/null || {
|
||||||
|
log_warn "Container migration failed, trying to build and run temporary container..."
|
||||||
|
# Build and run a temporary container for migration
|
||||||
|
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" run --rm "$service" npx prisma migrate deploy 2>/dev/null || \
|
||||||
|
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" run --rm "$service" npx prisma db push --accept-data-loss 2>/dev/null || {
|
||||||
|
log_warn "Migration failed for $service"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elif command -v npx &>/dev/null; then
|
||||||
|
# Local development: use npx directly
|
||||||
|
cd "$service_dir"
|
||||||
|
npx prisma migrate deploy 2>/dev/null || npx prisma db push --accept-data-loss
|
||||||
|
cd "$SCRIPT_DIR"
|
||||||
|
else
|
||||||
|
# No npx and no container - try docker compose run
|
||||||
|
log_info "No local npx, using docker compose run for migration"
|
||||||
|
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" run --rm "$service" npx prisma migrate deploy 2>/dev/null || \
|
||||||
|
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" run --rm "$service" npx prisma db push --accept-data-loss 2>/dev/null || {
|
||||||
|
log_warn "Migration failed for $service"
|
||||||
|
}
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
@ -298,8 +352,15 @@ db_status() {
|
||||||
echo "────────────────────────────────────────────────────"
|
echo "────────────────────────────────────────────────────"
|
||||||
|
|
||||||
for db in "${MINING_DATABASES[@]}"; do
|
for db in "${MINING_DATABASES[@]}"; do
|
||||||
if PGPASSWORD="$POSTGRES_PASSWORD" psql -h "$POSTGRES_HOST" -p "$POSTGRES_PORT" -U "$POSTGRES_USER" -d "$db" -c "SELECT 1" &>/dev/null; then
|
if run_psql "$db" "SELECT 1" &>/dev/null; then
|
||||||
table_count=$(PGPASSWORD="$POSTGRES_PASSWORD" psql -h "$POSTGRES_HOST" -p "$POSTGRES_PORT" -U "$POSTGRES_USER" -d "$db" -t -c "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'public';" 2>/dev/null | tr -d ' ')
|
# Get table count using run_psql helper
|
||||||
|
local table_count
|
||||||
|
if docker ps --format '{{.Names}}' 2>/dev/null | grep -q "^${POSTGRES_CONTAINER}$"; then
|
||||||
|
table_count=$(docker exec -e PGPASSWORD="$POSTGRES_PASSWORD" "$POSTGRES_CONTAINER" \
|
||||||
|
psql -h localhost -U "$POSTGRES_USER" -d "$db" -t -c "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'public';" 2>/dev/null | tr -d ' ')
|
||||||
|
else
|
||||||
|
table_count=$(PGPASSWORD="$POSTGRES_PASSWORD" psql -h "$POSTGRES_HOST" -p "$POSTGRES_PORT" -U "$POSTGRES_USER" -d "$db" -t -c "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'public';" 2>/dev/null | tr -d ' ')
|
||||||
|
fi
|
||||||
echo -e "${GREEN}$db${NC}\t${GREEN}UP${NC}\t\t$table_count tables"
|
echo -e "${GREEN}$db${NC}\t${GREEN}UP${NC}\t\t$table_count tables"
|
||||||
else
|
else
|
||||||
echo -e "${RED}$db${NC}\t\t${RED}DOWN${NC}\t\t-"
|
echo -e "${RED}$db${NC}\t\t${RED}DOWN${NC}\t\t-"
|
||||||
|
|
@ -684,7 +745,7 @@ health_check() {
|
||||||
# Check databases
|
# Check databases
|
||||||
echo -e "${BOLD}Databases:${NC}"
|
echo -e "${BOLD}Databases:${NC}"
|
||||||
for db in "${MINING_DATABASES[@]}"; do
|
for db in "${MINING_DATABASES[@]}"; do
|
||||||
if PGPASSWORD="$POSTGRES_PASSWORD" psql -h "$POSTGRES_HOST" -p "$POSTGRES_PORT" -U "$POSTGRES_USER" -d "$db" -c "SELECT 1" &>/dev/null; then
|
if run_psql "$db" "SELECT 1" &>/dev/null; then
|
||||||
echo -e " ${GREEN}✓${NC} $db"
|
echo -e " ${GREEN}✓${NC} $db"
|
||||||
else
|
else
|
||||||
echo -e " ${RED}✗${NC} $db"
|
echo -e " ${RED}✗${NC} $db"
|
||||||
|
|
@ -738,19 +799,26 @@ health_check() {
|
||||||
show_stats() {
|
show_stats() {
|
||||||
print_section "2.0 System Statistics"
|
print_section "2.0 System Statistics"
|
||||||
|
|
||||||
|
local stats_sql="
|
||||||
|
SELECT tablename AS table,
|
||||||
|
pg_size_pretty(pg_total_relation_size(schemaname || '.' || tablename)) AS size
|
||||||
|
FROM pg_tables
|
||||||
|
WHERE schemaname = 'public'
|
||||||
|
ORDER BY pg_total_relation_size(schemaname || '.' || tablename) DESC
|
||||||
|
LIMIT 10;
|
||||||
|
"
|
||||||
|
|
||||||
for db in "${MINING_DATABASES[@]}"; do
|
for db in "${MINING_DATABASES[@]}"; do
|
||||||
echo -e "${BOLD}Database: $db${NC}"
|
echo -e "${BOLD}Database: $db${NC}"
|
||||||
|
|
||||||
if PGPASSWORD="$POSTGRES_PASSWORD" psql -h "$POSTGRES_HOST" -p "$POSTGRES_PORT" -U "$POSTGRES_USER" -d "$db" -c "SELECT 1" &>/dev/null; then
|
if run_psql "$db" "SELECT 1" &>/dev/null; then
|
||||||
# Get table row counts
|
# Get table stats using Docker or local psql
|
||||||
PGPASSWORD="$POSTGRES_PASSWORD" psql -h "$POSTGRES_HOST" -p "$POSTGRES_PORT" -U "$POSTGRES_USER" -d "$db" -t -c "
|
if docker ps --format '{{.Names}}' 2>/dev/null | grep -q "^${POSTGRES_CONTAINER}$"; then
|
||||||
SELECT tablename AS table,
|
docker exec -e PGPASSWORD="$POSTGRES_PASSWORD" "$POSTGRES_CONTAINER" \
|
||||||
pg_size_pretty(pg_total_relation_size(schemaname || '.' || tablename)) AS size
|
psql -h localhost -U "$POSTGRES_USER" -d "$db" -t -c "$stats_sql" 2>/dev/null || echo " Could not get table stats"
|
||||||
FROM pg_tables
|
else
|
||||||
WHERE schemaname = 'public'
|
PGPASSWORD="$POSTGRES_PASSWORD" psql -h "$POSTGRES_HOST" -p "$POSTGRES_PORT" -U "$POSTGRES_USER" -d "$db" -t -c "$stats_sql" 2>/dev/null || echo " Could not get table stats"
|
||||||
ORDER BY pg_total_relation_size(schemaname || '.' || tablename) DESC
|
fi
|
||||||
LIMIT 10;
|
|
||||||
" 2>/dev/null || echo " Could not get table stats"
|
|
||||||
else
|
else
|
||||||
echo " Database not available"
|
echo " Database not available"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue