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 possible two vacuums concurrently processing the same relfilenode. #400

Merged
merged 3 commits into from
May 21, 2024

Conversation

MasahikoSawada
Copy link
Contributor

Previously, while swapping the target table and its temp table, we used to acquire an AccessExclusiveLock on only the target table but not on its temp table. So the following scenario could happen:

  1. Run (auto) vacuum on the temp table.
  2. Swap the target table's relfile node and the temp table's relfilenode, and commit.
  3. Run (auto) vacuum on the target table.

1 and 3 run concurrently on different tables but these tables use the same relfilenode. In the reported case, since concurrent changes (INSERT/UPDATE/DELETE) can also run concurrently, the second vacuum ended up removing newly added tuples.

To fix the issue, this commit changes the pg_repack command so that it acquires an AcessExclusiveLock also on the temp table before swapping these tables.

Issue: #399

Previously, while swapping the target table and its temp table, we
used to acquire an AccessExclusiveLock on only the target table but
not on its temp table. So the following scenario could happen:

1. Run (auto) vacuum on the temp table.
2. Swap the target table's relfile node and the temp table's
relfilenode, and commit.
3. Run (auto) vacuum on the target table.

1 and 3 run concurrently on different tables but these tables use the
same relfilenode. In the reported case, since concurrent
changes (INSERT/UPDATE/DELETE) can also run concurrently, the second
vacuum ended up removing newly added tuples.

To fix the issue, this commit changes the pg_repack command so that it
acquires an AcessExclusiveLock also on the temp table before swapping
these tables.

Issue: reorg#399
@Melkij
Copy link
Collaborator

Melkij commented May 20, 2024

Thanks! It looks like pg_reorg originally relied on autovacuum=off , but that's really not enough (anti-wraparound autovacuum can still start). Explicit blocking is much more correct.
Will merge in a couple of days if there are no objections.

@MasahikoSawada
Copy link
Contributor Author

Thank you for looking at the fix.

I guess we might want to check in repack_swap() if two relations are locked in AccessExclusiveMode for sure, for example by using CheckRelationLockedByMe(). What do you think?

@Melkij
Copy link
Collaborator

Melkij commented May 20, 2024

sounds like good check. Although for now it should be conditional #if PG_VERSION_NUM >= 120000. CheckRelationLockedByMe does not exist in all versions we still support.

@za-arthur
Copy link
Collaborator

Thank you for the PR!

Would it make sense to assign 0 to temp_oid after initializing repack_table?

repack_table table;

I guess we might want to check in repack_swap() if two relations are locked in AccessExclusiveMode for sure, for example by using CheckRelationLockedByMe(). What do you think?

Indeed, it might be a good addition. I think instead Assert that check should raise a runtime error.

@MasahikoSawada
Copy link
Contributor Author

Thank you for reviewing the change! I've pushed the changes.

I use LockHeldByMe() instead of CheckRelationLockedByMe() since we don't open relations. These checks are available only on > PG12.

Copy link
Collaborator

@za-arthur za-arthur left a comment

Choose a reason for hiding this comment

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

Thanks for the fix! Looks good to me.

@MasahikoSawada MasahikoSawada merged commit f3e6353 into reorg:master May 21, 2024
10 checks passed
@MasahikoSawada
Copy link
Contributor Author

Thank you for reviewing the change! I've merged it.

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.

3 participants