[#1298] writecache: Add restore-mode flag for Seal command

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
This commit is contained in:
Dmitrii Stepanov 2024-08-06 13:20:33 +03:00
parent 8e51d7849a
commit 5c01bd5be8
11 changed files with 36 additions and 8 deletions

View file

@ -9,6 +9,8 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
const restoreModeFlag = "restore-mode"
var writecacheShardCmd = &cobra.Command{ var writecacheShardCmd = &cobra.Command{
Use: "writecache", Use: "writecache",
Short: "Operations with storage node's write-cache", Short: "Operations with storage node's write-cache",
@ -26,10 +28,12 @@ func sealWritecache(cmd *cobra.Command, _ []string) {
pk := key.Get(cmd) pk := key.Get(cmd)
ignoreErrors, _ := cmd.Flags().GetBool(ignoreErrorsFlag) ignoreErrors, _ := cmd.Flags().GetBool(ignoreErrorsFlag)
restoreMode, _ := cmd.Flags().GetBool(restoreModeFlag)
req := &control.SealWriteCacheRequest{Body: &control.SealWriteCacheRequest_Body{ req := &control.SealWriteCacheRequest{Body: &control.SealWriteCacheRequest_Body{
Shard_ID: getShardIDList(cmd), Shard_ID: getShardIDList(cmd),
IgnoreErrors: ignoreErrors, IgnoreErrors: ignoreErrors,
RestoreMode: restoreMode,
}} }}
signRequest(cmd, pk, req) signRequest(cmd, pk, req)
@ -68,6 +72,7 @@ func initControlShardsWritecacheCmd() {
ff.StringSlice(shardIDFlag, nil, "List of shard IDs in base58 encoding") ff.StringSlice(shardIDFlag, nil, "List of shard IDs in base58 encoding")
ff.Bool(shardAllFlag, false, "Process all shards") ff.Bool(shardAllFlag, false, "Process all shards")
ff.Bool(ignoreErrorsFlag, true, "Skip invalid/unreadable objects") ff.Bool(ignoreErrorsFlag, true, "Skip invalid/unreadable objects")
ff.Bool(restoreModeFlag, false, "Restore writecache's mode after sealing")
sealWritecacheShardCmd.MarkFlagsMutuallyExclusive(shardIDFlag, shardAllFlag) sealWritecacheShardCmd.MarkFlagsMutuallyExclusive(shardIDFlag, shardAllFlag)
} }

View file

@ -70,6 +70,7 @@ func (e *StorageEngine) FlushWriteCache(ctx context.Context, p FlushWriteCachePr
type SealWriteCachePrm struct { type SealWriteCachePrm struct {
ShardIDs []*shard.ID ShardIDs []*shard.ID
IgnoreErrors bool IgnoreErrors bool
RestoreMode bool
} }
type ShardSealResult struct { type ShardSealResult struct {
@ -88,6 +89,7 @@ func (e *StorageEngine) SealWriteCache(ctx context.Context, prm SealWriteCachePr
trace.WithAttributes( trace.WithAttributes(
attribute.Int("shard_id_count", len(prm.ShardIDs)), attribute.Int("shard_id_count", len(prm.ShardIDs)),
attribute.Bool("ignore_errors", prm.IgnoreErrors), attribute.Bool("ignore_errors", prm.IgnoreErrors),
attribute.Bool("restore_mode", prm.RestoreMode),
)) ))
defer span.End() defer span.End()
@ -114,7 +116,7 @@ func (e *StorageEngine) SealWriteCache(ctx context.Context, prm SealWriteCachePr
return nil return nil
} }
err := sh.SealWriteCache(egCtx, shard.SealWriteCachePrm{IgnoreErrors: prm.IgnoreErrors}) err := sh.SealWriteCache(egCtx, shard.SealWriteCachePrm{IgnoreErrors: prm.IgnoreErrors, RestoreMode: prm.RestoreMode})
resGuard.Lock() resGuard.Lock()
defer resGuard.Unlock() defer resGuard.Unlock()

View file

@ -4,6 +4,7 @@ import (
"context" "context"
"errors" "errors"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/writecache"
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace" "go.opentelemetry.io/otel/trace"
@ -59,6 +60,7 @@ func (s *Shard) FlushWriteCache(ctx context.Context, p FlushWriteCachePrm) error
type SealWriteCachePrm struct { type SealWriteCachePrm struct {
IgnoreErrors bool IgnoreErrors bool
RestoreMode bool
} }
// SealWriteCache flushes all data from the write-cache and moves it to degraded read only mode. // SealWriteCache flushes all data from the write-cache and moves it to degraded read only mode.
@ -67,6 +69,7 @@ func (s *Shard) SealWriteCache(ctx context.Context, p SealWriteCachePrm) error {
trace.WithAttributes( trace.WithAttributes(
attribute.String("shard_id", s.ID().String()), attribute.String("shard_id", s.ID().String()),
attribute.Bool("ignore_errors", p.IgnoreErrors), attribute.Bool("ignore_errors", p.IgnoreErrors),
attribute.Bool("restore_mode", p.RestoreMode),
)) ))
defer span.End() defer span.End()
@ -84,5 +87,5 @@ func (s *Shard) SealWriteCache(ctx context.Context, p SealWriteCachePrm) error {
return ErrDegradedMode return ErrDegradedMode
} }
return s.writeCache.Seal(ctx, p.IgnoreErrors) return s.writeCache.Seal(ctx, writecache.SealPrm{IgnoreErrors: p.IgnoreErrors, RestoreMode: p.RestoreMode})
} }

View file

@ -9,20 +9,29 @@ import (
"go.opentelemetry.io/otel/trace" "go.opentelemetry.io/otel/trace"
) )
func (c *cache) Seal(ctx context.Context, ignoreErrors bool) error { func (c *cache) Seal(ctx context.Context, prm SealPrm) error {
ctx, span := tracing.StartSpanFromContext(ctx, "writecache.Seal", ctx, span := tracing.StartSpanFromContext(ctx, "writecache.Seal",
trace.WithAttributes( trace.WithAttributes(
attribute.Bool("ignore_errors", ignoreErrors), attribute.Bool("ignore_errors", prm.IgnoreErrors),
attribute.Bool("restore_mode", prm.RestoreMode),
)) ))
defer span.End() defer span.End()
c.modeMtx.Lock() c.modeMtx.Lock()
defer c.modeMtx.Unlock() defer c.modeMtx.Unlock()
sourceMode := c.mode
// flush will be done by setMode // flush will be done by setMode
err := c.setMode(ctx, mode.DegradedReadOnly, ignoreErrors) err := c.setMode(ctx, mode.DegradedReadOnly, prm.IgnoreErrors)
if err == nil { if err != nil {
c.metrics.SetMode(mode.ComponentDisabled) return err
}
c.metrics.SetMode(mode.ComponentDisabled)
if prm.RestoreMode {
err = c.setMode(ctx, sourceMode, prm.IgnoreErrors)
if err == nil {
c.metrics.SetMode(mode.ConvertToComponentMode(sourceMode))
}
} }
return err return err
} }

View file

@ -20,6 +20,11 @@ type Info struct {
Path string Path string
} }
type SealPrm struct {
IgnoreErrors bool
RestoreMode bool
}
// Cache represents write-cache for objects. // Cache represents write-cache for objects.
type Cache interface { type Cache interface {
Get(ctx context.Context, address oid.Address) (*objectSDK.Object, error) Get(ctx context.Context, address oid.Address) (*objectSDK.Object, error)
@ -36,7 +41,7 @@ type Cache interface {
SetLogger(*logger.Logger) SetLogger(*logger.Logger)
DumpInfo() Info DumpInfo() Info
Flush(context.Context, bool, bool) error Flush(context.Context, bool, bool) error
Seal(context.Context, bool) error Seal(context.Context, SealPrm) error
Init() error Init() error
Open(ctx context.Context, mode mode.Mode) error Open(ctx context.Context, mode mode.Mode) error

Binary file not shown.

View file

@ -19,6 +19,7 @@ func (s *Server) SealWriteCache(ctx context.Context, req *control.SealWriteCache
prm := engine.SealWriteCachePrm{ prm := engine.SealWriteCachePrm{
ShardIDs: s.getShardIDList(req.GetBody().GetShard_ID()), ShardIDs: s.getShardIDList(req.GetBody().GetShard_ID()),
IgnoreErrors: req.GetBody().GetIgnoreErrors(), IgnoreErrors: req.GetBody().GetIgnoreErrors(),
RestoreMode: req.GetBody().GetRestoreMode(),
} }
res, err := s.s.SealWriteCache(ctx, prm) res, err := s.s.SealWriteCache(ctx, prm)

Binary file not shown.

View file

@ -655,6 +655,9 @@ message SealWriteCacheRequest {
// Flag indicating whether object read errors should be ignored. // Flag indicating whether object read errors should be ignored.
bool ignore_errors = 2; bool ignore_errors = 2;
// If true, then writecache will be sealed, but mode will be restored to the current one.
bool restore_mode = 4;
} }
Body body = 1; Body body = 1;

Binary file not shown.

Binary file not shown.