Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

issue-2722: add use-intermediate-write-buffer tag if scrubbing found a mismatch #2836

Merged
merged 4 commits into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cloud/blockstore/config/storage.proto
Original file line number Diff line number Diff line change
Expand Up @@ -1103,4 +1103,8 @@ message TStorageServiceConfig
optional uint32 ForcedCompactionRangeCountPerRun = 401;

optional bool YdbViewerServiceEnabled = 402;

// When enabled, tag "use-intermediate-write-buffer" will be added
// after scrubbing finds a mismatch
optional bool AutomaticallyEnableBufferCopyingAfterChecksumMismatch = 403;
}
5 changes: 5 additions & 0 deletions cloud/blockstore/libs/storage/api/public.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@

namespace NCloud::NBlockStore::NStorage {

////////////////////////////////////////////////////////////////////////////////

constexpr TStringBuf IntermediateWriteBufferTagName =
"use-intermediate-write-buffer";

////////////////////////////////////////////////////////////////////////////////
// BackpressureReport event descriptor

Expand Down
26 changes: 26 additions & 0 deletions cloud/blockstore/libs/storage/api/service.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ namespace NCloud::NBlockStore::NStorage {
xxx(ChangeVolumeBinding, __VA_ARGS__) \
xxx(GetVolumeStats, __VA_ARGS__) \
xxx(RunVolumesLivenessCheck, __VA_ARGS__) \
xxx(AddTags, __VA_ARGS__) \
// BLOCKSTORE_SERVICE_REQUESTS

////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -160,6 +161,28 @@ struct TEvService
{}
};

//
// AddTags
//

struct TAddTagsRequest
{
const TString DiskId;
const TVector<TString> Tags;

TAddTagsRequest() = default;

TAddTagsRequest(
TString diskId,
TVector<TString> tags)
: DiskId(std::move(diskId))
, Tags(std::move(tags))
{}
};

struct TAddTagsResponse
{};

//
// VolumeMountStateChanged
//
Expand Down Expand Up @@ -317,6 +340,9 @@ struct TEvService
EvQueryAgentsInfoRequest = EvBegin + 89,
EvQueryAgentsInfoResponse = EvBegin + 90,

EvAddTagsRequest = EvBegin + 91,
EvAddTagsResponse = EvBegin + 92,

EvEnd
};

Expand Down
1 change: 1 addition & 0 deletions cloud/blockstore/libs/storage/core/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,7 @@ TDuration MSeconds(ui32 value)
xxx(ScrubbingBandwidth, ui64, 20 )\
xxx(MaxScrubbingBandwidth, ui64, 50 )\
xxx(MinScrubbingBandwidth, ui64, 5 )\
xxx(AutomaticallyEnableBufferCopyingAfterChecksumMismatch, bool, false )\
\
xxx(OptimizeVoidBuffersTransferForReadsEnabled, bool, false )\
xxx(VolumeHistoryCleanupItemCount, ui32, 100'000 )\
Expand Down
2 changes: 2 additions & 0 deletions cloud/blockstore/libs/storage/core/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,8 @@ class TStorageConfig
[[nodiscard]] bool GetCalculateSplittedUsedQuotaMetric() const;

bool GetYdbViewerServiceEnabled() const;

bool GetAutomaticallyEnableBufferCopyingAfterChecksumMismatch() const;
};

ui64 GetAllocationUnit(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,11 @@ void TMirrorPartitionActor::CompareChecksums(const TActorContext& ctx)
DiskId.c_str(),
DescribeRange(GetScrubbingRange()).c_str());

if (Config->GetAutomaticallyEnableBufferCopyingAfterChecksumMismatch())
WilyTiger marked this conversation as resolved.
Show resolved Hide resolved
{
AddTagForBufferCopying(ctx);
}

for (size_t i = 0; i < checksums.size(); i++) {
LOG_ERROR(
ctx,
Expand Down Expand Up @@ -275,6 +280,22 @@ void TMirrorPartitionActor::StartResyncRange(
BlockDigestGenerator);
}

void TMirrorPartitionActor::AddTagForBufferCopying(
const NActors::TActorContext& ctx)
{
auto requestInfo = CreateRequestInfo(
SelfId(),
0, // cookie
MakeIntrusive<TCallContext>());

TVector<TString> tags({TString(IntermediateWriteBufferTagName)});
auto request = std::make_unique<TEvService::TEvAddTagsRequest>(
DiskId,
std::move(tags));

ctx.Send(MakeStorageServiceId(), std::move(request));
}

void TMirrorPartitionActor::ReplyAndDie(const TActorContext& ctx)
{
NCloud::Reply(ctx, *Poisoner, std::make_unique<TEvents::TEvPoisonTaken>());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ class TMirrorPartitionActor final
const NActors::TActorContext& ctx,
ui64 scrubbingRangeId);
void StartResyncRange(const NActors::TActorContext& ctx);
void AddTagForBufferCopying(const NActors::TActorContext& ctx);

private:
STFUNC(StateWork);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,10 @@ struct TTestEnv
)
);

Runtime.AddLocalService(
WilyTiger marked this conversation as resolved.
Show resolved Hide resolved
MakeStorageServiceId(),
TActorSetupCmd(new TStorageServiceMock(), TMailboxType::Simple, 0));

NKikimr::SetupTabletServices(Runtime);
}

Expand Down Expand Up @@ -1179,7 +1183,25 @@ Y_UNIT_TEST_SUITE(TMirrorPartitionTest)
TDynamicCountersPtr critEventsCounters = new TDynamicCounters();
InitCriticalEventsCounter(critEventsCounters);

TTestEnv env(runtime);
NProto::TStorageServiceConfig config;
config.SetAutomaticallyEnableBufferCopyingAfterChecksumMismatch(true);
TTestEnv env(runtime, config);

bool tagEnabled = false;
runtime.SetEventFilter([&] (auto& runtime, auto& event) {
Y_UNUSED(runtime);
if (event->GetTypeRewrite() == TEvService::EvAddTagsRequest)
{
using TRequest =
TEvService::TEvAddTagsRequest;
WilyTiger marked this conversation as resolved.
Show resolved Hide resolved
const auto& tags = event->template Get<TRequest>()->Tags;
UNIT_ASSERT_VALUES_EQUAL(1, tags.size());
UNIT_ASSERT_VALUES_EQUAL(IntermediateWriteBufferTagName, tags[0]);
tagEnabled = true;
WilyTiger marked this conversation as resolved.
Show resolved Hide resolved
}

return false;
});

const auto range1 = TBlockRange64::WithLength(0, 2);
env.WriteMirror(range1, 'A');
Expand All @@ -1200,6 +1222,7 @@ Y_UNIT_TEST_SUITE(TMirrorPartitionTest)

UNIT_ASSERT_VALUES_EQUAL(2, mirroredDiskMinorityChecksumMismatch->Val());
UNIT_ASSERT_VALUES_EQUAL(2, counters.Simple.ChecksumMismatches.Value);
UNIT_ASSERT(tagEnabled);

const auto range3 = TBlockRange64::WithLength(1025, 50);
env.WriteMirror(range3, 'A');
Expand Down
41 changes: 41 additions & 0 deletions cloud/blockstore/libs/storage/partition_nonrepl/ut_env.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,47 @@ class TDummyActor final

////////////////////////////////////////////////////////////////////////////////

class TStorageServiceMock final: public NActors::TActor<TStorageServiceMock>
{
public:
TStorageServiceMock()
: TActor(&TThis::StateWork)
{
}

private:
STFUNC(StateWork)
{
switch (ev->GetTypeRewrite()) {
HFunc(NActors::TEvents::TEvPoisonPill, HandlePoisonPill);

HFunc(TEvService::TEvAddTagsRequest, HandleAddTagsRequest);

default:
Y_ABORT("Unexpected event %x", ev->GetTypeRewrite());
}
}

void HandlePoisonPill(
const NActors::TEvents::TEvPoisonPill::TPtr& ev,
const NActors::TActorContext& ctx)
{
Y_UNUSED(ev);

Die(ctx);
}

void HandleAddTagsRequest(
const TEvService::TEvAddTagsRequest::TPtr& ev,
const NActors::TActorContext& ctx)
{
Y_UNUSED(ev);
Y_UNUSED(ctx);
}
};

////////////////////////////////////////////////////////////////////////////////

class TPartitionClient
{
private:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,35 @@ STFUNC(TModifyTagsActionActor::StateWaitReady)

////////////////////////////////////////////////////////////////////////////////

void TServiceActor::HandleAddTags(
const TEvService::TEvAddTagsRequest::TPtr& ev,
const NActors::TActorContext& ctx)
{
auto* msg = ev->Get();

auto requestInfo = CreateRequestInfo(
SelfId(),
0, // cookie
MakeIntrusive<TCallContext>());

NPrivateProto::TModifyTagsRequest modifyTagsRequest;
modifyTagsRequest.SetDiskId(msg->DiskId);
for (const auto& tag: msg->Tags) {
modifyTagsRequest.AddTagsToAdd(tag);
}

TString input;
google::protobuf::util::MessageToJsonString(modifyTagsRequest, &input);

NCloud::Register(
ctx,
std::make_unique<TModifyTagsActionActor>(
std::move(requestInfo),
std::move(input)));
}

////////////////////////////////////////////////////////////////////////////////

TResultOrError<IActorPtr> TServiceActor::CreateModifyTagsActionActor(
TRequestInfoPtr requestInfo,
TString input)
Expand Down
2 changes: 1 addition & 1 deletion cloud/blockstore/libs/storage/volume/volume_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ void TVolumeState::Reset()
TDuration::TryParse(value, MaxTimedOutDeviceStateDuration);
} else if (tag == "use-fastpath") {
UseFastPath = true;
} else if (tag == "use-intermediate-write-buffer") {
} else if (tag == IntermediateWriteBufferTagName) {
UseIntermediateWriteBuffer = true;
}
}
Expand Down
Loading