[#1992] writecache: Allow to open in NOSYNC mode

Applicable only to FSTree as we cannot handle corrupted databases
properly yet.

Signed-off-by: Evgenii Stratonikov <evgeniy@morphbits.ru>
This commit is contained in:
Evgenii Stratonikov 2022-10-28 13:09:38 +03:00 committed by fyrchik
parent b6930f2219
commit 98a152256b
8 changed files with 33 additions and 9 deletions

View file

@ -129,6 +129,7 @@ type shardCfg struct {
maxObjSize uint64 maxObjSize uint64
flushWorkerCount int flushWorkerCount int
sizeLimit uint64 sizeLimit uint64
noSync bool
} }
piloramaCfg struct { piloramaCfg struct {
@ -219,6 +220,7 @@ func (a *applicationConfiguration) readConfig(c *config.Config) error {
wc.smallObjectSize = writeCacheCfg.SmallObjectSize() wc.smallObjectSize = writeCacheCfg.SmallObjectSize()
wc.flushWorkerCount = writeCacheCfg.WorkersNumber() wc.flushWorkerCount = writeCacheCfg.WorkersNumber()
wc.sizeLimit = writeCacheCfg.SizeLimit() wc.sizeLimit = writeCacheCfg.SizeLimit()
wc.noSync = writeCacheCfg.NoSync()
} }
// blobstor with substorages // blobstor with substorages
@ -644,7 +646,7 @@ func (c *cfg) shardOpts() []shardOptsWithID {
writecache.WithSmallObjectSize(wcRead.smallObjectSize), writecache.WithSmallObjectSize(wcRead.smallObjectSize),
writecache.WithFlushWorkersCount(wcRead.flushWorkerCount), writecache.WithFlushWorkersCount(wcRead.flushWorkerCount),
writecache.WithMaxCacheSize(wcRead.sizeLimit), writecache.WithMaxCacheSize(wcRead.sizeLimit),
writecache.WithNoSync(wcRead.noSync),
writecache.WithLogger(c.log), writecache.WithLogger(c.log),
) )
} }

View file

@ -68,6 +68,7 @@ func TestEngineSection(t *testing.T) {
require.Equal(t, pl.MaxBatchSize(), 200) require.Equal(t, pl.MaxBatchSize(), 200)
require.Equal(t, false, wc.Enabled()) require.Equal(t, false, wc.Enabled())
require.Equal(t, true, wc.NoSync())
require.Equal(t, "tmp/0/cache", wc.Path()) require.Equal(t, "tmp/0/cache", wc.Path())
require.EqualValues(t, 16384, wc.SmallObjectSize()) require.EqualValues(t, 16384, wc.SmallObjectSize())
@ -113,6 +114,7 @@ func TestEngineSection(t *testing.T) {
require.Equal(t, 100, pl.MaxBatchSize()) require.Equal(t, 100, pl.MaxBatchSize())
require.Equal(t, true, wc.Enabled()) require.Equal(t, true, wc.Enabled())
require.Equal(t, false, wc.NoSync())
require.Equal(t, "tmp/1/cache", wc.Path()) require.Equal(t, "tmp/1/cache", wc.Path())
require.EqualValues(t, 16384, wc.SmallObjectSize()) require.EqualValues(t, 16384, wc.SmallObjectSize())

View file

@ -115,6 +115,13 @@ func (x *Config) SizeLimit() uint64 {
return SizeLimitDefault return SizeLimitDefault
} }
// NoSync returns the value of "no_sync" config parameter.
//
// Returns false if the value is not a boolean.
func (x *Config) NoSync() bool {
return config.BoolSafe((*config.Config)(x), "no_sync")
}
// BoltDB returns config instance for querying bolt db specific parameters. // BoltDB returns config instance for querying bolt db specific parameters.
func (x *Config) BoltDB() *boltdbconfig.Config { func (x *Config) BoltDB() *boltdbconfig.Config {
return (*boltdbconfig.Config)(x) return (*boltdbconfig.Config)(x)

View file

@ -92,6 +92,7 @@ NEOFS_STORAGE_SHARD_0_RESYNC_METABASE=false
NEOFS_STORAGE_SHARD_0_MODE=read-only NEOFS_STORAGE_SHARD_0_MODE=read-only
### Write cache config ### Write cache config
NEOFS_STORAGE_SHARD_0_WRITECACHE_ENABLED=false NEOFS_STORAGE_SHARD_0_WRITECACHE_ENABLED=false
NEOFS_STORAGE_SHARD_0_WRITECACHE_NO_SYNC=true
NEOFS_STORAGE_SHARD_0_WRITECACHE_PATH=tmp/0/cache NEOFS_STORAGE_SHARD_0_WRITECACHE_PATH=tmp/0/cache
NEOFS_STORAGE_SHARD_0_WRITECACHE_SMALL_OBJECT_SIZE=16384 NEOFS_STORAGE_SHARD_0_WRITECACHE_SMALL_OBJECT_SIZE=16384
NEOFS_STORAGE_SHARD_0_WRITECACHE_MAX_OBJECT_SIZE=134217728 NEOFS_STORAGE_SHARD_0_WRITECACHE_MAX_OBJECT_SIZE=134217728

View file

@ -137,6 +137,7 @@
"resync_metabase": false, "resync_metabase": false,
"writecache": { "writecache": {
"enabled": false, "enabled": false,
"no_sync": true,
"path": "tmp/0/cache", "path": "tmp/0/cache",
"small_object_size": 16384, "small_object_size": 16384,
"max_object_size": 134217728, "max_object_size": 134217728,

View file

@ -157,6 +157,7 @@ storage:
writecache: writecache:
enabled: false enabled: false
no_sync: true
path: tmp/0/cache # write-cache root directory path: tmp/0/cache # write-cache root directory
capacity: 3221225472 # approximate write-cache total size, bytes capacity: 3221225472 # approximate write-cache total size, bytes

View file

@ -50,6 +50,8 @@ type options struct {
maxBatchSize int maxBatchSize int
// maxBatchDelay is the maximum batch wait time for the small object database. // maxBatchDelay is the maximum batch wait time for the small object database.
maxBatchDelay time.Duration maxBatchDelay time.Duration
// noSync is true iff FSTree allows unsynchronized writes.
noSync bool
} }
// WithLogger sets logger. // WithLogger sets logger.
@ -130,3 +132,13 @@ func WithMaxBatchDelay(d time.Duration) Option {
} }
} }
} }
// WithNoSync sets an option to allow returning to caller on PUT before write is persisted.
// Note, that we use this flag for FSTree only and DO NOT use it for a bolt DB because
// we cannot yet properly handle the corrupted database during the startup. This SHOULD NOT
// be relied upon and may be changed in future.
func WithNoSync(noSync bool) Option {
return func(o *options) {
o.noSync = noSync
}
}

View file

@ -56,14 +56,12 @@ func (c *cache) openStore(readOnly bool) error {
} }
} }
c.fsTree = &fstree.FSTree{ c.fsTree = fstree.New(
Info: fstree.Info{ fstree.WithPath(c.path),
Permissions: os.ModePerm, fstree.WithPerm(os.ModePerm),
RootPath: c.path, fstree.WithDepth(1),
}, fstree.WithDirNameLen(1),
Depth: 1, fstree.WithNoSync(c.noSync))
DirNameLen: 1,
}
// Write-cache can be opened multiple times during `SetMode`. // Write-cache can be opened multiple times during `SetMode`.
// flushed map must not be re-created in this case. // flushed map must not be re-created in this case.