mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-09-07 09:05:55 +00:00
scratch space for FB-992: create benchmark for checkpointing
Note also the commented-out debug printf in checkpoint, there as a reference. This is interesting because it turns out that MOST of checkpoint writes is not actually writing new pages in most cases. The actual "pages in WAL : pages in map" ratio is typically around 30:1 apparently. This would likely be different in cases where we were updating existing data, though. This is scratch space to prep for an actual work. The final results will likely be different.
This commit is contained in:
parent
65ab92f364
commit
3ed4487ae2
2 changed files with 87 additions and 0 deletions
|
|
@ -200,6 +200,7 @@ func (db *DB) checkpoint() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// fmt.Printf("checkpoint: walPageN %d, PageMap size %d\n", db.walPageN, db.pageMap.size)
|
||||
for i := 0; i < db.walPageN; i++ {
|
||||
page, err := db.readWALPageAt(i)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import (
|
|||
|
||||
_ "net/http/pprof"
|
||||
|
||||
"github.com/felixge/fgprof"
|
||||
"github.com/molecula/featurebase/v2/rbf"
|
||||
rbfcfg "github.com/molecula/featurebase/v2/rbf/cfg"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
|
@ -336,6 +337,91 @@ func TestDB_MultiTx(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// benchmarkOneCheckpoint
|
||||
func benchmarkOneCheckpoint(b *testing.B) {
|
||||
cfg := rbfcfg.NewDefaultConfig()
|
||||
// extremely low to force checkpointing
|
||||
cfg.MinWALCheckpointSize = rbf.PageSize * 16
|
||||
cfg.MaxWALCheckpointSize = rbf.PageSize * 64
|
||||
var _ rbfcfg.Config
|
||||
db := MustOpenDB(b, cfg)
|
||||
defer MustCloseDB(b, db)
|
||||
|
||||
// Run multiple readers in separate goroutines.
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
for i := 0; i < 4; i++ {
|
||||
g.Go(func() error {
|
||||
for {
|
||||
if ctx.Err() != nil {
|
||||
return nil // cancelled, return no error
|
||||
} else if err := func() error {
|
||||
tx, err := db.Begin(false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
// time.Sleep(time.Duration(rand.Intn(int(3 * time.Millisecond))))
|
||||
|
||||
for i := 0; i < rand.Intn(1000); i++ {
|
||||
v := rand.Intn(1 << 20)
|
||||
if _, err := tx.Contains("x", uint64(v)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// time.Sleep(time.Duration(rand.Intn(int(3 * time.Millisecond))))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Continuously set/clear bits while readers are executing.
|
||||
for i := 0; i < 1000; i++ {
|
||||
func() {
|
||||
tx, err := db.Begin(true)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
for j := 0; j < rand.Intn(100); j++ {
|
||||
v := rand.Intn(1 << 20)
|
||||
if _, err := tx.Add("x", uint64(v)); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// Stop readers & wait.
|
||||
cancel()
|
||||
if err := g.Wait(); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDbCheckpoint(b *testing.B) {
|
||||
out, err := os.Create("cp.out")
|
||||
if err != nil {
|
||||
b.Fatalf("creating log file: %v", err)
|
||||
}
|
||||
done := fgprof.Start(out, fgprof.FormatPprof)
|
||||
for i := 0; i < b.N; i++ {
|
||||
benchmarkOneCheckpoint(b)
|
||||
}
|
||||
done()
|
||||
}
|
||||
|
||||
// better diagnosis of deadlocks/hung situations versus just really slow "Quick" tests.
|
||||
func TestMain(m *testing.M) {
|
||||
l, err := net.Listen("tcp", ":0")
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue