Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSami Hiltunen <shiltunen@gitlab.com>2021-10-21 17:28:33 +0300
committerSami Hiltunen <shiltunen@gitlab.com>2022-05-16 16:34:50 +0300
commitaec4a9343a82c80b919bb081a86fa60d6115a6c7 (patch)
treec1f1ee958b0094650e47ce5b1dedacc53c129e3c /internal/praefect/router_per_repository.go
parent3e92c2cf29a757444e11b39f61e58a8820751e2a (diff)
Generate unique replica paths for repositories
Renaming, creating and deleting repositories is racy in Praefect. They can also partially fail in awkward ways due to Praefect first applying the operations on the disks of the Gitalys and later updating its metadata store. In order to make these operations atomic, there's been ongoing work in the background to make it possible to perform these in the database in a manner that races are not possible and partial failures do not end up conflicting with future operations. Renames can be fixed by doing the rename atomically in the database without moving any repositories on the disks. Deletes can be modeled as simply deleting the repository's database record. Creates are atomic by creating the repository's database record as the last step in the process. The last piece of the puzzle is to ensure repositories always land in different directories on the disk. This ensures that a partial failure doesn't block a future operation from succeeding. This commit implements that piece by deriving a unique path for each repository to store their replicas. Existing repositories stay where they are but newly created repositories will land in unique directories. Create might succeed on a disk but fail to be persisted in the database. Prior to this change, attempting to recreate a repository might fail due to the stale state on the disk. With this in place, the next attempt at creating the repository would still succeed as the new attempt would land the repository in a different directory on the disk. Deletes have the same problem prior to this commit. The repository's metadata may be successfully deleted but if we fail to delete the repository from the disk, future creations and renames may fail if they conflict with the stale state. As creates now always land in a different directory, the stale state no longer causes problems. Renames will work purely in the database, so any stale state on the disk will not affect them. Changelog: fixed
Diffstat (limited to 'internal/praefect/router_per_repository.go')
-rw-r--r--internal/praefect/router_per_repository.go15
1 files changed, 13 insertions, 2 deletions
diff --git a/internal/praefect/router_per_repository.go b/internal/praefect/router_per_repository.go
index 6f1b4e7bd..7067cb36e 100644
--- a/internal/praefect/router_per_repository.go
+++ b/internal/praefect/router_per_repository.go
@@ -5,8 +5,11 @@ import (
"errors"
"fmt"
+ "gitlab.com/gitlab-org/gitaly/v14/internal/git/housekeeping"
+ "gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag"
"gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore"
"gitlab.com/gitlab-org/gitaly/v14/internal/praefect/nodes"
+ "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/praefectutil"
"google.golang.org/grpc"
)
@@ -307,11 +310,19 @@ func (r *PerRepositoryRouter) RouteRepositoryCreation(ctx context.Context, virtu
return RepositoryMutatorRoute{}, fmt.Errorf("reserve repository id: %w", err)
}
+ replicaPath := relativePath
+ if featureflag.PraefectGeneratedReplicaPaths.IsEnabled(ctx) {
+ replicaPath = praefectutil.DeriveReplicaPath(id)
+ if housekeeping.IsRailsPoolPath(relativePath) {
+ replicaPath = praefectutil.DerivePoolPath(id)
+ }
+ }
+
replicationFactor := r.defaultReplicationFactors[virtualStorage]
if replicationFactor == 1 {
return RepositoryMutatorRoute{
RepositoryID: id,
- ReplicaPath: relativePath,
+ ReplicaPath: replicaPath,
Primary: primary,
}, nil
}
@@ -360,7 +371,7 @@ func (r *PerRepositoryRouter) RouteRepositoryCreation(ctx context.Context, virtu
return RepositoryMutatorRoute{
RepositoryID: id,
- ReplicaPath: relativePath,
+ ReplicaPath: replicaPath,
AdditionalReplicaPath: additionalReplicaPath,
Primary: primary,
Secondaries: secondaries,