main.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. package main
  2. import (
  3. "TsDB2/DB"
  4. "fmt"
  5. "os"
  6. "time"
  7. )
  8. type Record struct {
  9. DB.BaseModel
  10. Name string `vrtx:"maxlen:32"`
  11. Age int64
  12. Score int64
  13. }
  14. const dbPath = "stress_small.db"
  15. func testConfig(bpCapacity int, dirtyThreshold int, rows int) (success bool, elapsed time.Duration, errMsg string) {
  16. os.Remove(dbPath)
  17. db, err := DB.Open(dbPath)
  18. if err != nil {
  19. return false, 0, fmt.Sprintf("Open failed: %v", err)
  20. }
  21. defer db.Close()
  22. // 设置小配置
  23. db.SetBufferPoolCapacity(bpCapacity)
  24. db.SetDirtyThreshold(dirtyThreshold)
  25. db.SetAutoCommitDelay(0) // 禁用防抖,只靠脏页阈值
  26. tbl, err := DB.UseTable[Record](db, "test")
  27. if err != nil {
  28. return false, 0, fmt.Sprintf("UseTable failed: %v", err)
  29. }
  30. start := time.Now()
  31. // 使用 channel 检测死锁(5秒超时)
  32. done := make(chan error, 1)
  33. go func() {
  34. for i := 1; i <= rows; i++ {
  35. err := tbl.Insert(&Record{
  36. Name: fmt.Sprintf("Emp%07d", i),
  37. Age: int64(20 + i%40),
  38. Score: int64(i % 1000),
  39. })
  40. if err != nil {
  41. done <- fmt.Errorf("Insert failed at row %d: %v", i, err)
  42. return
  43. }
  44. }
  45. done <- nil
  46. }()
  47. select {
  48. case err := <-done:
  49. elapsed = time.Since(start)
  50. if err != nil {
  51. return false, elapsed, err.Error()
  52. }
  53. // 验证数据
  54. db.Commit()
  55. count, _ := tbl.Count()
  56. if int(count) != rows {
  57. return false, elapsed, fmt.Sprintf("Count mismatch: expected %d, got %d", rows, count)
  58. }
  59. // 重开验证
  60. db.Close()
  61. db2, _ := DB.Open(dbPath)
  62. defer db2.Close()
  63. tbl2, _ := DB.UseTable[Record](db2, "test")
  64. count2, _ := tbl2.Count()
  65. if int(count2) != rows {
  66. return false, elapsed, fmt.Sprintf("After reopen count mismatch: expected %d, got %d", rows, count2)
  67. }
  68. return true, elapsed, ""
  69. case <-time.After(10 * time.Second):
  70. return false, time.Since(start), "DEADLOCK DETECTED (10s timeout)"
  71. }
  72. }
  73. func main() {
  74. fmt.Println("==============================================")
  75. fmt.Println(" 小配置压力测试")
  76. fmt.Print("==============================================\n\n")
  77. rows := 5000
  78. fmt.Printf("测试场景: 插入 %d 行数据\n\n", rows)
  79. fmt.Println("配置组合测试:")
  80. fmt.Println(" BP=BufferPool容量, DT=DirtyThreshold")
  81. fmt.Println("")
  82. // 测试矩阵
  83. configs := []struct {
  84. bp int
  85. dt int
  86. }{
  87. {100, 10}, // 极小
  88. {100, 50}, // 小
  89. {100, 100}, // 小
  90. {200, 50}, // 小
  91. {200, 100}, // 中小
  92. {500, 100}, // 中小
  93. {500, 200}, // 中
  94. {1000, 200}, // 中
  95. {1000, 500}, // 中大
  96. }
  97. fmt.Printf("%-8s %-8s %-10s %-10s %s\n", "BP(页)", "DT(页)", "耗时", "结果", "说明")
  98. fmt.Println("-------- -------- ---------- ---------- -------------------")
  99. passCount := 0
  100. failCount := 0
  101. for _, cfg := range configs {
  102. success, elapsed, errMsg := testConfig(cfg.bp, cfg.dt, rows)
  103. status := "✅ PASS"
  104. detail := fmt.Sprintf("%.2fs", elapsed.Seconds())
  105. if !success {
  106. status = "❌ FAIL"
  107. detail = errMsg
  108. failCount++
  109. } else {
  110. passCount++
  111. }
  112. memBP := float64(cfg.bp) * 16 / 1024
  113. memDT := float64(cfg.dt) * 16 / 1024
  114. desc := fmt.Sprintf("BP=%.1fMB, DT=%.1fMB", memBP, memDT)
  115. fmt.Printf("%-8d %-8d %-10s %-10s %s\n", cfg.bp, cfg.dt, detail, status, desc)
  116. }
  117. fmt.Println("")
  118. fmt.Printf("结果: %d 通过, %d 失败\n", passCount, failCount)
  119. if failCount > 0 {
  120. fmt.Println("\n⚠️ 发现配置问题,需要调整默认值!")
  121. } else {
  122. fmt.Println("\n✅ 所有配置都正常工作!")
  123. }
  124. }