Change mode of shard components #1121
48 changed files with 215 additions and 114 deletions
|
@ -14,7 +14,16 @@ Each mode is characterized by two important properties:
|
||||||
| `read-only` | Read-only mode, only read operations are allowed, metabase is available. |
|
| `read-only` | Read-only mode, only read operations are allowed, metabase is available. |
|
||||||
| `degraded` | Degraded mode in which metabase and write-cache is disabled. It shouldn't be used at all, because metabase can contain important indices, such as LOCK objects info and modifying operation in this mode can lead to unexpected behaviour. The purpose of this mode is to allow PUT/DELETE operations without the metabase if really necessary. |
|
| `degraded` | Degraded mode in which metabase and write-cache is disabled. It shouldn't be used at all, because metabase can contain important indices, such as LOCK objects info and modifying operation in this mode can lead to unexpected behaviour. The purpose of this mode is to allow PUT/DELETE operations without the metabase if really necessary. |
|
||||||
| `degraded-read-only` | Same as `degraded`, but with only read operations allowed. This mode is used during SSD replacement and/or when the metabase error counter exceeds threshold. |
|
| `degraded-read-only` | Same as `degraded`, but with only read operations allowed. This mode is used during SSD replacement and/or when the metabase error counter exceeds threshold. |
|
||||||
| `disabled` | Currently used only in config file to temporarily disable a shard. |
|
| `disabled` | Currently used only in config file to temporarily disable a shard.
|
||||||
|
|
||||||
|
## Shard and Component Status
|
||||||
|
|
||||||
|
| Shard Mode | Metabase Mode | Blobstore Mode | Writecache Mode | Pilorama Mode | Blobovnicza Tree Mode | FSTree Mode |
|
||||||
|
|-----------------------|---------------|----------------|-----------------|---------------|-----------------------|-------------|
|
||||||
|
| `Read-Write` | READ_WRITE | READ_WRITE | READ_WRITE | READ_WRITE | READ_WRITE | READ_WRITE |
|
||||||
|
| `Read-Only` | READ_ONLY | READ_ONLY | READ_ONLY | READ_ONLY | READ_ONLY | READ_ONLY |
|
||||||
|
| `Degraded-Read-Write` | CLOSED | READ_WRITE | CLOSED | CLOSED | READ_WRITE | READ_WRITE |
|
||||||
|
| `Degraded-Read-Only` | CLOSED | READ_ONLY | CLOSED | CLOSED | READ_ONLY | READ_ONLY |
|
||||||
|
|
||||||
## Transition order
|
## Transition order
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/testutil"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/testutil"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger/test"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger/test"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
@ -23,7 +24,7 @@ func TestBlobovniczaTree_Concurrency(t *testing.T) {
|
||||||
WithBlobovniczaShallowWidth(10),
|
WithBlobovniczaShallowWidth(10),
|
||||||
WithBlobovniczaShallowDepth(1),
|
WithBlobovniczaShallowDepth(1),
|
||||||
WithRootPath(t.TempDir()))
|
WithRootPath(t.TempDir()))
|
||||||
require.NoError(t, st.Open(false))
|
require.NoError(t, st.Open(mode.ComponentReadWrite))
|
||||||
require.NoError(t, st.Init())
|
require.NoError(t, st.Init())
|
||||||
defer func() {
|
defer func() {
|
||||||
require.NoError(t, st.Close())
|
require.NoError(t, st.Close())
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
|
@ -16,9 +17,9 @@ import (
|
||||||
var errFailedToChangeExtensionReadOnly = errors.New("failed to change blobovnicza extension: read only mode")
|
var errFailedToChangeExtensionReadOnly = errors.New("failed to change blobovnicza extension: read only mode")
|
||||||
|
|
||||||
// Open opens blobovnicza tree.
|
// Open opens blobovnicza tree.
|
||||||
func (b *Blobovniczas) Open(readOnly bool) error {
|
func (b *Blobovniczas) Open(mode mode.ComponentMode) error {
|
||||||
b.readOnly = readOnly
|
b.readOnly = mode.ReadOnly()
|
||||||
b.metrics.SetMode(readOnly)
|
b.metrics.SetMode(mode)
|
||||||
b.metrics.SetRebuildStatus(rebuildStatusNotStarted)
|
b.metrics.SetRebuildStatus(rebuildStatusNotStarted)
|
||||||
b.openManagers()
|
b.openManagers()
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobovnicza"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobovnicza"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/internal/blobstortest"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/internal/blobstortest"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -54,7 +55,7 @@ func openAndCloseTestTree(t *testing.T, depth, width uint64, path string) {
|
||||||
WithBlobovniczaShallowWidth(width),
|
WithBlobovniczaShallowWidth(width),
|
||||||
WithRootPath(path),
|
WithRootPath(path),
|
||||||
)
|
)
|
||||||
require.NoError(t, blz.Open(false))
|
require.NoError(t, blz.Open(mode.ComponentReadWrite))
|
||||||
require.NoError(t, blz.Init())
|
require.NoError(t, blz.Init())
|
||||||
require.NoError(t, blz.Close())
|
require.NoError(t, blz.Close())
|
||||||
}
|
}
|
||||||
|
@ -85,7 +86,7 @@ func TestObjectsAvailableAfterDepthAndWidthEdit(t *testing.T) {
|
||||||
WithRootPath(rootDir),
|
WithRootPath(rootDir),
|
||||||
)
|
)
|
||||||
|
|
||||||
require.NoError(t, blz.Open(false))
|
require.NoError(t, blz.Open(mode.ComponentReadWrite))
|
||||||
require.NoError(t, blz.Init())
|
require.NoError(t, blz.Init())
|
||||||
|
|
||||||
obj35 := blobstortest.NewObject(10 * 1024)
|
obj35 := blobstortest.NewObject(10 * 1024)
|
||||||
|
@ -123,7 +124,7 @@ func TestObjectsAvailableAfterDepthAndWidthEdit(t *testing.T) {
|
||||||
WithRootPath(rootDir),
|
WithRootPath(rootDir),
|
||||||
)
|
)
|
||||||
|
|
||||||
require.NoError(t, blz.Open(false))
|
require.NoError(t, blz.Open(mode.ComponentReadWrite))
|
||||||
require.NoError(t, blz.Init())
|
require.NoError(t, blz.Init())
|
||||||
|
|
||||||
gRes, err = blz.Get(context.Background(), common.GetPrm{
|
gRes, err = blz.Get(context.Background(), common.GetPrm{
|
||||||
|
@ -160,7 +161,7 @@ func TestObjectsAvailableAfterDepthAndWidthEdit(t *testing.T) {
|
||||||
WithBlobovniczaShallowWidth(5),
|
WithBlobovniczaShallowWidth(5),
|
||||||
WithRootPath(rootDir),
|
WithRootPath(rootDir),
|
||||||
)
|
)
|
||||||
require.NoError(t, blz.Open(false))
|
require.NoError(t, blz.Open(mode.ComponentReadWrite))
|
||||||
require.NoError(t, blz.Init())
|
require.NoError(t, blz.Init())
|
||||||
|
|
||||||
gRes, err = blz.Get(context.Background(), common.GetPrm{
|
gRes, err = blz.Get(context.Background(), common.GetPrm{
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/internal/blobstortest"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/internal/blobstortest"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger/test"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger/test"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
@ -24,7 +25,7 @@ func TestExistsInvalidStorageID(t *testing.T) {
|
||||||
WithBlobovniczaShallowDepth(2),
|
WithBlobovniczaShallowDepth(2),
|
||||||
WithRootPath(dir),
|
WithRootPath(dir),
|
||||||
WithBlobovniczaSize(1<<20))
|
WithBlobovniczaSize(1<<20))
|
||||||
require.NoError(t, b.Open(false))
|
require.NoError(t, b.Open(mode.ComponentReadWrite))
|
||||||
require.NoError(t, b.Init())
|
require.NoError(t, b.Init())
|
||||||
defer func() { require.NoError(t, b.Close()) }()
|
defer func() { require.NoError(t, b.Close()) }()
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||||
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
|
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
@ -18,7 +19,7 @@ func TestIterateSortedLeavesAndDBPathsAreSame(t *testing.T) {
|
||||||
WithRootPath(t.TempDir()),
|
WithRootPath(t.TempDir()),
|
||||||
)
|
)
|
||||||
blz.createDBInAdvance = true
|
blz.createDBInAdvance = true
|
||||||
require.NoError(t, blz.Open(false))
|
require.NoError(t, blz.Open(mode.ComponentReadWrite))
|
||||||
require.NoError(t, blz.Init())
|
require.NoError(t, blz.Init())
|
||||||
defer func() {
|
defer func() {
|
||||||
require.NoError(t, blz.Close())
|
require.NoError(t, blz.Close())
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobovnicza"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobovnicza"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -18,7 +19,7 @@ type Metrics interface {
|
||||||
|
|
||||||
SetParentID(parentID string)
|
SetParentID(parentID string)
|
||||||
|
|
||||||
SetMode(readOnly bool)
|
SetMode(mode.ComponentMode)
|
||||||
Close()
|
Close()
|
||||||
|
|
||||||
SetRebuildStatus(status string)
|
SetRebuildStatus(status string)
|
||||||
|
@ -37,7 +38,7 @@ type Metrics interface {
|
||||||
type noopMetrics struct{}
|
type noopMetrics struct{}
|
||||||
|
|
||||||
func (m *noopMetrics) SetParentID(string) {}
|
func (m *noopMetrics) SetParentID(string) {}
|
||||||
func (m *noopMetrics) SetMode(bool) {}
|
func (m *noopMetrics) SetMode(mode.ComponentMode) {}
|
||||||
func (m *noopMetrics) Close() {}
|
func (m *noopMetrics) Close() {}
|
||||||
func (m *noopMetrics) SetRebuildStatus(string) {}
|
func (m *noopMetrics) SetRebuildStatus(string) {}
|
||||||
func (m *noopMetrics) SetRebuildPercent(uint32) {}
|
func (m *noopMetrics) SetRebuildPercent(uint32) {}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobovnicza"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobovnicza"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/internal/blobstortest"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/internal/blobstortest"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger/test"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger/test"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
||||||
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
|
@ -138,7 +139,7 @@ func testRebuildFailoverValidate(t *testing.T, dir string, obj *objectSDK.Object
|
||||||
WithBlobovniczaSize(100*1024*1024),
|
WithBlobovniczaSize(100*1024*1024),
|
||||||
WithWaitBeforeDropDB(0),
|
WithWaitBeforeDropDB(0),
|
||||||
WithOpenedCacheSize(1000))
|
WithOpenedCacheSize(1000))
|
||||||
require.NoError(t, b.Open(false))
|
require.NoError(t, b.Open(mode.ComponentReadWrite))
|
||||||
require.NoError(t, b.Init())
|
require.NoError(t, b.Init())
|
||||||
|
|
||||||
var dPrm common.DeletePrm
|
var dPrm common.DeletePrm
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/internal/blobstortest"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/internal/blobstortest"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger/test"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger/test"
|
||||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
@ -53,7 +54,7 @@ func TestBlobovniczaTreeRebuildLargeObject(t *testing.T) {
|
||||||
WithWaitBeforeDropDB(0),
|
WithWaitBeforeDropDB(0),
|
||||||
WithOpenedCacheSize(1000),
|
WithOpenedCacheSize(1000),
|
||||||
WithMoveBatchSize(3))
|
WithMoveBatchSize(3))
|
||||||
require.NoError(t, b.Open(false))
|
require.NoError(t, b.Open(mode.ComponentReadWrite))
|
||||||
require.NoError(t, b.Init())
|
require.NoError(t, b.Init())
|
||||||
|
|
||||||
obj := blobstortest.NewObject(64 * 1024) // 64KB object
|
obj := blobstortest.NewObject(64 * 1024) // 64KB object
|
||||||
|
@ -81,7 +82,7 @@ func TestBlobovniczaTreeRebuildLargeObject(t *testing.T) {
|
||||||
WithWaitBeforeDropDB(0),
|
WithWaitBeforeDropDB(0),
|
||||||
WithOpenedCacheSize(1000),
|
WithOpenedCacheSize(1000),
|
||||||
WithMoveBatchSize(3))
|
WithMoveBatchSize(3))
|
||||||
require.NoError(t, b.Open(false))
|
require.NoError(t, b.Open(mode.ComponentReadWrite))
|
||||||
require.NoError(t, b.Init())
|
require.NoError(t, b.Init())
|
||||||
|
|
||||||
metaStub := &storageIDUpdateStub{
|
metaStub := &storageIDUpdateStub{
|
||||||
|
@ -120,7 +121,7 @@ func testBlobovniczaTreeRebuildHelper(t *testing.T, sourceDepth, sourceWidth, ta
|
||||||
WithWaitBeforeDropDB(0),
|
WithWaitBeforeDropDB(0),
|
||||||
WithOpenedCacheSize(1000),
|
WithOpenedCacheSize(1000),
|
||||||
WithMoveBatchSize(3))
|
WithMoveBatchSize(3))
|
||||||
require.NoError(t, b.Open(false))
|
require.NoError(t, b.Open(mode.ComponentReadWrite))
|
||||||
require.NoError(t, b.Init())
|
require.NoError(t, b.Init())
|
||||||
|
|
||||||
eg, egCtx := errgroup.WithContext(context.Background())
|
eg, egCtx := errgroup.WithContext(context.Background())
|
||||||
|
@ -161,7 +162,7 @@ func testBlobovniczaTreeRebuildHelper(t *testing.T, sourceDepth, sourceWidth, ta
|
||||||
WithWaitBeforeDropDB(0),
|
WithWaitBeforeDropDB(0),
|
||||||
WithOpenedCacheSize(1000),
|
WithOpenedCacheSize(1000),
|
||||||
WithMoveBatchSize(50))
|
WithMoveBatchSize(50))
|
||||||
require.NoError(t, b.Open(false))
|
require.NoError(t, b.Open(mode.ComponentReadWrite))
|
||||||
require.NoError(t, b.Init())
|
require.NoError(t, b.Init())
|
||||||
|
|
||||||
for addr, storageID := range storageIDs {
|
for addr, storageID := range storageIDs {
|
||||||
|
|
|
@ -4,12 +4,13 @@ import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/compression"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/compression"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Storage represents key-value object storage.
|
// Storage represents key-value object storage.
|
||||||
// It is used as a building block for a blobstor of a shard.
|
// It is used as a building block for a blobstor of a shard.
|
||||||
type Storage interface {
|
type Storage interface {
|
||||||
Open(readOnly bool) error
|
Open(mode mode.ComponentMode) error
|
||||||
Init() error
|
Init() error
|
||||||
Close() error
|
Close() error
|
||||||
|
|
||||||
|
|
|
@ -27,15 +27,14 @@ func (b *BlobStor) Open(ctx context.Context, mode mode.Mode) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BlobStor) openBlobStor(ctx context.Context, mode mode.Mode) error {
|
func (b *BlobStor) openBlobStor(ctx context.Context, mod mode.Mode) error {
|
||||||
readOnly := mode.ReadOnly()
|
|
||||||
for i := range b.storage {
|
for i := range b.storage {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return ctx.Err()
|
return ctx.Err()
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
err := b.storage[i].Storage.Open(readOnly)
|
err := b.storage[i].Storage.Open(mode.ConvertToComponentMode(mod))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
package fstree
|
package fstree
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Open implements common.Storage.
|
// Open implements common.Storage.
|
||||||
func (t *FSTree) Open(ro bool) error {
|
func (t *FSTree) Open(mode mode.ComponentMode) error {
|
||||||
t.readOnly = ro
|
t.readOnly = mode.ReadOnly()
|
||||||
t.metrics.SetMode(ro)
|
t.metrics.SetMode(mode)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
|
||||||
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
|
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
|
||||||
|
@ -43,7 +44,7 @@ func TestObjectCounter(t *testing.T) {
|
||||||
WithDepth(2),
|
WithDepth(2),
|
||||||
WithDirNameLen(2),
|
WithDirNameLen(2),
|
||||||
WithFileCounter(counter))
|
WithFileCounter(counter))
|
||||||
require.NoError(t, fst.Open(false))
|
require.NoError(t, fst.Open(mode.ComponentReadWrite))
|
||||||
require.NoError(t, fst.Init())
|
require.NoError(t, fst.Init())
|
||||||
|
|
||||||
counterValue := counter.Value()
|
counterValue := counter.Value()
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
package fstree
|
package fstree
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||||
|
)
|
||||||
|
|
||||||
type Metrics interface {
|
type Metrics interface {
|
||||||
SetParentID(parentID string)
|
SetParentID(parentID string)
|
||||||
|
|
||||||
SetMode(readOnly bool)
|
SetMode(mode mode.ComponentMode)
|
||||||
Close()
|
Close()
|
||||||
|
|
||||||
Iterate(d time.Duration, success bool)
|
Iterate(d time.Duration, success bool)
|
||||||
|
@ -20,7 +24,7 @@ type Metrics interface {
|
||||||
type noopMetrics struct{}
|
type noopMetrics struct{}
|
||||||
|
|
||||||
func (m *noopMetrics) SetParentID(string) {}
|
func (m *noopMetrics) SetParentID(string) {}
|
||||||
func (m *noopMetrics) SetMode(bool) {}
|
func (m *noopMetrics) SetMode(mode.ComponentMode) {}
|
||||||
func (m *noopMetrics) Close() {}
|
func (m *noopMetrics) Close() {}
|
||||||
func (m *noopMetrics) Iterate(time.Duration, bool) {}
|
func (m *noopMetrics) Iterate(time.Duration, bool) {}
|
||||||
func (m *noopMetrics) Delete(time.Duration, bool) {}
|
func (m *noopMetrics) Delete(time.Duration, bool) {}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
|
|
||||||
objectCore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
|
objectCore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -14,13 +15,13 @@ import (
|
||||||
// cons must return a storage which is NOT opened.
|
// cons must return a storage which is NOT opened.
|
||||||
func TestControl(t *testing.T, cons Constructor, min, max uint64) {
|
func TestControl(t *testing.T, cons Constructor, min, max uint64) {
|
||||||
s := cons(t)
|
s := cons(t)
|
||||||
require.NoError(t, s.Open(false))
|
require.NoError(t, s.Open(mode.ComponentReadWrite))
|
||||||
require.NoError(t, s.Init())
|
require.NoError(t, s.Init())
|
||||||
|
|
||||||
objects := prepare(t, 10, s, min, max)
|
objects := prepare(t, 10, s, min, max)
|
||||||
require.NoError(t, s.Close())
|
require.NoError(t, s.Close())
|
||||||
|
|
||||||
require.NoError(t, s.Open(true))
|
require.NoError(t, s.Open(mode.ComponentReadOnly))
|
||||||
for i := range objects {
|
for i := range objects {
|
||||||
var prm common.GetPrm
|
var prm common.GetPrm
|
||||||
prm.Address = objects[i].addr
|
prm.Address = objects[i].addr
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
||||||
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
|
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
@ -12,7 +13,7 @@ import (
|
||||||
|
|
||||||
func TestDelete(t *testing.T, cons Constructor, min, max uint64) {
|
func TestDelete(t *testing.T, cons Constructor, min, max uint64) {
|
||||||
s := cons(t)
|
s := cons(t)
|
||||||
require.NoError(t, s.Open(false))
|
require.NoError(t, s.Open(mode.ComponentReadWrite))
|
||||||
require.NoError(t, s.Init())
|
require.NoError(t, s.Init())
|
||||||
defer func() { require.NoError(t, s.Close()) }()
|
defer func() { require.NoError(t, s.Close()) }()
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,14 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||||
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
|
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestExists(t *testing.T, cons Constructor, min, max uint64) {
|
func TestExists(t *testing.T, cons Constructor, min, max uint64) {
|
||||||
s := cons(t)
|
s := cons(t)
|
||||||
require.NoError(t, s.Open(false))
|
require.NoError(t, s.Open(mode.ComponentReadWrite))
|
||||||
require.NoError(t, s.Init())
|
require.NoError(t, s.Init())
|
||||||
defer func() { require.NoError(t, s.Close()) }()
|
defer func() { require.NoError(t, s.Close()) }()
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
||||||
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
|
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
@ -12,7 +13,7 @@ import (
|
||||||
|
|
||||||
func TestGet(t *testing.T, cons Constructor, min, max uint64) {
|
func TestGet(t *testing.T, cons Constructor, min, max uint64) {
|
||||||
s := cons(t)
|
s := cons(t)
|
||||||
require.NoError(t, s.Open(false))
|
require.NoError(t, s.Open(mode.ComponentReadWrite))
|
||||||
require.NoError(t, s.Init())
|
require.NoError(t, s.Init())
|
||||||
defer func() { require.NoError(t, s.Close()) }()
|
defer func() { require.NoError(t, s.Close()) }()
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
||||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||||
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
|
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
|
||||||
|
@ -14,7 +15,7 @@ import (
|
||||||
|
|
||||||
func TestGetRange(t *testing.T, cons Constructor, min, max uint64) {
|
func TestGetRange(t *testing.T, cons Constructor, min, max uint64) {
|
||||||
s := cons(t)
|
s := cons(t)
|
||||||
require.NoError(t, s.Open(false))
|
require.NoError(t, s.Open(mode.ComponentReadWrite))
|
||||||
require.NoError(t, s.Init())
|
require.NoError(t, s.Init())
|
||||||
defer func() { require.NoError(t, s.Close()) }()
|
defer func() { require.NoError(t, s.Close()) }()
|
||||||
|
|
||||||
|
|
|
@ -6,12 +6,13 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestIterate(t *testing.T, cons Constructor, min, max uint64) {
|
func TestIterate(t *testing.T, cons Constructor, min, max uint64) {
|
||||||
s := cons(t)
|
s := cons(t)
|
||||||
require.NoError(t, s.Open(false))
|
require.NoError(t, s.Open(mode.ComponentReadWrite))
|
||||||
require.NoError(t, s.Init())
|
require.NoError(t, s.Init())
|
||||||
defer func() { require.NoError(t, s.Close()) }()
|
defer func() { require.NoError(t, s.Close()) }()
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
package memstore
|
package memstore
|
||||||
|
|
||||||
import "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/compression"
|
import (
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/compression"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||||
|
)
|
||||||
|
|
||||||
func (s *memstoreImpl) Open(readOnly bool) error {
|
func (s *memstoreImpl) Open(mod mode.ComponentMode) error {
|
||||||
s.readOnly = readOnly
|
s.readOnly = mod.ReadOnly()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/internal/blobstortest"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/internal/blobstortest"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger/test"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger/test"
|
||||||
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
@ -18,7 +19,7 @@ func TestSimpleLifecycle(t *testing.T) {
|
||||||
WithLogger(test.NewLogger(t)),
|
WithLogger(test.NewLogger(t)),
|
||||||
)
|
)
|
||||||
defer func() { require.NoError(t, s.Close()) }()
|
defer func() { require.NoError(t, s.Close()) }()
|
||||||
require.NoError(t, s.Open(false))
|
require.NoError(t, s.Open(mode.ComponentReadWrite))
|
||||||
require.NoError(t, s.Init())
|
require.NoError(t, s.Init())
|
||||||
|
|
||||||
obj := blobstortest.NewObject(1024)
|
obj := blobstortest.NewObject(1024)
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/fstree"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/fstree"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/memstore"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/memstore"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/testutil"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/testutil"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
|
@ -22,7 +23,7 @@ type storage struct {
|
||||||
func (s storage) open(b *testing.B) common.Storage {
|
func (s storage) open(b *testing.B) common.Storage {
|
||||||
st := s.create(b.TempDir())
|
st := s.create(b.TempDir())
|
||||||
|
|
||||||
require.NoError(b, st.Open(false))
|
require.NoError(b, st.Open(mode.ComponentReadWrite))
|
||||||
require.NoError(b, st.Init())
|
require.NoError(b, st.Init())
|
||||||
|
|
||||||
return st
|
return st
|
||||||
|
|
|
@ -3,12 +3,13 @@ package teststore
|
||||||
import (
|
import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/compression"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/compression"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||||
)
|
)
|
||||||
|
|
||||||
type cfg struct {
|
type cfg struct {
|
||||||
st common.Storage
|
st common.Storage
|
||||||
overrides struct {
|
overrides struct {
|
||||||
Open func(readOnly bool) error
|
Open func(mode mode.ComponentMode) error
|
||||||
Init func() error
|
Init func() error
|
||||||
Close func() error
|
Close func() error
|
||||||
|
|
||||||
|
@ -35,7 +36,7 @@ func WithSubstorage(st common.Storage) Option {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithOpen(f func(bool) error) Option { return func(c *cfg) { c.overrides.Open = f } }
|
func WithOpen(f func(mode.ComponentMode) error) Option { return func(c *cfg) { c.overrides.Open = f } }
|
||||||
func WithInit(f func() error) Option { return func(c *cfg) { c.overrides.Init = f } }
|
func WithInit(f func() error) Option { return func(c *cfg) { c.overrides.Init = f } }
|
||||||
func WithClose(f func() error) Option { return func(c *cfg) { c.overrides.Close = f } }
|
func WithClose(f func() error) Option { return func(c *cfg) { c.overrides.Close = f } }
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/compression"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/compression"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestStore is a common.Storage implementation for testing/mocking purposes.
|
// TestStore is a common.Storage implementation for testing/mocking purposes.
|
||||||
|
@ -50,16 +51,16 @@ func (s *TestStore) SetOption(opt Option) {
|
||||||
opt(s.cfg)
|
opt(s.cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *TestStore) Open(readOnly bool) error {
|
func (s *TestStore) Open(mod mode.ComponentMode) error {
|
||||||
s.mu.RLock()
|
s.mu.RLock()
|
||||||
defer s.mu.RUnlock()
|
defer s.mu.RUnlock()
|
||||||
switch {
|
switch {
|
||||||
case s.overrides.Open != nil:
|
case s.overrides.Open != nil:
|
||||||
return s.overrides.Open(readOnly)
|
return s.overrides.Open(mod)
|
||||||
case s.st != nil:
|
case s.st != nil:
|
||||||
return s.st.Open(readOnly)
|
return s.st.Open(mod)
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("unexpected storage call: Open(%v)", readOnly))
|
panic(fmt.Sprintf("unexpected storage call: Open(%v)", mod.String()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ func TestInitializationFailure(t *testing.T) {
|
||||||
openFileMetabase: os.OpenFile,
|
openFileMetabase: os.OpenFile,
|
||||||
openFilePilorama: os.OpenFile,
|
openFilePilorama: os.OpenFile,
|
||||||
})
|
})
|
||||||
largeFileStorage.SetOption(teststore.WithOpen(func(ro bool) error {
|
largeFileStorage.SetOption(teststore.WithOpen(func(primitiveMode mode.ComponentMode) error {
|
||||||
return teststore.ErrDiskExploded
|
return teststore.ErrDiskExploded
|
||||||
}))
|
}))
|
||||||
beforeReload := func() {
|
beforeReload := func() {
|
||||||
|
|
|
@ -171,8 +171,8 @@ func (m *writeCacheMetrics) SetEstimateSize(db, fstree uint64) {
|
||||||
m.metrics.SetEstimateSize(m.shardID, m.path, writecache.StorageTypeFSTree.String(), fstree)
|
m.metrics.SetEstimateSize(m.shardID, m.path, writecache.StorageTypeFSTree.String(), fstree)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *writeCacheMetrics) SetMode(mode mode.Mode) {
|
func (m *writeCacheMetrics) SetMode(mod mode.ComponentMode) {
|
||||||
m.metrics.SetMode(m.shardID, mode.String())
|
m.metrics.SetMode(m.shardID, mod.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *writeCacheMetrics) SetActualCounters(db, fstree uint64) {
|
func (m *writeCacheMetrics) SetActualCounters(db, fstree uint64) {
|
||||||
|
|
|
@ -38,16 +38,16 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Open boltDB instance for metabase.
|
// Open boltDB instance for metabase.
|
||||||
func (db *DB) Open(_ context.Context, mode mode.Mode) error {
|
func (db *DB) Open(_ context.Context, m mode.Mode) error {
|
||||||
db.modeMtx.Lock()
|
db.modeMtx.Lock()
|
||||||
defer db.modeMtx.Unlock()
|
defer db.modeMtx.Unlock()
|
||||||
db.mode = mode
|
db.mode = m
|
||||||
db.metrics.SetMode(mode)
|
db.metrics.SetMode(mode.ConvertToComponentModeDegraded(m))
|
||||||
|
|
||||||
if mode.NoMetabase() {
|
if m.NoMetabase() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return db.openDB(mode)
|
return db.openDB(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) openDB(mode mode.Mode) error {
|
func (db *DB) openDB(mode mode.Mode) error {
|
||||||
|
@ -239,15 +239,15 @@ func (db *DB) Reload(opts ...Option) (bool, error) {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
db.mode = mode.Degraded
|
db.mode = mode.Disabled
|
||||||
db.metrics.SetMode(mode.Degraded)
|
db.metrics.SetMode(mode.ComponentDisabled)
|
||||||
db.info.Path = c.info.Path
|
db.info.Path = c.info.Path
|
||||||
if err := db.openBolt(); err != nil {
|
if err := db.openBolt(); err != nil {
|
||||||
return false, metaerr.Wrap(fmt.Errorf("%w: %v", ErrDegradedMode, err))
|
return false, metaerr.Wrap(fmt.Errorf("%w: %v", ErrDegradedMode, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
db.mode = mode.ReadWrite
|
db.mode = mode.ReadWrite
|
||||||
db.metrics.SetMode(mode.ReadWrite)
|
db.metrics.SetMode(mode.ComponentReadWrite)
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
type Metrics interface {
|
type Metrics interface {
|
||||||
SetParentID(parentID string)
|
SetParentID(parentID string)
|
||||||
|
|
||||||
SetMode(m mode.Mode)
|
SetMode(m mode.ComponentMode)
|
||||||
Close()
|
Close()
|
||||||
|
|
||||||
AddMethodDuration(method string, d time.Duration, success bool)
|
AddMethodDuration(method string, d time.Duration, success bool)
|
||||||
|
@ -18,6 +18,6 @@ type Metrics interface {
|
||||||
type noopMetrics struct{}
|
type noopMetrics struct{}
|
||||||
|
|
||||||
func (m *noopMetrics) SetParentID(string) {}
|
func (m *noopMetrics) SetParentID(string) {}
|
||||||
func (m *noopMetrics) SetMode(mode.Mode) {}
|
func (m *noopMetrics) SetMode(mode.ComponentMode) {}
|
||||||
func (m *noopMetrics) Close() {}
|
func (m *noopMetrics) Close() {}
|
||||||
func (m *noopMetrics) AddMethodDuration(string, time.Duration, bool) {}
|
func (m *noopMetrics) AddMethodDuration(string, time.Duration, bool) {}
|
||||||
|
|
|
@ -35,6 +35,6 @@ func (db *DB) SetMode(m mode.Mode) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
db.mode = m
|
db.mode = m
|
||||||
db.metrics.SetMode(m)
|
db.metrics.SetMode(mode.ConvertToComponentModeDegraded(m))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ func (db *DB) SetShardID(id []byte, mode metamode.Mode) error {
|
||||||
|
|
||||||
err := db.writeShardID(id)
|
err := db.writeShardID(id)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
db.metrics.SetMode(mode)
|
db.metrics.SetMode(metamode.ConvertToComponentModeDegraded(mode))
|
||||||
}
|
}
|
||||||
|
|
||||||
if cErr := db.close(); cErr != nil {
|
if cErr := db.close(); cErr != nil {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobovnicza"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobovnicza"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/blobovniczatree"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/blobovniczatree"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||||
metrics_impl "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/metrics"
|
metrics_impl "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/metrics"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -34,8 +35,8 @@ func (m *blobovniczaTreeMetrics) SetParentID(parentID string) {
|
||||||
m.shardID = parentID
|
m.shardID = parentID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *blobovniczaTreeMetrics) SetMode(readOnly bool) {
|
func (m *blobovniczaTreeMetrics) SetMode(mod mode.ComponentMode) {
|
||||||
m.m.SetBlobobvnizcaTreeMode(m.shardID, m.path, readOnly)
|
m.m.SetBlobobvnizcaTreeMode(m.shardID, m.path, mod)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *blobovniczaTreeMetrics) Close() {
|
func (m *blobovniczaTreeMetrics) Close() {
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/fstree"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/fstree"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||||
metrics_impl "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/metrics"
|
metrics_impl "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/metrics"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -25,8 +26,8 @@ func (m *fstreeMetrics) SetParentID(parentID string) {
|
||||||
m.shardID = parentID
|
m.shardID = parentID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *fstreeMetrics) SetMode(readOnly bool) {
|
func (m *fstreeMetrics) SetMode(mod mode.ComponentMode) {
|
||||||
m.m.SetMode(m.shardID, m.path, readOnly)
|
m.m.SetMode(m.shardID, m.path, mod)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *fstreeMetrics) Close() {
|
func (m *fstreeMetrics) Close() {
|
||||||
|
|
|
@ -26,7 +26,7 @@ func (m *metabaseMetrics) SetParentID(parentID string) {
|
||||||
m.shardID = parentID
|
m.shardID = parentID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *metabaseMetrics) SetMode(mode mode.Mode) {
|
func (m *metabaseMetrics) SetMode(mode mode.ComponentMode) {
|
||||||
m.m.SetMode(m.shardID, m.path, mode.String())
|
m.m.SetMode(m.shardID, m.path, mode.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,8 @@ func (m *piloramaMetrics) SetParentID(id string) {
|
||||||
m.shardID = id
|
m.shardID = id
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *piloramaMetrics) SetMode(mode mode.Mode) {
|
func (m *piloramaMetrics) SetMode(mod mode.ComponentMode) {
|
||||||
m.m.SetMode(m.shardID, mode)
|
m.m.SetMode(m.shardID, mod)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *piloramaMetrics) Close() {
|
func (m *piloramaMetrics) Close() {
|
||||||
|
|
|
@ -109,7 +109,7 @@ func (t *boltForest) SetMode(m mode.Mode) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
t.mode = m
|
t.mode = m
|
||||||
t.metrics.SetMode(m)
|
t.metrics.SetMode(mode.ConvertToComponentModeDegraded(m))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,8 +123,8 @@ func (t *boltForest) Open(_ context.Context, mode mode.Mode) error {
|
||||||
return t.openBolt(mode)
|
return t.openBolt(mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *boltForest) openBolt(mode mode.Mode) error {
|
func (t *boltForest) openBolt(m mode.Mode) error {
|
||||||
readOnly := mode.ReadOnly()
|
readOnly := m.ReadOnly()
|
||||||
err := util.MkdirAllX(filepath.Dir(t.path), t.perm)
|
err := util.MkdirAllX(filepath.Dir(t.path), t.perm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return metaerr.Wrap(fmt.Errorf("can't create dir %s for the pilorama: %w", t.path, err))
|
return metaerr.Wrap(fmt.Errorf("can't create dir %s for the pilorama: %w", t.path, err))
|
||||||
|
@ -143,7 +143,7 @@ func (t *boltForest) openBolt(mode mode.Mode) error {
|
||||||
|
|
||||||
t.db.MaxBatchSize = t.maxBatchSize
|
t.db.MaxBatchSize = t.maxBatchSize
|
||||||
t.db.MaxBatchDelay = t.maxBatchDelay
|
t.db.MaxBatchDelay = t.maxBatchDelay
|
||||||
t.metrics.SetMode(mode)
|
t.metrics.SetMode(mode.ConvertToComponentModeDegraded(m))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
type Metrics interface {
|
type Metrics interface {
|
||||||
SetParentID(id string)
|
SetParentID(id string)
|
||||||
|
|
||||||
SetMode(m mode.Mode)
|
SetMode(m mode.ComponentMode)
|
||||||
Close()
|
Close()
|
||||||
|
|
||||||
AddMethodDuration(method string, d time.Duration, success bool)
|
AddMethodDuration(method string, d time.Duration, success bool)
|
||||||
|
@ -18,6 +18,6 @@ type Metrics interface {
|
||||||
type noopMetrics struct{}
|
type noopMetrics struct{}
|
||||||
|
|
||||||
func (m *noopMetrics) SetParentID(string) {}
|
func (m *noopMetrics) SetParentID(string) {}
|
||||||
func (m *noopMetrics) SetMode(mode.Mode) {}
|
func (m *noopMetrics) SetMode(mode.ComponentMode) {}
|
||||||
func (m *noopMetrics) Close() {}
|
func (m *noopMetrics) Close() {}
|
||||||
func (m *noopMetrics) AddMethodDuration(string, time.Duration, bool) {}
|
func (m *noopMetrics) AddMethodDuration(string, time.Duration, bool) {}
|
||||||
|
|
|
@ -37,7 +37,7 @@ func (s *Shard) handleMetabaseFailure(stage string, err error) error {
|
||||||
|
|
||||||
err = s.SetMode(mode.DegradedReadOnly)
|
err = s.SetMode(mode.DegradedReadOnly)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not switch to mode %s", mode.DegradedReadOnly)
|
return fmt.Errorf("could not switch to mode %s", mode.Mode(mode.DegradedReadOnly))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,27 +8,41 @@ type Mode uint32
|
||||||
const (
|
const (
|
||||||
// ReadWrite is a Mode value for shard that is available
|
// ReadWrite is a Mode value for shard that is available
|
||||||
// for read and write operations. Default shard mode.
|
// for read and write operations. Default shard mode.
|
||||||
ReadWrite Mode = 0
|
ReadWrite Mode = 0b000
|
||||||
|
|
||||||
// DegradedReadOnly is a Mode value for shard that is set automatically
|
// ReadOnly is a Mode value for shard that does not
|
||||||
// after a certain number of errors is encountered. It is the same as
|
// accept write operation but is readable.
|
||||||
// `mode.Degraded` but also is read-only.
|
ReadOnly Mode = 0b001
|
||||||
DegradedReadOnly = Degraded | ReadOnly
|
|
||||||
|
// Degraded is a Mode value for shard when the metabase is unavailable.
|
||||||
|
// It is hard to perform some modifying operations in this mode, thus it can only be set by an administrator.
|
||||||
|
Degraded Mode = 0b010
|
||||||
|
|
||||||
// Disabled mode is a mode where a shard is disabled.
|
// Disabled mode is a mode where a shard is disabled.
|
||||||
// An existing shard can't have this mode, but it can be used in
|
// An existing shard can't have this mode, but it can be used in
|
||||||
// the configuration or control service commands.
|
// the configuration or control service commands.
|
||||||
Disabled = math.MaxUint32
|
Disabled Mode = math.MaxUint32
|
||||||
|
|
||||||
|
// DegradedReadOnly is a Mode value for shard that is set automatically
|
||||||
|
// after a certain number of errors is encountered. It is the same as
|
||||||
|
// `mode.Degraded` but also is read-only.
|
||||||
|
DegradedReadOnly Mode = Degraded | ReadOnly
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
// ComponentMode represents basic operation modes for shared components, including READ, READ_WRITE, and DISABLED.
|
||||||
// ReadOnly is a Mode value for shard that does not
|
type ComponentMode uint32
|
||||||
// accept write operation but is readable.
|
|
||||||
ReadOnly Mode = 1 << iota
|
|
||||||
|
|
||||||
// Degraded is a Mode value for shard when the metabase is unavailable.
|
const (
|
||||||
// It is hard to perform some modifying operations in this mode, thus it can only be set by an administrator.
|
// ComponentReadWrite is a Mode value for component that is available
|
||||||
Degraded
|
// for read and write operations. Default component mode.
|
||||||
|
ComponentReadWrite ComponentMode = 0
|
||||||
|
|
||||||
|
// ComponentReadOnly is a Mode value for component that does not
|
||||||
|
// accept write operation but is readable.
|
||||||
|
ComponentReadOnly ComponentMode = 0b001
|
||||||
|
|
||||||
|
// ComponentDisabled mode is a mode where a component is disabled.
|
||||||
|
ComponentDisabled ComponentMode = math.MaxUint32
|
||||||
)
|
)
|
||||||
|
|
||||||
func (m Mode) String() string {
|
func (m Mode) String() string {
|
||||||
|
@ -48,6 +62,19 @@ func (m Mode) String() string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m ComponentMode) String() string {
|
||||||
|
switch m {
|
||||||
|
default:
|
||||||
|
return "UNDEFINED"
|
||||||
|
case ComponentReadWrite:
|
||||||
|
return "READ_WRITE"
|
||||||
|
case ComponentReadOnly:
|
||||||
|
return "READ_ONLY"
|
||||||
|
case ComponentDisabled:
|
||||||
|
return "CLOSED"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NoMetabase returns true iff m is operating without the metabase.
|
// NoMetabase returns true iff m is operating without the metabase.
|
||||||
func (m Mode) NoMetabase() bool {
|
func (m Mode) NoMetabase() bool {
|
||||||
return m&Degraded != 0
|
return m&Degraded != 0
|
||||||
|
@ -58,6 +85,39 @@ func (m Mode) ReadOnly() bool {
|
||||||
return m&ReadOnly != 0
|
return m&ReadOnly != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReadOnly returns true iff m prohibits modifying operations with shard.
|
||||||
|
func (m ComponentMode) ReadOnly() bool {
|
||||||
|
return m&ComponentReadOnly != 0
|
||||||
|
}
|
||||||
|
|
||||||
func (m Mode) Disabled() bool {
|
func (m Mode) Disabled() bool {
|
||||||
return m == Disabled
|
return m == Disabled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m ComponentMode) Disabled() bool {
|
||||||
|
return m == ComponentDisabled
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConvertToComponentModeDegraded converts a ShardMode to a corresponding ComponentMode.
|
||||||
|
// Disables the component if the node is in degraded mode. Used in Metabase, Writecache, Pilorama.
|
||||||
|
func ConvertToComponentModeDegraded(m Mode) ComponentMode {
|
||||||
|
if m.NoMetabase() || m.Disabled() {
|
||||||
|
return ComponentDisabled
|
||||||
|
}
|
||||||
|
if m.ReadOnly() {
|
||||||
|
return ComponentReadOnly
|
||||||
|
}
|
||||||
|
return ComponentReadWrite
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConvertToComponentMode converts a ShardMode to a corresponding ComponentMode.
|
||||||
|
// Ignores the degraded mode of the node. Used in Blobstore.
|
||||||
|
func ConvertToComponentMode(m Mode) ComponentMode {
|
||||||
|
if m.Disabled() {
|
||||||
|
return ComponentDisabled
|
||||||
|
}
|
||||||
|
if m.ReadOnly() {
|
||||||
|
return ComponentReadOnly
|
||||||
|
}
|
||||||
|
return ComponentReadWrite
|
||||||
|
}
|
||||||
|
|
|
@ -95,14 +95,14 @@ func (c *cache) DumpInfo() Info {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open opens and initializes database. Reads object counters from the ObjectCounters instance.
|
// Open opens and initializes database. Reads object counters from the ObjectCounters instance.
|
||||||
func (c *cache) Open(_ context.Context, mode mode.Mode) error {
|
func (c *cache) Open(_ context.Context, mod mode.Mode) error {
|
||||||
c.modeMtx.Lock()
|
c.modeMtx.Lock()
|
||||||
defer c.modeMtx.Unlock()
|
defer c.modeMtx.Unlock()
|
||||||
c.mode = mode
|
c.mode = mod
|
||||||
if mode.NoMetabase() {
|
if mod.NoMetabase() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
err := c.openStore(mode.ReadOnly())
|
err := c.openStore(mode.ConvertToComponentModeDegraded(mod))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return metaerr.Wrap(err)
|
return metaerr.Wrap(err)
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ func (c *cache) Open(_ context.Context, mode mode.Mode) error {
|
||||||
|
|
||||||
// Init runs necessary services.
|
// Init runs necessary services.
|
||||||
func (c *cache) Init() error {
|
func (c *cache) Init() error {
|
||||||
c.metrics.SetMode(c.mode)
|
c.metrics.SetMode(mode.ConvertToComponentModeDegraded(c.mode))
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
c.cancel = cancel
|
c.cancel = cancel
|
||||||
c.runFlushLoop(ctx)
|
c.runFlushLoop(ctx)
|
||||||
|
|
|
@ -294,7 +294,7 @@ func (c *cache) Flush(ctx context.Context, ignoreErrors, seal bool) error {
|
||||||
if err := c.setMode(ctx, m, ignoreErrors); err != nil {
|
if err := c.setMode(ctx, m, ignoreErrors); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
c.metrics.SetMode(m)
|
c.metrics.SetMode(mode.ConvertToComponentModeDegraded(m))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ type Metrics interface {
|
||||||
Evict(st StorageType)
|
Evict(st StorageType)
|
||||||
|
|
||||||
SetEstimateSize(db, fstree uint64)
|
SetEstimateSize(db, fstree uint64)
|
||||||
SetMode(m mode.Mode)
|
SetMode(m mode.ComponentMode)
|
||||||
SetActualCounters(db, fstree uint64)
|
SetActualCounters(db, fstree uint64)
|
||||||
SetPath(path string)
|
SetPath(path string)
|
||||||
Close()
|
Close()
|
||||||
|
@ -49,7 +49,7 @@ func (metricsStub) Put(time.Duration, bool, StorageType) {}
|
||||||
|
|
||||||
func (metricsStub) SetEstimateSize(uint64, uint64) {}
|
func (metricsStub) SetEstimateSize(uint64, uint64) {}
|
||||||
|
|
||||||
func (metricsStub) SetMode(mode.Mode) {}
|
func (metricsStub) SetMode(mode.ComponentMode) {}
|
||||||
|
|
||||||
func (metricsStub) SetActualCounters(uint64, uint64) {}
|
func (metricsStub) SetActualCounters(uint64, uint64) {}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ func (c *cache) SetMode(m mode.Mode) error {
|
||||||
|
|
||||||
err := c.setMode(ctx, m, true)
|
err := c.setMode(ctx, m, true)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
c.metrics.SetMode(m)
|
c.metrics.SetMode(mode.ConvertToComponentModeDegraded(m))
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ func (c *cache) setMode(ctx context.Context, m mode.Mode, ignoreErrors bool) err
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = c.openStore(m.ReadOnly()); err != nil {
|
if err = c.openStore(mode.ConvertToComponentModeDegraded(m)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ func (c *cache) Seal(ctx context.Context, ignoreErrors bool) error {
|
||||||
// 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, ignoreErrors)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
c.metrics.SetMode(mode.DegradedReadOnly)
|
c.metrics.SetMode(mode.ComponentDisabled)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/fstree"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/fstree"
|
||||||
storagelog "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/log"
|
storagelog "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/log"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
||||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
|
@ -25,13 +26,13 @@ type store struct {
|
||||||
|
|
||||||
const dbName = "small.bolt"
|
const dbName = "small.bolt"
|
||||||
|
|
||||||
func (c *cache) openStore(readOnly bool) error {
|
func (c *cache) openStore(mod mode.ComponentMode) error {
|
||||||
err := util.MkdirAllX(c.path, os.ModePerm)
|
err := util.MkdirAllX(c.path, os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
c.db, err = OpenDB(c.path, readOnly, c.openFile)
|
c.db, err = OpenDB(c.path, mod.ReadOnly(), c.openFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not open database: %w", err)
|
return fmt.Errorf("could not open database: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -39,7 +40,7 @@ func (c *cache) openStore(readOnly bool) error {
|
||||||
c.db.MaxBatchSize = c.maxBatchSize
|
c.db.MaxBatchSize = c.maxBatchSize
|
||||||
c.db.MaxBatchDelay = c.maxBatchDelay
|
c.db.MaxBatchDelay = c.maxBatchDelay
|
||||||
|
|
||||||
if !readOnly {
|
if !mod.ReadOnly() {
|
||||||
err = c.db.Update(func(tx *bbolt.Tx) error {
|
err = c.db.Update(func(tx *bbolt.Tx) error {
|
||||||
_, err := tx.CreateBucketIfNotExists(defaultBucket)
|
_, err := tx.CreateBucketIfNotExists(defaultBucket)
|
||||||
return err
|
return err
|
||||||
|
@ -57,7 +58,7 @@ func (c *cache) openStore(readOnly bool) error {
|
||||||
fstree.WithNoSync(c.noSync),
|
fstree.WithNoSync(c.noSync),
|
||||||
fstree.WithFileCounter(&c.objCounters),
|
fstree.WithFileCounter(&c.objCounters),
|
||||||
)
|
)
|
||||||
if err := c.fsTree.Open(readOnly); err != nil {
|
if err := c.fsTree.Open(mod); err != nil {
|
||||||
return fmt.Errorf("could not open FSTree: %w", err)
|
return fmt.Errorf("could not open FSTree: %w", err)
|
||||||
}
|
}
|
||||||
if err := c.fsTree.Init(); err != nil {
|
if err := c.fsTree.Init(); err != nil {
|
||||||
|
|
|
@ -4,12 +4,13 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/metrics"
|
"git.frostfs.info/TrueCloudLab/frostfs-observability/metrics"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BlobobvnizcaMetrics interface {
|
type BlobobvnizcaMetrics interface {
|
||||||
SetBlobobvnizcaTreeMode(shardID, path string, readOnly bool)
|
SetBlobobvnizcaTreeMode(shardID, path string, mode mode.ComponentMode)
|
||||||
CloseBlobobvnizcaTree(shardID, path string)
|
CloseBlobobvnizcaTree(shardID, path string)
|
||||||
BlobobvnizcaTreeMethodDuration(shardID, path string, method string, d time.Duration, success bool, withStorageID NullBool)
|
BlobobvnizcaTreeMethodDuration(shardID, path string, method string, d time.Duration, success bool, withStorageID NullBool)
|
||||||
AddBlobobvnizcaTreePut(shardID, path string, size int)
|
AddBlobobvnizcaTreePut(shardID, path string, size int)
|
||||||
|
@ -98,8 +99,8 @@ func newBlobovnicza() *blobovnicza {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *blobovnicza) SetBlobobvnizcaTreeMode(shardID, path string, readOnly bool) {
|
func (b *blobovnicza) SetBlobobvnizcaTreeMode(shardID, path string, mod mode.ComponentMode) {
|
||||||
b.treeMode.SetMode(shardID, path, modeFromBool(readOnly))
|
b.treeMode.SetMode(shardID, path, mod.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *blobovnicza) CloseBlobobvnizcaTree(shardID, path string) {
|
func (b *blobovnicza) CloseBlobobvnizcaTree(shardID, path string) {
|
||||||
|
|
|
@ -4,12 +4,13 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/metrics"
|
"git.frostfs.info/TrueCloudLab/frostfs-observability/metrics"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FSTreeMetrics interface {
|
type FSTreeMetrics interface {
|
||||||
SetMode(shardID, path string, readOnly bool)
|
SetMode(shardID, path string, mode mode.ComponentMode)
|
||||||
Close(shardID, path string)
|
Close(shardID, path string)
|
||||||
|
|
||||||
MethodDuration(shardID, path string, method string, d time.Duration, success bool)
|
MethodDuration(shardID, path string, method string, d time.Duration, success bool)
|
||||||
|
@ -48,8 +49,8 @@ func newFSTreeMetrics() *fstreeMetrics {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *fstreeMetrics) SetMode(shardID, path string, readOnly bool) {
|
func (m *fstreeMetrics) SetMode(shardID, path string, mod mode.ComponentMode) {
|
||||||
m.mode.SetMode(shardID, path, modeFromBool(readOnly))
|
m.mode.SetMode(shardID, path, mod.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *fstreeMetrics) Close(shardID, path string) {
|
func (m *fstreeMetrics) Close(shardID, path string) {
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type PiloramaMetrics interface {
|
type PiloramaMetrics interface {
|
||||||
SetMode(shardID string, m mode.Mode)
|
SetMode(shardID string, m mode.ComponentMode)
|
||||||
Close(shardID string)
|
Close(shardID string)
|
||||||
|
|
||||||
AddMethodDuration(shardID string, method string, d time.Duration, success bool)
|
AddMethodDuration(shardID string, method string, d time.Duration, success bool)
|
||||||
|
@ -33,7 +33,7 @@ type piloramaMetrics struct {
|
||||||
reqDuration *prometheus.HistogramVec
|
reqDuration *prometheus.HistogramVec
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *piloramaMetrics) SetMode(shardID string, mode mode.Mode) {
|
func (m *piloramaMetrics) SetMode(shardID string, mode mode.ComponentMode) {
|
||||||
m.mode.SetMode(shardID, mode.String())
|
m.mode.SetMode(shardID, mode.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue