WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Conversation

@thoro
Copy link

@thoro thoro commented Dec 14, 2025

Disclaimer: This code was generated by Opus 4.5 based on my ideas and prompt. It was tested with some test databases in a k8s cluster, but I do lack the full understanding of the code to say this is a good change / idea.

This is based on my second PR #3015 and further improves how quickly dbs are deleted after they are marked. I specifically ran into these issues when trying to restore from a backup, and the secrets inside of k8s run out of sync. This makes the operator extremly slow and unresponsive, therefore the idea of syncing each database in it's own go routine - most of the code anyways usually waits on network i/o.

Here is what was adapted:

    Improve sync responsiveness with background execution and context cancellation

    This change improves the responsiveness of the operator when handling
    deletion requests by running sync operations in the background and
    using context cancellation to interrupt stuck operations.

    Changes:
    - Add context field to Cluster struct, passed through New()
    - Add Cancel() method to cancel cluster's context
    - Add StartSync/EndSync/NeedsResync for managing background sync state
    - Run Sync() in a background goroutine so worker can process other events
    - Add context-aware DB connection methods (initDbConnWithContext)
    - Add RetryWithContext() that respects context cancellation
    - Cancel cluster context immediately when DeletionTimestamp detected
    - Use context-aware connections in syncRoles/syncDatabases

    Flow:
    1. Sync event spawns background goroutine and returns immediately
    2. If another sync arrives while one is running, needsResync flag is set
    3. When sync completes, it checks needsResync and requeues if needed
    4. Delete cancels context -> stuck DB operations return early -> mutex released
    5. Delete proceeds without waiting for slow/stuck sync operations    

When a Postgres cluster has a finalizer, deleting it sets a DeletionTimestamp
but doesn't remove the object until the finalizer is cleared. The operator
was not properly handling these DeletionTimestamp changes:

1. postgresqlUpdate() was filtering out events where only DeletionTimestamp
   changed (it only checked Spec and Annotations), causing the delete to
   never be processed.

2. EventUpdate case in processEvent() didn't check for DeletionTimestamp,
   so even if the event reached the processor, it would run Update() instead
   of Delete().

3. removeFinalizer() used a cached object with stale resourceVersion,
   causing "object has been modified" errors.

Fixes:
- Add explicit DeletionTimestamp check in postgresqlUpdate() to queue the event
- Add DeletionTimestamp check in EventUpdate to call Delete() when set
- Fetch latest object from API before removing finalizer to avoid conflicts
…cellation

This change improves the responsiveness of the operator when handling
deletion requests by running sync operations in the background and
using context cancellation to interrupt stuck operations.

Changes:
- Add context field to Cluster struct, passed through New()
- Add Cancel() method to cancel cluster's context
- Add StartSync/EndSync/NeedsResync for managing background sync state
- Run Sync() in a background goroutine so worker can process other events
- Add context-aware DB connection methods (initDbConnWithContext)
- Add RetryWithContext() that respects context cancellation
- Cancel cluster context immediately when DeletionTimestamp detected
- Use context-aware connections in syncRoles/syncDatabases
- StartSync/NeedsResync check context cancellation to prevent new syncs
  during deletion (no need for separate deleted flag)

Flow:
1. Sync event spawns background goroutine and returns immediately
2. If another sync arrives while one is running, needsResync flag is set
3. When sync completes, it checks needsResync and requeues if needed
4. Delete cancels context -> stuck DB operations return early -> mutex released
5. StartSync/NeedsResync return false when context cancelled
6. Delete proceeds without waiting for slow/stuck sync operations
@zalando-robot
Copy link

Cannot start a pipeline due to:

No accountable user for this pipeline: no Zalando employee associated to this GitHub username

Click on pipeline status check Details link below for more information.

@FxKu FxKu added the major Major feature changes or updates, e.g. feature rollout to a new country, new API calls. label Dec 15, 2025
@FxKu FxKu moved this to Waiting for review in Postgres Operator Dec 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

major Major feature changes or updates, e.g. feature rollout to a new country, new API calls.

Projects

Status: Waiting for review

Development

Successfully merging this pull request may close these issues.

3 participants