diff options
author | Sami Hiltunen <shiltunen@gitlab.com> | 2022-06-13 19:34:13 +0300 |
---|---|---|
committer | Sami Hiltunen <shiltunen@gitlab.com> | 2022-06-13 19:34:13 +0300 |
commit | 4e84eaf02f3a5403ef44c3f51b8e46c57e24ed02 (patch) | |
tree | a3ae2885a94f66a5ea6931d6ac5e7277d07ed1ea | |
parent | 93d46d0be8467aa4849f981d390357d6a3491420 (diff) | |
parent | 8e94bb2baee1634525a4648342a9d20efb4ca608 (diff) |
Merge branch 'pks-praefect-fix-remove-maintenance-jobs-migration' into 'master'
datastore: Fix migration that prunes maintenance-style replication jobs
Closes #4275
See merge request gitlab-org/gitaly!4608
-rw-r--r-- | internal/praefect/datastore/migrations/20220520083313_remove_maintenance_replication_events.go | 63 |
1 files changed, 52 insertions, 11 deletions
diff --git a/internal/praefect/datastore/migrations/20220520083313_remove_maintenance_replication_events.go b/internal/praefect/datastore/migrations/20220520083313_remove_maintenance_replication_events.go index 09330c942..21a95dd49 100644 --- a/internal/praefect/datastore/migrations/20220520083313_remove_maintenance_replication_events.go +++ b/internal/praefect/datastore/migrations/20220520083313_remove_maintenance_replication_events.go @@ -6,17 +6,58 @@ func init() { m := &migrate.Migration{ Id: "20220520083313_remove_maintenance_replication_events", Up: []string{ - `DELETE FROM replication_queue WHERE job->>'change' IN ( - 'gc', - 'repack_full', - 'repack_incremental', - 'cleanup', - 'pack_refs', - 'write_commit_graph', - 'midx_repack', - 'optimize_repository', - 'prune_unreachable_objects' - )`, + ` +-- Find all jobs which are maintenance-style jobs first. +WITH maintenance_job AS ( + SELECT id FROM replication_queue WHERE job->>'change' IN ( + 'gc', + 'repack_full', + 'repack_incremental', + 'cleanup', + 'pack_refs', + 'write_commit_graph', + 'midx_repack', + 'optimize_repository', + 'prune_unreachable_objects' + ) +), + +-- Now we have to prune the job locks before deleting the maintenance job +-- itself because the lock has a reference on the job. +deleted_maintenance_job_lock AS ( + DELETE FROM replication_queue_job_lock + WHERE job_id IN (SELECT id FROM maintenance_job) + RETURNING lock_id +), + +-- With job locks having been deleted we can now delete the maintenance jobs. +deleted_maintenance_job AS ( + DELETE FROM replication_queue + WHERE id IN (SELECT id FROM maintenance_job) +) + +-- Finally, we need to release replication queue locks in case we have removed +-- all jobs which kept the lock. +UPDATE replication_queue_lock +SET acquired = FALSE +WHERE id IN ( + SELECT existing.lock_id + -- We do so by unlocking all locks where the count of deleted job locks is + -- the same as the count of existing job locks. If there happen to be any + -- other jobs we haven't deleted then the lock stays acquired. This is the + -- same logic as used in AcknowledgeStale. + FROM ( + SELECT lock_id, COUNT(*) AS amount + FROM deleted_maintenance_job_lock + GROUP BY lock_id + ) AS removed + JOIN ( + SELECT lock_id, COUNT(*) AS amount + FROM replication_queue_job_lock + WHERE lock_id IN (select lock_id FROM deleted_maintenance_job_lock) + GROUP BY lock_id + ) AS existing ON removed.lock_id = existing.lock_id AND removed.amount = existing.amount +)`, }, Down: []string{ // We cannot get this data back anymore. |