package main import ( "TsDB2/DB" "fmt" "os" "time" ) type Record struct { DB.BaseModel Name string `vrtx:"maxlen:32"` Age int64 Score int64 } const dbPath = "stress_small.db" func testConfig(bpCapacity int, dirtyThreshold int, rows int) (success bool, elapsed time.Duration, errMsg string) { os.Remove(dbPath) db, err := DB.Open(dbPath) if err != nil { return false, 0, fmt.Sprintf("Open failed: %v", err) } defer db.Close() // 设置小配置 db.SetBufferPoolCapacity(bpCapacity) db.SetDirtyThreshold(dirtyThreshold) db.SetAutoCommitDelay(0) // 禁用防抖,只靠脏页阈值 tbl, err := DB.UseTable[Record](db, "test") if err != nil { return false, 0, fmt.Sprintf("UseTable failed: %v", err) } start := time.Now() // 使用 channel 检测死锁(5秒超时) done := make(chan error, 1) go func() { for i := 1; i <= rows; i++ { err := tbl.Insert(&Record{ Name: fmt.Sprintf("Emp%07d", i), Age: int64(20 + i%40), Score: int64(i % 1000), }) if err != nil { done <- fmt.Errorf("Insert failed at row %d: %v", i, err) return } } done <- nil }() select { case err := <-done: elapsed = time.Since(start) if err != nil { return false, elapsed, err.Error() } // 验证数据 db.Commit() count, _ := tbl.Count() if int(count) != rows { return false, elapsed, fmt.Sprintf("Count mismatch: expected %d, got %d", rows, count) } // 重开验证 db.Close() db2, _ := DB.Open(dbPath) defer db2.Close() tbl2, _ := DB.UseTable[Record](db2, "test") count2, _ := tbl2.Count() if int(count2) != rows { return false, elapsed, fmt.Sprintf("After reopen count mismatch: expected %d, got %d", rows, count2) } return true, elapsed, "" case <-time.After(10 * time.Second): return false, time.Since(start), "DEADLOCK DETECTED (10s timeout)" } } func main() { fmt.Println("==============================================") fmt.Println(" 小配置压力测试") fmt.Print("==============================================\n\n") rows := 5000 fmt.Printf("测试场景: 插入 %d 行数据\n\n", rows) fmt.Println("配置组合测试:") fmt.Println(" BP=BufferPool容量, DT=DirtyThreshold") fmt.Println("") // 测试矩阵 configs := []struct { bp int dt int }{ {100, 10}, // 极小 {100, 50}, // 小 {100, 100}, // 小 {200, 50}, // 小 {200, 100}, // 中小 {500, 100}, // 中小 {500, 200}, // 中 {1000, 200}, // 中 {1000, 500}, // 中大 } fmt.Printf("%-8s %-8s %-10s %-10s %s\n", "BP(页)", "DT(页)", "耗时", "结果", "说明") fmt.Println("-------- -------- ---------- ---------- -------------------") passCount := 0 failCount := 0 for _, cfg := range configs { success, elapsed, errMsg := testConfig(cfg.bp, cfg.dt, rows) status := "✅ PASS" detail := fmt.Sprintf("%.2fs", elapsed.Seconds()) if !success { status = "❌ FAIL" detail = errMsg failCount++ } else { passCount++ } memBP := float64(cfg.bp) * 16 / 1024 memDT := float64(cfg.dt) * 16 / 1024 desc := fmt.Sprintf("BP=%.1fMB, DT=%.1fMB", memBP, memDT) fmt.Printf("%-8d %-8d %-10s %-10s %s\n", cfg.bp, cfg.dt, detail, status, desc) } fmt.Println("") fmt.Printf("结果: %d 通过, %d 失败\n", passCount, failCount) if failCount > 0 { fmt.Println("\n⚠️ 发现配置问题,需要调整默认值!") } else { fmt.Println("\n✅ 所有配置都正常工作!") } }