Bladeren bron

test(driver): 生产形态仿真 — 40轮×(预编译批插200行+周期清理触发索引重建)

monitor_metrics 同款结构 (宽二级索引 service_name + ts 索引), GORM 形态
Prepare+Exec, 累计 8000 行穿过批量删→BuildFromSorted 重建→持续插入的完整
循环 (生产 panic 路径), 校验存活行数/二级索引等值命中。含 -race。
yl32940 3 weken geleden
bovenliggende
commit
75f18a4a8b
1 gewijzigde bestanden met toevoegingen van 72 en 0 verwijderingen
  1. 72 0
      DB/driver/prod_shape_sim_test.go

+ 72 - 0
DB/driver/prod_shape_sim_test.go

@@ -0,0 +1,72 @@
+package vrtxsql
+
+import (
+	"database/sql"
+	"fmt"
+	"testing"
+)
+
+// 生产形态仿真: monitor_metrics 同款结构 + GORM 驱动路径 + 周期清理(触发索引重建) + 持续插入。
+func TestProdShapeSimulation(t *testing.T) {
+	dsn := t.TempDir() + "/prod.db"
+	db, err := sql.Open("vrtx", dsn)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer db.Close()
+	if _, err := db.Exec(`CREATE TABLE monitor_metrics (
+		id BIGINT PRIMARY KEY,
+		service_name VARCHAR(128),
+		ts BIGINT,
+		cnt BIGINT)`); err != nil {
+		t.Fatal(err)
+	}
+	if _, err := db.Exec(`CREATE INDEX idx_name ON monitor_metrics (service_name)`); err != nil {
+		t.Fatal(err)
+	}
+	if _, err := db.Exec(`CREATE INDEX idx_ts ON monitor_metrics (ts)`); err != nil {
+		t.Fatal(err)
+	}
+	// GORM 形态: Prepare + 批量循环 Exec (5秒一轮监控的密度, 放大 40 轮)
+	stmt, err := db.Prepare(`INSERT INTO monitor_metrics (id, service_name, ts, cnt) VALUES (?, ?, ?, ?)`)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer stmt.Close()
+	id := int64(0)
+	insertRound := func(n int, base int64) {
+		for i := 0; i < n; i++ {
+			id++
+			svc := fmt.Sprintf("service-%02d-with-a-fairly-long-name-for-wide-secondary-keys", i%17)
+			if _, err := stmt.Exec(id, svc, base+int64(i), int64(i)); err != nil {
+				t.Fatalf("插入 id=%d: %v", id, err)
+			}
+		}
+	}
+	deleteBelow := func(bound int64) {
+		if _, err := db.Exec(`DELETE FROM monitor_metrics WHERE ts < ?`, bound); err != nil {
+			t.Fatalf("清理 ts<%d: %v", bound, err)
+		}
+	}
+	for round := 0; round < 40; round++ {
+		insertRound(200, int64(round*1000))      // 每轮 200 行 (一行 total + 每服务行)
+		deleteBelow(int64(round*1000 - 500))     // 周期清理 → 触发批量删+索引重建
+	}
+	// 校验: 只有最后一轮的 200 行存活 (早期轮次被后续清理删光)
+	var total int64
+	if err := db.QueryRow(`SELECT COUNT(*) FROM monitor_metrics`).Scan(&total); err != nil {
+		t.Fatal(err)
+	}
+	if total != 200 {
+		t.Fatalf("行数不一致: total=%d 期望 200", total)
+	}
+	var n int64
+	if err := db.QueryRow(`SELECT COUNT(*) FROM monitor_metrics WHERE service_name = ?`,
+		"service-05-with-a-fairly-long-name-for-wide-secondary-keys").Scan(&n); err != nil {
+		t.Fatal(err)
+	}
+	if n == 0 {
+		t.Fatal("二级索引等值查 0 行")
+	}
+	t.Logf("仿真完成: 累计插入 %d 行, 存活 %d, 索引等值命中 %d", id, total, n)
+}