Skip to content

Commit 0bd98f5

Browse files
PS-11001: Enable purge_binlogs on the s3 storage backend
1 parent 0ad42fc commit 0bd98f5

5 files changed

Lines changed: 25 additions & 28 deletions

File tree

mtr/binlog_streaming/include/set_up_binsrv_environment.inc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ if ($storage_backend == s3)
4242
--let $aws_s3_bucket = $MTR_BINSRV_AWS_S3_BUCKET
4343
if ($MTR_BINSRV_AWS_S3_ENDPOINT != '')
4444
{
45-
eval SET @storage_uri = CONCAT('http://', '$MTR_BINSRV_AWS_ACCESS_KEY_ID', ':', '$MTR_BINSRV_AWS_SECRET_ACCESS_KEY', '@', '$MTR_BINSRV_AWS_S3_ENDPOINT', '/$MTR_BINSRV_AWS_S3_BUCKET', '$binsrv_storage_path');
45+
eval SET @storage_uri = CONCAT('http://', '$MTR_BINSRV_AWS_ACCESS_KEY_ID', ':', REPLACE('$MTR_BINSRV_AWS_SECRET_ACCESS_KEY', '/', '%2F'), '@', '$MTR_BINSRV_AWS_S3_ENDPOINT', '/', '$MTR_BINSRV_AWS_S3_BUCKET', '$binsrv_storage_path');
4646
}
4747
if ($MTR_BINSRV_AWS_S3_ENDPOINT == '')
4848
{
@@ -51,7 +51,7 @@ if ($storage_backend == s3)
5151
{
5252
--let $qualified_bucket = $qualified_bucket.$MTR_BINSRV_AWS_S3_REGION
5353
}
54-
eval SET @storage_uri = CONCAT('s3://', '$MTR_BINSRV_AWS_ACCESS_KEY_ID', ':', '$MTR_BINSRV_AWS_SECRET_ACCESS_KEY', '@', '$qualified_bucket', '$binsrv_storage_path');
54+
eval SET @storage_uri = CONCAT('s3://', '$MTR_BINSRV_AWS_ACCESS_KEY_ID', ':', REPLACE('$MTR_BINSRV_AWS_SECRET_ACCESS_KEY', '/', '%2F'), '@', '$qualified_bucket', '$binsrv_storage_path');
5555
}
5656
}
5757

mtr/binlog_streaming/t/purge_binlogs.test

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,8 @@
22

33
--source ../include/v80_v84_compatibility_defines.inc
44

5-
# identifying backend storage type ('file' or 's3') early - 'purge_binlogs'
6-
# is supported only on the local filesystem backend
75
--source ../include/identify_storage_backend.inc
86

9-
if ($storage_backend == s3)
10-
{
11-
--skip purge_binlogs is supported only on the local filesystem backend
12-
}
13-
147
# in case of --repeat=N, we need to start from a fresh binary log to make
158
# this test deterministic
169
--echo *** Resetting replication at the very beginning of the test.

src/app.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,13 +1058,6 @@ bool handle_purge_binlogs(std::string_view config_file_path,
10581058
const auto &replication_config = config.root().get<"replication">();
10591059
const auto replication_mode{replication_config.get<"mode">()};
10601060

1061-
// for now, only file backend supported
1062-
if (storage_config.get<"backend">() != binsrv::storage_backend_type::file) {
1063-
throw std::runtime_error(
1064-
"purge_binlogs is only supported on the local filesystem storage "
1065-
"backend");
1066-
}
1067-
10681061
binsrv::storage storage{storage_config,
10691062
binsrv::storage_construction_mode_type::purging,
10701063
replication_mode};

src/binsrv/s3_storage_backend.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
#include <aws/s3-crt/S3CrtClient.h>
5454

5555
#include <aws/s3-crt/model/BucketLocationConstraint.h>
56+
#include <aws/s3-crt/model/DeleteObjectRequest.h>
5657
#include <aws/s3-crt/model/GetBucketLocationRequest.h>
5758
#include <aws/s3-crt/model/GetBucketLocationResult.h>
5859
#include <aws/s3-crt/model/GetObjectRequest.h>
@@ -171,6 +172,8 @@ class s3_storage_backend::aws_context : private aws_context_base {
171172
void put_object_from_span(const qualified_object_path &dest,
172173
util::const_byte_span content) const;
173174

175+
void delete_object(const qualified_object_path &target) const;
176+
174177
[[nodiscard]] storage_object_name_container
175178
list_objects(const qualified_object_path &prefix);
176179

@@ -346,6 +349,23 @@ void s3_storage_backend::aws_context::put_object_from_span(
346349
put_object_from_stream(dest, content_stream);
347350
}
348351

352+
// TODO: Consider deleting several objects in one request by using
353+
// `DeleteObjects()` AWS SDK C++ API call
354+
void s3_storage_backend::aws_context::delete_object(
355+
const qualified_object_path &target) const {
356+
Aws::S3Crt::Model::DeleteObjectRequest delete_object_request;
357+
delete_object_request.SetBucket(target.bucket);
358+
delete_object_request.SetKey(target.object_path.generic_string());
359+
360+
const auto delete_object_outcome{
361+
client_->DeleteObject(delete_object_request)};
362+
363+
if (!delete_object_outcome.IsSuccess()) {
364+
raise_s3_error_from_outcome("cannot delete object from S3 bucket",
365+
delete_object_outcome.GetError());
366+
}
367+
}
368+
349369
[[nodiscard]] storage_object_name_container
350370
s3_storage_backend::aws_context::list_objects(
351371
const qualified_object_path &prefix) {
@@ -679,10 +699,9 @@ void s3_storage_backend::do_put_object(std::string_view name,
679699
{.bucket = bucket_, .object_path = get_object_path(name)}, content);
680700
}
681701

682-
void s3_storage_backend::do_remove_object(
683-
[[maybe_unused]] std::string_view name) {
684-
util::exception_location().raise<std::logic_error>(
685-
"remove_object is not supported on the S3 storage backend");
702+
void s3_storage_backend::do_remove_object(std::string_view name) {
703+
impl_->delete_object(
704+
{.bucket = bucket_, .object_path = get_object_path(name)});
686705
}
687706

688707
void s3_storage_backend::do_fsync() {

src/binsrv/storage.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
#include "binsrv/binlog_file_metadata.hpp"
3434
#include "binsrv/replication_mode_type.hpp"
3535
#include "binsrv/storage_backend_factory.hpp"
36-
#include "binsrv/storage_backend_type.hpp"
3736
#include "binsrv/storage_config.hpp"
3837
#include "binsrv/storage_metadata.hpp"
3938

@@ -54,13 +53,6 @@ storage::storage(const storage_config &config,
5453
replication_mode_type replication_mode)
5554
: construction_mode_{construction_mode}, backend_{},
5655
replication_mode_{replication_mode} {
57-
if (construction_mode_ == storage_construction_mode_type::purging &&
58-
config.get<"backend">() != storage_backend_type::file) {
59-
util::exception_location().raise<std::runtime_error>(
60-
"purge_binlogs is only supported on the local filesystem storage "
61-
"backend");
62-
}
63-
6456
const auto &checkpoint_size_opt{config.get<"checkpoint_size">()};
6557
if (checkpoint_size_opt.has_value()) {
6658
checkpoint_size_bytes_ = checkpoint_size_opt->get_value();

0 commit comments

Comments
 (0)