Skip to content

Commit 6c7ed0d

Browse files
authored
Evwrite optimizations (#11428)
1 parent 4790237 commit 6c7ed0d

File tree

7 files changed

+75
-87
lines changed

7 files changed

+75
-87
lines changed

ydb/core/kqp/common/buffer/buffer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ struct TKqpBufferWriterSettings {
1111
IKqpTransactionManagerPtr TxManager;
1212
NWilson::TTraceId TraceId;
1313
TIntrusivePtr<TKqpCounters> Counters;
14+
TIntrusivePtr<NTxProxy::TTxProxyMon> TxProxyMon;
1415
};
1516

1617
NActors::IActor* CreateKqpBufferWriterActor(TKqpBufferWriterSettings&& settings);

ydb/core/kqp/common/kqp_tx.cpp

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -251,23 +251,12 @@ bool HasOlapTableReadInTx(const NKqpProto::TKqpPhyQuery& physicalQuery) {
251251
return false;
252252
}
253253

254-
bool HasOlapTableWriteInStage(const NKqpProto::TKqpPhyStage& stage, const google::protobuf::RepeatedPtrField< ::NKqpProto::TKqpPhyTable>& tables) {
254+
bool HasOlapTableWriteInStage(const NKqpProto::TKqpPhyStage& stage) {
255255
for (const auto& sink : stage.GetSinks()) {
256256
if (sink.GetTypeCase() == NKqpProto::TKqpSink::kInternalSink && sink.GetInternalSink().GetSettings().Is<NKikimrKqp::TKqpTableSinkSettings>()) {
257257
NKikimrKqp::TKqpTableSinkSettings settings;
258258
YQL_ENSURE(sink.GetInternalSink().GetSettings().UnpackTo(&settings), "Failed to unpack settings");
259-
260-
const bool isOlapSink = std::any_of(
261-
std::begin(tables),
262-
std::end(tables),
263-
[&](const NKqpProto::TKqpPhyTable& table) {
264-
return table.GetKind() == NKqpProto::EKqpPhyTableKind::TABLE_KIND_OLAP
265-
&& google::protobuf::util::MessageDifferencer::Equals(table.GetId(), settings.GetTable());
266-
});
267-
268-
if (isOlapSink) {
269-
return true;
270-
}
259+
return settings.GetIsOlap();
271260
}
272261
}
273262
return false;
@@ -276,7 +265,7 @@ bool HasOlapTableWriteInStage(const NKqpProto::TKqpPhyStage& stage, const google
276265
bool HasOlapTableWriteInTx(const NKqpProto::TKqpPhyQuery& physicalQuery) {
277266
for (const auto &tx : physicalQuery.GetTransactions()) {
278267
for (const auto &stage : tx.GetStages()) {
279-
if (HasOlapTableWriteInStage(stage, tx.GetTables())) {
268+
if (HasOlapTableWriteInStage(stage)) {
280269
return true;
281270
}
282271
}
@@ -325,18 +314,7 @@ bool HasOltpTableWriteInTx(const NKqpProto::TKqpPhyQuery& physicalQuery) {
325314
if (sink.GetTypeCase() == NKqpProto::TKqpSink::kInternalSink && sink.GetInternalSink().GetSettings().Is<NKikimrKqp::TKqpTableSinkSettings>()) {
326315
NKikimrKqp::TKqpTableSinkSettings settings;
327316
YQL_ENSURE(sink.GetInternalSink().GetSettings().UnpackTo(&settings), "Failed to unpack settings");
328-
329-
const bool isOltpSink = std::any_of(
330-
std::begin(tx.GetTables()),
331-
std::end(tx.GetTables()),
332-
[&](const NKqpProto::TKqpPhyTable& table) {
333-
return table.GetKind() == NKqpProto::EKqpPhyTableKind::TABLE_KIND_DS
334-
&& google::protobuf::util::MessageDifferencer::Equals(table.GetId(), settings.GetTable());
335-
});
336-
337-
if (isOltpSink) {
338-
return true;
339-
}
317+
return !settings.GetIsOlap();
340318
}
341319
}
342320
}

ydb/core/kqp/common/kqp_tx.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -507,9 +507,7 @@ bool NeedSnapshot(const TKqpTransactionContext& txCtx, const NYql::TKikimrConfig
507507
bool commitTx, const NKqpProto::TKqpPhyQuery& physicalQuery);
508508

509509
bool HasOlapTableReadInTx(const NKqpProto::TKqpPhyQuery& physicalQuery);
510-
bool HasOlapTableWriteInStage(
511-
const NKqpProto::TKqpPhyStage& stage,
512-
const google::protobuf::RepeatedPtrField< ::NKqpProto::TKqpPhyTable>& tables);
510+
bool HasOlapTableWriteInStage(const NKqpProto::TKqpPhyStage& stage);
513511
bool HasOlapTableWriteInTx(const NKqpProto::TKqpPhyQuery& physicalQuery);
514512
bool HasOltpTableReadInTx(const NKqpProto::TKqpPhyQuery& physicalQuery);
515513
bool HasOltpTableWriteInTx(const NKqpProto::TKqpPhyQuery& physicalQuery);

ydb/core/kqp/executer_actor/kqp_data_executer.cpp

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,6 @@ class TKqpDataExecuter : public TKqpExecuterBase<TKqpDataExecuter, EExecType::Da
221221
return ReplyErrorAndDie(Ydb::StatusIds::ABORTED, {});
222222
}
223223

224-
ResponseEv->Record.MutableResponse()->SetStatus(Ydb::StatusIds::SUCCESS);
225-
Counters->TxProxyMon->ReportStatusOK->Inc();
226-
227224
auto addLocks = [this](const ui64 taskId, const auto& data) {
228225
if (data.GetData().template Is<NKikimrTxDataShard::TEvKqpInputActorResultInfo>()) {
229226
NKikimrTxDataShard::TEvKqpInputActorResultInfo info;
@@ -256,11 +253,13 @@ class TKqpDataExecuter : public TKqpExecuterBase<TKqpDataExecuter, EExecType::Da
256253
ShardIdToTableInfo->Add(lock.GetDataShard(), stageInfo.Meta.TableKind == ETableKind::Olap, stageInfo.Meta.TablePath);
257254
if (TxManager) {
258255
YQL_ENSURE(stageInfo.Meta.TableKind == ETableKind::Olap);
259-
TxManager->AddShard(lock.GetDataShard(), stageInfo.Meta.TableKind == ETableKind::Olap, stageInfo.Meta.TablePath);
260-
TxManager->AddAction(lock.GetDataShard(), IKqpTransactionManager::EAction::WRITE);
256+
IKqpTransactionManager::TActionFlags flags = IKqpTransactionManager::EAction::WRITE;
261257
if (info.GetHasRead()) {
262-
TxManager->AddAction(lock.GetDataShard(), IKqpTransactionManager::EAction::READ);
258+
flags |= IKqpTransactionManager::EAction::READ;
263259
}
260+
261+
TxManager->AddShard(lock.GetDataShard(), stageInfo.Meta.TableKind == ETableKind::Olap, stageInfo.Meta.TablePath);
262+
TxManager->AddAction(lock.GetDataShard(), flags);
264263
TxManager->AddLock(lock.GetDataShard(), lock);
265264
}
266265
}
@@ -337,6 +336,9 @@ class TKqpDataExecuter : public TKqpExecuterBase<TKqpDataExecuter, EExecType::Da
337336
}
338337

339338
void MakeResponseAndPassAway() {
339+
ResponseEv->Record.MutableResponse()->SetStatus(Ydb::StatusIds::SUCCESS);
340+
Counters->TxProxyMon->ReportStatusOK->Inc();
341+
340342
ResponseEv->Snapshot = GetSnapshot();
341343

342344
if (!Locks.empty() || (TxManager && TxManager->HasLocks())) {
@@ -1942,10 +1944,6 @@ class TKqpDataExecuter : public TKqpExecuterBase<TKqpDataExecuter, EExecType::Da
19421944
return false;
19431945
}
19441946

1945-
bool HasOlapSink(const NKqpProto::TKqpPhyStage& stage, const google::protobuf::RepeatedPtrField< ::NKqpProto::TKqpPhyTable>& tables) {
1946-
return NKqp::HasOlapTableWriteInStage(stage, tables);
1947-
}
1948-
19491947
void Execute() {
19501948
LWTRACK(KqpDataExecuterStartExecute, ResponseEv->Orbit, TxId);
19511949

ydb/core/kqp/runtime/kqp_write_actor.cpp

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -303,10 +303,11 @@ class TKqpTableWriteActor : public TActorBootstrapped<TKqpTableWriteActor> {
303303
// TODO: Maybe there are better ways to initialize new shards...
304304
for (const auto& shardInfo : ShardedWriteController->GetPendingShards()) {
305305
TxManager->AddShard(shardInfo.ShardId, IsOlap(), TablePath);
306-
TxManager->AddAction(shardInfo.ShardId, IKqpTransactionManager::EAction::WRITE);
306+
IKqpTransactionManager::TActionFlags flags = IKqpTransactionManager::EAction::WRITE;
307307
if (shardInfo.HasRead) {
308-
TxManager->AddAction(shardInfo.ShardId, IKqpTransactionManager::EAction::READ);
308+
flags |= IKqpTransactionManager::EAction::READ;
309309
}
310+
TxManager->AddAction(shardInfo.ShardId, flags);
310311
}
311312
}
312313

@@ -540,7 +541,6 @@ class TKqpTableWriteActor : public TActorBootstrapped<TKqpTableWriteActor> {
540541
<< " ShardID=" << ev->Get()->Record.GetOrigin() << ","
541542
<< " Sink=" << this->SelfId() << "."
542543
<< getIssues().ToOneLineString());
543-
544544
// TODO: Add new status for splits in datashard. This is tmp solution.
545545
if (getIssues().ToOneLineString().Contains("in a pre/offline state assuming this is due to a finished split (wrong shard state)")) {
546546
ResetShardRetries(ev->Get()->Record.GetOrigin(), ev->Cookie);
@@ -561,13 +561,12 @@ class TKqpTableWriteActor : public TActorBootstrapped<TKqpTableWriteActor> {
561561
<< " ShardID=" << ev->Get()->Record.GetOrigin() << ","
562562
<< " Sink=" << this->SelfId() << "."
563563
<< getIssues().ToOneLineString());
564-
565-
RuntimeError(
566-
TStringBuilder() << "Disk space exhausted for table `"
567-
<< TablePath << "`. "
568-
<< getIssues().ToOneLineString(),
569-
NYql::NDqProto::StatusIds::PRECONDITION_FAILED,
570-
getIssues());
564+
RuntimeError(
565+
TStringBuilder() << "Disk space exhausted for table `"
566+
<< TablePath << "`. "
567+
<< getIssues().ToOneLineString(),
568+
NYql::NDqProto::StatusIds::UNAVAILABLE,
569+
getIssues());
571570
return;
572571
}
573572
case NKikimrDataEvents::TEvWriteResult::STATUS_OVERLOADED: {
@@ -670,7 +669,7 @@ class TKqpTableWriteActor : public TActorBootstrapped<TKqpTableWriteActor> {
670669
preparedInfo.Coordinator = domainCoordinators.Select(*TxId);
671670
}
672671

673-
OnMessageAcknowledged(ev->Get()->Record.GetOrigin());
672+
OnMessageReceived(ev->Get()->Record.GetOrigin());
674673
const auto result = ShardedWriteController->OnMessageAcknowledged(
675674
ev->Get()->Record.GetOrigin(), ev->Cookie);
676675
if (result) {
@@ -713,7 +712,7 @@ class TKqpTableWriteActor : public TActorBootstrapped<TKqpTableWriteActor> {
713712
return;
714713
}
715714

716-
OnMessageAcknowledged(ev->Get()->Record.GetOrigin());
715+
OnMessageReceived(ev->Get()->Record.GetOrigin());
717716
const auto result = ShardedWriteController->OnMessageAcknowledged(
718717
ev->Get()->Record.GetOrigin(), ev->Cookie);
719718
if (result && result->IsShardEmpty && Mode == EMode::IMMEDIATE_COMMIT) {
@@ -723,7 +722,7 @@ class TKqpTableWriteActor : public TActorBootstrapped<TKqpTableWriteActor> {
723722
}
724723
}
725724

726-
void OnMessageAcknowledged(const ui64 shardId) {
725+
void OnMessageReceived(const ui64 shardId) {
727726
if (auto it = SendTime.find(shardId); it != std::end(SendTime)) {
728727
Counters->WriteActorWritesLatencyHistogram->Collect((TInstant::Now() - it->second).MilliSeconds());
729728
SendTime.erase(it);
@@ -847,7 +846,7 @@ class TKqpTableWriteActor : public TActorBootstrapped<TKqpTableWriteActor> {
847846
<< ", Attempts=" << metadata->SendAttempts << ", Mode=" << static_cast<int>(Mode));
848847
Send(
849848
PipeCacheId,
850-
new TEvPipeCache::TEvForward(evWrite.release(), shardId, true),
849+
new TEvPipeCache::TEvForward(evWrite.release(), shardId, /* subscribe */ true),
851850
IEventHandle::FlagTrackDelivery,
852851
metadata->Cookie,
853852
TableWriteActorSpan.GetTraceId());
@@ -1270,6 +1269,7 @@ class TKqpBufferWriteActor :public TActorBootstrapped<TKqpBufferWriteActor>, pub
12701269
, Alloc(std::make_shared<NKikimr::NMiniKQL::TScopedAlloc>(__LOCATION__))
12711270
, TypeEnv(*Alloc)
12721271
, Counters(settings.Counters)
1272+
, TxProxyMon(settings.TxProxyMon)
12731273
, BufferWriteActor(TWilsonKqp::BufferWriteActor, NWilson::TTraceId(settings.TraceId), "TKqpBufferWriteActor", NWilson::EFlags::AUTO_END)
12741274
, BufferWriteActorState(TWilsonKqp::BufferWriteActorState, BufferWriteActor.GetTraceId(),
12751275
"BufferWriteActorState::Writing", NWilson::EFlags::AUTO_END)
@@ -1552,6 +1552,7 @@ class TKqpBufferWriteActor :public TActorBootstrapped<TKqpBufferWriteActor>, pub
15521552
FillEvWritePrepare(evWrite.get(), shardId, *TxId, TxManager);
15531553
}
15541554

1555+
SendTime[shardId] = TInstant::Now();
15551556
CA_LOG_D("Send EvWrite (external) to ShardID=" << shardId << ", isPrepare=" << !isRollback << ", isImmediateCommit=" << isRollback << ", TxId=" << evWrite->Record.GetTxId()
15561557
<< ", LockTxId=" << evWrite->Record.GetLockTxId() << ", LockNodeId=" << evWrite->Record.GetLockNodeId()
15571558
<< ", Locks= " << [&]() {
@@ -1565,10 +1566,11 @@ class TKqpBufferWriteActor :public TActorBootstrapped<TKqpBufferWriteActor>, pub
15651566
<< ", OperationsCount=" << 0 << ", IsFinal=" << 1
15661567
<< ", Attempts=" << 0);
15671568

1569+
// TODO: Track latecy
15681570
Send(
15691571
NKikimr::MakePipePerNodeCacheID(false),
1570-
new TEvPipeCache::TEvForward(evWrite.release(), shardId, true),
1571-
0,
1572+
new TEvPipeCache::TEvForward(evWrite.release(), shardId, /* subscribe */ true),
1573+
IEventHandle::FlagTrackDelivery,
15721574
0);
15731575
}
15741576
}
@@ -1672,26 +1674,30 @@ class TKqpBufferWriteActor :public TActorBootstrapped<TKqpBufferWriteActor>, pub
16721674

16731675
switch (res->GetStatus()) {
16741676
case TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusAccepted:
1675-
// TODO: metrics
1677+
TxProxyMon->ClientTxStatusAccepted->Inc();
16761678
break;
16771679
case TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusProcessed:
1680+
TxProxyMon->ClientTxStatusProcessed->Inc();
16781681
break;
16791682
case TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusConfirmed:
1683+
TxProxyMon->ClientTxStatusConfirmed->Inc();
16801684
break;
16811685

16821686
case TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusPlanned:
1687+
TxProxyMon->ClientTxStatusPlanned->Inc();
16831688
break;
16841689

16851690
case TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusOutdated:
16861691
case TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusDeclined:
16871692
case TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusDeclinedNoSpace:
16881693
case TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusRestarting:
1689-
// TODO: CancelProposal???
1694+
TxProxyMon->ClientTxStatusCoordinatorDeclined->Inc();
16901695
ReplyErrorAndDie(TStringBuilder() << "Failed to plan transaction, status: " << res->GetStatus(), NYql::NDqProto::StatusIds::UNAVAILABLE, {});
16911696
break;
16921697

16931698
case TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusUnknown:
16941699
case TEvTxProxy::TEvProposeTransactionStatus::EStatus::StatusAborted:
1700+
TxProxyMon->ClientTxStatusCoordinatorDeclined->Inc();
16951701
ReplyErrorAndDie(TStringBuilder() << "Unexpected TEvProposeTransactionStatus status: " << res->GetStatus(), NYql::NDqProto::StatusIds::INTERNAL_ERROR, {});
16961702
break;
16971703
}
@@ -1797,7 +1803,6 @@ class TKqpBufferWriteActor :public TActorBootstrapped<TKqpBufferWriteActor>, pub
17971803
<< " ShardID=" << ev->Get()->Record.GetOrigin() << ","
17981804
<< " Sink=" << this->SelfId() << "."
17991805
<< getIssues().ToOneLineString());
1800-
18011806
ReplyErrorAndDie(
18021807
TStringBuilder() << "Internal error for table. "
18031808
<< getIssues().ToOneLineString(),
@@ -1810,11 +1815,10 @@ class TKqpBufferWriteActor :public TActorBootstrapped<TKqpBufferWriteActor>, pub
18101815
<< " ShardID=" << ev->Get()->Record.GetOrigin() << ","
18111816
<< " Sink=" << this->SelfId() << "."
18121817
<< getIssues().ToOneLineString());
1813-
18141818
ReplyErrorAndDie(
18151819
TStringBuilder() << "Disk space exhausted for table. "
18161820
<< getIssues().ToOneLineString(),
1817-
NYql::NDqProto::StatusIds::PRECONDITION_FAILED,
1821+
NYql::NDqProto::StatusIds::UNAVAILABLE,
18181822
getIssues());
18191823
return;
18201824
}
@@ -1824,7 +1828,6 @@ class TKqpBufferWriteActor :public TActorBootstrapped<TKqpBufferWriteActor>, pub
18241828
<< " Sink=" << this->SelfId() << "."
18251829
<< " Ignored this error."
18261830
<< getIssues().ToOneLineString());
1827-
// TODO: support waiting
18281831
ReplyErrorAndDie(
18291832
TStringBuilder() << "Tablet " << ev->Get()->Record.GetOrigin() << " is overloaded."
18301833
<< getIssues().ToOneLineString(),
@@ -1886,11 +1889,23 @@ class TKqpBufferWriteActor :public TActorBootstrapped<TKqpBufferWriteActor>, pub
18861889
}
18871890
}
18881891

1892+
void OnMessageReceived(const ui64 shardId) {
1893+
if (auto it = SendTime.find(shardId); it != std::end(SendTime)) {
1894+
Counters->WriteActorWritesLatencyHistogram->Collect((TInstant::Now() - it->second).MilliSeconds());
1895+
SendTime.erase(it);
1896+
}
1897+
}
1898+
18891899
void ProcessWritePreparedShard(NKikimr::NEvents::TDataEvents::TEvWriteResult::TPtr& ev) {
18901900
if (State != EState::PREPARING) {
18911901
CA_LOG_D("Ignored write prepared event.");
18921902
return;
18931903
}
1904+
OnMessageReceived(ev->Get()->Record.GetOrigin());
1905+
CA_LOG_D("Got prepared result TxId=" << ev->Get()->Record.GetTxId()
1906+
<< ", TabletId=" << ev->Get()->Record.GetOrigin()
1907+
<< ", Cookie=" << ev->Cookie);
1908+
18941909
const auto& record = ev->Get()->Record;
18951910
IKqpTransactionManager::TPrepareResult preparedInfo;
18961911
preparedInfo.ShardId = record.GetOrigin();
@@ -1912,6 +1927,7 @@ class TKqpBufferWriteActor :public TActorBootstrapped<TKqpBufferWriteActor>, pub
19121927
CA_LOG_D("Ignored write completed event.");
19131928
return;
19141929
}
1930+
OnMessageReceived(ev->Get()->Record.GetOrigin());
19151931
CA_LOG_D("Got completed result TxId=" << ev->Get()->Record.GetTxId()
19161932
<< ", TabletId=" << ev->Get()->Record.GetOrigin()
19171933
<< ", Cookie=" << ev->Cookie
@@ -2033,6 +2049,9 @@ class TKqpBufferWriteActor :public TActorBootstrapped<TKqpBufferWriteActor>, pub
20332049
IShardedWriteControllerPtr ShardedWriteController = nullptr;
20342050

20352051
TIntrusivePtr<TKqpCounters> Counters;
2052+
TIntrusivePtr<NTxProxy::TTxProxyMon> TxProxyMon;
2053+
THashMap<ui64, TInstant> SendTime;
2054+
20362055
NWilson::TSpan BufferWriteActor;
20372056
NWilson::TSpan BufferWriteActorState;
20382057
};

0 commit comments

Comments
 (0)