-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
fix: Limit concurrent schema cache loads #4643
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
Open
mkleczek
wants to merge
2
commits into
PostgREST:main
Choose a base branch
from
mkleczek:use-advisory-locks-to-throttle-schema-cache-loading
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+250
−29
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this assumes that all other instances are running with the same user as the current session?
That seems overly specific to a certain use-case for something to put into PostgREST.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it really overly specific?
I cannot imagine hundreds (or even tens) of PostgREST instances connected to the same database, each configured differently using different user and listening for the same schema changes... What would be the goal of doing that?
The thundering herd issue in reality happens only in clustered environments where identical PostgREST instances are started to horizontally scale the cluster.
This patch prevents thundering herd issue in such cases.
Do you have any other cases in mind?
Also - do you have any ideas how to estimate the size of the PostgREST cluster without this assumption?
@steve-chavez WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can easily imagine a multi-tenant use-case, where each tenant gets their own authenticator role and their own PostgREST instance - but all connecting to the same database.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would be a schema based multitentancy with shared role structure but for some reason stateless PostgREST instances have to be separate but listening on the same channel. In other words in such setup one tenant running
NOTIFY pgrstwould force other tenants to reload the schema cache. Why would someone do that???What's more - how many such PostgREST instances do you imagine in such a setup? So many that it would cause thundering herd problem?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would that be schema based multitenancy? I don't see it that way. They'd all be using the same schema, but need different JWT settings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we currently reloading the schema on a different connection than where we listen to notifications?
That seems like a bug in itself to me: If we listen on the primary, but load the schema from the replica, there is no guarantee, that the schema changes we actually want to load are already available on the replica. That means we might actually end up with a stale schema cache, even when the replica catches up afterwards.
I had assumed that not to be the case, was my assumption wrong?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it's exactly as you mention, LISTEN on the primary and reload on the replica. I had the same concern on #4642 (comment).
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Loading from master is no better but in the opposite direction: an instance can have newer schema cache than the actual schema on the replica.
There are no good solutions with current
LISTEN/NOTIFYbased architecture but it is unrelated to this PR - see also my comment here: #4642 (comment)I've created #4842 to discuss it further.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the conclusion in that issue is that "loading the schema cache from the primary is likely the best idea", I suggest we assume for now, that this happens / will be the case.
Since we need to start with something and need to make a compromise somewhere, I suggest we ignore this scenario, where we overestimate the schema reloads per replica. We can consider it part of the "schema cache reloads should really happen via the primary instead" issue.
So let's try to find a way to reliably count listener threads against the primary. As pointed out, I believe basing it off of the current role is unreliable. Steve pointed out that basing it off of the
application_nameis potentially unreliable as well.Any other ideas?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixing #4642 (possibly with this PR) must be a prerequisite to the above (otherwise thundering herd vulnerability is amplified as all PostgREST instances are going to hit master).
I think we should rather aim for the rule throttling must be done in the same database transaction as schema cache loading (regardless of which connection is used for querying) - thundering herd issue is really per db server instance
This would mean merging this PR (as it implements this strategy) and in subsequent PR changing the connection used for schema cache querying.
These issues are really orthogonal: one is about "what should be the source of schema cache data" and another is about "making sure the source of schema cache data, whatever it is, is not overloaded by concurrent requests".
There is also another dimension here: it is safer to underestimate than to overestimate the number of PostgREST instances.
Basing the calculation off the
current_rolecan only underestimate instances (ie. there can be other instances connected using different user but they won't be counted towards the limit).Since all instances, regardless of
session_useruse the same db locks for throttling, it means that it fixes the thundering herd problem in all scenarios (it is just that the limit might be lower than optimal in the scenario @wolfgangwalther described).So IMHO it is safe to merge this PR as is and we can change the strategy to be more liberal (ie. not underestimating) in the future.
@steve-chavez @wolfgangwalther WDYT?