From 08afe1504dccdec9fb588905278142f699787c12 Mon Sep 17 00:00:00 2001 From: Gabriel Mazetto Date: Fri, 9 Mar 2018 09:15:30 +0100 Subject: Add scope to ExclusiveLease clear and document the rake task --- doc/administration/raketasks/maintenance.md | 28 ++++++++++++++++++++++++++++ lib/gitlab/exclusive_lease.rb | 4 ++-- lib/tasks/gitlab/exclusive_lease.rake | 6 +++--- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/doc/administration/raketasks/maintenance.md b/doc/administration/raketasks/maintenance.md index ecf92c379fd..2b4252a7b1d 100644 --- a/doc/administration/raketasks/maintenance.md +++ b/doc/administration/raketasks/maintenance.md @@ -240,3 +240,31 @@ sudo gitlab-rake gitlab:tcp_check[example.com,80] cd /home/git/gitlab sudo -u git -H bundle exec rake gitlab:tcp_check[example.com,80] RAILS_ENV=production ``` + +## Clear exclusive lease (DANGER) + +GitLab uses a shared lock mechanism: `ExclusiveLease` to prevent simultaneous operations +in a shared resource. An example is running periodic garbage collection on repositories. + +In very specific situations, a operation locked by an Exclusive Lease can fail without +releasing the lock. If you can't wait for it to expire, you can run this task to manually +clear it. + +To clear all exclusive leases: + +DANGER: **DANGER**: +Don't run it while GitLab or Sidekiq is running + +```bash +sudo gitlab-rake gitlab:exclusive_lease:clear +``` + +To specify a lease `type` or lease `type + id`, specify a scope: + +```bash +# to clear all leases for repository garbage collection: +sudo gitlab-rake gitlab:exclusive_lease:clear[project_housekeeping:*] + +# to clear a lease for repository garbage collection in a specific project: (id=4) +sudo gitlab-rake gitlab:exclusive_lease:clear[project_housekeeping:4] +``` diff --git a/lib/gitlab/exclusive_lease.rb b/lib/gitlab/exclusive_lease.rb index d928301c011..12b5e240962 100644 --- a/lib/gitlab/exclusive_lease.rb +++ b/lib/gitlab/exclusive_lease.rb @@ -43,9 +43,9 @@ module Gitlab # Removes any existing exclusive_lease from redis # Don't run this in a live system without making sure no one is using the leases - def self.reset_all! + def self.reset_all!(scope = '*') Gitlab::Redis::SharedState.with do |redis| - redis.scan_each(match: redis_shared_state_key('*')).each do |key| + redis.scan_each(match: redis_shared_state_key(scope)).each do |key| redis.del(key) end end diff --git a/lib/tasks/gitlab/exclusive_lease.rake b/lib/tasks/gitlab/exclusive_lease.rake index 27582819e0b..83722bf6d94 100644 --- a/lib/tasks/gitlab/exclusive_lease.rake +++ b/lib/tasks/gitlab/exclusive_lease.rake @@ -1,8 +1,8 @@ namespace :gitlab do namespace :exclusive_lease do - desc 'GitLab | Clear existing exclusive leases' - task clear: :environment do - Gitlab::ExclusiveLease.reset_all! + desc 'GitLab | Clear existing exclusive leases for specified scope (default: *)' + task :clear, [:scope] => [:environment] do |_, args| + args[:scope].nil? ? Gitlab::ExclusiveLease.reset_all! : Gitlab::ExclusiveLease.reset_all!(args[:scope]) puts 'All exclusive lease entries were removed.' end end -- cgit v1.2.1