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

settings: add functionality for settings override #73774

Merged
merged 1 commit into from
Dec 22, 2021

Conversation

RaduBerinde
Copy link
Member

This commit adds override functionality to the SettingsWatcher.

We define an OverrideMonitor interface that is used to discover the
overrides and listen for updates. The logic in SettingsWatcher is
updated to return the override whenever there is one set, otherwise
return the current value as normal.

On non-system tenants, an OverrideMonitor implementation will use
new tenant connector APIs to allow the host cluster to override
settings (see the separate RFC).

Release note: None

@RaduBerinde RaduBerinde requested review from dt and ajwerner December 14, 2021 03:48
@cockroach-teamcity
Copy link
Member

This change is Reviewable

@RaduBerinde RaduBerinde added the do-not-merge bors won't merge a PR with this label. label Dec 14, 2021
@RaduBerinde
Copy link
Member Author

I don't plan to merge this until the RFC #73349 is merged. I just want to put some of the main implementation features into place so the rest of the work can be easily divided in smaller tasks.

Copy link
Contributor

@ajwerner ajwerner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic here seems fine.

How do we plan on presenting to users whether tenant-rw settings are currently overridden? The logic for SHOW CLUSTER SETTING mostly just reads from the setting value (except for the version setting).

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @dt and @RaduBerinde)


pkg/server/settingswatcher/settings_watcher.go, line 244 at r1 (raw file):

	defer s.mu.Unlock()

	for key, val := range newOverrides {

should we add something defensive to guard against the version setting being overridden?

@RaduBerinde RaduBerinde force-pushed the tenant-settings-work branch 2 times, most recently from b3f1530 to 230223b Compare December 14, 2021 06:11
Copy link
Member Author

@RaduBerinde RaduBerinde left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gasp good question. I can't think of a very easy way to do it that isn't racy. We can add a mutex and an overridden FastIntSet to cluster.Settings and modify the Updater to change both the FastIntSet and the setting value under the mutex. Then we can provide some kind of API to get the value and whether it was overridden under that same mutex.

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @ajwerner and @dt)


pkg/server/settingswatcher/settings_watcher.go, line 244 at r1 (raw file):

Previously, ajwerner wrote…

should we add something defensive to guard against the version setting being overridden?

Added. Though I see now that the updater ignores any Set() calls for the version anyway.

@RaduBerinde RaduBerinde removed the do-not-merge bors won't merge a PR with this label. label Dec 21, 2021
@RaduBerinde
Copy link
Member Author

Rebased, this is ready for review.

This commit adds override functionality to the `SettingsWatcher`.

We define an `OverrideMonitor` interface that is used to discover the
overrides and listen for updates. The logic in `SettingsWatcher` is
updated to return the override whenever there is one set, otherwise
return the current value as normal.

On non-system tenants, an `OverrideMonitor` implementation will use
new tenant connector APIs to allow the host cluster to override
settings (see the separate RFC).

Release note: None
@dt
Copy link
Member

dt commented Dec 21, 2021

I'm not terribly concerned about the race potential?

Like, settings have never been transactional -- we show the values as of when we read the settings.SV for each individual row, and they might change while we iterate.

For each name, I'd probably go to the OverridesMonitor first and ask if it is overridden and if so, with what value. If it returns ok and a value, we show the returned value and indicate it is an override, and if not then fall back to reading the setting itself, which will probably not return an overridden value. /2¢

@RaduBerinde
Copy link
Member Author

Yeah, that's definitely an option. Anyway, I will defer that issue for now; I added it to a list of task in a tracking issue.

// Overrides retrieves the current set of setting overrides, as a map from
// setting key to RawValue. Any settings that are present must be set to the
// overridden value.
Overrides() map[string]RawValue
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just to confirm my understanding: the expected implementation of OverridesMonitor will internally keep tenant-specific overrides and all-tenant overrides and return the merged map here, right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OverridesMonitor will do an RPC through the tenant connector to listen for overrides. The host side of that API will "merge" the overrides. The tenant side won't be able to tell what kind of override it was.

Copy link
Member

@dt dt Dec 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm. I think we should reconsider that -- but it doesn't really change the API used here either way, so I'm happy to wait on that until the implementation of the monitor and its corresponding host RPC API to litigate that.

(basically I just don't want deleting one all-tenants override to force a read of the every tenant's possible per-tenant override for that setting, so I want them to be stateful and keep track of two layers)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with that goal. My plan was along the lines of a single process per KV node that watches the entire tenant_settings table and keeps all the information in memory, updating any connected tenants as necessary. I expect that we won't have a ton of entries in that table - thinking we'll have a handful of all-tenant settings and a few one-off tenant-specific settings.

@RaduBerinde
Copy link
Member Author

TFTR!

bors r+

@craig
Copy link
Contributor

craig bot commented Dec 22, 2021

Build succeeded:

@craig craig bot merged commit cadf1bf into cockroachdb:master Dec 22, 2021
@RaduBerinde RaduBerinde deleted the tenant-settings-work branch December 22, 2021 15:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants