private $mAllowLagged;
/** @var integer Seconds to spend waiting on slave lag to resolve */
private $mWaitTimeout;
-
/** @var array LBFactory information */
private $mParentInfo;
+
/** @var string The LoadMonitor subclass name */
private $mLoadMonitorClass;
/** @var LoadMonitor */
/** @var integer Total connections opened */
private $connsOpened = 0;
+ /** @var TransactionProfiler */
+ protected $trxProfiler;
+
/** @var integer Warn when this many connection are held */
const CONN_HELD_WARN_THRESHOLD = 10;
/** @var integer Default 'max lag' when unspecified */
}
$this->srvCache = ObjectCache::getLocalServerInstance();
+
+ if ( isset( $params['trxProfiler'] ) ) {
+ $this->trxProfiler = $params['trxProfiler'];
+ } else {
+ $this->trxProfiler = new TransactionProfiler();
+ }
}
/**
if ( isset( $this->mServers[$i]['max lag'] ) ) {
$maxServerLag = min( $maxServerLag, $this->mServers[$i]['max lag'] );
}
+
+ $host = $this->getServerName( $i );
if ( $lag === false ) {
- wfDebugLog( 'replication', "Server #$i is not replicating" );
+ wfDebugLog( 'replication', "Server $host (#$i) is not replicating?" );
unset( $loads[$i] );
} elseif ( $lag > $maxServerLag ) {
- wfDebugLog( 'replication', "Server #$i is excessively lagged ($lag seconds)" );
+ wfDebugLog( 'replication', "Server $host (#$i) has >= $lag seconds of lag" );
unset( $loads[$i] );
}
}
return false;
}
- # wfDebugLog( 'connect', var_export( $loads, true ) );
-
# Return a random representative of the remainder
return ArrayUtils::pickRandom( $loads );
}
$nonErrorLoads = $this->mGroupLoads[$group];
} else {
# No loads for this group, return false and the caller can use some other group
- wfDebug( __METHOD__ . ": no loads for group $group\n" );
+ wfDebugLog( 'connect', __METHOD__ . ": no loads for group $group\n" );
return false;
}
}
}
$serverName = $this->getServerName( $i );
- wfDebug( __METHOD__ . ": using server $serverName for group '$group'\n" );
+ wfDebugLog( 'connect', __METHOD__ .
+ ": using server $serverName for group '$group'\n" );
}
return $i;
*
* @param int $i Server index
* @param string|bool $wiki Wiki ID, or false for the current wiki
- * @return DatabaseBase
- *
- * @access private
+ * @return DatabaseBase|bool Returns false on errors
*/
public function openConnection( $i, $wiki = false ) {
if ( $wiki !== false ) {
$conn = $this->reallyOpenConnection( $server, false );
$serverName = $this->getServerName( $i );
if ( $conn->isOpen() ) {
- wfDebug( "Connected to database $i at $serverName\n" );
+ wfDebugLog( 'connect', "Connected to database $i at $serverName\n" );
$this->mConns['local'][$i][0] = $conn;
} else {
- wfDebug( "Failed to connect to database $i at $serverName\n" );
+ wfDebugLog( 'connect', "Failed to connect to database $i at $serverName\n" );
$this->mErrorConnection = $conn;
$conn = false;
}
$server['dbname'] = $dbNameOverride;
}
+ // Let the handle know what the cluster master is (e.g. "db1052")
+ $masterName = $this->getServerName( 0 );
+ $server['clusterMasterHost'] = $masterName;
+
// Log when many connection are made on requests
if ( ++$this->connsOpened >= self::CONN_HELD_WARN_THRESHOLD ) {
- $masterAddr = $this->getServerName( 0 );
wfDebugLog( 'DBPerformance', __METHOD__ . ": " .
- "{$this->connsOpened}+ connections made (master=$masterAddr)\n" .
+ "{$this->connsOpened}+ connections made (master=$masterName)\n" .
wfBacktrace( true ) );
}
}
$db->setLBInfo( $server );
+ $db->setLazyMasterHandle(
+ $this->getLazyConnectionRef( DB_MASTER, array(), $db->getWikiID() )
+ );
+ $db->setTransactionProfiler( $this->trxProfiler );
return $db;
}
for ( $i = 1; $i < $serverCount; $i++ ) {
$conn = $this->getAnyOpenConnection( $i );
if ( $conn ) {
- wfDebug( "Master pos fetched from slave\n" );
-
return $conn->getSlavePos();
}
}
} else {
- wfDebug( "Master pos fetched from master\n" );
-
return $masterConn->getMasterPos();
}
/**
* Commit transactions on all open connections
+ * @param string $fname Caller name
*/
- public function commitAll() {
+ public function commitAll( $fname = __METHOD__ ) {
foreach ( $this->mConns as $conns2 ) {
foreach ( $conns2 as $conns3 ) {
/** @var DatabaseBase[] $conns3 */
foreach ( $conns3 as $conn ) {
if ( $conn->trxLevel() ) {
- $conn->commit( __METHOD__, 'flush' );
+ $conn->commit( $fname, 'flush' );
}
}
}
}
/**
- * Issue COMMIT only on master, only if queries were done on connection
+ * Issue COMMIT only on master, only if queries were done on connection
+ * @param string $fname Caller name
*/
- public function commitMasterChanges() {
+ public function commitMasterChanges( $fname = __METHOD__ ) {
$masterIndex = $this->getWriterIndex();
foreach ( $this->mConns as $conns2 ) {
if ( empty( $conns2[$masterIndex] ) ) {
/** @var DatabaseBase $conn */
foreach ( $conns2[$masterIndex] as $conn ) {
if ( $conn->trxLevel() && $conn->writesOrCallbacksPending() ) {
- $conn->commit( __METHOD__, 'flush' );
+ $conn->commit( $fname, 'flush' );
}
}
}
/**
* Issue ROLLBACK only on master, only if queries were done on connection
+ * @param string $fname Caller name
+ * @throws DBExpectedError
* @since 1.23
*/
- public function rollbackMasterChanges() {
+ public function rollbackMasterChanges( $fname = __METHOD__ ) {
$failedServers = array();
$masterIndex = $this->getWriterIndex();
foreach ( $conns2[$masterIndex] as $conn ) {
if ( $conn->trxLevel() && $conn->writesOrCallbacksPending() ) {
try {
- $conn->rollback( __METHOD__, 'flush' );
+ $conn->rollback( $fname, 'flush' );
} catch ( DBError $e ) {
MWExceptionHandler::logException( $e );
$failedServers[] = $conn->getServer();
|| $this->lastMasterChangeTimestamp() > microtime( true ) - $age );
}
+ /**
+ * Get the list of callers that have pending master changes
+ *
+ * @return array
+ * @since 1.27
+ */
+ public function pendingMasterChangeCallers() {
+ $fnames = array();
+
+ $masterIndex = $this->getWriterIndex();
+ foreach ( $this->mConns as $conns2 ) {
+ if ( empty( $conns2[$masterIndex] ) ) {
+ continue;
+ }
+ /** @var DatabaseBase $conn */
+ foreach ( $conns2[$masterIndex] as $conn ) {
+ $fnames = array_merge( $fnames, $conn->pendingWriteCallers() );
+ }
+ }
+
+ return $fnames;
+ }
+
/**
* @param mixed $value
* @return mixed