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>2020-08-06 13:31:16 +0300
committerSami Hiltunen <shiltunen@gitlab.com>2020-08-07 13:41:17 +0300
commit9d0937cc128d601681a8d5a1effb20a4c3813a76 (patch)
tree71bfa9c54c74c772ffa9e517d8009bf04a8073b5
parent9e5dfd987388c905b584f58b48afede245721ec7 (diff)
report only read-only repositories by default in dataloss
`dataloss` command currenly display every outdated repository on a virtual storage by default. While outdated secondaries should also be fixed, they do not require immediate administrator action as they do not affect the writability of the repository. Secondaries might also be outdated only temporarily until a replication job brings them up to date. Outdated primary requires administrator action to enable the repository for writes again. This is currently a permanent state until administrator takes action. To reduce the noise from the tool, this commit only displays read-only repositories by default. Listing outdated writable repositories is still supported via the `-partially-replicated` flag.
-rw-r--r--changelogs/unreleased/smh-dataloss-filter-read-only.yml5
-rw-r--r--cmd/praefect/subcmd_dataloss.go32
-rw-r--r--cmd/praefect/subcmd_dataloss_test.go35
-rw-r--r--internal/praefect/service/info/dataloss.go10
-rw-r--r--proto/go/gitalypb/praefect.pb.go138
-rw-r--r--proto/praefect.proto10
-rw-r--r--ruby/proto/gitaly/praefect_pb.rb2
-rw-r--r--ruby/proto/gitaly/praefect_services_pb.rb3
8 files changed, 160 insertions, 75 deletions
diff --git a/changelogs/unreleased/smh-dataloss-filter-read-only.yml b/changelogs/unreleased/smh-dataloss-filter-read-only.yml
new file mode 100644
index 000000000..bc4b0b8f9
--- /dev/null
+++ b/changelogs/unreleased/smh-dataloss-filter-read-only.yml
@@ -0,0 +1,5 @@
+---
+title: Report only read-only repositories by default in dataloss
+merge_request: 2449
+author:
+type: changed
diff --git a/cmd/praefect/subcmd_dataloss.go b/cmd/praefect/subcmd_dataloss.go
index db23ccd5e..460e374ba 100644
--- a/cmd/praefect/subcmd_dataloss.go
+++ b/cmd/praefect/subcmd_dataloss.go
@@ -21,8 +21,9 @@ func (err unexpectedPositionalArgsError) Error() string {
}
type datalossSubcommand struct {
- output io.Writer
- virtualStorage string
+ output io.Writer
+ virtualStorage string
+ includePartiallyReplicated bool
}
func newDatalossSubcommand() *datalossSubcommand {
@@ -32,6 +33,12 @@ func newDatalossSubcommand() *datalossSubcommand {
func (cmd *datalossSubcommand) FlagSet() *flag.FlagSet {
fs := flag.NewFlagSet("dataloss", flag.ContinueOnError)
fs.StringVar(&cmd.virtualStorage, "virtual-storage", "", "virtual storage to check for data loss")
+ fs.BoolVar(&cmd.includePartiallyReplicated, "partially-replicated", false, strings.TrimSpace(`
+Additionally include repositories which are fully up to date on the
+primary but outdated on some secondaries. Such repositories are writable
+and do not suffer from data loss. The data on the primary is not fully
+replicated to all secondaries which leads to increased risk of data loss
+following a failover.`))
return fs
}
@@ -74,7 +81,8 @@ func (cmd *datalossSubcommand) Exec(flags *flag.FlagSet, cfg config.Config) erro
for _, vs := range virtualStorages {
resp, err := client.DatalossCheck(context.Background(), &gitalypb.DatalossCheckRequest{
- VirtualStorage: vs,
+ VirtualStorage: vs,
+ IncludePartiallyReplicated: cmd.includePartiallyReplicated,
})
if err != nil {
return fmt.Errorf("error checking: %v", err)
@@ -83,14 +91,24 @@ func (cmd *datalossSubcommand) Exec(flags *flag.FlagSet, cfg config.Config) erro
cmd.println(0, "Virtual storage: %s", vs)
cmd.println(1, "Primary: %s", resp.Primary)
if len(resp.Repositories) == 0 {
- cmd.println(1, "All repositories are up to date!")
+ msg := "All repositories are writable!"
+ if cmd.includePartiallyReplicated {
+ msg = "All repositories are up to date!"
+ }
+
+ cmd.println(1, msg)
continue
}
cmd.println(1, "Outdated repositories:")
- for _, r := range resp.Repositories {
- cmd.println(2, "%s:", r.RelativePath)
- for _, s := range r.Storages {
+ for _, repo := range resp.Repositories {
+ mode := "writable"
+ if repo.ReadOnly {
+ mode = "read-only"
+ }
+
+ cmd.println(2, "%s (%s):", repo.RelativePath, mode)
+ for _, s := range repo.Storages {
plural := ""
if s.BehindBy > 1 {
plural = "s"
diff --git a/cmd/praefect/subcmd_dataloss_test.go b/cmd/praefect/subcmd_dataloss_test.go
index 15daeba45..ee6113f07 100644
--- a/cmd/praefect/subcmd_dataloss_test.go
+++ b/cmd/praefect/subcmd_dataloss_test.go
@@ -59,27 +59,50 @@ func TestDatalossSubcommand(t *testing.T) {
error: unexpectedPositionalArgsError{Command: "dataloss"},
},
{
- desc: "data loss",
+ desc: "data loss with read-only repositories",
args: []string{"-virtual-storage=virtual-storage-1"}, output: `Virtual storage: virtual-storage-1
Primary: gitaly-1
Outdated repositories:
- repository-1:
+ repository-2 (read-only):
+ gitaly-1 is behind by 1 change or less
+`,
+ },
+ {
+ desc: "data loss with partially replicated repositories",
+ args: []string{"-virtual-storage=virtual-storage-1", "-partially-replicated"}, output: `Virtual storage: virtual-storage-1
+ Primary: gitaly-1
+ Outdated repositories:
+ repository-1 (writable):
gitaly-2 is behind by 1 change or less
gitaly-3 is behind by 2 changes or less
- repository-2:
+ repository-2 (read-only):
+ gitaly-1 is behind by 1 change or less
+`,
+ },
+ {
+ desc: "multiple virtual storages with read-only repositories",
+ virtualStorages: []*config.VirtualStorage{{Name: "virtual-storage-2"}, {Name: "virtual-storage-1"}},
+ output: `Virtual storage: virtual-storage-1
+ Primary: gitaly-1
+ Outdated repositories:
+ repository-2 (read-only):
gitaly-1 is behind by 1 change or less
+Virtual storage: virtual-storage-2
+ Primary: gitaly-4
+ All repositories are writable!
`,
},
{
- desc: "multiple virtual storages",
+ desc: "multiple virtual storages with partially replicated repositories",
+ args: []string{"-partially-replicated"},
virtualStorages: []*config.VirtualStorage{{Name: "virtual-storage-2"}, {Name: "virtual-storage-1"}},
output: `Virtual storage: virtual-storage-1
Primary: gitaly-1
Outdated repositories:
- repository-1:
+ repository-1 (writable):
gitaly-2 is behind by 1 change or less
gitaly-3 is behind by 2 changes or less
- repository-2:
+ repository-2 (read-only):
gitaly-1 is behind by 1 change or less
Virtual storage: virtual-storage-2
Primary: gitaly-4
diff --git a/internal/praefect/service/info/dataloss.go b/internal/praefect/service/info/dataloss.go
index 5ce72ce7f..cf657685f 100644
--- a/internal/praefect/service/info/dataloss.go
+++ b/internal/praefect/service/info/dataloss.go
@@ -20,18 +20,28 @@ func (s *Server) DatalossCheck(ctx context.Context, req *gitalypb.DatalossCheckR
pbRepos := make([]*gitalypb.DatalossCheckResponse_Repository, 0, len(outdatedRepos))
for relativePath, storages := range outdatedRepos {
+ readOnly := false
pbStorages := make([]*gitalypb.DatalossCheckResponse_Repository_Storage, 0, len(storages))
for name, behindBy := range storages {
+ if name == shard.Primary.GetStorage() {
+ readOnly = true
+ }
+
pbStorages = append(pbStorages, &gitalypb.DatalossCheckResponse_Repository_Storage{
Name: name,
BehindBy: int64(behindBy),
})
}
+ if !req.IncludePartiallyReplicated && !readOnly {
+ continue
+ }
+
sort.Slice(pbStorages, func(i, j int) bool { return pbStorages[i].Name < pbStorages[j].Name })
pbRepos = append(pbRepos, &gitalypb.DatalossCheckResponse_Repository{
RelativePath: relativePath,
+ ReadOnly: readOnly,
Storages: pbStorages,
})
}
diff --git a/proto/go/gitalypb/praefect.pb.go b/proto/go/gitalypb/praefect.pb.go
index 3e156657d..e674376e7 100644
--- a/proto/go/gitalypb/praefect.pb.go
+++ b/proto/go/gitalypb/praefect.pb.go
@@ -111,10 +111,15 @@ func (m *SetAuthoritativeStorageResponse) XXX_DiscardUnknown() {
var xxx_messageInfo_SetAuthoritativeStorageResponse proto.InternalMessageInfo
type DatalossCheckRequest struct {
- VirtualStorage string `protobuf:"bytes,1,opt,name=virtual_storage,json=virtualStorage,proto3" json:"virtual_storage,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ VirtualStorage string `protobuf:"bytes,1,opt,name=virtual_storage,json=virtualStorage,proto3" json:"virtual_storage,omitempty"`
+ // include_partially_replicated decides whether to include repositories which are fully up to date
+ // on the primary but are outdated on some secondaries. Such repositories are still writable and do
+ // not suffer from data loss. The data on the primary is not fully replicated which increases the
+ // chances of data loss following a failover.
+ IncludePartiallyReplicated bool `protobuf:"varint,2,opt,name=include_partially_replicated,json=includePartiallyReplicated,proto3" json:"include_partially_replicated,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
}
func (m *DatalossCheckRequest) Reset() { *m = DatalossCheckRequest{} }
@@ -149,6 +154,13 @@ func (m *DatalossCheckRequest) GetVirtualStorage() string {
return ""
}
+func (m *DatalossCheckRequest) GetIncludePartiallyReplicated() bool {
+ if m != nil {
+ return m.IncludePartiallyReplicated
+ }
+ return false
+}
+
type DatalossCheckResponse struct {
// current primary storage
Primary string `protobuf:"bytes,1,opt,name=primary,proto3" json:"primary,omitempty"`
@@ -202,10 +214,12 @@ type DatalossCheckResponse_Repository struct {
// relative path of the repository with outdated replicas
RelativePath string `protobuf:"bytes,1,opt,name=relative_path,json=relativePath,proto3" json:"relative_path,omitempty"`
// storages on which the repository is outdated
- Storages []*DatalossCheckResponse_Repository_Storage `protobuf:"bytes,2,rep,name=storages,proto3" json:"storages,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ Storages []*DatalossCheckResponse_Repository_Storage `protobuf:"bytes,2,rep,name=storages,proto3" json:"storages,omitempty"`
+ // read_only indicates whether the repository is in read-only mode.
+ ReadOnly bool `protobuf:"varint,3,opt,name=read_only,json=readOnly,proto3" json:"read_only,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
}
func (m *DatalossCheckResponse_Repository) Reset() { *m = DatalossCheckResponse_Repository{} }
@@ -247,6 +261,13 @@ func (m *DatalossCheckResponse_Repository) GetStorages() []*DatalossCheckRespons
return nil
}
+func (m *DatalossCheckResponse_Repository) GetReadOnly() bool {
+ if m != nil {
+ return m.ReadOnly
+ }
+ return false
+}
+
type DatalossCheckResponse_Repository_Storage struct {
// name of the storage
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
@@ -596,52 +617,55 @@ func init() {
func init() { proto.RegisterFile("praefect.proto", fileDescriptor_d32bf44842ead735) }
var fileDescriptor_d32bf44842ead735 = []byte{
- // 715 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0x4d, 0x6e, 0xd3, 0x40,
- 0x18, 0x95, 0x9d, 0xd0, 0xba, 0x5f, 0xfa, 0x93, 0x0e, 0x2d, 0x0d, 0x06, 0xda, 0xd4, 0x08, 0x1a,
- 0x89, 0x36, 0xa9, 0x52, 0x24, 0x24, 0x76, 0xb4, 0x65, 0x51, 0x54, 0x41, 0xe5, 0x4a, 0x2c, 0xd8,
- 0x58, 0x63, 0x67, 0x9a, 0x0c, 0x38, 0x1e, 0x33, 0x33, 0xa9, 0x94, 0x1b, 0x70, 0x03, 0x0e, 0xc0,
- 0x8a, 0x05, 0x27, 0x40, 0x6c, 0xb9, 0x01, 0xc7, 0xe0, 0x02, 0xac, 0x90, 0xed, 0xb1, 0xeb, 0x24,
- 0x4e, 0x8b, 0xc2, 0xce, 0xf3, 0xfd, 0xbc, 0x6f, 0xde, 0x7b, 0x33, 0x63, 0x58, 0x0e, 0x39, 0x26,
- 0x17, 0xc4, 0x93, 0xcd, 0x90, 0x33, 0xc9, 0xd0, 0x5c, 0x97, 0x4a, 0xec, 0x0f, 0x4d, 0xf0, 0x69,
- 0xa0, 0x62, 0xe6, 0xa2, 0xe8, 0x61, 0x4e, 0x3a, 0xc9, 0xca, 0xfa, 0xaa, 0xc1, 0xe6, 0x39, 0x91,
- 0x2f, 0x06, 0xb2, 0xc7, 0x38, 0x95, 0x58, 0xd2, 0x4b, 0x72, 0x2e, 0x19, 0xc7, 0x5d, 0x62, 0x93,
- 0x8f, 0x03, 0x22, 0x24, 0xda, 0x83, 0x95, 0x4b, 0xca, 0xe5, 0x00, 0xfb, 0x8e, 0x48, 0x32, 0x35,
- 0xad, 0xae, 0x35, 0x16, 0x0e, 0xcb, 0x9f, 0x7e, 0xee, 0x6a, 0xf6, 0xb2, 0x4a, 0xaa, 0x2e, 0xf4,
- 0x10, 0x96, 0x38, 0xf1, 0x63, 0x20, 0x27, 0xc4, 0xb2, 0x57, 0xd3, 0xa3, 0x62, 0x7b, 0x31, 0x0d,
- 0x9e, 0x61, 0xd9, 0x43, 0x07, 0xb0, 0x8e, 0xf3, 0x23, 0x33, 0xe4, 0x52, 0x5c, 0xbc, 0x86, 0x0b,
- 0xf6, 0x63, 0x6d, 0xc3, 0xd6, 0xd4, 0xad, 0x8a, 0x90, 0x05, 0x82, 0x58, 0x2f, 0x61, 0xed, 0x18,
- 0x4b, 0xec, 0x33, 0x21, 0x8e, 0x7a, 0xc4, 0xfb, 0x30, 0x1b, 0x07, 0xeb, 0x87, 0x0e, 0xeb, 0x63,
- 0x38, 0xc9, 0x00, 0x54, 0x83, 0xf9, 0x90, 0xd3, 0x3e, 0xe6, 0xc3, 0x04, 0xc0, 0x4e, 0x97, 0xe8,
- 0x14, 0x16, 0x39, 0x09, 0x99, 0xa0, 0x92, 0x71, 0x4a, 0x44, 0x4d, 0xaf, 0x97, 0x1a, 0x95, 0x76,
- 0xa3, 0x99, 0x58, 0xd0, 0x2c, 0x84, 0x6b, 0xda, 0x69, 0xc7, 0xd0, 0x1e, 0xe9, 0x36, 0xbf, 0x6b,
- 0x00, 0x57, 0xc9, 0x49, 0x51, 0xb5, 0x02, 0x51, 0x4f, 0xc1, 0x50, 0xe4, 0xd2, 0xe9, 0xfb, 0xff,
- 0x3a, 0xbd, 0x99, 0x0a, 0x99, 0x21, 0x98, 0xcf, 0x61, 0x3e, 0xb5, 0x14, 0x41, 0x39, 0xc0, 0x7d,
- 0x25, 0x99, 0x1d, 0x7f, 0xa3, 0x7b, 0xb0, 0xe0, 0x92, 0x1e, 0x0d, 0x3a, 0x8e, 0x3b, 0x8c, 0x2d,
- 0x2e, 0xd9, 0x46, 0x12, 0x38, 0x1c, 0x5a, 0x6f, 0xe0, 0x6e, 0x8e, 0x19, 0x09, 0x7d, 0xea, 0x61,
- 0x91, 0x7a, 0xd1, 0x06, 0xc8, 0xa8, 0x26, 0x2a, 0x56, 0xda, 0x28, 0xdd, 0x68, 0xae, 0x2d, 0x57,
- 0x65, 0x7d, 0xd1, 0xc1, 0x2c, 0x42, 0x54, 0xae, 0xbc, 0x1e, 0x75, 0xa5, 0xd2, 0x7e, 0x5a, 0x80,
- 0x37, 0xd6, 0x94, 0x4b, 0x1d, 0x13, 0x89, 0xa9, 0x2f, 0xae, 0xbc, 0x3c, 0x03, 0x83, 0xab, 0x72,
- 0xa5, 0xe4, 0x6c, 0x80, 0x19, 0x8a, 0xe9, 0xc1, 0xea, 0x44, 0x7a, 0x16, 0x25, 0x90, 0x09, 0x86,
- 0x17, 0x99, 0x28, 0x06, 0x7d, 0x75, 0xb3, 0xb2, 0xb5, 0xf5, 0x4b, 0x83, 0x8d, 0x23, 0x16, 0x08,
- 0x2a, 0x24, 0x09, 0xbc, 0xe1, 0x7f, 0xdc, 0x00, 0xf4, 0x08, 0x96, 0x25, 0xe6, 0x5d, 0x22, 0xb3,
- 0xea, 0x64, 0xd8, 0x52, 0x12, 0x4d, 0xcb, 0x9e, 0xc0, 0x2a, 0x27, 0x17, 0x84, 0x93, 0xc0, 0x1b,
- 0xbf, 0xc3, 0xd5, 0x2c, 0x91, 0x16, 0x3f, 0x83, 0x8d, 0x0e, 0x15, 0xd8, 0xf5, 0x89, 0xc3, 0x89,
- 0xc7, 0x02, 0x8f, 0xfa, 0x3e, 0xc5, 0x92, 0xb2, 0xa0, 0x56, 0xae, 0x6b, 0x0d, 0xc3, 0xbe, 0xa3,
- 0xd2, 0xf6, 0x68, 0xd6, 0xfa, 0xad, 0x41, 0x6d, 0x92, 0x97, 0xf2, 0x7e, 0x17, 0x50, 0x24, 0x8f,
- 0x53, 0x74, 0x3f, 0xaa, 0x51, 0xc6, 0xce, 0xdf, 0x91, 0x1d, 0x58, 0x51, 0xbc, 0xc6, 0x54, 0x54,
- 0x74, 0x8f, 0x54, 0x14, 0xed, 0x45, 0xb0, 0x29, 0xb3, 0xac, 0x36, 0xa1, 0x76, 0xc5, 0x39, 0x2b,
- 0xdf, 0x84, 0x4a, 0xe4, 0xb5, 0xf3, 0x9e, 0xb9, 0x0e, 0xed, 0xc4, 0x7c, 0xca, 0xf6, 0x42, 0x14,
- 0x7a, 0xc5, 0xdc, 0x93, 0x4e, 0xb1, 0x50, 0xb7, 0x8a, 0x85, 0x6a, 0x7f, 0x2b, 0xc1, 0xed, 0x33,
- 0xf5, 0x92, 0x9f, 0x04, 0x17, 0xec, 0x9c, 0xf0, 0x4b, 0xea, 0x11, 0x44, 0x00, 0x4d, 0x1e, 0x3f,
- 0xb4, 0x7d, 0xdd, 0xd1, 0x8c, 0xcd, 0x37, 0xad, 0x9b, 0x4f, 0xaf, 0x65, 0xfc, 0xf9, 0xdc, 0x28,
- 0x1b, 0x7a, 0x55, 0x43, 0x18, 0xaa, 0xe3, 0x6a, 0xa3, 0xad, 0x14, 0x61, 0xca, 0xf9, 0x32, 0xeb,
- 0xd3, 0x0b, 0xc6, 0x06, 0xe8, 0xfb, 0x1a, 0x7a, 0x0b, 0x4b, 0x23, 0x4f, 0x12, 0xba, 0x3f, 0xe5,
- 0xa5, 0x4a, 0xc0, 0x1f, 0x5c, 0xfb, 0x8e, 0xe5, 0xb6, 0x2e, 0x61, 0x63, 0xca, 0x2f, 0x02, 0x3d,
- 0x4e, 0x31, 0xae, 0xff, 0xdd, 0x99, 0x3b, 0x37, 0xd6, 0x8d, 0x4c, 0xd5, 0xaa, 0xfa, 0xe1, 0xfe,
- 0xbb, 0xa8, 0xc7, 0xc7, 0x6e, 0xd3, 0x63, 0xfd, 0x56, 0xf2, 0xb9, 0xc7, 0x78, 0xb7, 0x95, 0x20,
- 0xb5, 0xe2, 0x5f, 0x6d, 0xab, 0xcb, 0xd4, 0x3a, 0x74, 0xdd, 0xb9, 0x38, 0x74, 0xf0, 0x37, 0x00,
- 0x00, 0xff, 0xff, 0xb0, 0xb3, 0x43, 0x09, 0xb1, 0x07, 0x00, 0x00,
+ // 765 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0xcd, 0x6e, 0xd3, 0x4c,
+ 0x14, 0x95, 0x93, 0x7c, 0xad, 0x7b, 0xd3, 0x9f, 0x74, 0xbe, 0x96, 0x06, 0x53, 0xfa, 0x63, 0x04,
+ 0x8d, 0x44, 0x9b, 0x54, 0x29, 0x12, 0x12, 0x2b, 0x68, 0xbb, 0x29, 0xaa, 0x68, 0xe4, 0x4a, 0x2c,
+ 0xd8, 0x58, 0x63, 0x7b, 0x9a, 0x0c, 0x4c, 0x3c, 0x66, 0x3c, 0xa9, 0xe4, 0x27, 0x80, 0x37, 0xe0,
+ 0x01, 0x58, 0xb1, 0xe0, 0x35, 0x78, 0x03, 0x24, 0xc4, 0x3b, 0xf0, 0x02, 0xac, 0x90, 0xed, 0xb1,
+ 0x9b, 0x1f, 0xa7, 0x45, 0x65, 0x67, 0xdf, 0x7b, 0xee, 0x99, 0xb9, 0xe7, 0xdc, 0x99, 0x81, 0xc5,
+ 0x40, 0x60, 0x72, 0x41, 0x5c, 0xd9, 0x0c, 0x04, 0x97, 0x1c, 0xcd, 0x74, 0xa9, 0xc4, 0x2c, 0x32,
+ 0x80, 0x51, 0x5f, 0xc5, 0x8c, 0xf9, 0xb0, 0x87, 0x05, 0xf1, 0xd2, 0x3f, 0xf3, 0x8b, 0x06, 0x1b,
+ 0xe7, 0x44, 0xbe, 0x18, 0xc8, 0x1e, 0x17, 0x54, 0x62, 0x49, 0x2f, 0xc9, 0xb9, 0xe4, 0x02, 0x77,
+ 0x89, 0x45, 0xde, 0x0f, 0x48, 0x28, 0xd1, 0x1e, 0x2c, 0x5d, 0x52, 0x21, 0x07, 0x98, 0xd9, 0x61,
+ 0x9a, 0xa9, 0x6b, 0x5b, 0x5a, 0x63, 0xee, 0xb0, 0xf2, 0xf1, 0xdb, 0xae, 0x66, 0x2d, 0xaa, 0xa4,
+ 0xaa, 0x42, 0x0f, 0x60, 0x41, 0x10, 0x96, 0x10, 0xd9, 0x01, 0x96, 0xbd, 0x7a, 0x29, 0x06, 0x5b,
+ 0xf3, 0x59, 0xb0, 0x83, 0x65, 0x0f, 0x1d, 0xc0, 0x2a, 0x1e, 0x5e, 0x32, 0x67, 0x2e, 0x27, 0xe0,
+ 0x15, 0x5c, 0xb0, 0x1f, 0x73, 0x1b, 0x36, 0xa7, 0x6e, 0x35, 0x0c, 0xb8, 0x1f, 0x12, 0xf3, 0x83,
+ 0x06, 0x2b, 0xc7, 0x58, 0x62, 0xc6, 0xc3, 0xf0, 0xa8, 0x47, 0xdc, 0x77, 0xb7, 0x6c, 0xe2, 0x39,
+ 0xac, 0x53, 0xdf, 0x65, 0x03, 0x2f, 0xee, 0x41, 0x48, 0x8a, 0x19, 0x8b, 0x6c, 0x41, 0x02, 0x46,
+ 0x5d, 0x2c, 0x89, 0x97, 0xf4, 0xa4, 0x5b, 0x86, 0xc2, 0x74, 0x32, 0x88, 0x95, 0x23, 0xcc, 0x9f,
+ 0x25, 0x58, 0x1d, 0xdb, 0x49, 0xba, 0x47, 0x54, 0x87, 0xd9, 0x40, 0xd0, 0x3e, 0x16, 0x51, 0xba,
+ 0x05, 0x2b, 0xfb, 0x45, 0xa7, 0x30, 0x2f, 0x48, 0xc0, 0x43, 0x2a, 0xb9, 0xa0, 0x24, 0xac, 0x97,
+ 0xb6, 0xca, 0x8d, 0x6a, 0xbb, 0xd1, 0x4c, 0x5d, 0x6c, 0x16, 0xd2, 0x35, 0xad, 0xac, 0x22, 0xb2,
+ 0x46, 0xaa, 0x8d, 0x1f, 0x1a, 0xc0, 0x55, 0x72, 0xd2, 0x17, 0xad, 0xc0, 0x97, 0x53, 0xd0, 0x95,
+ 0x3c, 0xd9, 0xea, 0xfb, 0x7f, 0xbb, 0x7a, 0x33, 0xf3, 0x22, 0x67, 0x40, 0xf7, 0x60, 0x4e, 0x10,
+ 0xec, 0xd9, 0xdc, 0x67, 0x51, 0xe2, 0xac, 0x6e, 0xe9, 0x71, 0xe0, 0xcc, 0x67, 0x91, 0xf1, 0x0c,
+ 0x66, 0x33, 0xb5, 0x11, 0x54, 0x7c, 0xdc, 0x57, 0x8e, 0x58, 0xc9, 0x77, 0x5c, 0xeb, 0x90, 0x1e,
+ 0xf5, 0x3d, 0xdb, 0x89, 0x12, 0xb9, 0xcb, 0x96, 0x9e, 0x06, 0x0e, 0x23, 0xf3, 0x0c, 0xee, 0x0e,
+ 0xb5, 0x9d, 0x8a, 0x1e, 0x66, 0x56, 0xb7, 0x01, 0x72, 0x1d, 0x52, 0x89, 0xab, 0x6d, 0x94, 0x75,
+ 0x31, 0x54, 0x36, 0x84, 0x32, 0x3f, 0x97, 0xc0, 0x28, 0x62, 0x54, 0x96, 0xbd, 0x1a, 0xb5, 0xac,
+ 0xda, 0x7e, 0x52, 0xc0, 0x37, 0x56, 0x34, 0x94, 0x3a, 0x26, 0x12, 0x53, 0x16, 0x5e, 0x19, 0xdd,
+ 0x01, 0x5d, 0x0d, 0x53, 0x26, 0xf3, 0xed, 0x08, 0x73, 0x16, 0xc3, 0x85, 0xe5, 0x89, 0xf4, 0x6d,
+ 0x94, 0x40, 0x06, 0xe8, 0x6e, 0xec, 0x70, 0x38, 0xe8, 0xab, 0x93, 0x9b, 0xff, 0x9b, 0xdf, 0x35,
+ 0x58, 0x3b, 0xe2, 0x7e, 0x48, 0x43, 0x49, 0x7c, 0x37, 0xfa, 0x97, 0x03, 0xf6, 0x10, 0x16, 0x25,
+ 0x16, 0x5d, 0x22, 0x73, 0x74, 0xba, 0xd8, 0x42, 0x1a, 0xcd, 0x60, 0x8f, 0x61, 0x59, 0x90, 0x0b,
+ 0x22, 0x88, 0xef, 0x8e, 0xdf, 0x11, 0xb5, 0x3c, 0x91, 0x81, 0x9f, 0xc2, 0x9a, 0x47, 0x43, 0xec,
+ 0x30, 0x62, 0x0b, 0xe2, 0x72, 0xdf, 0xa5, 0x8c, 0x51, 0x2c, 0x29, 0xf7, 0xeb, 0x95, 0x64, 0xf8,
+ 0xee, 0xa8, 0xb4, 0x35, 0x9a, 0x35, 0x7f, 0x69, 0x50, 0x9f, 0xec, 0x4b, 0x79, 0xbf, 0x0b, 0x28,
+ 0x96, 0xc7, 0x2e, 0x3a, 0x3c, 0xb5, 0x38, 0x63, 0x0d, 0x1f, 0xa0, 0x1d, 0x58, 0x52, 0x7d, 0x8d,
+ 0xa9, 0xa8, 0xda, 0x3d, 0x52, 0x51, 0xb4, 0x17, 0xd3, 0x66, 0x9d, 0xe5, 0xd8, 0xb4, 0xb5, 0xab,
+ 0x9e, 0x73, 0xf8, 0x06, 0x54, 0x63, 0xaf, 0xed, 0xb7, 0xdc, 0xb1, 0xa9, 0x97, 0xf4, 0x53, 0xb1,
+ 0xe6, 0xe2, 0xd0, 0x4b, 0xee, 0x9c, 0x78, 0xc5, 0x42, 0xfd, 0x57, 0x2c, 0x54, 0xfb, 0x6b, 0x19,
+ 0xfe, 0xef, 0xa8, 0x97, 0xe2, 0xc4, 0xbf, 0xe0, 0xe7, 0x44, 0x5c, 0x52, 0x97, 0x20, 0x02, 0x68,
+ 0x72, 0xfc, 0xd0, 0xf6, 0x75, 0xa3, 0x99, 0x98, 0x6f, 0x98, 0x37, 0x4f, 0xaf, 0xa9, 0xff, 0xfe,
+ 0xd4, 0xa8, 0xe8, 0xa5, 0x9a, 0x86, 0x30, 0xd4, 0xc6, 0xd5, 0x46, 0x9b, 0x19, 0xc3, 0x94, 0xf9,
+ 0x32, 0xb6, 0xa6, 0x03, 0xc6, 0x16, 0x28, 0xed, 0x6b, 0xe8, 0x35, 0x2c, 0x8c, 0xdc, 0x57, 0x68,
+ 0x7d, 0xca, 0x35, 0x96, 0x92, 0xdf, 0xbf, 0xf6, 0x92, 0x1b, 0xda, 0xba, 0x84, 0xb5, 0x29, 0x4f,
+ 0x10, 0x7a, 0x94, 0x71, 0x5c, 0xff, 0x9c, 0x1a, 0x3b, 0x37, 0xe2, 0x46, 0x56, 0xd5, 0x6a, 0xa5,
+ 0xc3, 0xfd, 0x37, 0x71, 0x0d, 0xc3, 0x4e, 0xd3, 0xe5, 0xfd, 0x56, 0xfa, 0xb9, 0xc7, 0x45, 0xb7,
+ 0x95, 0x32, 0xb5, 0x92, 0xa7, 0xbc, 0xd5, 0xe5, 0xea, 0x3f, 0x70, 0x9c, 0x99, 0x24, 0x74, 0xf0,
+ 0x27, 0x00, 0x00, 0xff, 0xff, 0x95, 0xbb, 0xed, 0x49, 0x11, 0x08, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -662,8 +686,7 @@ type PraefectInfoServiceClient interface {
// back indicating which repos are consistent with the primary and which ones
// need repair.
ConsistencyCheck(ctx context.Context, in *ConsistencyCheckRequest, opts ...grpc.CallOption) (PraefectInfoService_ConsistencyCheckClient, error)
- // DatalossCheck checks for nodes which are not up to date with the previous writable primary.
- // This indicates possible data loss after a failover event.
+ // DatalossCheck checks for outdated repository replicas.
DatalossCheck(ctx context.Context, in *DatalossCheckRequest, opts ...grpc.CallOption) (*DatalossCheckResponse, error)
// SetAuthoritativeStorage sets the authoritative storage for a repository on a given virtual storage.
// This causes the current version of the repository on the authoritative storage to be considered the
@@ -746,8 +769,7 @@ type PraefectInfoServiceServer interface {
// back indicating which repos are consistent with the primary and which ones
// need repair.
ConsistencyCheck(*ConsistencyCheckRequest, PraefectInfoService_ConsistencyCheckServer) error
- // DatalossCheck checks for nodes which are not up to date with the previous writable primary.
- // This indicates possible data loss after a failover event.
+ // DatalossCheck checks for outdated repository replicas.
DatalossCheck(context.Context, *DatalossCheckRequest) (*DatalossCheckResponse, error)
// SetAuthoritativeStorage sets the authoritative storage for a repository on a given virtual storage.
// This causes the current version of the repository on the authoritative storage to be considered the
diff --git a/proto/praefect.proto b/proto/praefect.proto
index aaad1570f..18db7f6f9 100644
--- a/proto/praefect.proto
+++ b/proto/praefect.proto
@@ -25,8 +25,7 @@ service PraefectInfoService {
};
}
- // DatalossCheck checks for nodes which are not up to date with the previous writable primary.
- // This indicates possible data loss after a failover event.
+ // DatalossCheck checks for outdated repository replicas.
rpc DatalossCheck(DatalossCheckRequest) returns (DatalossCheckResponse) {
option (op_type) = {
op: ACCESSOR
@@ -55,6 +54,11 @@ message SetAuthoritativeStorageResponse {}
message DatalossCheckRequest {
string virtual_storage = 1 [(storage)=true];
+ // include_partially_replicated decides whether to include repositories which are fully up to date
+ // on the primary but are outdated on some secondaries. Such repositories are still writable and do
+ // not suffer from data loss. The data on the primary is not fully replicated which increases the
+ // chances of data loss following a failover.
+ bool include_partially_replicated = 2;
}
message DatalossCheckResponse {
@@ -70,6 +74,8 @@ message DatalossCheckResponse {
string relative_path = 1;
// storages on which the repository is outdated
repeated Storage storages = 2;
+ // read_only indicates whether the repository is in read-only mode.
+ bool read_only = 3;
}
// current primary storage
diff --git a/ruby/proto/gitaly/praefect_pb.rb b/ruby/proto/gitaly/praefect_pb.rb
index 2900a3368..b0bda2392 100644
--- a/ruby/proto/gitaly/praefect_pb.rb
+++ b/ruby/proto/gitaly/praefect_pb.rb
@@ -16,6 +16,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
end
add_message "gitaly.DatalossCheckRequest" do
optional :virtual_storage, :string, 1
+ optional :include_partially_replicated, :bool, 2
end
add_message "gitaly.DatalossCheckResponse" do
optional :primary, :string, 1
@@ -24,6 +25,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
add_message "gitaly.DatalossCheckResponse.Repository" do
optional :relative_path, :string, 1
repeated :storages, :message, 2, "gitaly.DatalossCheckResponse.Repository.Storage"
+ optional :read_only, :bool, 3
end
add_message "gitaly.DatalossCheckResponse.Repository.Storage" do
optional :name, :string, 1
diff --git a/ruby/proto/gitaly/praefect_services_pb.rb b/ruby/proto/gitaly/praefect_services_pb.rb
index 55a931953..5d1e4ae70 100644
--- a/ruby/proto/gitaly/praefect_services_pb.rb
+++ b/ruby/proto/gitaly/praefect_services_pb.rb
@@ -20,8 +20,7 @@ module Gitaly
# back indicating which repos are consistent with the primary and which ones
# need repair.
rpc :ConsistencyCheck, Gitaly::ConsistencyCheckRequest, stream(Gitaly::ConsistencyCheckResponse)
- # DatalossCheck checks for nodes which are not up to date with the previous writable primary.
- # This indicates possible data loss after a failover event.
+ # DatalossCheck checks for outdated repository replicas.
rpc :DatalossCheck, Gitaly::DatalossCheckRequest, Gitaly::DatalossCheckResponse
# SetAuthoritativeStorage sets the authoritative storage for a repository on a given virtual storage.
# This causes the current version of the repository on the authoritative storage to be considered the