diff --git a/backend/internal/repository/migrations_runner.go b/backend/internal/repository/migrations_runner.go index 9cf3b392..73db0bcb 100644 --- a/backend/internal/repository/migrations_runner.go +++ b/backend/internal/repository/migrations_runner.go @@ -8,6 +8,7 @@ import ( "errors" "fmt" "io/fs" + "log" "sort" "strings" "time" @@ -432,3 +433,51 @@ func pgAdvisoryUnlock(ctx context.Context, db *sql.DB) error { } return nil } + +// CheckUsageLogsPartitioning 检查 usage_logs 表是否已分区。 +// 如未分区且数据量较大,会输出醒目的警告提示运维人员考虑分区。 +func CheckUsageLogsPartitioning(ctx context.Context, db *sql.DB) { + var isPartitioned bool + err := db.QueryRowContext(ctx, ` + SELECT EXISTS( + SELECT 1 + FROM pg_partitioned_table pt + JOIN pg_class c ON c.oid = pt.partrelid + WHERE c.relname = 'usage_logs' + ) + `).Scan(&isPartitioned) + if err != nil { + // 查询失败时静默忽略,不影响启动 + return + } + + if isPartitioned { + return + } + + // 检查数据量 + var rowCount int64 + err = db.QueryRowContext(ctx, `SELECT COUNT(*) FROM usage_logs`).Scan(&rowCount) + if err != nil { + return + } + + // 数据量小于 10 万行时,分区不那么紧急 + if rowCount < 100000 { + return + } + + // 数据量较大且未分区,输出醒目警告 + log.Printf("================================================================================") + log.Printf("⚠️ PERFORMANCE WARNING: usage_logs table is NOT partitioned") + log.Printf(" Current rows: %d (threshold: 100,000)", rowCount) + log.Printf(" Large unpartitioned tables can cause:") + log.Printf(" - Slow queries and dashboard latency") + log.Printf(" - Index bloat and maintenance overhead") + log.Printf(" - Longer backup/restore times") + log.Printf(" Recommended actions:") + log.Printf(" 1. Review migrations/035_usage_logs_partitioning.sql for manual migration") + log.Printf(" 2. Plan partition conversion during low-traffic window") + log.Printf(" 3. Ensure UsageCleanupConfig is enabled for automatic cleanup") + log.Printf("================================================================================") +} diff --git a/backend/internal/setup/setup.go b/backend/internal/setup/setup.go index 5acdbd3b..9a1a82de 100644 --- a/backend/internal/setup/setup.go +++ b/backend/internal/setup/setup.go @@ -362,7 +362,13 @@ func initializeDatabase(cfg *SetupConfig) error { migrationCtx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() - return repository.ApplyMigrations(migrationCtx, db) + if err := repository.ApplyMigrations(migrationCtx, db); err != nil { + return err + } + + // 检查 usage_logs 分区状态(仅在首次部署时提示) + repository.CheckUsageLogsPartitioning(migrationCtx, db) + return nil } func createAdminUser(cfg *SetupConfig) (bool, string, error) {