mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-03 07:06:36 +08:00
58624db397
- Replace retention ALTER DELETE with MATERIALIZE TTL; use TRUNCATE for delete-all - Remove GORM ClickHouse pool; migrate user access log reads to ChConn - Drop query-side trim(remote_addr); enable wait_for_async_insert=1 - Add of_node_traffic_hourly MV and dashboard traffic trend fallback - Add GET /admin/status/clickhouse operational metrics endpoint
74 lines
2.2 KiB
Go
74 lines
2.2 KiB
Go
// Copyright 2026 Arctel.net
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package analytics
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/ClickHouse/clickhouse-go/v2/lib/driver"
|
|
)
|
|
|
|
const (
|
|
// CleanupModeTTLMaterialize expires rows via table TTL instead of ALTER DELETE mutations.
|
|
CleanupModeTTLMaterialize = "ttl_materialize"
|
|
// CleanupModeTruncate removes all rows via TRUNCATE TABLE.
|
|
CleanupModeTruncate = "truncate"
|
|
)
|
|
|
|
// CleanupOutcome describes a non-mutation ClickHouse cleanup operation.
|
|
type CleanupOutcome struct {
|
|
EligibleCount int64
|
|
Mode string
|
|
}
|
|
|
|
func countClickHouseRows(ctx context.Context, conn driver.Conn, countSQL string, countArgs []any) (int64, error) {
|
|
var count uint64
|
|
if err := conn.QueryRow(ctx, countSQL, countArgs...).Scan(&count); err != nil {
|
|
return 0, fmt.Errorf("count clickhouse rows: %w", err)
|
|
}
|
|
return safeInt64Count(count), nil
|
|
}
|
|
|
|
func materializeTableTTL(ctx context.Context, conn driver.Conn, tableName string) error {
|
|
sql := fmt.Sprintf("ALTER TABLE %s MATERIALIZE TTL", tableName)
|
|
if err := conn.Exec(ctx, sql); err != nil {
|
|
return fmt.Errorf("materialize ttl on %s: %w", tableName, err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func expireRowsViaTTL(ctx context.Context, conn driver.Conn, tableName string, countSQL string, countArgs []any) (CleanupOutcome, error) {
|
|
count, err := countClickHouseRows(ctx, conn, countSQL, countArgs)
|
|
if err != nil {
|
|
return CleanupOutcome{}, err
|
|
}
|
|
if count == 0 {
|
|
return CleanupOutcome{Mode: CleanupModeTTLMaterialize}, nil
|
|
}
|
|
if err := materializeTableTTL(ctx, conn, tableName); err != nil {
|
|
return CleanupOutcome{}, err
|
|
}
|
|
return CleanupOutcome{
|
|
EligibleCount: count,
|
|
Mode: CleanupModeTTLMaterialize,
|
|
}, nil
|
|
}
|
|
|
|
func truncateClickHouseTable(ctx context.Context, conn driver.Conn, tableName string) (CleanupOutcome, error) {
|
|
count, err := countClickHouseRows(ctx, conn, "SELECT count() FROM "+tableName, nil)
|
|
if err != nil {
|
|
return CleanupOutcome{}, err
|
|
}
|
|
if count == 0 {
|
|
return CleanupOutcome{Mode: CleanupModeTruncate}, nil
|
|
}
|
|
if err := conn.Exec(ctx, "TRUNCATE TABLE "+tableName); err != nil {
|
|
return CleanupOutcome{}, fmt.Errorf("truncate %s: %w", tableName, err)
|
|
}
|
|
return CleanupOutcome{
|
|
EligibleCount: count,
|
|
Mode: CleanupModeTruncate,
|
|
}, nil
|
|
} |