private $mDb = null;
/** @var float UNIX timestamp */
- private $lastSlaveWait = 0.0;
+ private $lastReplicationWait = 0.0;
/**
* Used when creating separate schema files.
* Set triggers like when to try to run deferred updates
* @since 1.28
*/
- public function setTriggers() {
+ public function setAgentAndTriggers() {
+ if ( function_exists( 'posix_getpwuid' ) ) {
+ $agent = posix_getpwuid( posix_geteuid() )['name'];
+ } else {
+ $agent = 'sysadmin';
+ }
+ $agent .= '@' . wfHostname();
+
+ $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+ // Add a comment for easy SHOW PROCESSLIST interpretation
+ $lbFactory->setAgentName(
+ mb_strlen( $agent ) > 15 ? mb_substr( $agent, 0, 15 ) . '...' : $agent
+ );
+ self::setLBFactoryTriggers( $lbFactory );
+ }
+
+ /**
+ * @param LBFactory $LBFactory
+ * @since 1.28
+ */
+ public static function setLBFactoryTriggers( LBFactory $LBFactory ) {
// Hook into period lag checks which often happen in long-running scripts
$lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
$lbFactory->setWaitForReplicationListener(
__METHOD__,
- [ 'DeferredUpdates', 'tryOpportunisticExecute' ]
+ function () {
+ global $wgCommandLineMode;
+ // Check config in case of JobRunner and unit tests
+ if ( $wgCommandLineMode ) {
+ DeferredUpdates::tryOpportunisticExecute( 'run' );
+ }
+ }
+ );
+ // Check for other windows to run them. A script may read or do a few writes
+ // to the master but mostly be writing to something else, like a file store.
+ $lbFactory->getMainLB()->setTransactionListener(
+ __METHOD__,
+ function ( $trigger ) {
+ global $wgCommandLineMode;
+ // Check config in case of JobRunner and unit tests
+ if ( $wgCommandLineMode && $trigger === IDatabase::TRIGGER_COMMIT ) {
+ DeferredUpdates::tryOpportunisticExecute( 'run' );
+ }
+ }
);
}
$wgLBFactoryConf['serverTemplate']['user'] = $wgDBuser;
$wgLBFactoryConf['serverTemplate']['password'] = $wgDBpassword;
}
- LBFactory::destroyInstance();
+ MediaWikiServices::getInstance()->getDBLoadBalancerFactory()->destroy();
}
// Per-script profiling; useful for debugging
* If not set, wfGetDB() will be used.
* This function has the same parameters as wfGetDB()
*
- * @param integer $db DB index (DB_SLAVE/DB_MASTER)
+ * @param integer $db DB index (DB_REPLICA/DB_MASTER)
* @param array $groups; default: empty array
* @param string|bool $wiki; default: current wiki
- * @return IDatabase
+ * @return Database
*/
protected function getDB( $db, $groups = [], $wiki = false ) {
if ( is_null( $this->mDb ) ) {
}
/**
- * Commit the transcation on a DB handle and wait for slaves to catch up
+ * Commit the transcation on a DB handle and wait for replica DBs to catch up
*
* This method makes it clear that commit() is called from a maintenance script,
* which has outermost scope. This is safe, unlike $dbw->commit() called in other places.
*
* @param IDatabase $dbw
* @param string $fname Caller name
- * @return bool Whether the slave wait succeeded
+ * @return bool Whether the replica DB wait succeeded
* @since 1.27
*/
protected function commitTransaction( IDatabase $dbw, $fname ) {
$dbw->commit( $fname );
+ try {
+ $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+ $lbFactory->waitForReplication(
+ [ 'timeout' => 30, 'ifWritesSince' => $this->lastReplicationWait ]
+ );
+ $this->lastReplicationWait = microtime( true );
- $ok = wfWaitForSlaves( $this->lastSlaveWait, false, '*', 30 );
- $this->lastSlaveWait = microtime( true );
-
- return $ok;
+ return true;
+ } catch ( DBReplicationWaitError $e ) {
+ return false;
+ }
}
/**
/**
* Lock the search index
- * @param DatabaseBase &$db
+ * @param Database &$db
*/
private function lockSearchindex( $db ) {
$write = [ 'searchindex' ];
/**
* Unlock the tables
- * @param DatabaseBase &$db
+ * @param Database &$db
*/
private function unlockSearchindex( $db ) {
$db->unlockTables( __CLASS__ . '::' . __METHOD__ );
/**
* Unlock and lock again
* Since the lock is low-priority, queued reads will be able to complete
- * @param DatabaseBase &$db
+ * @param Database &$db
*/
private function relockSearchindex( $db ) {
$this->unlockSearchindex( $db );
* Perform a search index update with locking
* @param int $maxLockTime The maximum time to keep the search index locked.
* @param string $callback The function that will update the function.
- * @param DatabaseBase $dbw
+ * @param Database $dbw
* @param array $results
*/
public function updateSearchIndex( $maxLockTime, $callback, $dbw, $results ) {
/**
* Update the searchindex table for a given pageid
- * @param DatabaseBase $dbw A database write handle
+ * @param Database $dbw A database write handle
* @param int $pageId The page ID to update.
* @return null|string
*/
return fgets( STDIN, 1024 );
}
+
+ /**
+ * Call this to set up the autoloader to allow classes to be used from the
+ * tests directory.
+ */
+ public static function requireTestsAutoloader() {
+ require_once __DIR__ . '/../tests/common/TestsAutoLoader.php';
+ }
}
/**