From bd418bd82b005a90af54e098626f94f2726bd3ac Mon Sep 17 00:00:00 2001 From: finley Date: Mon, 8 May 2023 23:36:56 +0800 Subject: [PATCH] bug fix: loadRdb forget to load set data struct --- aof/aof.go | 15 ++++++++++----- database/persistence.go | 11 ++++++++++- database/persistence_test.go | 2 ++ database/server.go | 14 +++++++++++++- redis.conf | 2 +- 5 files changed, 36 insertions(+), 8 deletions(-) diff --git a/aof/aof.go b/aof/aof.go index 5e171f6..f045b9d 100644 --- a/aof/aof.go +++ b/aof/aof.go @@ -248,6 +248,15 @@ func (persister *Persister) LoadAof(maxBytes int) { } } +// Fsync flushes aof file to disk +func (persister *Persister) Fsync() { + persister.pausingAof.Lock() + if err := persister.aofFile.Sync(); err != nil { + logger.Errorf("fsync failed: %v", err) + } + persister.pausingAof.Unlock() +} + // Close gracefully stops aof persistence procedure func (persister *Persister) Close() { if persister.aofFile != nil { @@ -268,11 +277,7 @@ func (persister *Persister) fsyncEverySecond() { for { select { case <-ticker.C: - persister.pausingAof.Lock() - if err := persister.aofFile.Sync(); err != nil { - logger.Errorf("fsync failed: %v", err) - } - persister.pausingAof.Unlock() + persister.Fsync() case <-persister.ctx.Done(): return } diff --git a/database/persistence.go b/database/persistence.go index 6730c5f..b2723c5 100644 --- a/database/persistence.go +++ b/database/persistence.go @@ -9,6 +9,7 @@ import ( "github.com/hdt3213/godis/config" "github.com/hdt3213/godis/datastruct/dict" List "github.com/hdt3213/godis/datastruct/list" + HashSet "github.com/hdt3213/godis/datastruct/set" SortedSet "github.com/hdt3213/godis/datastruct/sortedset" "github.com/hdt3213/godis/interface/database" "github.com/hdt3213/rdb/core" @@ -61,6 +62,15 @@ func (server *Server) LoadRDB(dec *core.Decoder) error { entity = &database.DataEntity{ Data: hash, } + case rdb.SetType: + setObj := o.(*rdb.SetObject) + set := HashSet.Make() + for _, mem := range setObj.Members { + set.Add(string(mem)) + } + entity = &database.DataEntity{ + Data: set, + } case rdb.ZSetType: zsetObj := o.(*rdb.ZSetObject) zSet := SortedSet.Make() @@ -81,7 +91,6 @@ func (server *Server) LoadRDB(dec *core.Decoder) error { } return true }) - } func NewPersister(db database.DBEngine, filename string, load bool, fsync string) (*aof.Persister, error) { diff --git a/database/persistence_test.go b/database/persistence_test.go index 41a77c6..a73fe00 100644 --- a/database/persistence_test.go +++ b/database/persistence_test.go @@ -32,6 +32,8 @@ func TestLoadRDB(t *testing.T) { asserts.AssertMultiBulkReply(t, result, []string{"1", "1"}) result = rdbDB.Exec(conn, utils.ToCmdLine("ZRange", "zset", "0", "1", "WITHSCORES")) asserts.AssertMultiBulkReply(t, result, []string{"1", "1"}) + result = rdbDB.Exec(conn, utils.ToCmdLine("SCard", "set")) + asserts.AssertIntReply(t, result, 1) config.Properties = &config.ServerProperties{ AppendOnly: false, diff --git a/database/server.go b/database/server.go index 8962c30..52c565c 100644 --- a/database/server.go +++ b/database/server.go @@ -2,6 +2,7 @@ package database import ( "fmt" + "os" "runtime/debug" "strconv" "strings" @@ -35,12 +36,23 @@ type Server struct { masterStatus *masterStatus } +func fileExists(filename string) bool { + info, err := os.Stat(filename) + return err == nil && !info.IsDir() +} + // NewStandaloneServer creates a standalone redis server, with multi database and all other funtions func NewStandaloneServer() *Server { server := &Server{} if config.Properties.Databases == 0 { config.Properties.Databases = 16 } + // creat tmp dir + err := os.MkdirAll(config.GetTmpDir(), os.ModePerm) + if err != nil { + panic(fmt.Errorf("create tmp dir failed: %v", err)) + } + // make db set server.dbSet = make([]*atomic.Value, config.Properties.Databases) for i := range server.dbSet { singleDB := makeDB() @@ -53,13 +65,13 @@ func NewStandaloneServer() *Server { // record aof validAof := false if config.Properties.AppendOnly { + validAof = fileExists(config.Properties.AppendFilename) aofHandler, err := NewPersister(server, config.Properties.AppendFilename, true, config.Properties.AppendFsync) if err != nil { panic(err) } server.bindPersister(aofHandler) - validAof = true } if config.Properties.RDBFilename != "" && !validAof { // load rdb diff --git a/redis.conf b/redis.conf index 6e299ba..deaf734 100644 --- a/redis.conf +++ b/redis.conf @@ -7,4 +7,4 @@ appendfilename appendonly.aof appendfsync everysec aof-use-rdb-preamble yes -#dbfilename test.rdb +dbfilename test.rdb