@@ -250,7 +250,8 @@ def cluster_info_query(self) -> str:
250250
251251 written_lsn = ("pg_catalog.pg_wal_lsn_diff(written_lsn, '0/0')::bigint"
252252 if self ._major_version >= 130000 else "NULL" )
253- extra = (", CASE WHEN latest_end_lsn IS NULL THEN NULL ELSE received_tli END, {0}, slot_name, "
253+ extra = (", CASE WHEN latest_end_lsn IS NULL THEN NULL ELSE received_tli END, {0}, "
254+ "pg_catalog.pg_wal_lsn_diff(latest_end_lsn, '0/0')::bigint, slot_name, "
254255 "conninfo, status, {1} FROM pg_catalog.pg_stat_get_wal_receiver()" ).format (written_lsn , extra )
255256 if self .role == PostgresqlRole .STANDBY_LEADER :
256257 extra = "timeline_id" + extra + ", pg_catalog.pg_control_checkpoint()"
@@ -491,7 +492,7 @@ def _cluster_info_state_get(self, name: str) -> Optional[Any]:
491492 result = self ._is_leader_retry (self ._query , self .cluster_info_query )[0 ]
492493 cluster_info_state = dict (zip (['timeline' , 'wal_position' , 'replay_lsn' ,
493494 'receive_lsn' , 'replay_paused' , 'pg_control_timeline' ,
494- 'received_tli' , 'write_location' , 'slot_name' , 'conninfo' ,
495+ 'received_tli' , 'write_location' , 'latest_end_lsn' , ' slot_name' , 'conninfo' ,
495496 'receiver_state' , 'restore_command' , 'slots' , 'synchronous_commit' ,
496497 'synchronous_standby_names' , 'pg_stat_replication' ], result ))
497498 if self ._should_query_slots and self .can_advance_slots :
@@ -511,6 +512,9 @@ def _cluster_info_state_get(self, name: str) -> Optional[Any]:
511512 def replay_lsn (self ) -> Optional [int ]:
512513 return self ._cluster_info_state_get ('replay_lsn' )
513514
515+ def latest_end_lsn (self ) -> Optional [int ]:
516+ return self ._cluster_info_state_get ('latest_end_lsn' )
517+
514518 def receive_lsn (self ) -> Optional [int ]:
515519 write = self ._cluster_info_state_get ('write_location' )
516520 received = self ._cluster_info_state_get ('receive_lsn' )
@@ -1252,12 +1256,16 @@ def _wal_position(is_primary: bool, wal_position: int,
12521256 receive_lsn : Optional [int ], replay_lsn : Optional [int ]) -> int :
12531257 return wal_position if is_primary else max (receive_lsn or 0 , replay_lsn or 0 )
12541258
1255- def timeline_wal_position (self ) -> Tuple [int , int , Optional [int ], Optional [int ], Optional [int ]]:
1259+ def timeline_wal_position (self ) -> Tuple [int , int , Optional [int ], Optional [int ], Optional [int ], Optional [ int ] ]:
12561260 """Get timeline and various wal positions.
12571261
1258- :returns: a tuple composed of 5 integers representing timeline, ``pg_current_wal_lsn()`` position
1259- on primary/the biggest value among receive and replay LSN on replicas, ``pg_control_checkpoint()``
1260- value on a standby leader, receive and replay LSN on replicas (if available).
1262+ :returns: a tuple composed of 6 integers representing
1263+ * timeline,
1264+ * ``pg_current_wal_lsn()`` position on the primary
1265+ or the biggest value among receive and replay LSN on replicas,
1266+ * ``pg_control_checkpoint()`` value on a standby leader,
1267+ * receive and replay LSN on replicas (if available),
1268+ * latest_end_lsn (the last known LSN on the primary)
12611269 """
12621270 # This method could be called from different threads (simultaneously with some other `_query` calls).
12631271 # If it is called not from main thread we will create a new cursor to execute statement.
@@ -1266,14 +1274,16 @@ def timeline_wal_position(self) -> Tuple[int, int, Optional[int], Optional[int],
12661274 wal_position = self ._cluster_info_state_get ('wal_position' ) or 0
12671275 replay_lsn = self .replay_lsn ()
12681276 receive_lsn = self .receive_lsn ()
1277+ latest_end_lsn = self .latest_end_lsn ()
12691278 pg_control_timeline = self ._cluster_info_state_get ('pg_control_timeline' )
12701279 else :
1271- timeline , wal_position , replay_lsn , receive_lsn , _ , pg_control_timeline , _ , write_location = \
1272- self ._query (self .cluster_info_query )[0 ][:8 ]
1280+ timeline , wal_position , replay_lsn , receive_lsn , _ , \
1281+ pg_control_timeline , _ , write_location , latest_end_lsn = \
1282+ self ._query (self .cluster_info_query )[0 ][:9 ]
12731283 receive_lsn = max (receive_lsn or 0 , write_location or 0 )
12741284
12751285 wal_position = self ._wal_position (bool (timeline ), wal_position , receive_lsn , replay_lsn )
1276- return timeline , wal_position , pg_control_timeline , receive_lsn , replay_lsn
1286+ return timeline , wal_position , pg_control_timeline , receive_lsn , replay_lsn , latest_end_lsn
12771287
12781288 def postmaster_start_time (self ) -> Optional [str ]:
12791289 try :
0 commit comments