Skip to content

Commit d3411b7

Browse files
authored
Merge pull request #1149 from percona/PBM-1564-inc-backup-different-storage-err
PBM-1564: Incremental backup fails with "source backup is stored on a different storage"
2 parents 09e4059 + 7975f6d commit d3411b7

File tree

7 files changed

+210
-2
lines changed

7 files changed

+210
-2
lines changed

cmd/pbm-agent/pitr.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ func canSlicingNow(ctx context.Context, conn connect.Client, stgCfg *config.Stor
160160
return errors.Wrap(err, "get backup metadata")
161161
}
162162

163-
if bcp.Type == defs.LogicalBackup && bcp.Store.Equal(stgCfg) {
163+
if bcp.Type == defs.LogicalBackup && bcp.Store.IsSameStorage(stgCfg) {
164164
return lock.ConcurrentOpError{l.LockHeader}
165165
}
166166
}

pbm/backup/physical.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ func (b *Backup) doPhysical(
232232
}
233233
}
234234

235-
if !b.config.Storage.Equal(&src.Store.StorageConf) {
235+
if !b.config.Storage.IsSameStorage(&src.Store.StorageConf) {
236236
return errors.New("cannot use the configured storage: " +
237237
"source backup is stored on a different storage")
238238
}

pbm/config/config.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,32 @@ func (s *StorageConf) Equal(other *StorageConf) bool {
274274
return false
275275
}
276276

277+
// IsSameStorage returns true if specified config params describes
278+
// the same instance of the storage.
279+
// It ignores storage properties, and just compare parts that specifies
280+
// the storage instance.
281+
func (s *StorageConf) IsSameStorage(other *StorageConf) bool {
282+
if s.Type != other.Type {
283+
return false
284+
}
285+
286+
switch s.Type {
287+
case storage.S3:
288+
return s.S3.IsSameStorage(other.S3)
289+
case storage.Azure:
290+
return s.Azure.IsSameStorage(other.Azure)
291+
case storage.GCS:
292+
return s.GCS.IsSameStorage(other.GCS)
293+
case storage.Filesystem:
294+
// FS is the same if it's equal
295+
return s.Filesystem.Equal(other.Filesystem)
296+
case storage.Blackhole:
297+
return true
298+
}
299+
300+
return false
301+
}
302+
277303
func (s *StorageConf) Cast() error {
278304
switch s.Type {
279305
case storage.Filesystem:

pbm/config/config_test.go

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
package config
2+
3+
import (
4+
"testing"
5+
6+
"github.com/percona/percona-backup-mongodb/pbm/storage/azure"
7+
"github.com/percona/percona-backup-mongodb/pbm/storage/gcs"
8+
"github.com/percona/percona-backup-mongodb/pbm/storage/s3"
9+
)
10+
11+
func TestIsSameStorage(t *testing.T) {
12+
t.Run("S3", func(t *testing.T) {
13+
cfg := &s3.Config{
14+
Region: "eu",
15+
EndpointURL: "ep.com",
16+
Bucket: "b1",
17+
Prefix: "p1",
18+
ForcePathStyle: boolPtr(true),
19+
Credentials: s3.Credentials{
20+
AccessKeyID: "k1",
21+
SecretAccessKey: "k2",
22+
},
23+
UploadPartSize: 1000,
24+
MaxUploadParts: 10001,
25+
StorageClass: "sc",
26+
27+
InsecureSkipTLSVerify: false,
28+
}
29+
eq := &s3.Config{
30+
Region: "eu",
31+
Bucket: "b1",
32+
Prefix: "p1",
33+
}
34+
if !cfg.IsSameStorage(eq) {
35+
t.Errorf("config storage should identify the same instance: cfg=%+v, eq=%+v", cfg, eq)
36+
}
37+
38+
neq := cfg.Clone()
39+
neq.Region = "us"
40+
if cfg.IsSameStorage(neq) {
41+
t.Errorf("storage instances has different region: cfg=%+v, eq=%+v", cfg, neq)
42+
}
43+
44+
neq = cfg.Clone()
45+
neq.Bucket = "b2"
46+
if cfg.IsSameStorage(neq) {
47+
t.Errorf("storage instances has different bucket: cfg=%+v, eq=%+v", cfg, neq)
48+
}
49+
50+
neq = cfg.Clone()
51+
neq.Prefix = "p2"
52+
if cfg.IsSameStorage(neq) {
53+
t.Errorf("storage instances has different prefix: cfg=%+v, eq=%+v", cfg, neq)
54+
}
55+
})
56+
57+
t.Run("Azure", func(t *testing.T) {
58+
cfg := &azure.Config{
59+
Account: "a1",
60+
Container: "c1",
61+
EndpointURL: "az.com",
62+
Prefix: "p1",
63+
Credentials: azure.Credentials{
64+
Key: "k",
65+
},
66+
}
67+
68+
eq := &azure.Config{
69+
Account: "a1",
70+
Container: "c1",
71+
Prefix: "p1",
72+
}
73+
if !cfg.IsSameStorage(eq) {
74+
t.Errorf("config storage should identify the same instance: cfg=%+v, eq=%+v", cfg, eq)
75+
}
76+
77+
neq := cfg.Clone()
78+
neq.Account = "a2"
79+
if cfg.IsSameStorage(neq) {
80+
t.Errorf("storage instances has different account: cfg=%+v, eq=%+v", cfg, neq)
81+
}
82+
83+
neq = cfg.Clone()
84+
neq.Container = "c2"
85+
if cfg.IsSameStorage(neq) {
86+
t.Errorf("storage instances has different container: cfg=%+v, eq=%+v", cfg, neq)
87+
}
88+
89+
neq = cfg.Clone()
90+
neq.Prefix = "p2"
91+
if cfg.IsSameStorage(neq) {
92+
t.Errorf("storage instances has different prefix: cfg=%+v, eq=%+v", cfg, neq)
93+
}
94+
})
95+
96+
t.Run("GCS", func(t *testing.T) {
97+
cfg := &gcs.Config{
98+
Bucket: "b1",
99+
Prefix: "p1",
100+
Credentials: gcs.Credentials{
101+
PrivateKey: "abc",
102+
},
103+
ChunkSize: 1000,
104+
}
105+
106+
eq := &gcs.Config{
107+
Bucket: "b1",
108+
Prefix: "p1",
109+
}
110+
if !cfg.IsSameStorage(eq) {
111+
t.Errorf("config storage should identify the same instance: cfg=%+v, eq=%+v", cfg, eq)
112+
}
113+
114+
neq := cfg.Clone()
115+
neq.Bucket = "b2"
116+
if cfg.IsSameStorage(neq) {
117+
t.Errorf("storage instances has different bucket: cfg=%+v, eq=%+v", cfg, neq)
118+
}
119+
120+
neq = cfg.Clone()
121+
neq.Prefix = "p2"
122+
if cfg.IsSameStorage(neq) {
123+
t.Errorf("storage instances has different prefix: cfg=%+v, eq=%+v", cfg, neq)
124+
}
125+
})
126+
}
127+
128+
func boolPtr(b bool) *bool {
129+
return &b
130+
}

pbm/storage/azure/azure.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,24 @@ func (cfg *Config) Equal(other *Config) bool {
7979
return true
8080
}
8181

82+
// IsSameStorage identifies the same instance of the Azure storage.
83+
func (cfg *Config) IsSameStorage(other *Config) bool {
84+
if cfg == nil || other == nil {
85+
return cfg == other
86+
}
87+
88+
if cfg.Account != other.Account {
89+
return false
90+
}
91+
if cfg.Container != other.Container {
92+
return false
93+
}
94+
if cfg.Prefix != other.Prefix {
95+
return false
96+
}
97+
return true
98+
}
99+
82100
// resolveEndpointURL returns endpoint url based on provided
83101
// EndpointURL or associated EndpointURLMap configuration fields.
84102
// If specified EndpointURLMap overrides EndpointURL field.

pbm/storage/gcs/gcs.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,22 @@ func (cfg *Config) Equal(other *Config) bool {
108108
return true
109109
}
110110

111+
// IsSameStorage identifies the same instance of the GCS storage.
112+
func (cfg *Config) IsSameStorage(other *Config) bool {
113+
if cfg == nil || other == nil {
114+
return cfg == other
115+
}
116+
117+
if cfg.Bucket != other.Bucket {
118+
return false
119+
}
120+
if cfg.Prefix != other.Prefix {
121+
return false
122+
}
123+
124+
return true
125+
}
126+
111127
func New(opts *Config, node string, l log.LogEvent) (*GCS, error) {
112128
g := &GCS{
113129
opts: opts,

pbm/storage/s3/s3.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,24 @@ func (cfg *Config) Equal(other *Config) bool {
188188
return true
189189
}
190190

191+
// IsSameStorage identifies the same instance of the S3 storage.
192+
func (cfg *Config) IsSameStorage(other *Config) bool {
193+
if cfg == nil || other == nil {
194+
return cfg == other
195+
}
196+
197+
if cfg.Region != other.Region {
198+
return false
199+
}
200+
if cfg.Bucket != other.Bucket {
201+
return false
202+
}
203+
if cfg.Prefix != other.Prefix {
204+
return false
205+
}
206+
return true
207+
}
208+
191209
func (cfg *Config) Cast() error {
192210
if cfg.Region == "" {
193211
cfg.Region = defaultS3Region

0 commit comments

Comments
 (0)