@@ -155,7 +155,7 @@ void XClusterTargetManager::CreateXClusterSafeTimeTableAndStartService() {
155155Status XClusterTargetManager::GetXClusterSafeTime (
156156 GetXClusterSafeTimeResponsePB* resp, const LeaderEpoch& epoch) {
157157 RETURN_NOT_OK_SET_CODE (
158- safe_time_service_->GetXClusterSafeTimeInfoFromMap (epoch, resp),
158+ safe_time_service_->ComputeAndGetXClusterSafeTimeInfo (epoch, * resp),
159159 MasterError (MasterErrorPB::INTERNAL_ERROR));
160160
161161 // Also fill out the namespace_name for each entry.
@@ -199,16 +199,14 @@ Status XClusterTargetManager::GetXClusterSafeTimeForNamespace(
199199
200200 RETURN_NOT_OK (safe_time_service_->ComputeSafeTime (epoch.leader_term ));
201201 auto safe_time_ht =
202- VERIFY_RESULT (GetXClusterSafeTimeForNamespace (epoch, req->namespace_id (), req->filter ()));
202+ VERIFY_RESULT (GetXClusterSafeTimeForNamespace (req->namespace_id (), req->filter ()));
203203 resp->set_safe_time_ht (safe_time_ht.ToUint64 ());
204204 return Status::OK ();
205205}
206206
207207Result<HybridTime> XClusterTargetManager::GetXClusterSafeTimeForNamespace (
208- const LeaderEpoch& epoch, const NamespaceId& namespace_id,
209- const XClusterSafeTimeFilter& filter) {
210- return safe_time_service_->GetXClusterSafeTimeForNamespace (
211- epoch.leader_term , namespace_id, filter);
208+ const NamespaceId& namespace_id, const XClusterSafeTimeFilter& filter) const {
209+ return safe_time_service_->GetXClusterSafeTimeForNamespace (namespace_id, filter);
212210}
213211
214212Status XClusterTargetManager::RefreshXClusterSafeTimeMap (const LeaderEpoch& epoch) {
@@ -429,9 +427,11 @@ XClusterTargetManager::GetXClusterStatus() const {
429427 const auto cluster_config_pb = VERIFY_RESULT (catalog_manager_.GetClusterConfig ());
430428 const auto replication_infos = catalog_manager_.GetAllXClusterUniverseReplicationInfos ();
431429
430+ const auto namespace_safe_time = GetXClusterNamespaceToSafeTimeMap ();
431+
432432 for (const auto & replication_info : replication_infos) {
433- auto replication_group_status =
434- VERIFY_RESULT ( GetUniverseReplicationInfo (replication_info, cluster_config_pb));
433+ auto replication_group_status = VERIFY_RESULT (
434+ GetUniverseReplicationInfo (replication_info, cluster_config_pb, namespace_safe_time ));
435435
436436 for (auto & [_, tables] : replication_group_status.table_statuses_by_namespace ) {
437437 for (auto & table : tables) {
@@ -454,7 +454,8 @@ XClusterTargetManager::GetXClusterStatus() const {
454454
455455Result<XClusterInboundReplicationGroupStatus> XClusterTargetManager::GetUniverseReplicationInfo (
456456 const SysUniverseReplicationEntryPB& replication_info_pb,
457- const SysClusterConfigEntryPB& cluster_config_pb) const {
457+ const SysClusterConfigEntryPB& cluster_config_pb,
458+ const XClusterNamespaceToSafeTimeMap& namespace_safe_time) const {
458459 XClusterInboundReplicationGroupStatus result;
459460 result.replication_group_id =
460461 xcluster::ReplicationGroupId (replication_info_pb.replication_group_id ());
@@ -475,10 +476,18 @@ Result<XClusterInboundReplicationGroupStatus> XClusterTargetManager::GetUniverse
475476 for (const auto & namespace_info : replication_info_pb.db_scoped_info ().namespace_infos ()) {
476477 result.db_scope_namespace_id_map [namespace_info.consumer_namespace_id ()] =
477478 namespace_info.producer_namespace_id ();
479+
478480 result.db_scoped_info += Format (
479481 " \n namespace: $0\n consumer_namespace_id: $1\n producer_namespace_id: $2" ,
480482 catalog_manager_.GetNamespaceName (namespace_info.consumer_namespace_id ()),
481483 namespace_info.consumer_namespace_id (), namespace_info.producer_namespace_id ());
484+
485+ auto safe_time_info = FindOrNull (namespace_safe_time, namespace_info.consumer_namespace_id ());
486+ if (safe_time_info) {
487+ result.db_scoped_info += Format (
488+ " \n safe_time: $0" ,
489+ Timestamp (safe_time_info->GetPhysicalValueMicros ()).ToHumanReadableTime ());
490+ }
482491 }
483492 }
484493
@@ -566,6 +575,23 @@ Status XClusterTargetManager::PopulateXClusterStatusJson(JsonWriter& jw) const {
566575 }
567576 jw.EndArray ();
568577
578+ const auto safe_time_map = GetXClusterNamespaceToSafeTimeMap ();
579+ if (!safe_time_map.empty ()) {
580+ jw.String (" safe_time_map" );
581+ jw.StartArray ();
582+ for (const auto & [namespace_id, safe_time] : safe_time_map) {
583+ jw.StartObject ();
584+ jw.String (" consumer_namespace_id" );
585+ jw.String (namespace_id);
586+
587+ jw.String (" safe_time" );
588+ jw.String (safe_time.ToString ());
589+
590+ jw.EndObject ();
591+ }
592+ jw.EndArray ();
593+ }
594+
569595 jw.String (" consumer_registry" );
570596 jw.Protobuf (cluster_config.consumer_registry ());
571597
@@ -602,10 +628,12 @@ Result<XClusterInboundReplicationGroupStatus> XClusterTargetManager::GetUniverse
602628 auto replication_info = catalog_manager_.GetUniverseReplication (replication_group_id);
603629 SCHECK_FORMAT (replication_info, NotFound, " Replication group $0 not found" , replication_group_id);
604630
631+ static const XClusterNamespaceToSafeTimeMap empty_namespace_safe_time;
632+
605633 const auto cluster_config = VERIFY_RESULT (catalog_manager_.GetClusterConfig ());
606634 // Make pb copy to avoid potential deadlock while calling GetUniverseReplicationInfo.
607635 auto pb = replication_info->LockForRead ()->pb ;
608- return GetUniverseReplicationInfo (pb, cluster_config);
636+ return GetUniverseReplicationInfo (pb, cluster_config, empty_namespace_safe_time );
609637}
610638
611639Status XClusterTargetManager::ClearXClusterFieldsAfterYsqlDDL (
0 commit comments