@@ -2001,7 +2001,8 @@ void TPersQueue::HandleWriteRequest(const ui64 responseCookie, const TActorId& p
20012001 " Tablet " << TabletID () <<
20022002 " Write in transaction." <<
20032003 " Partition: " << req.GetPartition () <<
2004- " , WriteId: " << req.GetWriteId ());
2004+ " , WriteId: " << req.GetWriteId () <<
2005+ " , NeedSupportivePartition: " << req.GetNeedSupportivePartition ());
20052006 }
20062007
20072008 for (ui32 i = 0 ; i < req.CmdWriteSize (); ++i) {
@@ -2198,7 +2199,8 @@ void TPersQueue::HandleReserveBytesRequest(const ui64 responseCookie, const TAct
21982199 " Tablet " << TabletID () <<
21992200 " Reserve bytes in transaction." <<
22002201 " Partition: " << req.GetPartition () <<
2201- " , WriteId: " << req.GetWriteId ());
2202+ " , WriteId: " << req.GetWriteId () <<
2203+ " , NeedSupportivePartition: " << req.GetNeedSupportivePartition ());
22022204 }
22032205
22042206 InitResponseBuilder (responseCookie, 1 , COUNTER_LATENCY_PQ_RESERVE_BYTES);
@@ -2574,6 +2576,8 @@ void TPersQueue::HandleWriteRequestForSupportivePartition(const ui64 responseCoo
25742576 const NKikimrClient::TPersQueuePartitionRequest& req,
25752577 const TActorContext& ctx)
25762578{
2579+ Y_ABORT_UNLESS (req.HasWriteId ());
2580+
25772581 const TPartitionInfo& partition = GetPartitionInfo (req);
25782582 const TActorId& actorId = partition.Actor ;
25792583
@@ -2648,6 +2652,14 @@ void TPersQueue::HandleEventForSupportivePartition(const ui64 responseCookie,
26482652 sender);
26492653 }
26502654 } else {
2655+ if (!req.GetNeedSupportivePartition ()) {
2656+ ReplyError (ctx,
2657+ responseCookie,
2658+ NPersQueue::NErrorCode::PRECONDITION_FAILED,
2659+ " lost messages" );
2660+ return ;
2661+ }
2662+
26512663 //
26522664 // этап 1:
26532665 // - создать запись в TxWrites
@@ -2665,6 +2677,7 @@ void TPersQueue::HandleEventForSupportivePartition(const ui64 responseCookie,
26652677 TPartitionId partitionId (originalPartitionId, writeId, NextSupportivePartitionId++);
26662678
26672679 writeInfo.Partitions .emplace (originalPartitionId, partitionId);
2680+ TxWritesChanged = true ;
26682681 AddSupportivePartition (partitionId);
26692682
26702683 Y_ABORT_UNLESS (Partitions.contains (partitionId));
@@ -3115,6 +3128,38 @@ void TPersQueue::Handle(TEvPersQueue::TEvProposeTransaction::TPtr& ev, const TAc
31153128
31163129}
31173130
3131+ bool TPersQueue::CheckTxWriteOperation (const NKikimrPQ::TPartitionOperation& operation,
3132+ ui64 writeId) const
3133+ {
3134+ TPartitionId partitionId (operation.GetPartitionId (),
3135+ writeId,
3136+ operation.GetSupportivePartition ());
3137+ return Partitions.contains (partitionId);
3138+ }
3139+
3140+ bool TPersQueue::CheckTxWriteOperations (const NKikimrPQ::TDataTransaction& txBody) const
3141+ {
3142+ if (!txBody.HasWriteId ()) {
3143+ return true ;
3144+ }
3145+
3146+ ui64 writeId = txBody.GetWriteId ();
3147+
3148+ for (auto & operation : txBody.GetOperations ()) {
3149+ auto isWrite = [](const NKikimrPQ::TPartitionOperation& o) {
3150+ return !o.HasBegin ();
3151+ };
3152+
3153+ if (isWrite (operation)) {
3154+ if (!CheckTxWriteOperation (operation, writeId)) {
3155+ return false ;
3156+ }
3157+ }
3158+ }
3159+
3160+ return true ;
3161+ }
3162+
31183163void TPersQueue::HandleDataTransaction (TAutoPtr<TEvPersQueue::TEvProposeTransaction> ev,
31193164 const TActorContext& ctx)
31203165{
@@ -3123,23 +3168,6 @@ void TPersQueue::HandleDataTransaction(TAutoPtr<TEvPersQueue::TEvProposeTransact
31233168 Y_ABORT_UNLESS (event.HasData ());
31243169 const NKikimrPQ::TDataTransaction& txBody = event.GetData ();
31253170
3126- for (auto & operation : txBody.GetOperations ()) {
3127- Y_ABORT_UNLESS (!operation.HasPath () || (operation.GetPath () == TopicPath));
3128-
3129- bool isWriteOperation = !operation.HasBegin ();
3130-
3131- LOG_DEBUG_S (ctx, NKikimrServices::PERSQUEUE,
3132- " Tablet " << TabletID () <<
3133- " tx=" << event.GetTxId () <<
3134- " , write_id=" << txBody.GetWriteId () <<
3135- " , path=" << operation.GetPath () <<
3136- " , partition=" << operation.GetPartitionId () <<
3137- " , consumer=" << operation.GetConsumer () <<
3138- " , begin=" << operation.GetBegin () <<
3139- " , end=" << operation.GetEnd () <<
3140- " , is_write=" << isWriteOperation);
3141- }
3142-
31433171 if (TabletState != NKikimrPQ::ENormal) {
31443172 SendProposeTransactionAbort (ActorIdFromProto (event.GetSourceActor ()),
31453173 event.GetTxId (),
@@ -3158,6 +3186,13 @@ void TPersQueue::HandleDataTransaction(TAutoPtr<TEvPersQueue::TEvProposeTransact
31583186 return ;
31593187 }
31603188
3189+ if (!CheckTxWriteOperations (txBody)) {
3190+ SendProposeTransactionAbort (ActorIdFromProto (event.GetSourceActor ()),
3191+ event.GetTxId (),
3192+ ctx);
3193+ return ;
3194+ }
3195+
31613196 TMaybe<TPartitionId> partitionId = FindPartitionId (txBody);
31623197 if (!partitionId.Defined ()) {
31633198 SendProposeTransactionAbort (ActorIdFromProto (event.GetSourceActor ()),
@@ -3392,7 +3427,8 @@ void TPersQueue::BeginWriteTxs(const TActorContext& ctx)
33923427 CanProcessPlanStepQueue () ||
33933428 CanProcessWriteTxs () ||
33943429 CanProcessDeleteTxs () ||
3395- CanProcessTxWrites ()
3430+ CanProcessTxWrites () ||
3431+ TxWritesChanged
33963432 ;
33973433 if (!canProcess) {
33983434 return ;
@@ -3441,6 +3477,8 @@ void TPersQueue::EndWriteTxs(const NKikimrClient::TResponse& resp,
34413477 return ;
34423478 }
34433479
3480+ TxWritesChanged = false ;
3481+
34443482 SendReplies (ctx);
34453483 CheckChangedTxStates (ctx);
34463484 CreateSupportivePartitionActors (ctx);
@@ -4473,6 +4511,7 @@ void TPersQueue::Handle(TEvPQ::TEvDeletePartitionDone::TPtr& ev, const TActorCon
44734511 }
44744512 TxWrites.erase (writeId);
44754513 }
4514+ TxWritesChanged = true ;
44764515
44774516 TryWriteTxs (ctx);
44784517}
0 commit comments