@@ -30,6 +30,7 @@ TInitializer::TInitializer(TPartition* partition)
3030 Steps.push_back (MakeHolder<TInitInfoRangeStep>(this ));
3131 Steps.push_back (MakeHolder<TInitDataRangeStep>(this ));
3232 Steps.push_back (MakeHolder<TInitDataStep>(this ));
33+ Steps.push_back (MakeHolder<TInitEndWriteTimestampStep>(this ));
3334
3435 CurrentStep = Steps.begin ();
3536}
@@ -316,6 +317,8 @@ void TInitMetaStep::LoadMeta(const NKikimrClient::TResponse& kvResponse, const T
316317 }
317318 */
318319 Partition ()->SubDomainOutOfSpace = meta.GetSubDomainOutOfSpace ();
320+ Partition ()->EndWriteTimestamp = TInstant::MilliSeconds (meta.GetLastMessageWriteTimestamp ());
321+ Partition ()->PendingWriteTimestamp = Partition ()->EndWriteTimestamp ;
319322 if (Partition ()->IsSupportive ()) {
320323 const auto & counterData = meta.GetCounterData ();
321324 Partition ()->BytesWrittenGrpc .SetSavedValue (counterData.GetBytesWrittenGrpc ());
@@ -653,6 +656,112 @@ void TInitDataStep::Handle(TEvKeyValue::TEvResponse::TPtr &ev, const TActorConte
653656}
654657
655658
659+ //
660+ // TInitEndWriteTimestampStep
661+ //
662+
663+ TInitEndWriteTimestampStep::TInitEndWriteTimestampStep (TInitializer* initializer)
664+ : TBaseKVStep(initializer, " TInitEndWriteTimestampStep" , true ) {
665+ }
666+
667+ void TInitEndWriteTimestampStep::Execute (const TActorContext &ctx) {
668+ if (Partition ()->EndWriteTimestamp != TInstant::Zero () || Partition ()->EndOffset <= Partition ()->StartOffset ) {
669+ PQ_LOG_D (" Initializing EndWriteTimestamp of the topic '" << Partition ()->TopicName ()
670+ << " ' partition " << Partition ()->Partition
671+ << " skiped because already initialized." );
672+ return Done (ctx);
673+ }
674+
675+ PQ_LOG_D (" Initializing EndWriteTimestamp of the topic '" << Partition ()->TopicName ()
676+ << " ' partition " << Partition ()->Partition
677+ << " EndOffset " << Partition ()->EndOffset
678+ << " StartOffset " << Partition ()->StartOffset
679+ << " ." );
680+
681+ auto & head = Partition ()->Head ;
682+ for (auto it = head.GetBatches ().rbegin (); it != head.GetBatches ().rend (); ++it) {
683+ if (!it->Empty ()) {
684+ Partition ()->EndWriteTimestamp = head.GetBatches ().back ().GetLastMessageWriteTimestamp ();
685+ Partition ()->PendingWriteTimestamp = Partition ()->EndWriteTimestamp ;
686+
687+ PQ_LOG_I (" Initializing EndWriteTimestamp of the topic '" << Partition ()->TopicName ()
688+ << " ' partition " << Partition ()->Partition
689+ << " from head completed. Value " << Partition ()->EndWriteTimestamp );
690+
691+ return Done (ctx);
692+ }
693+ }
694+
695+ if (Partition ()->DataKeysBody .empty ()) {
696+ PQ_LOG_I (" Initializing EndWriteTimestamp of the topic '" << Partition ()->TopicName ()
697+ << " ' partition " << Partition ()->Partition
698+ << " skiped because DataKeys is empty." );
699+
700+ return Done (ctx);
701+ }
702+
703+ auto & p = Partition ()->DataKeysBody .back ();
704+
705+ THolder<TEvKeyValue::TEvRequest> request (new TEvKeyValue::TEvRequest);
706+ auto read = request->Record .AddCmdRead ();
707+ read->SetKey ({p.Key .Data (), p.Key .Size ()});
708+ ctx.Send (Partition ()->Tablet , request.Release ());
709+ }
710+
711+ void TInitEndWriteTimestampStep::Handle (TEvKeyValue::TEvResponse::TPtr &ev, const TActorContext &ctx) {
712+ if (!ValidateResponse (*this , ev, ctx)) {
713+ PoisonPill (ctx);
714+ return ;
715+ }
716+
717+ auto & response = ev->Get ()->Record ;
718+ Y_ABORT_UNLESS (1 == response.ReadResultSize ());
719+
720+ auto & read = response.GetReadResult (0 );
721+ Y_ABORT_UNLESS (read.HasStatus ());
722+ switch (read.GetStatus ()) {
723+ case NKikimrProto::OK: {
724+ auto & key = Partition ()->DataKeysBody .back ().Key ;
725+
726+ for (TBlobIterator it (key, read.GetValue ()); it.IsValid (); it.Next ()) {
727+ auto b = it.GetBatch ();
728+ if (!b.Empty ()) {
729+ Partition ()->EndWriteTimestamp = b.GetLastMessageWriteTimestamp ();
730+ }
731+ }
732+
733+ PQ_LOG_I (" Initializing EndWriteTimestamp of the topic '" << Partition ()->TopicName ()
734+ << " ' partition " << Partition ()->Partition
735+ << " from last blob completed. Value " << Partition ()->EndWriteTimestamp );
736+
737+ Partition ()->PendingWriteTimestamp = Partition ()->EndWriteTimestamp ;
738+
739+ break ;
740+ }
741+ case NKikimrProto::OVERRUN:
742+ Y_ABORT (" implement overrun in readresult!!" );
743+ return ;
744+ case NKikimrProto::NODATA:
745+ Y_ABORT (" NODATA can't be here" );
746+ return ;
747+ case NKikimrProto::ERROR:
748+ PQ_LOG_ERROR (" tablet " << Partition ()->TabletID << " HandleOnInit topic '" << TopicName ()
749+ << " ' partition " << PartitionId ()
750+ << " status NKikimrProto::ERROR result message: \" " << read.GetMessage ()
751+ << " \" errorReason: \" " << response.GetErrorReason () << " \" "
752+ );
753+ PoisonPill (ctx);
754+ return ;
755+ default :
756+ Cerr << " ERROR " << read.GetStatus () << " message: \" " << read.GetMessage () << " \"\n " ;
757+ Y_ABORT (" bad status" );
758+
759+ };
760+
761+ Done (ctx);
762+ }
763+
764+
656765//
657766// TPartition
658767//
0 commit comments