prod_shape_sim_test.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package vrtxsql
  2. import (
  3. "database/sql"
  4. "fmt"
  5. "testing"
  6. )
  7. // 生产形态仿真: monitor_metrics 同款结构 + GORM 驱动路径 + 周期清理(触发索引重建) + 持续插入。
  8. func TestProdShapeSimulation(t *testing.T) {
  9. dsn := t.TempDir() + "/prod.db"
  10. db, err := sql.Open("vrtx", dsn)
  11. if err != nil {
  12. t.Fatal(err)
  13. }
  14. defer db.Close()
  15. if _, err := db.Exec(`CREATE TABLE monitor_metrics (
  16. id BIGINT PRIMARY KEY,
  17. service_name VARCHAR(128),
  18. ts BIGINT,
  19. cnt BIGINT)`); err != nil {
  20. t.Fatal(err)
  21. }
  22. if _, err := db.Exec(`CREATE INDEX idx_name ON monitor_metrics (service_name)`); err != nil {
  23. t.Fatal(err)
  24. }
  25. if _, err := db.Exec(`CREATE INDEX idx_ts ON monitor_metrics (ts)`); err != nil {
  26. t.Fatal(err)
  27. }
  28. // GORM 形态: Prepare + 批量循环 Exec (5秒一轮监控的密度, 放大 40 轮)
  29. stmt, err := db.Prepare(`INSERT INTO monitor_metrics (id, service_name, ts, cnt) VALUES (?, ?, ?, ?)`)
  30. if err != nil {
  31. t.Fatal(err)
  32. }
  33. defer stmt.Close()
  34. id := int64(0)
  35. insertRound := func(n int, base int64) {
  36. for i := 0; i < n; i++ {
  37. id++
  38. svc := fmt.Sprintf("service-%02d-with-a-fairly-long-name-for-wide-secondary-keys", i%17)
  39. if _, err := stmt.Exec(id, svc, base+int64(i), int64(i)); err != nil {
  40. t.Fatalf("插入 id=%d: %v", id, err)
  41. }
  42. }
  43. }
  44. deleteBelow := func(bound int64) {
  45. if _, err := db.Exec(`DELETE FROM monitor_metrics WHERE ts < ?`, bound); err != nil {
  46. t.Fatalf("清理 ts<%d: %v", bound, err)
  47. }
  48. }
  49. for round := 0; round < 40; round++ {
  50. insertRound(200, int64(round*1000)) // 每轮 200 行 (一行 total + 每服务行)
  51. deleteBelow(int64(round*1000 - 500)) // 周期清理 → 触发批量删+索引重建
  52. }
  53. // 校验: 只有最后一轮的 200 行存活 (早期轮次被后续清理删光)
  54. var total int64
  55. if err := db.QueryRow(`SELECT COUNT(*) FROM monitor_metrics`).Scan(&total); err != nil {
  56. t.Fatal(err)
  57. }
  58. if total != 200 {
  59. t.Fatalf("行数不一致: total=%d 期望 200", total)
  60. }
  61. var n int64
  62. if err := db.QueryRow(`SELECT COUNT(*) FROM monitor_metrics WHERE service_name = ?`,
  63. "service-05-with-a-fairly-long-name-for-wide-secondary-keys").Scan(&n); err != nil {
  64. t.Fatal(err)
  65. }
  66. if n == 0 {
  67. t.Fatal("二级索引等值查 0 行")
  68. }
  69. t.Logf("仿真完成: 累计插入 %d 行, 存活 %d, 索引等值命中 %d", id, total, n)
  70. }