Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

settingswatcher: call a function upon updates to TenantReadOnly settings #111210

Merged
merged 4 commits into from
Sep 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions pkg/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -2143,8 +2143,16 @@ func (s *topLevelServer) PreStart(ctx context.Context) error {
return err
}

if err := s.node.tenantSettingsWatcher.Start(workersCtx, s.sqlServer.execCfg.SystemTableIDResolver); err != nil {
return errors.Wrap(err, "failed to initialize the tenant settings watcher")
startSettingsWatcher := true
if serverKnobs := s.cfg.TestingKnobs.Server; serverKnobs != nil {
if serverKnobs.(*TestingKnobs).DisableSettingsWatcher {
startSettingsWatcher = false
}
}
if startSettingsWatcher {
if err := s.node.tenantSettingsWatcher.Start(workersCtx, s.sqlServer.execCfg.SystemTableIDResolver); err != nil {
return errors.Wrap(err, "failed to initialize the tenant settings watcher")
}
}
if err := s.tenantCapabilitiesWatcher.Start(ctx); err != nil {
return errors.Wrap(err, "initializing tenant capabilities")
Expand Down
16 changes: 15 additions & 1 deletion pkg/server/settings_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,23 @@ var _ settingswatcher.Storage = (*settingsCacheWriter)(nil)
func storeCachedSettingsKVs(ctx context.Context, eng storage.Engine, kvs []roachpb.KeyValue) error {
batch := eng.NewBatch()
defer batch.Close()

// Remove previous entries -- they are now stale.
if _, _, _, err := storage.MVCCDeleteRange(ctx, batch,
keys.LocalStoreCachedSettingsKeyMin,
keys.LocalStoreCachedSettingsKeyMax,
0 /* no limit */, hlc.Timestamp{}, storage.MVCCWriteOptions{}, false /* returnKeys */); err != nil {
return err
}

// Now we can populate the cache with new entries.
for _, kv := range kvs {
kv.Value.Timestamp = hlc.Timestamp{} // nb: Timestamp is not part of checksum
cachedSettingsKey := keys.StoreCachedSettingsKey(kv.Key)
// A new value is added, or an existing value is updated.
log.VEventf(ctx, 1, "storing cached setting: %s -> %+v", cachedSettingsKey, kv.Value)
if err := storage.MVCCPut(
ctx, batch, keys.StoreCachedSettingsKey(kv.Key), hlc.Timestamp{}, kv.Value, storage.MVCCWriteOptions{},
ctx, batch, cachedSettingsKey, hlc.Timestamp{}, kv.Value, storage.MVCCWriteOptions{},
); err != nil {
return err
}
Expand Down Expand Up @@ -151,6 +164,7 @@ func initializeCachedSettings(
" skipping settings updates.")
}
settingKey := settings.InternalKey(settingKeyS)
log.VEventf(ctx, 1, "loaded cached setting: %s -> %+v", settingKey, val)
if err := updater.Set(ctx, settingKey, val); err != nil {
log.Warningf(ctx, "setting %q to %v failed: %+v", settingKey, val, err)
}
Expand Down
59 changes: 59 additions & 0 deletions pkg/server/settings_cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ package server
import (
"context"
"fmt"
"strings"
"testing"
"time"

Expand All @@ -24,6 +25,7 @@ import (
"github.com/cockroachdb/cockroach/pkg/storage"
"github.com/cockroachdb/cockroach/pkg/testutils"
"github.com/cockroachdb/cockroach/pkg/testutils/serverutils"
"github.com/cockroachdb/cockroach/pkg/testutils/sqlutils"
"github.com/cockroachdb/cockroach/pkg/util/leaktest"
"github.com/cockroachdb/cockroach/pkg/util/log"
"github.com/cockroachdb/errors"
Expand Down Expand Up @@ -146,3 +148,60 @@ Actual: %+v
return nil
})
}

func TestCachedSettingDeletionIsPersisted(t *testing.T) {
defer leaktest.AfterTest(t)()
defer log.Scope(t).Close(t)

hasKey := func(kvs []roachpb.KeyValue, key string) bool {
for _, kv := range kvs {
if strings.Contains(string(kv.Key), key) {
return true
}
}
return false
}

ctx := context.Background()

ts, sqlDB, _ := serverutils.StartServer(t, base.TestServerArgs{
DefaultTestTenant: base.TestIsSpecificToStorageLayerAndNeedsASystemTenant,
})
defer ts.Stopper().Stop(ctx)
db := sqlutils.MakeSQLRunner(sqlDB)

// Make the test faster.
st := ts.ClusterSettings()
closedts.TargetDuration.Override(ctx, &st.SV, 10*time.Millisecond)
closedts.SideTransportCloseInterval.Override(ctx, &st.SV, 10*time.Millisecond)
kvserver.RangeFeedRefreshInterval.Override(ctx, &st.SV, 10*time.Millisecond)

// Customize a setting.
db.Exec(t, `SET CLUSTER SETTING ui.display_timezone = 'America/New_York'`)
// The setting won't propagate to the store until the setting watcher caches
// up with the rangefeed, which might take a while.
testutils.SucceedsSoon(t, func() error {
store, err := ts.GetStores().(*kvserver.Stores).GetStore(1)
require.NoError(t, err)
settings, err := loadCachedSettingsKVs(context.Background(), store.TODOEngine())
require.NoError(t, err)
if !hasKey(settings, `ui.display_timezone`) {
return errors.New("cached setting not found")
}
return nil
})

// Reset the setting.
db.Exec(t, `RESET CLUSTER SETTING ui.display_timezone`)
// Check that the setting is eventually deleted from the store.
testutils.SucceedsSoon(t, func() error {
store, err := ts.GetStores().(*kvserver.Stores).GetStore(1)
require.NoError(t, err)
settings, err := loadCachedSettingsKVs(context.Background(), store.TODOEngine())
require.NoError(t, err)
if hasKey(settings, `ui.display_timezone`) {
return errors.New("cached setting was still found")
}
return nil
})
}
Loading