|
|
|
@ -28,6 +28,7 @@ const (
|
|
|
|
|
const (
|
|
|
|
|
metaFileName = "meta.json"
|
|
|
|
|
tmpSuffix = ".tmp"
|
|
|
|
|
fullNeededFile = "FULL_NEEDED"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// stats captures stats for the Store.
|
|
|
|
@ -69,6 +70,7 @@ func (s *LockingSink) Cancel() error {
|
|
|
|
|
// Store stores Snapshots.
|
|
|
|
|
type Store struct {
|
|
|
|
|
dir string
|
|
|
|
|
fullNeededPath string
|
|
|
|
|
sinkMu sync.Mutex
|
|
|
|
|
logger *log.Logger
|
|
|
|
|
}
|
|
|
|
@ -81,6 +83,7 @@ func NewStore(dir string) (*Store, error) {
|
|
|
|
|
|
|
|
|
|
str := &Store{
|
|
|
|
|
dir: dir,
|
|
|
|
|
fullNeededPath: filepath.Join(dir, fullNeededFile),
|
|
|
|
|
logger: log.New(os.Stderr, "[snapshot-store] ", log.LstdFlags),
|
|
|
|
|
}
|
|
|
|
|
str.logger.Printf("store initialized using %s", dir)
|
|
|
|
@ -153,6 +156,9 @@ func (s *Store) Open(id string) (*raft.SnapshotMeta, io.ReadCloser, error) {
|
|
|
|
|
|
|
|
|
|
// FullNeeded returns true if a full snapshot is needed.
|
|
|
|
|
func (s *Store) FullNeeded() (bool, error) {
|
|
|
|
|
if fileExists(s.fullNeededPath) {
|
|
|
|
|
return true, nil
|
|
|
|
|
}
|
|
|
|
|
snaps, err := s.getSnapshots()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return false, err
|
|
|
|
@ -160,6 +166,16 @@ func (s *Store) FullNeeded() (bool, error) {
|
|
|
|
|
return len(snaps) == 0, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SetFullNeeded sets the flag that indicates a full snapshot is needed.
|
|
|
|
|
// This flag will be cleared when a snapshot is successfully persisted.
|
|
|
|
|
func (s *Store) SetFullNeeded() error {
|
|
|
|
|
f, err := os.Create(s.fullNeededPath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
return f.Close()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Stats returns stats about the Snapshot Store.
|
|
|
|
|
func (s *Store) Stats() (map[string]interface{}, error) {
|
|
|
|
|
snapshots, err := s.getSnapshots()
|
|
|
|
@ -322,6 +338,15 @@ func (s *Store) getDBPath() (string, error) {
|
|
|
|
|
return filepath.Join(s.dir, snapshots[len(snapshots)-1].ID+".db"), nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// unsetFullNeeded removes the flag that indicates a full snapshot is needed.
|
|
|
|
|
func (s *Store) unsetFullNeeded() error {
|
|
|
|
|
err := os.Remove(s.fullNeededPath)
|
|
|
|
|
if err != nil && !os.IsNotExist(err) {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RemoveAllTmpSnapshotData removes all temporary Snapshot data from the directory.
|
|
|
|
|
// This process is defined as follows: for every directory in dir, if the directory
|
|
|
|
|
// is a temporary directory, remove the directory. Then remove all other files
|
|
|
|
|