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

Fix concurrency handling in PostgreSQL WITH statements #9442

Open
vxgmichel opened this issue Jan 27, 2025 · 0 comments
Open

Fix concurrency handling in PostgreSQL WITH statements #9442

vxgmichel opened this issue Jan 27, 2025 · 0 comments

Comments

@vxgmichel
Copy link
Contributor

vxgmichel commented Jan 27, 2025

Follow up after #9428 and #9441

The code base incorrectly assumes that PostgreSQL runs WITH statements in order. This is not the case at all.

This is especially a problem when concurrency is handled by locking topics or other rows using FOR SHARE and FOR UPDATE.

In general, we cannot assume that the data selected in a query that does a FOR SHARE/FOR UPDATE is read after the lock is taken, unless the data comes from the very row AND table being locked. In practice, the opposite happens creating race conditions such as the ones explained in #9428.

For instance, consider a query like this one:

WITH locked_realm AS MATERIALIZED (
    SELECT realm._id, last_timestamp
    FROM realm_topic
    INNER JOIN realm ON realm._id = realm_topic.realm
    WHERE realm_id = $1
    FOR UPDATE OF realm_topic
)
SELECT realm._id, key_index, last_timestamp
FROM locked_realm
INNER JOIN realm ON locked_realm._id = realm._id

One could assume that postgre will first run the subquery locking the realm before reading the key index in the other subquery. In practice, the opposite happen if two of such queries run concurrently (i.e the key index returned will be outdated).

The obvious fix is to run the locking requests in their own queries, and only then use the locked id to perform a complementary read query. This has been done on #9441, but a full sweep of the postgre queries in the code base should be done to apply the same approach to other topics, invitations, etc.

Note that there might be other places where the locking is done implicitly by inserting or updating, but the problem still remains.

@vxgmichel vxgmichel assigned vxgmichel and unassigned vxgmichel Jan 29, 2025
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

No branches or pull requests

1 participant