* @return array|null ('lag': seconds or false on error, 'since': UNIX timestamp of BEGIN)
* @since 1.27
*/
- protected function getTransactionLagStatus() {
+ final protected function getTransactionLagStatus() {
return $this->trxLevel
? [ 'lag' => $this->trxReplicaLag, 'since' => $this->trxTimestamp() ]
: null;
protected function getLagFromPtHeartbeat() {
$options = $this->lagDetectionOptions;
+ if ( $this->trxLevel ) {
+ // Avoid returning higher and higher lag value due to snapshot age
+ // given that the isolation level will typically be REPEATABLE-READ
+ $this->queryLogger->warning(
+ "Using cached lag value for {db_server} due to active transaction",
+ $this->getLogContext( [ 'method' => __METHOD__ ] )
+ );
+
+ return $this->getTransactionLagStatus()['lag'];
+ }
+
if ( isset( $options['conds'] ) ) {
// Best method for multi-DC setups: use logical channel names
$data = $this->getHeartbeatData( $options['conds'] );
}
$conn = $this->parent->getAnyOpenConnection( $i );
- if ( $conn ) {
+ if ( $conn && !$conn->trxLevel() ) {
+ # Handles with open transactions are avoided since they might be subject
+ # to REPEATABLE-READ snapshots, which could affect the lag estimate query.
$close = false; // already open
} else {
$conn = $this->parent->openConnection( $i, '' );