forked from TrueCloudLab/frostfs-node
[#82] services/tree: Save last synchronized height in a persistent storage
Remember the last synchronized height and use it after service restart. Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
This commit is contained in:
parent
3e6fd4c611
commit
6cd806f998
3 changed files with 18 additions and 26 deletions
|
@ -13,6 +13,7 @@ Changelog for FrostFS Node
|
||||||
- Reload config for pprof and metrics on SIGHUP in `neofs-node` (#1868)
|
- Reload config for pprof and metrics on SIGHUP in `neofs-node` (#1868)
|
||||||
- Multiple configs support (#44)
|
- Multiple configs support (#44)
|
||||||
- Parameters `nns-name` and `nns-zone` for command `frostfs-cli container create` (#37)
|
- Parameters `nns-name` and `nns-zone` for command `frostfs-cli container create` (#37)
|
||||||
|
- Tree service now saves the last synchronization height which persists across restarts (#82)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Change `frostfs_node_engine_container_size` to counting sizes of logical objects
|
- Change `frostfs_node_engine_container_size` to counting sizes of logical objects
|
||||||
|
|
|
@ -31,10 +31,8 @@ type Service struct {
|
||||||
syncChan chan struct{}
|
syncChan chan struct{}
|
||||||
syncPool *ants.Pool
|
syncPool *ants.Pool
|
||||||
|
|
||||||
// cnrMap maps contrainer and tree ID to the minimum height which was fetched from _each_ client.
|
// cnrMap contains existing (used) container IDs.
|
||||||
// This allows us to better handle split-brain scenario, because we always synchronize
|
cnrMap map[cidSDK.ID]struct{}
|
||||||
// from the last seen height. The inner map is read-only and should not be modified in-place.
|
|
||||||
cnrMap map[cidSDK.ID]map[string]uint64
|
|
||||||
// cnrMapMtx protects cnrMap
|
// cnrMapMtx protects cnrMap
|
||||||
cnrMapMtx sync.Mutex
|
cnrMapMtx sync.Mutex
|
||||||
}
|
}
|
||||||
|
@ -63,7 +61,7 @@ func New(opts ...Option) *Service {
|
||||||
s.replicateLocalCh = make(chan applyOp)
|
s.replicateLocalCh = make(chan applyOp)
|
||||||
s.replicationTasks = make(chan replicationTask, s.replicatorWorkerCount)
|
s.replicationTasks = make(chan replicationTask, s.replicatorWorkerCount)
|
||||||
s.containerCache.init(s.containerCacheSize)
|
s.containerCache.init(s.containerCacheSize)
|
||||||
s.cnrMap = make(map[cidSDK.ID]map[string]uint64)
|
s.cnrMap = make(map[cidSDK.ID]struct{})
|
||||||
s.syncChan = make(chan struct{})
|
s.syncChan = make(chan struct{})
|
||||||
s.syncPool, _ = ants.NewPool(defaultSyncWorkerCount)
|
s.syncPool, _ = ants.NewPool(defaultSyncWorkerCount)
|
||||||
|
|
||||||
|
|
|
@ -86,30 +86,23 @@ func (s *Service) synchronizeAllTrees(ctx context.Context, cid cid.ID) error {
|
||||||
return fmt.Errorf("could not fetch tree ID list: %w", outErr)
|
return fmt.Errorf("could not fetch tree ID list: %w", outErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.cnrMapMtx.Lock()
|
|
||||||
oldStatus := s.cnrMap[cid]
|
|
||||||
s.cnrMapMtx.Unlock()
|
|
||||||
|
|
||||||
syncStatus := map[string]uint64{}
|
|
||||||
for i := range treesToSync {
|
|
||||||
syncStatus[treesToSync[i]] = 0
|
|
||||||
}
|
|
||||||
for tid := range oldStatus {
|
|
||||||
if _, ok := syncStatus[tid]; ok {
|
|
||||||
syncStatus[tid] = oldStatus[tid]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tid := range treesToSync {
|
for _, tid := range treesToSync {
|
||||||
h := s.synchronizeTree(ctx, d, syncStatus[tid], tid, nodes)
|
h, err := s.forest.TreeLastSyncHeight(d.CID, tid)
|
||||||
if syncStatus[tid] < h {
|
if err != nil && !errors.Is(err, pilorama.ErrTreeNotFound) {
|
||||||
syncStatus[tid] = h
|
s.log.Warn("could not get last synchronized height for a tree",
|
||||||
|
zap.Stringer("cid", d.CID),
|
||||||
|
zap.String("tree", tid))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
newHeight := s.synchronizeTree(ctx, d, h, tid, nodes)
|
||||||
|
if h < newHeight {
|
||||||
|
if err := s.forest.TreeUpdateLastSyncHeight(d.CID, tid, newHeight); err != nil {
|
||||||
|
s.log.Warn("could not update last synchronized height for a tree",
|
||||||
|
zap.Stringer("cid", d.CID),
|
||||||
|
zap.String("tree", tid))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s.cnrMapMtx.Lock()
|
|
||||||
s.cnrMap[cid] = syncStatus
|
|
||||||
s.cnrMapMtx.Unlock()
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue