Restore Object Pools when restoring an object pool

Pool repositories are persisted in the database, and when the DB is
restored, the data need to be restored on disk. This is done by
resetting the state machine and rescheduling the object pool creation.

This is not an exact replica of the state like at the time of the
creation of the backup. However, the data is consistent again.

Dumping isn't required as internally GitLab uses git bundles which
bundle all refs and include all objects in the bundle that they require,
reduplicating as more repositories get backed up. This does require more
data to be stored.

Fixes https://gitlab.com/gitlab-org/gitaly/issues/1355
This commit is contained in:
Zeger-Jan van de Weg 2018-12-10 09:31:28 +01:00
parent 7cb0dd9859
commit 89a407dc3b
No known key found for this signature in database
GPG Key ID: 65F6A8D64A88ABAC
6 changed files with 39 additions and 1 deletions

View File

@ -84,6 +84,10 @@ class PoolRepository < ActiveRecord::Base
source_project.repository.raw)
end
def inspect
"#<#{self.class.name} id:#{id} state:#{state} disk_path:#{disk_path} source_project: #{source_project.full_path}>"
end
private
def correct_disk_path

View File

@ -0,0 +1,5 @@
---
title: Restore Object Pools when restoring an object pool
merge_request: 23682
author:
type: added

View File

@ -657,6 +657,7 @@ Restoring database tables:
- Loading fixture wikis...[SKIPPING]
Restoring repositories:
- Restoring repository abcd... [DONE]
- Object pool 1 ...
Deleting tmp directories...[DONE]
```

View File

@ -4,6 +4,7 @@ require 'yaml'
module Backup
class Repository
include Gitlab::ShellAdapter
attr_reader :progress
def initialize(progress)
@ -75,7 +76,6 @@ module Backup
def restore
prepare_directories
gitlab_shell = Gitlab::Shell.new
Project.find_each(batch_size: 1000) do |project|
progress.print " * #{project.full_path} ... "
@ -118,6 +118,8 @@ module Backup
end
end
end
restore_object_pools
end
protected
@ -159,5 +161,17 @@ module Backup
def display_repo_path(project)
project.hashed_storage?(:repository) ? "#{project.full_path} (#{project.disk_path})" : project.full_path
end
def restore_object_pools
PoolRepository.includes(:source_project).find_each do |pool|
progress.puts " - Object pool #{pool.disk_path}..."
pool.source_project ||= pool.member_projects.first.root_of_fork_network
pool.state = 'none'
pool.save
pool.schedule
end
end
end
end

View File

@ -67,6 +67,19 @@ describe Backup::Repository do
end
end
end
context 'restoring object pools' do
it 'schedules restoring of the pool' do
pool_repository = create(:pool_repository, :failed)
pool_repository.delete_object_pool
subject.restore
pool_repository.reload
expect(pool_repository).not_to be_failed
expect(pool_repository.object_pool.exists?).to be(true)
end
end
end
describe '#prepare_directories', :seed_helper do

View File

@ -74,6 +74,7 @@ describe 'gitlab:app namespace rake task' do
it 'invokes restoration on match' do
allow(YAML).to receive(:load_file)
.and_return({ gitlab_version: gitlab_version })
expect(Rake::Task['gitlab:db:drop_tables']).to receive(:invoke)
expect(Rake::Task['gitlab:backup:db:restore']).to receive(:invoke)
expect(Rake::Task['gitlab:backup:repo:restore']).to receive(:invoke)