$this->trxWriteCallers = [];
// First SELECT after BEGIN will establish the snapshot in REPEATABLE-READ.
// Get an estimate of the replication lag before any such queries.
+ $this->trxReplicaLag = null; // clear cached value first
$this->trxReplicaLag = $this->getApproximateLagStatus()['lag'];
// T147697: make explicitTrxActive() return true until begin() finishes. This way, no
// caller will think its OK to muck around with the transaction just because startAtomic()
}
public function getSessionLagStatus() {
- return $this->getTransactionLagStatus() ?: $this->getApproximateLagStatus();
+ return $this->getRecordedTransactionLagStatus() ?: $this->getApproximateLagStatus();
}
/**
* is this lag plus transaction duration. If they don't, it is still
* safe to be pessimistic. This returns null if there is no transaction.
*
+ * This returns null if the lag status for this transaction was not yet recorded.
+ *
* @return array|null ('lag': seconds or false on error, 'since': UNIX timestamp of BEGIN)
* @since 1.27
*/
- final protected function getTransactionLagStatus() {
- return $this->trxLevel
+ final protected function getRecordedTransactionLagStatus() {
+ return ( $this->trxLevel && $this->trxReplicaLag !== null )
? [ 'lag' => $this->trxReplicaLag, 'since' => $this->trxTimestamp() ]
: null;
}
protected function getLagFromPtHeartbeat() {
$options = $this->lagDetectionOptions;
- $staleness = $this->trxLevel
- ? microtime( true ) - $this->trxTimestamp()
- : 0;
- if ( $staleness > self::LAG_STALE_WARN_THRESHOLD ) {
- // 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__ ] )
- );
+ $currentTrxInfo = $this->getRecordedTransactionLagStatus();
+ if ( $currentTrxInfo ) {
+ // There is an active transaction and the initial lag was already queried
+ $staleness = microtime( true ) - $currentTrxInfo['since'];
+ if ( $staleness > self::LAG_STALE_WARN_THRESHOLD ) {
+ // 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__, 'age' => $staleness ] )
+ );
+ }
- return $this->getTransactionLagStatus()['lag'];
+ return $currentTrxInfo['lag'];
}
if ( isset( $options['conds'] ) ) {