@@ -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 ()->HeadKeys .empty () && Partition ()->DataKeysBody .empty ())) {
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+ << " ." );
678+
679+ auto & head = Partition ()->Head ;
680+ for (auto it = head.GetBatches ().rbegin (); it != head.GetBatches ().rend (); ++it) {
681+ if (!it->Empty ()) {
682+ Partition ()->EndWriteTimestamp = head.GetBatches ().back ().GetLastMessageWriteTimestamp ();
683+ Partition ()->PendingWriteTimestamp = Partition ()->EndWriteTimestamp ;
684+
685+ PQ_LOG_I (" Initializing EndWriteTimestamp of the topic '" << Partition ()->TopicName ()
686+ << " ' partition " << Partition ()->Partition
687+ << " from head completed. Value " << Partition ()->EndWriteTimestamp );
688+
689+ return Done (ctx);
690+ }
691+ }
692+
693+ if (Partition ()->DataKeysBody .empty ()) {
694+ PQ_LOG_I (" Initializing EndWriteTimestamp of the topic '" << Partition ()->TopicName ()
695+ << " ' partition " << Partition ()->Partition
696+ << " skiped because DataKeys is empty." );
697+
698+ return Done (ctx);
699+ }
700+
701+ auto & p = Partition ()->DataKeysBody .back ();
702+
703+ THolder<TEvKeyValue::TEvRequest> request (new TEvKeyValue::TEvRequest);
704+ auto read = request->Record .AddCmdRead ();
705+ read->SetKey ({p.Key .Data (), p.Key .Size ()});
706+
707+ ctx.Send (Partition ()->Tablet , request.Release ());
708+ }
709+
710+ void TInitEndWriteTimestampStep::Handle (TEvKeyValue::TEvResponse::TPtr &ev, const TActorContext &ctx) {
711+ if (!ValidateResponse (*this , ev, ctx)) {
712+ PoisonPill (ctx);
713+ return ;
714+ }
715+
716+ auto & response = ev->Get ()->Record ;
717+ Y_ABORT_UNLESS (1 == response.ReadResultSize ());
718+
719+ auto & read = response.GetReadResult (0 );
720+ Y_ABORT_UNLESS (read.HasStatus ());
721+ switch (read.GetStatus ()) {
722+ case NKikimrProto::OK: {
723+ auto & key = Partition ()->DataKeysBody .back ().Key ;
724+
725+ for (TBlobIterator it (key, read.GetValue ()); it.IsValid (); it.Next ()) {
726+ auto b = it.GetBatch ();
727+ b.Unpack ();
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