Skip to content

Commit

Permalink
objtools: fix 5GiB+ server-side copies on S3 (#9357)
Browse files Browse the repository at this point in the history
  • Loading branch information
andyasp authored Sep 23, 2024
1 parent 3b5a9b3 commit 685e06d
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 11 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@
* [ENHANCEMENT] `tsdb-series`: Added `-min-time` and `-max-time` options to filter samples that are used for computing data-points per minute. #8844
* [ENHANCEMENT] `mimir-rules-action`: Added new input to support matching target namespaces by regex. #9244
* [ENHANCEMENT] `mimir-rules-action`: Added new inputs to support ignoring namespaces and ignoring namespaces by regex. #9258 #9324
* [BUGFIX] `copyblocks`, `undelete-blocks`, `copyprefix`: use a multipart upload to server-side copy objects greater than 5GiB in size on S3. #9357

## 2.13.0

Expand Down
40 changes: 29 additions & 11 deletions pkg/util/objtools/s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,22 +77,40 @@ func (bkt *s3Bucket) Get(ctx context.Context, objectName string, options GetOpti
return obj, nil
}

const maxSingleCopySize int64 = 5 * (1024 * 1024 * 1024) // 5 GiB

func (bkt *s3Bucket) ServerSideCopy(ctx context.Context, objectName string, dstBucket Bucket, options CopyOptions) error {
d, ok := dstBucket.(*s3Bucket)
if !ok {
return errors.New("destination Bucket wasn't an S3 Bucket")
}
_, err := d.client.CopyObject(ctx,
minio.CopyDestOptions{
Bucket: d.bucketName,
Object: options.destinationObjectName(objectName),
},
minio.CopySrcOptions{
Bucket: bkt.bucketName,
Object: objectName,
VersionID: options.SourceVersionID,
},
)

stat, err := bkt.client.StatObject(ctx, bkt.bucketName, objectName, minio.StatObjectOptions{
VersionID: options.SourceVersionID,
})
if err != nil {
return err
}

dstOptions := minio.CopyDestOptions{
Bucket: d.bucketName,
Object: options.destinationObjectName(objectName),
}

srcOptions := minio.CopySrcOptions{
Bucket: bkt.bucketName,
Object: objectName,
VersionID: options.SourceVersionID,
}

if stat.Size <= maxSingleCopySize {
_, err := d.client.CopyObject(ctx, dstOptions, srcOptions)
return err
}

// Uses a multi-part upload
// Due to https://github.com/minio/minio-go/issues/1683 this likely does not work cross-region
_, err = d.client.ComposeObject(ctx, dstOptions, srcOptions)
return err
}

Expand Down

0 comments on commit 685e06d

Please sign in to comment.