-
Notifications
You must be signed in to change notification settings - Fork 3
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
Use advisory lock when assigning sequence IDs #401
Conversation
Just realized the generate script doesn't actually re-generate the queries, so I haven't actually tested the new queries. Will fix that, oops! |
-- Ensures that the generated sequence ID matches the insertion order | ||
-- Only released at the end of the enclosing transaction - beware if called within a long transaction | ||
PERFORM | ||
pg_advisory_xact_lock(hashtext('group_messages_sequence')); |
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.
With the way this is queried, do we actually care that the group_messages
table IDs are globally monotonically increasing. What if we made the lock key the group_id
instead?
Unlike with replication, no one is querying across multiple groups.
Same goes for welcome messages.
We could get away with doing the same for inbox logs too, even if there is a bit of a global namespace for those because of the address mapping. But that doesn't rely on the sequence_id
being monotonically increasing, so I think it's fine to have that lock be scoped as well.
Great nuance @neekolas, this gives us more concurrency. Some implementation notes:
|
-- Ensures that the generated sequence ID matches the insertion order | ||
-- Only released at the end of the enclosing transaction - beware if called within a long transaction | ||
PERFORM | ||
pg_advisory_xact_lock(hashtext('group_messages_sequence'), hashtext(encode(group_id, 'hex'))); |
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.
We could cut down on the number of hashes by concatenating the two strings before hashing if we're concerned about perf
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.
Another good option if perf becomes an issue. Separated it for this implementation to reduce collisions (especially against other tables)
Hoping for this to be an invisible change - relying on existing unit tests for verification.
Whenever we add a table that relies on a sequence for ordering, we should consider adding a Postgres stored function that performs insertions by taking an advisory lock first. This ensures that inserts on the table are processed serially.
For these stored functions, I've matched the params and param ordering to the existing queries. I also allowed unique constraint errors to bubble up rather than specifying
ON CONFLICT
, to match the existing queries.The
dev/up
script also generates the protos, and I don't see a convenient way to exclude the protos for the replication project. However, I assume that at some point we will need them on this server, for forwards-compatibility purposes.