'GenericArrayObject' => __DIR__ . '/includes/libs/GenericArrayObject.php',
'GetConfiguration' => __DIR__ . '/maintenance/getConfiguration.php',
'GetLagTimes' => __DIR__ . '/maintenance/getLagTimes.php',
- 'GetSlaveServer' => __DIR__ . '/maintenance/getSlaveServer.php',
+ 'GetSlaveServer' => __DIR__ . '/maintenance/getReplicaServer.php',
'GetTextMaint' => __DIR__ . '/maintenance/getText.php',
'GitInfo' => __DIR__ . '/includes/GitInfo.php',
'GlobalDependency' => __DIR__ . '/includes/cache/CacheDependency.php',
+++ /dev/null
-<!DOCTYPE html>
-<html lang="en" dir="ltr">
-<head>
- <meta charset="utf-8">
- <link rel="stylesheet" href="../../resources/src/mediawiki.action/mediawiki.action.history.diff.css">
- <link rel="stylesheet" media="print" href="../../resources/src/mediawiki.action/mediawiki.action.history.diff.print.css">
-</head>
-<body>
-
-<p>This show various styles for our diff action. Style sheet: <code><a href="../../resources/src/mediawiki.action/mediawiki.action.history.diff.css">resources/src/mediawiki.action/mediawiki.action.history.diff.css</a></code>.</p>
-<p>This file might help us fix our diff colors which have been a recurring issues among the community for a loooong time.</p>
-<p>Try it out in print mode, too. Style sheet: <code><a href="../../resources/src/mediawiki.action/mediawiki.action.history.diff.print.css">resources/src/mediawiki.action/mediawiki.action.history.diff.print.css</a></code>.</p>
-
-<p>Practical example copied from MediaWiki's HTML output:</p>
-
-<table class="diff diff-contentalign-left">
- <colgroup><col class="diff-marker">
- <col class="diff-content">
- <col class="diff-marker">
- <col class="diff-content">
- </colgroup>
-<tbody>
-<tr>
- <td class="diff-marker">−</td>
- <td class="diff-deletedline"><div>Lorem ipsum dolor sit amet<del class="diffchange diffchange-inline">, consectetur adipisicing elit</del>, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div></td>
- <td class="diff-marker">+</td>
- <td class="diff-addedline"><div>Lorem ipsum dolor sit amet, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div></td>
-</tr>
-<tr>
- <td class="diff-marker">−</td>
- <td class="diff-deletedline"></td>
- <td colspan="2" class="diff-empty"> </td>
-</tr>
-<tr>
- <td class="diff-marker">−</td>
- <td class="diff-deletedline"><div>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div></td>
- <td colspan="2" class="diff-empty"> </td>
-</tr>
-<tr>
- <td class="diff-marker"> </td>
- <td class="diff-context"></td>
- <td class="diff-marker"> </td>
- <td class="diff-context"></td>
-</tr>
-<tr>
- <td class="diff-marker"> </td>
- <td class="diff-context"><div>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</div></td>
- <td class="diff-marker"> </td>
- <td class="diff-context"><div>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</div></td>
-</tr>
-<tr>
- <td class="diff-marker"> </td>
- <td class="diff-context"></td>
- <td class="diff-marker"> </td>
- <td class="diff-context"></td>
-</tr>
-<tr>
- <td class="diff-marker">−</td>
- <td class="diff-deletedline"><div>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim<del class="diffchange diffchange-inline"> id est laborum</del>.</div></td>
- <td class="diff-marker">+</td>
- <td class="diff-addedline"><div>Excepteur sint occaecat cupidatat non proident, sunt<ins class="diffchange diffchange-inline"> reprehenderit in voluptate</ins> in culpa qui officia deserunt mollit anim.</div></td>
-</tr>
-<tr>
- <td colspan="2" class="diff-empty"> </td>
- <td class="diff-marker">+</td>
- <td class="diff-addedline"></td>
-</tr>
-<tr>
- <td colspan="2" class="diff-empty"> </td>
- <td class="diff-marker">+</td>
- <td class="diff-addedline"><div>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div></td>
-</tr>
-</tbody></table>
-
-<p>Below are some basic lines being applied one or two classes. Mainly for debugging purposes.</p>
-
-<table class="diff">
- <tr><th>Diff</th></tr>
-
- <tr><td class="diff-addedline"><code>diff-addedline</code>: added line</td></tr>
- <tr><td class="diff-deletedline"><code>diff-deletedline</code>: deleted line</td></tr>
- <tr><td class="diff-context"><code>diff-context</code>: context</td></tr>
-
- <tr><th>Same as above with a <code><ins></code> or <code><del></code> child element having the <code>diffchange</code> class:</th></tr>
-
- <tr><td class="diffchange">Diffchange</td></tr>
- <tr><td class="diff-addedline"><ins class="diffchange">Added line + diffchange</ins></td></tr>
- <tr><td class="diff-deletedline"><del class="diffchange">Deleted line + diffchange</del></td></tr>
-</table>
-
-</body>
-</html>
--- /dev/null
+<!DOCTYPE html>
+<html lang="en" dir="ltr">
+<head>
+ <meta charset="utf-8">
+ <link rel="stylesheet" href="../../resources/src/mediawiki/mediawiki.diff.styles.css">
+ <link rel="stylesheet" media="print" href="../../resources/src/mediawiki/mediawiki.diff.styles.print.css">
+</head>
+<body>
+
+<p>This show various styles for our diff action. Style sheet: <code><a href="../../resources/src/mediawiki/mediawiki.diff.styles.css">resources/src/mediawiki/mediawiki.diff.styles.css</a></code>.</p>
+<p>This file might help us fix our diff colors which have been a recurring issues among the community for a loooong time.</p>
+<p>Try it out in print mode, too. Style sheet: <code><a href="../../resources/src/mediawiki/mediawiki.diff.styles.print.css">resources/src/mediawiki/mediawiki.diff.styles.print.css</a></code>.</p>
+
+<p>Practical example copied from MediaWiki's HTML output:</p>
+
+<table class="diff diff-contentalign-left">
+ <colgroup><col class="diff-marker">
+ <col class="diff-content">
+ <col class="diff-marker">
+ <col class="diff-content">
+ </colgroup>
+<tbody>
+<tr>
+ <td class="diff-marker">−</td>
+ <td class="diff-deletedline"><div>Lorem ipsum dolor sit amet<del class="diffchange diffchange-inline">, consectetur adipisicing elit</del>, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div></td>
+ <td class="diff-marker">+</td>
+ <td class="diff-addedline"><div>Lorem ipsum dolor sit amet, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div></td>
+</tr>
+<tr>
+ <td class="diff-marker">−</td>
+ <td class="diff-deletedline"></td>
+ <td colspan="2" class="diff-empty"> </td>
+</tr>
+<tr>
+ <td class="diff-marker">−</td>
+ <td class="diff-deletedline"><div>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div></td>
+ <td colspan="2" class="diff-empty"> </td>
+</tr>
+<tr>
+ <td class="diff-marker"> </td>
+ <td class="diff-context"></td>
+ <td class="diff-marker"> </td>
+ <td class="diff-context"></td>
+</tr>
+<tr>
+ <td class="diff-marker"> </td>
+ <td class="diff-context"><div>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</div></td>
+ <td class="diff-marker"> </td>
+ <td class="diff-context"><div>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</div></td>
+</tr>
+<tr>
+ <td class="diff-marker"> </td>
+ <td class="diff-context"></td>
+ <td class="diff-marker"> </td>
+ <td class="diff-context"></td>
+</tr>
+<tr>
+ <td class="diff-marker">−</td>
+ <td class="diff-deletedline"><div>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim<del class="diffchange diffchange-inline"> id est laborum</del>.</div></td>
+ <td class="diff-marker">+</td>
+ <td class="diff-addedline"><div>Excepteur sint occaecat cupidatat non proident, sunt<ins class="diffchange diffchange-inline"> reprehenderit in voluptate</ins> in culpa qui officia deserunt mollit anim.</div></td>
+</tr>
+<tr>
+ <td colspan="2" class="diff-empty"> </td>
+ <td class="diff-marker">+</td>
+ <td class="diff-addedline"></td>
+</tr>
+<tr>
+ <td colspan="2" class="diff-empty"> </td>
+ <td class="diff-marker">+</td>
+ <td class="diff-addedline"><div>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div></td>
+</tr>
+</tbody></table>
+
+<p>Below are some basic lines being applied one or two classes. Mainly for debugging purposes.</p>
+
+<table class="diff">
+ <tr><th>Diff</th></tr>
+
+ <tr><td class="diff-addedline"><code>diff-addedline</code>: added line</td></tr>
+ <tr><td class="diff-deletedline"><code>diff-deletedline</code>: deleted line</td></tr>
+ <tr><td class="diff-context"><code>diff-context</code>: context</td></tr>
+
+ <tr><th>Same as above with a <code><ins></code> or <code><del></code> child element having the <code>diffchange</code> class:</th></tr>
+
+ <tr><td class="diffchange">Diffchange</td></tr>
+ <tr><td class="diff-addedline"><ins class="diffchange">Added line + diffchange</ins></td></tr>
+ <tr><td class="diff-deletedline"><del class="diffchange">Deleted line + diffchange</del></td></tr>
+</table>
+
+</body>
+</html>
$this->mReason = $options['reason'];
$this->mTimestamp = wfTimestamp( TS_MW, $options['timestamp'] );
- $this->mExpiry = wfGetDB( DB_SLAVE )->decodeExpiry( $options['expiry'] );
+ $this->mExpiry = wfGetDB( DB_REPLICA )->decodeExpiry( $options['expiry'] );
# Boolean settings
$this->mAuto = (bool)$options['auto'];
* @return Block|null
*/
public static function newFromID( $id ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->selectRow(
'ipblocks',
self::selectFields(),
* @return bool Whether a relevant block was found
*/
protected function newLoad( $vagueTarget = null ) {
- $db = wfGetDB( $this->mFromMaster ? DB_MASTER : DB_SLAVE );
+ $db = wfGetDB( $this->mFromMaster ? DB_MASTER : DB_REPLICA );
if ( $this->type !== null ) {
$conds = [
# range. We know that all blocks must be smaller than $wgBlockCIDRLimit,
# so we can improve performance by filtering on a LIKE clause
$chunk = self::getIpFragment( $start );
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$like = $dbr->buildLike( $chunk, $dbr->anyString() );
# Fairly hard to make a malicious SQL statement out of hex characters,
$this->mParentBlockId = $row->ipb_parent_block_id;
// I wish I didn't have to do this
- $this->mExpiry = wfGetDB( DB_SLAVE )->decodeExpiry( $row->ipb_expiry );
+ $this->mExpiry = wfGetDB( DB_REPLICA )->decodeExpiry( $row->ipb_expiry );
$this->isHardblock( !$row->ipb_anon_only );
$this->isAutoblocking( $row->ipb_enable_autoblock );
*/
protected function getDatabaseArray( $db = null ) {
if ( !$db ) {
- $db = wfGetDB( DB_SLAVE );
+ $db = wfGetDB( DB_REPLICA );
}
$expiry = $db->encodeExpiry( $this->mExpiry );
return;
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$options = [ 'ORDER BY' => 'rc_timestamp DESC' ];
$conds = [ 'rc_user_text' => (string)$block->getTarget() ];
* @param array $ipChain List of IPs (strings), usually retrieved from the
* X-Forwarded-For header of the request
* @param bool $isAnon Exclude anonymous-only blocks if false
- * @param bool $fromMaster Whether to query the master or slave database
+ * @param bool $fromMaster Whether to query the master or replica DB
* @return array Array of Blocks
* @since 1.22
*/
if ( $fromMaster ) {
$db = wfGetDB( DB_MASTER );
} else {
- $db = wfGetDB( DB_SLAVE );
+ $db = wfGetDB( DB_REPLICA );
}
$conds = $db->makeList( $conds, LIST_OR );
if ( !$isAnon ) {
return true;
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$row = $dbr->selectRow(
'category',
[ 'cat_id', 'cat_title', 'cat_pages', 'cat_subcats', 'cat_files' ],
*/
public function getMembers( $limit = false, $offset = '' ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$conds = [ 'cl_to' => $this->getName(), 'cl_from = page_id' ];
$options = [ 'ORDER BY' => 'cl_sortkey' ];
/** @var string "AND" or "OR" */
protected $mode;
- /** @var IDatabase Read-DB slave */
+ /** @var IDatabase Read-DB replica DB */
protected $dbr;
/**
* @return array Array of page_ids (those given to seed() that match the conditions)
*/
public function run() {
- $this->dbr = wfGetDB( DB_SLAVE );
+ $this->dbr = wfGetDB( DB_REPLICA );
while ( count( $this->next ) > 0 ) {
$this->scanNextLayer();
}
}
function doCategoryQuery() {
- $dbr = wfGetDB( DB_SLAVE, 'category' );
+ $dbr = wfGetDB( DB_REPLICA, 'category' );
$this->nextPage = [
'page' => null,
* - password: DB password
* - type: DB type
*
- * - load: Ratio of DB_SLAVE load, must be >=0, the sum of all loads must be >0.
+ * - load: Ratio of DB_REPLICA load, must be >=0, the sum of all loads must be >0.
* If this is zero for any given server, no normal query traffic will be
* sent to it. It will be excluded from lag checks in maintenance scripts.
* The only way it can receive traffic is if groupLoads is used.
* - DBO_COMPRESS -- uses internal compression in database connections,
* if available
*
- * - max lag: (optional) Maximum replication lag before a slave will taken out of rotation
+ * - max lag: (optional) Maximum replication lag before a replica DB goes out of rotation
* - is static: (optional) Set to true if the dataset is static and no replication is used.
* - cliMode: (optional) Connection handles will not assume that requests are short-lived
* nor that INSERT..SELECT can be rewritten into a buffered SELECT and INSERT.
* perhaps in some command-line scripts).
*
* The first server listed in this array (with key 0) will be the master. The
- * rest of the servers will be slaves. To prevent writes to your slaves due to
+ * rest of the servers will be replica DBs. To prevent writes to your replica DBs due to
* accidental misconfiguration or MediaWiki bugs, set read_only=1 on all your
- * slaves in my.cnf. You can set read_only mode at runtime using:
+ * replica DBs in my.cnf. You can set read_only mode at runtime using:
*
* @code
* SET @@read_only=1;
* @endcode
*
- * Since the effect of writing to a slave is so damaging and difficult to clean
+ * Since the effect of writing to a replica DB is so damaging and difficult to clean
* up, we at Wikimedia set read_only=1 in my.cnf on all our DB servers, even
* our masters, and then set read_only=0 on masters at runtime.
*/
$wgSquidMaxage = 18000;
/**
- * Cache timeout for the CDN when DB slave lag is high
+ * Cache timeout for the CDN when DB replica DB lag is high
* @see $wgSquidMaxage
* @since 1.27
*/
* If set, any SquidPurge call on a URL or URLs will send a second purge no less than
* this many seconds later via the job queue. This requires delayed job support.
* This should be safely higher than the 'max lag' value in $wgLBFactoryConf, so that
- * slave lag does not cause page to be stuck in stales states in CDN.
+ * replica DB lag does not cause page to be stuck in stales states in CDN.
*
* This also fixes race conditions in two-tiered CDN setups (e.g. cdn2 => cdn1 => MediaWiki).
* If a purge for a URL reaches cdn2 before cdn1 and a request reaches cdn2 for that URL,
$wgJobBackoffThrottling = [];
/**
- * Make job runners commit changes for slave-lag prone jobs one job at a time.
- * This is useful if there are many job workers that race on slave lag checks.
+ * Make job runners commit changes for replica DB-lag prone jobs one job at a time.
+ * This is useful if there are many job workers that race on replica DB lag checks.
* If set, jobs taking this many seconds of DB write time have serialized commits.
*
* Note that affected jobs may have worse lock contention. Also, if they affect
$wgAPIMaxUncachedDiffs = 1;
/**
- * Maximum amount of DB lag on a majority of DB slaves to tolerate
+ * Maximum amount of DB lag on a majority of DB replica DBs to tolerate
* before forcing bots to retry any write requests via API errors.
* This should be lower than the 'max lag' value in $wgLBFactoryConf.
*/
* Valid database indexes
* Operation-based indexes
*/
-define( 'DB_SLAVE', -1 ); # Read from the slave (or only server)
+define( 'DB_REPLICA', -1 ); # Read from a replica (or only server)
define( 'DB_MASTER', -2 ); # Write to master (or only server)
/**@}*/
# Obsolete aliases
+define( 'DB_SLAVE', -1 );
define( 'DB_READ', -1 );
define( 'DB_WRITE', -2 );
* @return bool|stdClass
*/
protected function getLastDelete() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$data = $dbr->selectRow(
[ 'logging', 'user' ],
[
* Check if the site is in read-only mode and return the message if so
*
* This checks wfConfiguredReadOnlyReason() and the main load balancer
- * for slave lag. This may result in DB_SLAVE connection being made.
+ * for replica DB lag. This may result in DB connection being made.
*
* @return string|bool String when in read-only mode; false otherwise
*/
* Get a Database object.
*
* @param int $db Index of the connection to get. May be DB_MASTER for the
- * master (for write queries), DB_SLAVE for potentially lagged read
+ * master (for write queries), DB_REPLICA for potentially lagged read
* queries, or an integer >= 0 for a particular server.
*
* @param string|string[] $groups Query groups. An array of group names that this query
*
* @param string|bool $wiki The wiki ID, or false for the current wiki
*
- * Note: multiple calls to wfGetDB(DB_SLAVE) during the course of one request
+ * Note: multiple calls to wfGetDB(DB_REPLICA) during the course of one request
* will always return the same object, unless the underlying connection or load
* balancer is manually destroyed.
*
}
/**
- * Waits for the slaves to catch up to the master position
+ * Waits for the replica DBs to catch up to the master position
*
* Use this when updating very large numbers of rows, as in maintenance scripts,
- * to avoid causing too much lag. Of course, this is a no-op if there are no slaves.
+ * to avoid causing too much lag. Of course, this is a no-op if there are no replica DBs.
*
* By default this waits on the main DB cluster of the current wiki.
* If $cluster is set to "*" it will wait on all DB clusters, including
if ( isset( self::$blobCache[$this->mOldId] ) ) {
$obj = self::$blobCache[$this->mOldId];
} else {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$row = $dbr->selectRow(
'text',
[ 'old_flags', 'old_text' ],
* @return string|bool
*/
function getText() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$row = $dbr->selectRow( 'cur', [ 'cur_text' ], [ 'cur_id' => $this->mCurId ] );
if ( !$row ) {
return false;
* @return array Array to be passed to Database::buildLike() or false on error
*/
public static function makeLikeArray( $filterEntry, $protocol = 'http://' ) {
- $db = wfGetDB( DB_SLAVE );
+ $db = wfGetDB( DB_REPLICA );
$target = $protocol . $filterEntry;
$bits = wfParseUrl( $target );
return null;
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
// Up to the value of $wgShowRollbackEditCount revisions are counted
$res = $dbr->select(
$request->response()->setCookie( 'UseCDNCache', 'false', $expires, $options );
}
- // Avoid letting a few seconds of slave lag cause a month of stale data. This logic is
+ // Avoid letting a few seconds of replica DB lag cause a month of stale data. This logic is
// also intimately related to the value of $wgCdnReboundPurgeDelay.
if ( $factory->laggedReplicaUsed() ) {
$maxAge = $config->get( 'CdnMaxageLagged' );
*/
class MergeHistory {
- /** @const int Maximum number of revisions that can be merged at once (avoid too much slave lag) */
+ /** @const int Maximum number of revisions that can be merged at once */
const REVISION_LIMIT = 5000;
/** @var Title Page from which history will be merged */
$lb->setArray( $arr );
# Fetch existence plus the hiddencat property
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$fields = array_merge(
LinkCache::getSelectFields(),
[ 'page_namespace', 'page_title', 'pp_value' ]
}
/**
- * Show a warning about slave lag
+ * Show a warning about replica DB lag
*
* If the lag is higher than $wgSlaveLagCritical seconds,
* then the warning is a bit more obvious. If the lag is
}
if ( $queryIDs ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$result = $dbr->select(
'page_props',
[
}
if ( $queryIDs != [] ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$result = $dbr->select(
'page_props',
[
* @return bool
*/
private function checkIfSent() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$sent = $dbr->selectField(
'updatelog', '1', [ 'ul_key' => $this->key ], __METHOD__ );
return $sent !== false;
*/
private function getOrCreatePingbackId() {
if ( !$this->id ) {
- $id = wfGetDB( DB_SLAVE )->selectField(
+ $id = wfGetDB( DB_REPLICA )->selectField(
'updatelog', 'ul_value', [ 'ul_key' => 'PingBack' ] );
if ( $id == false ) {
$t = Title::newFromText( $search, $ns );
$prefix = $t ? $t->getDBkey() : '';
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->select( 'page',
[ 'page_id', 'page_namespace', 'page_title' ],
[
} else {
// Use a join to get the latest revision
$conds[] = 'rev_id=page_latest';
- $db = wfGetDB( ( $flags & self::READ_LATEST ) ? DB_MASTER : DB_SLAVE );
+ $db = wfGetDB( ( $flags & self::READ_LATEST ) ? DB_MASTER : DB_REPLICA );
return self::loadFromConds( $db, $conds, $flags );
}
}
} else {
// Use a join to get the latest revision
$conds[] = 'rev_id = page_latest';
- $db = wfGetDB( ( $flags & self::READ_LATEST ) ? DB_MASTER : DB_SLAVE );
+ $db = wfGetDB( ( $flags & self::READ_LATEST ) ? DB_MASTER : DB_REPLICA );
return self::loadFromConds( $db, $conds, $flags );
}
}
* Given a set of conditions, fetch a revision
*
* This method is used then a revision ID is qualified and
- * will incorporate some basic slave/master fallback logic
+ * will incorporate some basic replica DB/master fallback logic
*
* @param array $conditions
* @param int $flags (optional)
* @return Revision|null
*/
private static function newFromConds( $conditions, $flags = 0 ) {
- $db = wfGetDB( ( $flags & self::READ_LATEST ) ? DB_MASTER : DB_SLAVE );
+ $db = wfGetDB( ( $flags & self::READ_LATEST ) ? DB_MASTER : DB_REPLICA );
$rev = self::loadFromConds( $db, $conditions, $flags );
// Make sure new pending/committed revision are visibile later on
*/
public static function fetchRevision( LinkTarget $title ) {
$row = self::fetchFromConds(
- wfGetDB( DB_SLAVE ),
+ wfGetDB( DB_REPLICA ),
[
'rev_id=page_latest',
'page_namespace' => $title->getNamespace(),
}
// rev_id is defined as NOT NULL, but this revision may not yet have been inserted.
if ( $this->mId !== null ) {
- $dbr = wfGetLB( $this->mWiki )->getConnectionRef( DB_SLAVE, [], $this->mWiki );
+ $dbr = wfGetLB( $this->mWiki )->getConnectionRef( DB_REPLICA, [], $this->mWiki );
$row = $dbr->selectRow(
[ 'page', 'revision' ],
self::selectPageFields(),
* @return RecentChange|null
*/
public function getRecentChange( $flags = 0 ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
list( $dbType, ) = DBAccessObjectUtils::getDBOptions( $flags );
}
if ( !$row ) {
- // Text data is immutable; check slaves first.
- $dbr = wfGetDB( DB_SLAVE );
+ // Text data is immutable; check replica DBs first.
+ $dbr = wfGetDB( DB_REPLICA );
$row = $dbr->selectRow( 'text',
[ 'old_text', 'old_flags' ],
[ 'old_id' => $textId ],
__METHOD__ );
}
- // Fallback to the master in case of slave lag. Also use FOR UPDATE if it was
+ // Fallback to the master in case of replica DB lag. Also use FOR UPDATE if it was
// used to fetch this revision to avoid missing the row due to REPEATABLE-READ.
$forUpdate = ( $this->mQueryFlags & self::READ_LOCKING == self::READ_LOCKING );
if ( !$row && ( $forUpdate || wfGetLB()->getServerCount() > 1 ) ) {
wfDebugLog( 'Revision', "No blob for text row '$textId' (revision {$this->getId()})." );
}
- # No negative caching -- negative hits on text rows may be due to corrupted slave servers
+ # No negative caching -- negative hits on text rows may be due to corrupted replica DB servers
if ( $wgRevisionCacheExpiry && $text !== false ) {
$processCache->set( $key, $text );
$cache->set( $key, $text, $wgRevisionCacheExpiry );
static function getTimestampFromId( $title, $id, $flags = 0 ) {
$db = ( $flags & self::READ_LATEST )
? wfGetDB( DB_MASTER )
- : wfGetDB( DB_SLAVE );
+ : wfGetDB( DB_REPLICA );
// Casting fix for databases that can't take '' for rev_id
if ( $id == '' ) {
$id = 0;
}
$this->mRefreshMutableFields = false;
- $dbr = wfGetLB( $this->mWiki )->getConnectionRef( DB_SLAVE, [], $this->mWiki );
+ $dbr = wfGetLB( $this->mWiki )->getConnectionRef( DB_REPLICA, [], $this->mWiki );
$row = $dbr->selectRow(
[ 'revision', 'user' ],
[ 'rev_deleted', 'user_name' ],
*/
public function reset() {
if ( !$this->res ) {
- $this->res = $this->doQuery( wfGetDB( DB_SLAVE ) );
+ $this->res = $this->doQuery( wfGetDB( DB_REPLICA ) );
} else {
$this->res->rewind();
}
# Update schema
$u = new SiteStatsUpdate( 0, 0, 0 );
$u->doUpdate();
- self::$row = self::doLoad( wfGetDB( DB_SLAVE ) );
+ self::$row = self::doLoad( wfGetDB( DB_REPLICA ) );
}
self::$loaded = true;
static function loadAndLazyInit() {
global $wgMiserMode;
- wfDebug( __METHOD__ . ": reading site_stats from slave\n" );
- $row = self::doLoad( wfGetDB( DB_SLAVE ) );
+ wfDebug( __METHOD__ . ": reading site_stats from replica DB\n" );
+ $row = self::doLoad( wfGetDB( DB_REPLICA ) );
if ( !self::isSane( $row ) ) {
// Might have just been initialized during this request? Underflow?
- wfDebug( __METHOD__ . ": site_stats damaged or missing on slave\n" );
+ wfDebug( __METHOD__ . ": site_stats damaged or missing on replica DB\n" );
$row = self::doLoad( wfGetDB( DB_MASTER ) );
}
// clean schema with mwdumper.
wfDebug( __METHOD__ . ": initializing damaged or missing site_stats\n" );
- SiteStatsInit::doAllAndCommit( wfGetDB( DB_SLAVE ) );
+ SiteStatsInit::doAllAndCommit( wfGetDB( DB_REPLICA ) );
$row = self::doLoad( wfGetDB( DB_MASTER ) );
}
wfMemcKey( 'SiteStats', 'groupcounts', $group ),
$cache::TTL_HOUR,
function ( $oldValue, &$ttl, array &$setOpts ) use ( $group ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$setOpts += Database::getCacheSetOptions( $dbr );
*/
static function pagesInNs( $ns ) {
if ( !isset( self::$pageCount[$ns] ) ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
self::$pageCount[$ns] = (int)$dbr->selectField(
'page',
'COUNT(*)',
} elseif ( $database ) {
$this->db = wfGetDB( DB_MASTER );
} else {
- $this->db = wfGetDB( DB_SLAVE, 'vslow' );
+ $this->db = wfGetDB( DB_REPLICA, 'vslow' );
}
}
* @return Title|null The new object, or null on an error
*/
public static function newFromID( $id, $flags = 0 ) {
- $db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
+ $db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_REPLICA );
$row = $db->selectRow(
'page',
self::getSelectFields(),
if ( !count( $ids ) ) {
return [];
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->select(
'page',
* @return Title|null An object representing the article, or null if no such article was found
*/
public static function nameOf( $id ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$s = $dbr->selectRow(
'page',
* @param string $action Action that permission needs to be checked for
* @param User $user User to check
* @param string $rigor One of (quick,full,secure)
- * - quick : does cheap permission checks from slaves (usable for GUI creation)
- * - full : does cheap and expensive checks possibly from a slave
+ * - quick : does cheap permission checks from replica DBs (usable for GUI creation)
+ * - full : does cheap and expensive checks possibly from a replica DB
* - secure : does cheap and expensive checks, using the master as needed
* @param array $ignoreErrors Array of Strings Set this to a list of message keys
* whose corresponding errors may be ignored.
* @param string $action Action that permission needs to be checked for
* @param User $user User to check
* @param string $rigor One of (quick,full,secure)
- * - quick : does cheap permission checks from slaves (usable for GUI creation)
- * - full : does cheap and expensive checks possibly from a slave
+ * - quick : does cheap permission checks from replica DBs (usable for GUI creation)
+ * - full : does cheap and expensive checks possibly from a replica DB
* - secure : does cheap and expensive checks, using the master as needed
* @param bool $short Set this to true to stop after the first permission error.
* @return array Array of arrays of the arguments to wfMessage to explain permissions problems.
}
if ( $this->mTitleProtection === null ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->select(
'protected_titles',
[
return [ $this->mHasCascadingRestrictions, $pagerestrictions ];
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
if ( $this->getNamespace() == NS_FILE ) {
$tables = [ 'imagelinks', 'page_restrictions' ];
* restrictions from page table (pre 1.10)
*/
public function loadRestrictionsFromRows( $rows, $oldFashionedRestrictions = null ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$restrictionTypes = $this->getRestrictionTypes();
*/
public function loadRestrictions( $oldFashionedRestrictions = null ) {
if ( !$this->mRestrictionsLoaded ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
if ( $this->exists() ) {
$res = $dbr->select(
'page_restrictions',
return [];
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$conds['page_namespace'] = $this->getNamespace();
$conds[] = 'page_title ' . $dbr->buildLike( $this->getDBkey() . '/', $dbr->anyString() );
$options = [];
if ( $this->getNamespace() < 0 ) {
$n = 0;
} else {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$n = $dbr->selectField( 'archive', 'COUNT(*)',
[ 'ar_namespace' => $this->getNamespace(), 'ar_title' => $this->getDBkey() ],
if ( $this->getNamespace() < 0 ) {
return false;
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$deleted = (bool)$dbr->selectField( 'archive', '1',
[ 'ar_namespace' => $this->getNamespace(), 'ar_title' => $this->getDBkey() ],
__METHOD__
if ( count( $options ) > 0 ) {
$db = wfGetDB( DB_MASTER );
} else {
- $db = wfGetDB( DB_SLAVE );
+ $db = wfGetDB( DB_REPLICA );
}
$res = $db->select(
return [];
}
- $db = wfGetDB( DB_SLAVE );
+ $db = wfGetDB( DB_REPLICA );
$blNamespace = "{$prefix}_namespace";
$blTitle = "{$prefix}_title";
return [];
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->select(
[ 'page', 'pagelinks' ],
[ 'pl_namespace', 'pl_title' ],
return $data;
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->select(
'categorylinks',
* @return int|bool Old revision ID, or false if none exists
*/
public function getPreviousRevisionID( $revId, $flags = 0 ) {
- $db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
+ $db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_REPLICA );
$revId = $db->selectField( 'revision', 'rev_id',
[
'rev_page' => $this->getArticleID( $flags ),
* @return int|bool Next revision ID, or false if none exists
*/
public function getNextRevisionID( $revId, $flags = 0 ) {
- $db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
+ $db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_REPLICA );
$revId = $db->selectField( 'revision', 'rev_id',
[
'rev_page' => $this->getArticleID( $flags ),
public function getFirstRevision( $flags = 0 ) {
$pageId = $this->getArticleID( $flags );
if ( $pageId ) {
- $db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
+ $db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_REPLICA );
$row = $db->selectRow( 'revision', Revision::selectFields(),
[ 'rev_page' => $pageId ],
__METHOD__,
* @return bool
*/
public function isNewPage() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
return (bool)$dbr->selectField( 'page', 'page_is_new', $this->pageCond(), __METHOD__ );
}
}
if ( $this->mIsBigDeletion === null ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$revCount = $dbr->selectRowCount(
'revision',
}
if ( $this->mEstimateRevisions === null ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$this->mEstimateRevisions = $dbr->estimateRowCount( 'revision', '*',
[ 'rev_page' => $this->getArticleID() ], __METHOD__ );
}
if ( !$old || !$new ) {
return 0; // nothing to compare
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$conds = [
'rev_page' => $this->getArticleID(),
'rev_timestamp > ' . $dbr->addQuotes( $dbr->timestamp( $old->getTimestamp() ) ),
}
return $authors;
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->select( 'revision', 'DISTINCT rev_user_text',
[
'rev_page' => $this->getArticleID(),
*/
public function getTouched( $db = null ) {
if ( $db === null ) {
- $db = wfGetDB( DB_SLAVE );
+ $db = wfGetDB( DB_REPLICA );
}
$touched = $db->selectField( 'page', 'page_touched', $this->pageCond(), __METHOD__ );
return $touched;
public function getRedirectsHere( $ns = null ) {
$redirs = [];
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$where = [
'rd_namespace' => $this->getNamespace(),
'rd_title' => $this->getDBkey(),
* @throws MWException
*/
private function getConnection() {
- return $this->loadBalancer->getConnection( DB_SLAVE, [ 'watchlist' ] );
+ return $this->loadBalancer->getConnection( DB_REPLICA, [ 'watchlist' ] );
}
/**
}
/**
- * @param int $slaveOrMaster DB_MASTER or DB_SLAVE
+ * @param int $dbIndex DB_MASTER or DB_REPLICA
*
* @return DatabaseBase
* @throws MWException
*/
- private function getConnection( $slaveOrMaster ) {
- return $this->loadBalancer->getConnection( $slaveOrMaster, [ 'watchlist' ] );
+ private function getConnection( $dbIndex ) {
+ return $this->loadBalancer->getConnection( $dbIndex, [ 'watchlist' ] );
}
/**
* @return int
*/
public function countWatchedItems( User $user ) {
- $dbr = $this->getConnection( DB_SLAVE );
+ $dbr = $this->getConnection( DB_REPLICA );
$return = (int)$dbr->selectField(
'watchlist',
'COUNT(*)',
* @return int
*/
public function countWatchers( LinkTarget $target ) {
- $dbr = $this->getConnection( DB_SLAVE );
+ $dbr = $this->getConnection( DB_REPLICA );
$return = (int)$dbr->selectField(
'watchlist',
'COUNT(*)',
* @throws MWException
*/
public function countVisitingWatchers( LinkTarget $target, $threshold ) {
- $dbr = $this->getConnection( DB_SLAVE );
+ $dbr = $this->getConnection( DB_REPLICA );
$visitingWatchers = (int)$dbr->selectField(
'watchlist',
'COUNT(*)',
public function countWatchersMultiple( array $targets, array $options = [] ) {
$dbOptions = [ 'GROUP BY' => [ 'wl_namespace', 'wl_title' ] ];
- $dbr = $this->getConnection( DB_SLAVE );
+ $dbr = $this->getConnection( DB_REPLICA );
if ( array_key_exists( 'minimumWatchers', $options ) ) {
$dbOptions['HAVING'] = 'COUNT(*) >= ' . (int)$options['minimumWatchers'];
array $targetsWithVisitThresholds,
$minimumWatchers = null
) {
- $dbr = $this->getConnection( DB_SLAVE );
+ $dbr = $this->getConnection( DB_REPLICA );
$conds = $this->getVisitingWatchersCondition( $dbr, $targetsWithVisitThresholds );
return false;
}
- $dbr = $this->getConnection( DB_SLAVE );
+ $dbr = $this->getConnection( DB_REPLICA );
$row = $dbr->selectRow(
'watchlist',
'wl_notificationtimestamp',
"wl_title {$options['sort']}"
];
}
- $db = $this->getConnection( $options['forWrite'] ? DB_MASTER : DB_SLAVE );
+ $db = $this->getConnection( $options['forWrite'] ? DB_MASTER : DB_REPLICA );
$res = $db->select(
'watchlist',
return $timestamps;
}
- $dbr = $this->getConnection( DB_SLAVE );
+ $dbr = $this->getConnection( DB_REPLICA );
$lb = new LinkBatch( $targetsToLoad );
$res = $dbr->select(
$queryOptions['LIMIT'] = $unreadLimit;
}
- $dbr = $this->getConnection( DB_SLAVE );
+ $dbr = $this->getConnection( DB_REPLICA );
$rowCount = $dbr->selectRowCount(
'watchlist',
'1',
return new FakeResultWrapper( [] );
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
if ( $direction === self::DIR_PREV ) {
list( $dirs, $oper ) = [ "ASC", ">=" ];
$title = $page->getTitle();
$id = $title->getArticleID();
- $dbr = wfGetDB( DB_SLAVE );
- $dbrWatchlist = wfGetDB( DB_SLAVE, 'watchlist' );
+ $dbr = wfGetDB( DB_REPLICA );
+ $dbrWatchlist = wfGetDB( DB_REPLICA, 'watchlist' );
$setOpts += Database::getCacheSetOptions( $dbr, $dbrWatchlist );
}
/**
- * Gets a default slave database connection object
+ * Gets a default replica DB connection object
* @return DatabaseBase
*/
protected function getDB() {
if ( !isset( $this->mSlaveDB ) ) {
- $this->mSlaveDB = wfGetDB( DB_SLAVE, 'api' );
+ $this->mSlaveDB = wfGetDB( DB_REPLICA, 'api' );
}
return $this->mSlaveDB;
* @param array $params
* @param bool|string $load Whether load the object's state from the database:
* - false: don't load (if the pageid is given, it will still be loaded)
- * - 'fromdb': load from a slave database
+ * - 'fromdb': load from a replica DB
* - 'fromdbmaster': load from the master database
* @return WikiPage
*/
}
}
- // If a majority of slaves are too lagged then disallow writes
- $slaveCount = wfGetLB()->getServerCount() - 1;
- if ( $numLagged >= ceil( $slaveCount / 2 ) ) {
+ // If a majority of replica DBs are too lagged then disallow writes
+ $replicaCount = wfGetLB()->getServerCount() - 1;
+ if ( $numLagged >= ceil( $replicaCount / 2 ) ) {
$laggedServers = implode( ', ', $laggedServers );
wfDebugLog(
'api-readonly',
$this->fld_patrolled = isset( $prop['patrolled'] );
$this->fld_tags = isset( $prop['tags'] );
- // Most of this code will use the 'contributions' group DB, which can map to slaves
+ // Most of this code will use the 'contributions' group DB, which can map to replica DBs
// with extra user based indexes or partioning by user. The additional metadata
- // queries should use a regular slave since the lookup pattern is not all by user.
- $dbSecondary = $this->getDB(); // any random slave
+ // queries should use a regular replica DB since the lookup pattern is not all by user.
+ $dbSecondary = $this->getDB(); // any random replica DB
// TODO: if the query is going only against the revision table, should this be done?
- $this->selectNamedDB( 'contributions', DB_SLAVE, 'contributions' );
+ $this->selectNamedDB( 'contributions', DB_REPLICA, 'contributions' );
$this->idMode = false;
if ( isset( $this->params['userprefix'] ) ) {
* @return void
*/
private function run( $resultPageSet = null ) {
- $this->selectNamedDB( 'watchlist', DB_SLAVE, 'watchlist' );
+ $this->selectNamedDB( 'watchlist', DB_REPLICA, 'watchlist' );
$params = $this->extractRequestParams();
* @return string|null TS_MW timestamp or null
*/
private static function lastEditTime( User $user ) {
- $time = wfGetDB( DB_SLAVE )->selectField(
+ $time = wfGetDB( DB_REPLICA )->selectField(
'recentchanges',
'MAX(rc_timestamp)',
[ 'rc_user_text' => $user->getName() ],
}
protected static function validateLogId( $logid ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$result = $dbr->selectField( 'logging', 'log_id', [ 'log_id' => $logid ],
__METHOD__ );
return (bool)$result;
$username = $user->getName();
- // Try the local user from the slave DB
+ // Try the local user from the replica DB
$localId = User::idFromName( $username );
$flags = User::READ_NORMAL;
return AuthenticationResponse::newAbstain();
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$row = $dbr->selectRow(
'user',
[
return false;
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$row = $dbr->selectRow(
'user',
[ 'user_newpassword', 'user_newpass_time' ],
}
/**
- * Get the slave connection to the database
+ * Get the replica DB connection to the database
* When non existing, will initialize the connection.
* @return DatabaseBase
*/
protected function getDB() {
if ( !isset( $this->db ) ) {
- $this->db = wfGetDB( DB_SLAVE );
+ $this->db = wfGetDB( DB_REPLICA );
}
return $this->db;
return;
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$table = [ 'user', 'user_properties' ];
$fields = [ 'user_name', 'up_value' ];
$conds = [ 'user_name' => $usersToCheck ];
}
// This is similar to LinkHolderArray::replaceInternal
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$table = 'page';
$fields = array_merge(
LinkCache::getSelectFields(),
}
// Some fields heavily used for linking...
- $db = $this->mForUpdate ? wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
+ $db = $this->mForUpdate ? wfGetDB( DB_MASTER ) : wfGetDB( DB_REPLICA );
$row = $db->selectRow( 'page', self::getSelectFields(),
[ 'page_namespace' => $nt->getNamespace(), 'page_title' => $nt->getDBkey() ],
$cache->set( $cacheKey, $blob,
// Add part of a day to TTL to avoid all modules expiring at once
$cache::TTL_WEEK + mt_rand( 0, $cache::TTL_DAY ),
- Database::getCacheSetOptions( wfGetDB( DB_SLAVE ) )
+ Database::getCacheSetOptions( wfGetDB( DB_REPLICA ) )
);
return $blob;
}
public function updateMessage( $key ) {
$moduleNames = $this->getResourceLoader()->getModulesByMessage( $key );
foreach ( $moduleNames as $moduleName ) {
- // Uses a holdoff to account for database slave lag (for MessageCache)
+ // Uses a holdoff to account for database replica DB lag (for MessageCache)
$this->wanCache->touchCheckKey( $this->wanCache->makeKey( __CLASS__, $moduleName ) );
}
}
$where[] = 'global cache is expired';
$staleCache = $cache;
} elseif ( $hashVolatile ) {
- # DB results are slave lag prone until the holdoff TTL passes.
+ # DB results are replica DB lag prone until the holdoff TTL passes.
# By then, updates should be reflected in loadFromDBWithLock().
# One thread renerates the cache while others use old values.
$where[] = 'global cache is expired/volatile';
function loadFromDB( $code, $mode = null ) {
global $wgMaxMsgCacheEntrySize, $wgLanguageCode, $wgAdaptiveMessageCache;
- $dbr = wfGetDB( ( $mode == self::FOR_UPDATE ) ? DB_MASTER : DB_SLAVE );
+ $dbr = wfGetDB( ( $mode == self::FOR_UPDATE ) ? DB_MASTER : DB_REPLICA );
$cache = [];
}
// Mark this cache as definitely "latest" (non-volatile) so
- // load() calls do try to refresh the cache with slave data
+ // load() calls do try to refresh the cache with replica DB data
$this->mCache[$code]['LATEST'] = time();
// Update caches if the lock was acquired
// Lookup basic info for users not yet loaded...
if ( count( $usersToQuery ) ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$table = [ 'user' ];
$conds = [ 'user_id' => $usersToQuery ];
$fields = [ 'user_name', 'user_real_name', 'user_registration', 'user_id' ];
if ( $this->writesDone && $this->dbw ) {
$db = $this->dbw; // see the changes in finishWrite()
} else {
- $db = wfGetDB( DB_SLAVE );
+ $db = wfGetDB( DB_REPLICA );
}
$value = $db->selectField(
/**
* T109700 - Default bot flag to true when there is no corresponding RC entry
* This means all changes caused by parser functions & Lua on reparse are marked as bot
- * Also in the case no RC entry could be found due to slave lag
+ * Also in the case no RC entry could be found due to replica DB lag
*/
$bot = 1;
$lastRevId = 0;
public static function newFromConds(
$conds,
$fname = __METHOD__,
- $dbType = DB_SLAVE
+ $dbType = DB_REPLICA
) {
$db = wfGetDB( $dbType );
$row = $db->selectRow( 'recentchanges', self::selectFields(), $conds, $fname );
// Might as well look for rcids and so on.
if ( !$rc_id ) {
- // Info might be out of date, somewhat fractionally, on slave.
+ // Info might be out of date, somewhat fractionally, on replica DB.
// LogEntry/LogPage and WikiPage match rev/log/rc timestamps,
// so use that relation to avoid full table scans.
if ( $log_id ) {
);
}
} elseif ( !$log_id && !$rev_id ) {
- // Info might be out of date, somewhat fractionally, on slave.
+ // Info might be out of date, somewhat fractionally, on replica DB.
$log_id = $dbw->selectField(
'recentchanges',
'rc_logid',
$tagsToAdd = array_diff( $tagsToAdd, $tagsToRemove );
// Update the summary row.
- // $prevTags can be out of date on slaves, especially when addTags is called consecutively,
+ // $prevTags can be out of date on replica DBs, especially when addTags is called consecutively,
// causing loss of tags added recently in tag_summary table.
$prevTags = $dbw->selectField( 'tag_summary', 'ts_tags', $tsConds, __METHOD__ );
$prevTags = $prevTags ? $prevTags : '';
throw new MWException( 'Unable to determine appropriate JOIN condition for tagging.' );
}
- $fields['ts_tags'] = wfGetDB( DB_SLAVE )->buildGroupConcatField(
+ $fields['ts_tags'] = wfGetDB( DB_REPLICA )->buildGroupConcatField(
',', 'change_tag', 'ct_tag', $join_cond
);
wfMemcKey( 'active-tags' ),
WANObjectCache::TTL_MINUTE * 5,
function ( $oldValue, &$ttl, array &$setOpts ) {
- $setOpts += Database::getCacheSetOptions( wfGetDB( DB_SLAVE ) );
+ $setOpts += Database::getCacheSetOptions( wfGetDB( DB_REPLICA ) );
// Ask extensions which tags they consider active
$extensionActive = [];
wfMemcKey( 'valid-tags-db' ),
WANObjectCache::TTL_MINUTE * 5,
function ( $oldValue, &$ttl, array &$setOpts ) use ( $fname ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$setOpts += Database::getCacheSetOptions( $dbr );
wfMemcKey( 'valid-tags-hook' ),
WANObjectCache::TTL_MINUTE * 5,
function ( $oldValue, &$ttl, array &$setOpts ) {
- $setOpts += Database::getCacheSetOptions( wfGetDB( DB_SLAVE ) );
+ $setOpts += Database::getCacheSetOptions( wfGetDB( DB_REPLICA ) );
$tags = [];
Hooks::run( 'ListDefinedTags', [ &$tags ] );
wfMemcKey( 'change-tag-statistics' ),
WANObjectCache::TTL_MINUTE * 5,
function ( $oldValue, &$ttl, array &$setOpts ) use ( $fname ) {
- $dbr = wfGetDB( DB_SLAVE, 'vslow' );
+ $dbr = wfGetDB( DB_REPLICA, 'vslow' );
$setOpts += Database::getCacheSetOptions( $dbr );
* have it / want it.
*/
public function getAutoDeleteReason( Title $title, &$hasHistory ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
// Get the last revision
$rev = Revision::newFromTitle( $title );
* Get an appropriate DB index and options for a query
*
* @param integer $bitfield
- * @return array (DB_MASTER/DB_SLAVE, SELECT options array)
+ * @return array (DB_MASTER/DB_REPLICA, SELECT options array)
*/
public static function getDBOptions( $bitfield ) {
$index = self::hasFlags( $bitfield, IDBAccessObject::READ_LATEST )
? DB_MASTER
- : DB_SLAVE;
+ : DB_REPLICA;
$options = [];
if ( self::hasFlags( $bitfield, IDBAccessObject::READ_EXCLUSIVE ) ) {
* though certain objects may assume READ_LATEST for common use case or legacy reasons.
*
* There are four types of reads:
- * - READ_NORMAL : Potentially cached read of data (e.g. from a slave or stale replica)
+ * - READ_NORMAL : Potentially cached read of data (e.g. from a replica DB or stale replica)
* - READ_LATEST : Up-to-date read as of transaction start (e.g. from master or a quorum read)
* - READ_LOCKING : Up-to-date read as of now, that locks (shared) the records
* - READ_EXCLUSIVE : Up-to-date read as of now, that locks (exclusive) the records
* All record locks persist for the duration of the transaction.
*
* A special constant READ_LATEST_IMMUTABLE can be used for fetching append-only data. Such
- * data is either (a) on a slave and up-to-date or (b) not yet there, but on the master/quorum.
- * Because the data is append-only, it can never be stale on a slave if present.
+ * data is either (a) on a replica DB and up-to-date or (b) not yet there, but on the master/quorum.
+ * Because the data is append-only, it can never be stale on a replica DB if present.
*
* Callers should use READ_NORMAL (or pass in no flags) unless the read determines a write.
* In theory, such cases may require READ_LOCKING, though to avoid contention, READ_LATEST is
*/
interface IDBAccessObject {
/** Constants for object loading bitfield flags (higher => higher QoS) */
- /** @var integer Read from a slave/non-quorum */
+ /** @var integer Read from a replica DB/non-quorum */
const READ_NORMAL = 0;
/** @var integer Read from the master/quorum */
const READ_LATEST = 1;
/** @var integer Read from the master/quorum and lock out other writers and locking readers */
const READ_EXCLUSIVE = 7; // READ_LOCKING (3) and "FOR UPDATE" (4)
- /** @var integer Read from a slave/non-quorum immutable data, using the master/quorum on miss */
+ /** @var integer Read from a replica DB or without a quorum, using the master/quorum on miss */
const READ_LATEST_IMMUTABLE = 8;
// Convenience constant for tracking how data was loaded (higher => higher QoS)
*/
public function getApproximateLagStatus() {
return [
- 'lag' => $this->getLBInfo( 'slave' ) ? $this->getLag() : 0,
+ 'lag' => $this->getLBInfo( 'replica' ) ? $this->getLag() : 0,
'since' => microtime( true )
];
}
}
$master = false;
} else {
- $serverInfo['slave'] = true;
+ $serverInfo['replica'] = true;
}
if ( isset( $this->templateOverridesByServer[$serverName] ) ) {
$serverInfo = $this->templateOverridesByServer[$serverName] + $serverInfo;
if ( $i == 0 ) {
$server['master'] = true;
} else {
- $server['slave'] = true;
+ $server['replica'] = true;
}
$server += [ 'flags' => DBO_DEFAULT ];
}
/**
* Set the master wait position
- * If a DB_SLAVE connection has been opened already, waits
+ * If a DB_REPLICA connection has been opened already, waits
* Otherwise sets a variable telling it to wait if such a connection is opened
* @param DBMasterPos $pos
*/
}
# Operation-based index
- if ( $i == DB_SLAVE ) {
+ if ( $i == DB_REPLICA ) {
$this->mLastError = 'Unknown error'; // reset error string
# Try the general server pool if $groups are unavailable.
$i = in_array( false, $groups, true )
/**
* This can happen in code like:
* foreach ( $dbs as $db ) {
- * $conn = $lb->getConnection( DB_SLAVE, [], $db );
+ * $conn = $lb->getConnection( DB_REPLICA, [], $db );
* ...
* $lb->reuseConnection( $conn );
* }
if ( !$this->laggedReplicaMode && $this->getServerCount() > 1 ) {
try {
// See if laggedReplicaMode gets set
- $conn = $this->getConnection( DB_SLAVE, false, $wiki );
+ $conn = $this->getConnection( DB_REPLICA, false, $wiki );
$this->reuseConnection( $conn );
} catch ( DBConnectionError $e ) {
// Avoid expensive re-connect attempts and failures
* @since 1.27
*/
public function safeWaitForMasterPos( IDatabase $conn, $pos = false, $timeout = 10 ) {
- if ( $this->getServerCount() == 1 || !$conn->getLBInfo( 'slave' ) ) {
+ if ( $this->getServerCount() == 1 || !$conn->getLBInfo( 'replica' ) ) {
return true; // server is not a replica DB
}
private static function runUpdate( DeferrableUpdate $update, LBFactory $lbFactory, $stage ) {
$guiError = null;
try {
- $lbFactory->beginMasterChanges( __METHOD__ );
+ $fnameTrxOwner = get_class( $update ) . '::doUpdate';
+ $lbFactory->beginMasterChanges( $fnameTrxOwner );
$update->doUpdate();
- $lbFactory->commitMasterChanges( __METHOD__ );
+ $lbFactory->commitMasterChanges( $fnameTrxOwner );
} catch ( Exception $e ) {
// Reporting GUI exceptions does not work post-send
if ( $e instanceof ErrorPageError && $stage === self::PRESEND ) {
*/
public static function cacheUpdate( $dbw ) {
global $wgActiveUserDays;
- $dbr = wfGetDB( DB_SLAVE, 'vslow' );
+ $dbr = wfGetDB( DB_REPLICA, 'vslow' );
# Get non-bot users than did some recent action other than making accounts.
# If account creation is included, the number gets inflated ~20+ fold on enwiki.
$activeUsers = $dbr->selectField(
*/
public function deletedLink( $id ) {
if ( $this->getUser()->isAllowed( 'deletedhistory' ) ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$row = $dbr->selectRow( 'archive', '*',
[ 'ar_rev_id' => $id ],
__METHOD__ );
RecentChange::isInRCLifespan( $this->mNewRev->getTimestamp(), 21600 )
) {
// Look for an unpatrolled change corresponding to this diff
- $db = wfGetDB( DB_SLAVE );
+ $db = wfGetDB( DB_REPLICA );
$change = RecentChange::newFromConds(
[
'rc_timestamp' => $db->timestamp( $this->mNewRev->getTimestamp() ),
}
/**
- * Add style sheets and supporting JS for diff display.
+ * Add style sheets for diff display.
*/
public function showDiffStyle() {
- $this->getOutput()->addModuleStyles( 'mediawiki.action.history.diff' );
+ $this->getOutput()->addModuleStyles( 'mediawiki.diff.styles' );
}
/**
}
// Load tags information for both revisions
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
if ( $this->mOldid !== false ) {
$this->mOldTags = $dbr->selectField(
'tag_summary',
}
/**
- * Get a slave database connection for the specified cluster
+ * Get a replica DB connection for the specified cluster
*
* @param string $cluster Cluster name
* @return IDatabase
wfDebug( "writable external store\n" );
}
- $db = $lb->getConnection( DB_SLAVE, [], $wiki );
+ $db = $lb->getConnection( DB_REPLICA, [], $wiki );
$db->clearFlag( DBO_TRX ); // sanity
return $db;
}
/**
- * Helper function for self::batchFetchBlobs for merging master/slave results
+ * Helper function for self::batchFetchBlobs for merging master/replica DB results
* @param array &$ret Current self::batchFetchBlobs return value
* @param array &$ids Map from blob_id to requested itemIDs
* @param mixed $res DB result from Database::select
* @return array Translated paths in same order
*/
public function getBackendPaths( array $paths, $latest = true ) {
- $db = $this->getDB( $latest ? DB_MASTER : DB_SLAVE );
+ $db = $this->getDB( $latest ? DB_MASTER : DB_REPLICA );
// @TODO: batching
$resolved = [];
* @return IDatabase
*/
function getSlaveDB() {
- return wfGetDB( DB_SLAVE, [], $this->wiki );
+ return wfGetDB( DB_REPLICA, [], $this->wiki );
}
/**
}
/**
- * Get a connection to the slave DB
+ * Get a connection to the replica DB
* @return DatabaseBase
*/
function getSlaveDB() {
- return wfGetDB( DB_SLAVE );
+ return wfGetDB( DB_REPLICA );
}
/**
}
/**
- * Get a callback to get a DB handle given an index (DB_SLAVE/DB_MASTER)
+ * Get a callback to get a DB handle given an index (DB_REPLICA/DB_MASTER)
* @return Closure
*/
protected function getDBFactory() {
if ( !$this->title || $this->title->getNamespace() == NS_FILE ) {
$this->dataLoaded = true; // set it here, to have also true on miss
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$row = $dbr->selectRow(
'filearchive',
self::selectFields(),
// Update article count statistics (T42009)
// The normal counting logic in WikiPage->doEditUpdates() is designed for
// one-revision-at-a-time editing, not bulk imports. In this situation it
- // suffers from issues of slave lag. We let WikiPage handle the total page
+ // suffers from issues of replica DB lag. We let WikiPage handle the total page
// and revision count, and we implement our own custom logic for the
// article (content page) count.
$page = WikiPage::factory( $title );
* and tree storage backends (SQL, CDB, and plain PHP arrays).
*
* All information is loaded on creation when called by $this->fetch( $prefix ).
- * All work is done on slave, because this should *never* change (except during
+ * All work is done on replica DB, because this should *never* change (except during
* schema updates etc, which aren't wiki-related)
*
* @since 1.28
$this->objectCache->makeKey( 'interwiki', $prefix ),
$this->objectCacheExpiry,
function ( $oldValue, &$ttl, array &$setOpts ) use ( $prefix ) {
- $dbr = wfGetDB( DB_SLAVE ); // TODO: inject LoadBalancer
+ $dbr = wfGetDB( DB_REPLICA ); // TODO: inject LoadBalancer
$setOpts += Database::getCacheSetOptions( $dbr );
* @return array[] Interwiki rows
*/
private function getAllPrefixesDB( $local ) {
- $db = wfGetDB( DB_SLAVE ); // TODO: inject DB LoadBalancer
+ $db = wfGetDB( DB_REPLICA ); // TODO: inject DB LoadBalancer
$where = [];
}
/**
- * Wait for any slaves or backup servers to catch up.
+ * Wait for any replica DBs or backup servers to catch up.
*
* This does nothing for certain queue classes.
*
}
// Build the full list of job rows to insert
$rows = array_merge( $rowList, array_values( $rowSet ) );
- // Insert the job rows in chunks to avoid slave lag...
+ // Insert the job rows in chunks to avoid replica DB lag...
foreach ( array_chunk( $rows, 50 ) as $rowBatch ) {
$dbw->insert( 'job', $rowBatch, $method );
}
*/
protected function getSlaveDB() {
try {
- return $this->getDB( DB_SLAVE );
+ return $this->getDB( DB_REPLICA );
} catch ( DBConnectionError $e ) {
throw new JobQueueConnectionError( "DBConnectionError:" . $e->getMessage() );
}
}
/**
- * @param int $index (DB_SLAVE/DB_MASTER)
+ * @param int $index (DB_REPLICA/DB_MASTER)
* @return DBConnRef
*/
protected function getDB( $index ) {
}
/**
- * Wait for any slaves or backup queue servers to catch up.
+ * Wait for any replica DBs or backup queue servers to catch up.
*
* This does nothing for certain queue classes.
*
protected $logger;
const MAX_ALLOWED_LAG = 3; // abort if more than this much DB lag is present
- const LAG_CHECK_PERIOD = 1.0; // check slave lag this many seconds
+ const LAG_CHECK_PERIOD = 1.0; // check replica DB lag this many seconds
const ERROR_BACKOFF_TTL = 1; // seconds to back off a queue due to errors
/**
// This check should not block as we want to try other wiki queues.
list( , $maxLag ) = wfGetLB( wfWikiID() )->getMaxLag();
if ( $maxLag >= self::MAX_ALLOWED_LAG ) {
- $response['reached'] = 'slave-lag-limit';
+ $response['reached'] = 'replica-lag-limit';
return $response;
}
$lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
$lbFactory->commitAll( __METHOD__ );
- // Catch huge single updates that lead to slave lag
+ // Catch huge single updates that lead to replica DB lag
$trxProfiler = Profiler::instance()->getTransactionProfiler();
$trxProfiler->setLogger( LoggerFactory::getInstance( 'DBPerformance' ) );
$trxProfiler->setExpectations( $wgTrxProfilerLimits['JobRunner'], __METHOD__ );
$jobsPopped = 0;
$timeMsTotal = 0;
$startTime = microtime( true ); // time since jobs started running
- $lastCheckTime = 1; // timestamp of last slave check
+ $lastCheckTime = 1; // timestamp of last replica DB check
do {
// Sync the persistent backoffs with concurrent runners
$backoffs = $this->syncBackoffDeltas( $backoffs, $backoffDeltas, $wait );
break;
}
- // Don't let any of the main DB slaves get backed up.
+ // Don't let any of the main DB replica DBs get backed up.
// This only waits for so long before exiting and letting
// other wikis in the farm (on different masters) get a chance.
$timePassed = microtime( true ) - $lastCheckTime;
'timeout' => self::MAX_ALLOWED_LAG
] );
} catch ( DBReplicationWaitError $e ) {
- $response['reached'] = 'slave-lag-limit';
+ $response['reached'] = 'replica-lag-limit';
break;
}
$lastCheckTime = microtime( true );
}
- // Don't let any queue slaves/backups fall behind
+ // Don't let any queue replica DBs/backups fall behind
if ( $jobsPopped > 0 && ( $jobsPopped % 100 ) == 0 ) {
$group->waitForBackups();
}
// Commit all outstanding connections that are in a transaction
// to get a fresh repeatable read snapshot on every connection.
- // Note that jobs are still responsible for handling slave lag.
+ // Note that jobs are still responsible for handling replica DB lag.
$lbFactory->flushReplicaSnapshots( __METHOD__ );
// Clear out title cache data from prior snapshots
LinkCache::singleton()->clear();
/**
* Issue a commit on all masters who are currently in a transaction and have
* made changes to the database. It also supports sometimes waiting for the
- * local wiki's slaves to catch up. See the documentation for
+ * local wiki's replica DBs to catch up. See the documentation for
* $wgJobSerialCommitThreshold for more.
*
* @param Job $job
$dbwSerial = false;
}
} else {
- // There are no slaves or writes are all to foreign DB (we don't handle that)
+ // There are no replica DBs or writes are all to foreign DB (we don't handle that)
$dbwSerial = false;
}
// This will trigger a rollback in the main loop
throw new DBError( $dbwSerial, "Timed out waiting on commit queue." );
}
- // Wait for the slave DBs to catch up
+ // Wait for the replica DBs to catch up
$pos = $lb->getMasterPos();
if ( $pos ) {
$lb->waitForAll( $pos );
return false;
}
- $dbr = wfGetDB( DB_SLAVE, [ 'recentchanges' ] );
- // Wait till the slave is caught up so that jobs for this page see each others' changes
+ $dbr = wfGetDB( DB_REPLICA, [ 'recentchanges' ] );
+ // Wait till the replica DB is caught up so that jobs for this page see each others' changes
if ( !wfGetLB()->safeWaitForMasterPos( $dbr ) ) {
- $this->setLastError( "Timed out while waiting for slave to catch up" );
+ $this->setLastError( "Timed out while waiting for replica DB to catch up" );
return false;
}
// Clear any stale REPEATABLE-READ snapshot
);
if ( $rcIds ) {
$dbw->delete( 'recentchanges', [ 'rc_id' => $rcIds ], __METHOD__ );
- // There might be more, so try waiting for slaves
+ // There might be more, so try waiting for replica DBs
try {
$factory->commitAndWaitForReplication(
__METHOD__, $ticket, [ 'timeout' => 3 ]
const PARSE_THRESHOLD_SEC = 1.0;
/** @var integer Lag safety margin when comparing root job times to last-refresh times */
const CLOCK_FUDGE = 10;
- /** @var integer How many seconds to wait for slaves to catch up */
+ /** @var integer How many seconds to wait for replica DBs to catch up */
const LAG_WAIT_TIMEOUT = 15;
function __construct( Title $title, array $params ) {
// Job to update all (or a range of) backlink pages for a page
if ( !empty( $this->params['recursive'] ) ) {
- // When the base job branches, wait for the slaves to catch up to the master.
+ // When the base job branches, wait for the replica DBs to catch up to the master.
// From then on, we know that any template changes at the time the base job was
// enqueued will be reflected in backlink page parses when the leaf jobs run.
if ( !isset( $params['range'] ) ) {
$skewedTimestamp = $this->params['rootJobTimestamp'];
if ( $opportunistic ) {
- // Neither clock skew nor DB snapshot/slave lag matter much for such
+ // Neither clock skew nor DB snapshot/replica DB lag matter much for such
// updates; focus on reusing the (often recently updated) cache
} else {
// For transclusion updates, the template changes must be reflected
/**
* A cache class that directs writes to one set of servers and reads to
- * another. This assumes that the servers used for reads are setup to slave
+ * another. This assumes that the servers used for reads are setup to replica DB
* those that writes go to. This can easily be used with redis for example.
*
* In the WAN scenario (e.g. multi-datacenter case), this is useful when
* - writeFactory : ObjectFactory::getObjectFromSpec array yeilding BagOStuff.
* This object will be used for writes (e.g. the master DB).
* - readFactory : ObjectFactory::getObjectFromSpec array yeilding BagOStuff.
- * This object will be used for reads (e.g. a slave DB).
+ * This object will be used for reads (e.g. a replica DB).
*
* @param array $params
* @throws InvalidArgumentException
*
* Example usage:
* @code
- * $dbr = wfGetDB( DB_SLAVE );
+ * $dbr = wfGetDB( DB_REPLICA );
* $setOpts = Database::getCacheSetOptions( $dbr );
* // Fetch the row from the DB
* $row = $dbr->selectRow( ... );
* @param integer $ttl Seconds to live. Special values are:
* - WANObjectCache::TTL_INDEFINITE: Cache forever
* @param array $opts Options map:
- * - lag : Seconds of slave lag. Typically, this is either the slave lag
- * before the data was read or, if applicable, the slave lag before
+ * - lag : Seconds of replica DB lag. Typically, this is either the replica DB lag
+ * before the data was read or, if applicable, the replica DB lag before
* the snapshot-isolated transaction the data was read from started.
* Default: 0 seconds
* - since : UNIX timestamp of the data in $value. Typically, this is either
* Keys using it via get(), getMulti(), or getWithSetCallback() will
* be invalidated. It is treated as being HOLDOFF_TTL seconds in the future
* by those methods to avoid race conditions where dependent keys get updated
- * with stale values (e.g. from a DB slave).
+ * with stale values (e.g. from a DB replica DB).
*
* This is typically useful for keys with hardcoded names or in some cases
* dynamically generated names where a low number of combinations exist.
* $cache::TTL_MINUTE,
* // Function that derives the new key value
* function ( $oldValue, &$ttl, array &$setOpts ) {
- * $dbr = wfGetDB( DB_SLAVE );
- * // Account for any snapshot/slave lag
+ * $dbr = wfGetDB( DB_REPLICA );
+ * // Account for any snapshot/replica DB lag
* $setOpts += Database::getCacheSetOptions( $dbr );
*
* return $dbr->selectRow( ... );
* $cache::TTL_DAY,
* // Function that derives the new key value
* function ( $oldValue, &$ttl, array &$setOpts ) {
- * $dbr = wfGetDB( DB_SLAVE );
- * // Account for any snapshot/slave lag
+ * $dbr = wfGetDB( DB_REPLICA );
+ * // Account for any snapshot/replica DB lag
* $setOpts += Database::getCacheSetOptions( $dbr );
*
* return CatConfig::newFromRow( $dbr->selectRow( ... ) );
* // Function that derives the new key value
* function ( $oldValue, &$ttl, array &$setOpts ) {
* // Determine new value from the DB
- * $dbr = wfGetDB( DB_SLAVE );
- * // Account for any snapshot/slave lag
+ * $dbr = wfGetDB( DB_REPLICA );
+ * // Account for any snapshot/replica DB lag
* $setOpts += Database::getCacheSetOptions( $dbr );
*
* return CatState::newFromResults( $dbr->select( ... ) );
* 10,
* // Function that derives the new key value
* function ( $oldValue, &$ttl, array &$setOpts ) {
- * $dbr = wfGetDB( DB_SLAVE );
- * // Account for any snapshot/slave lag
+ * $dbr = wfGetDB( DB_REPLICA );
+ * // Account for any snapshot/replica DB lag
* $setOpts += Database::getCacheSetOptions( $dbr );
*
* // Start off with the last cached list
* - pcTTL: Process cache the value in this PHP instance for this many seconds. This avoids
* network I/O when a key is read several times. This will not cache when the callback
* returns false, however. Note that any purges will not be seen while process cached;
- * since the callback should use slave DBs and they may be lagged or have snapshot
+ * since the callback should use replica DBs and they may be lagged or have snapshot
* isolation anyway, this should not typically matter.
* Default: WANObjectCache::TTL_UNCACHEABLE.
* - version: Integer version number. This allows for callers to make breaking changes to
$this->getDateCond( $year, $month );
$this->mTagFilter = $tagFilter;
- $this->mDb = wfGetDB( DB_SLAVE, 'logpager' );
+ $this->mDb = wfGetDB( DB_REPLICA, 'logpager' );
}
public function getDefaultQuery() {
* Purpose: Ephemeral global storage.
* Stored centrally within the primary data-center.
* Changes are applied there first and replicated to other DCs (best-effort).
- * To retrieve the latest value (e.g. not from a slave), use BagOStuff::READ_LATEST.
+ * To retrieve the latest value (e.g. not from a replica DB), use BagOStuff::READ_LATEST.
* This store may be subject to LRU style evictions.
*
* - ObjectCache::getInstance( $cacheType )
try {
if ( $this->getMasterLinkStatus( $conn ) === 'down' ) {
// If the master cannot be reached, fail-over to the next server.
- // If masters are in data-center A, and slaves in data-center B,
+ // If masters are in data-center A, and replica DBs in data-center B,
// this helps avoid the case were fail-over happens in A but not
// to the corresponding server in B (e.g. read/write mismatch).
continue;
}
/**
- * Check the master link status of a Redis server that is configured as a slave.
+ * Check the master link status of a Redis server that is configured as a replica DB.
* @param RedisConnRef $conn
* @return string|null Master link status (either 'up' or 'down'), or null
- * if the server is not a slave.
+ * if the server is not a replica DB.
*/
protected function getMasterLinkStatus( RedisConnRef $conn ) {
$info = $conn->info();
/** @var string */
protected $tableName = 'objectcache';
/** @var bool */
- protected $slaveOnly = false;
+ protected $replicaOnly = false;
/** @var int */
protected $syncTimeout = 3;
* required to hold the largest shard index. Data will be
* distributed across all tables by key hash. This is for
* MySQL bugs 61735 and 61736.
- * - slaveOnly: Whether to only use slave DBs and avoid triggering
+ * - slaveOnly: Whether to only use replica DBs and avoid triggering
* garbage collection logic of expired items. This only
* makes sense if the primary DB is used and only if get()
* calls will be used. This is used by ReplicatedBagOStuff.
- * - syncTimeout: Max seconds to wait for slaves to catch up for WRITE_SYNC.
+ * - syncTimeout: Max seconds to wait for replica DBs to catch up for WRITE_SYNC.
*
* @param array $params
*/
if ( isset( $params['syncTimeout'] ) ) {
$this->syncTimeout = $params['syncTimeout'];
}
- $this->slaveOnly = !empty( $params['slaveOnly'] );
+ $this->replicaOnly = !empty( $params['slaveOnly'] );
}
protected function getSeparateMainLB() {
$db = DatabaseBase::factory( $type, $info );
$db->clearFlag( DBO_TRX );
} else {
- $index = $this->slaveOnly ? DB_SLAVE : DB_MASTER;
+ $index = $this->replicaOnly ? DB_REPLICA : DB_MASTER;
if ( $this->getSeparateMainLB() ) {
$db = $this->getSeparateMainLB()->getConnection( $index );
$db->clearFlag( DBO_TRX ); // auto-commit mode
}
protected function garbageCollect() {
- if ( !$this->purgePeriod || $this->slaveOnly ) {
+ if ( !$this->purgePeriod || $this->replicaOnly ) {
// Disabled
return;
}
?: MediaWikiServices::getInstance()->getDBLoadBalancer();
if ( $lb->getServerCount() <= 1 ) {
- return true; // no slaves
+ return true; // no replica DBs
}
- // Main LB is used; wait for any slaves to catch up
+ // Main LB is used; wait for any replica DBs to catch up
$masterPos = $lb->getMasterPos();
$loop = new WaitConditionLoop(
return false;
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$oldestRevisionTimestamp = $dbr->selectField(
'revision',
'MIN( rev_timestamp )',
if ( !$rc ) {
// Don't cache: This can be hit if the page gets accessed very fast after
- // its creation / latest upload or in case we have high slave lag. In case
+ // its creation / latest upload or in case we have high replica DB lag. In case
// the revision is too old, we will already return above.
return false;
}
// This, as a side-effect, also makes sure that the following query isn't being run for
// pages with a larger history, unless the user has the 'bigdelete' right
// (and is about to delete this page).
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$revisions = $edits = (int)$dbr->selectField(
'revision',
'COUNT(rev_page)',
* @return ResultWrapper
*/
protected function queryImageLinks( $target, $limit ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
return $dbr->select(
[ 'imagelinks', 'page' ],
*
* @param int $id Article ID to load
* @param string|int $from One of the following values:
- * - "fromdb" or WikiPage::READ_NORMAL to select from a slave database
+ * - "fromdb" or WikiPage::READ_NORMAL to select from a replica DB
* - "fromdbmaster" or WikiPage::READ_LATEST to select from the master database
*
* @return WikiPage|null
}
$from = self::convertSelectType( $from );
- $db = wfGetDB( $from === self::READ_LATEST ? DB_MASTER : DB_SLAVE );
+ $db = wfGetDB( $from === self::READ_LATEST ? DB_MASTER : DB_REPLICA );
$row = $db->selectRow(
'page', self::selectFields(), [ 'page_id' => $id ], __METHOD__ );
if ( !$row ) {
* @since 1.20
* @param object $row Database row containing at least fields returned by selectFields().
* @param string|int $from Source of $data:
- * - "fromdb" or WikiPage::READ_NORMAL: from a slave DB
+ * - "fromdb" or WikiPage::READ_NORMAL: from a replica DB
* - "fromdbmaster" or WikiPage::READ_LATEST: from the master DB
* - "forupdate" or WikiPage::READ_LOCKING: from the master DB using SELECT FOR UPDATE
* @return WikiPage
*
* @param object|string|int $from One of the following:
* - A DB query result object.
- * - "fromdb" or WikiPage::READ_NORMAL to get from a slave DB.
+ * - "fromdb" or WikiPage::READ_NORMAL to get from a replica DB.
* - "fromdbmaster" or WikiPage::READ_LATEST to get from the master DB.
* - "forupdate" or WikiPage::READ_LOCKING to get from the master DB
* using SELECT FOR UPDATE.
$data = $this->pageDataFromTitle( wfGetDB( $index ), $this->mTitle, $opts );
if ( !$data
- && $index == DB_SLAVE
+ && $index == DB_REPLICA
&& wfGetLB()->getServerCount() > 1
&& wfGetLB()->hasOrMadeRecentMasterChanges()
) {
$data = $this->pageDataFromTitle( wfGetDB( $index ), $this->mTitle, $opts );
}
} else {
- // No idea from where the caller got this data, assume slave database.
+ // No idea from where the caller got this data, assume replica DB.
$data = $from;
$from = self::READ_NORMAL;
}
* @since 1.20
* @param object|bool $data DB row containing fields returned by selectFields() or false
* @param string|int $from One of the following:
- * - "fromdb" or WikiPage::READ_NORMAL if the data comes from a slave DB
+ * - "fromdb" or WikiPage::READ_NORMAL if the data comes from a replica DB
* - "fromdbmaster" or WikiPage::READ_LATEST if the data comes from the master DB
* - "forupdate" or WikiPage::READ_LOCKING if the data comes from
* the master DB using SELECT FOR UPDATE
*/
public function getOldestRevision() {
- // Try using the slave database first, then try the master
+ // Try using the replica DB first, then try the master
$continue = 2;
- $db = wfGetDB( DB_SLAVE );
+ $db = wfGetDB( DB_REPLICA );
$revSelectFields = Revision::selectFields();
$row = null;
$flags = Revision::READ_LOCKING;
} elseif ( $this->mDataLoadedFrom == self::READ_LATEST ) {
// Bug T93976: if page_latest was loaded from the master, fetch the
- // revision from there as well, as it may not exist yet on a slave DB.
+ // revision from there as well, as it may not exist yet on a replica DB.
// Also, this keeps the queries in the same REPEATABLE-READ snapshot.
$flags = Revision::READ_LATEST;
} else {
// links.
$hasLinks = (bool)count( $editInfo->output->getLinks() );
} else {
- $hasLinks = (bool)wfGetDB( DB_SLAVE )->selectField( 'pagelinks', 1,
+ $hasLinks = (bool)wfGetDB( DB_REPLICA )->selectField( 'pagelinks', 1,
[ 'pl_from' => $this->getId() ], __METHOD__ );
}
}
}
// Query the redirect table
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$row = $dbr->selectRow( 'redirect',
[ 'rd_namespace', 'rd_title', 'rd_fragment', 'rd_interwiki' ],
[ 'rd_from' => $this->getId() ],
public function getContributors() {
// @todo FIXME: This is expensive; cache this info somewhere.
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
if ( $dbr->implicitGroupby() ) {
$realNameField = 'user_real_name';
$baseRevId = null;
if ( $edittime && $sectionId !== 'new' ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$rev = Revision::loadFromTimestamp( $dbr, $this->mTitle, $edittime );
// Try the master if this thread may have just added it.
// This could be abstracted into a Revision method, but we don't want
// We get here if vary-revision is set. This means that this page references
// itself (such as via self-transclusion). In this case, we need to make sure
// that any such self-references refer to the newly-saved revision, and not
- // to the previous one, which could otherwise happen due to slave lag.
+ // to the previous one, which could otherwise happen due to replica DB lag.
$oldCallback = $edit->popts->getCurrentRevisionCallback();
$edit->popts->setCurrentRevisionCallback(
function ( Title $title, $parser = false ) use ( $revision, &$oldCallback ) {
if ( $title->getNamespace() == NS_CATEGORY ) {
// Load the Category object, which will schedule a job to create
- // the category table row if necessary. Checking a slave is ok
+ // the category table row if necessary. Checking a replica DB is ok
// here, in the worst case it'll run an unnecessary recount job on
// a category that probably doesn't have many members.
Category::newFromTitle( $title )->getID();
return TitleArray::newFromResult( new FakeResultWrapper( [] ) );
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->select( 'categorylinks',
[ 'cl_to AS page_title, ' . NS_CATEGORY . ' AS page_namespace' ],
// Have to do that since DatabaseBase::fieldNamesWithAlias treats numeric indexes
return [];
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->select( [ 'categorylinks', 'page_props', 'page' ],
[ 'cl_to' ],
[ 'cl_from' => $id, 'pp_page=page_id', 'pp_propname' => 'hiddencat',
}
$this->mIsBackwards = ( $this->mRequest->getVal( 'dir' ) == 'prev' );
- # Let the subclass set the DB here; otherwise use a slave DB for the current wiki
- $this->mDb = $this->mDb ?: wfGetDB( DB_SLAVE );
+ # Let the subclass set the DB here; otherwise use a replica DB for the current wiki
+ $this->mDb = $this->mDb ?: wfGetDB( DB_REPLICA );
$index = $this->getIndexField(); // column to sort on
$extraSort = $this->getExtraSortFields(); // extra columns to sort on for query planning
$output = $this->parent->getOutput();
$linkRenderer = $this->parent->getLinkRenderer();
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
# Sort by namespace
ksort( $this->internals );
if ( !$linkBatch->isEmpty() ) {
// construct query
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$fields = array_merge(
LinkCache::getSelectFields(),
[ 'page_namespace', 'page_title' ]
$pageId = $title->getArticleID();
$revId = $title->getLatestRevID();
- $rev = Revision::newKnownCurrent( wfGetDB( DB_SLAVE ), $pageId, $revId );
+ $rev = Revision::newKnownCurrent( wfGetDB( DB_REPLICA ), $pageId, $revId );
if ( $rev ) {
$rev->setTitle( $title );
}
*/
public function fetchScaryTemplateMaybeFromCache( $url ) {
global $wgTranscludeCacheExpiry;
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$tsCond = $dbr->timestamp( time() - $wgTranscludeCacheExpiry );
$obj = $dbr->selectRow( 'transcache', [ 'tc_time', 'tc_contents' ],
[ 'tc_url' => $url, "tc_time >= " . $dbr->addQuotes( $tsCond ) ] );
// Or else Database*::select() will explode, plus it's cheaper!
return;
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$skin = $context->getSkin();
$lang = $context->getLanguage();
$good = $fileCache->isCacheGood( wfTimestamp( TS_MW, time() - $maxage ) );
if ( !$good ) {
try { // RL always hits the DB on file cache miss...
- wfGetDB( DB_SLAVE );
+ wfGetDB( DB_REPLICA );
} catch ( DBConnectionError $e ) { // ...check if we need to fallback to cache
$good = $fileCache->isCacheGood(); // cache existence check
}
// Try in-object cache first
if ( !isset( $this->fileDeps[$vary] ) ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$deps = $dbr->selectField( 'module_deps',
'md_deps',
[
/**
* Get the Database object used in getTitleInfo().
*
- * Defaults to the local slave DB. Subclasses may want to override this to return a foreign
+ * Defaults to the local replica DB. Subclasses may want to override this to return a foreign
* database object, or null if getTitleInfo() shouldn't access the database.
*
* NOTE: This ONLY works for getTitleInfo() and isKnownEmpty(), NOT FOR ANYTHING ELSE.
* @return IDatabase|null
*/
protected function getDB() {
- return wfGetDB( DB_SLAVE );
+ return wfGetDB( DB_REPLICA );
}
/**
}
public static function suggestTarget( $target, array $ids ) {
- $result = wfGetDB( DB_SLAVE )->select( 'logging',
+ $result = wfGetDB( DB_REPLICA )->select( 'logging',
'log_type',
[ 'log_id' => $ids ],
__METHOD__,
* @return bool|mixed
*/
public static function checkRevisionExistence( $title, $revid ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$exists = $dbr->selectField( 'revision', '1',
[ 'rev_id' => $revid ], __METHOD__ );
if ( $db ) {
$this->db = $db;
} else {
- $this->db = wfGetDB( DB_SLAVE );
+ $this->db = wfGetDB( DB_REPLICA );
}
}
} elseif ( $configType !== null ) {
$class = $configType;
} else {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$class = $dbr->getSearchEngine();
}
if ( is_null( self::$mMinSearchLength ) ) {
$sql = "SHOW GLOBAL VARIABLES LIKE 'ft\\_min\\_word\\_len'";
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$result = $dbr->query( $sql, __METHOD__ );
$row = $result->fetchObject();
$result->free();
protected function loadSites() {
$this->sites = new SiteList();
- $dbr = $this->dbLoadBalancer->getConnection( DB_SLAVE );
+ $dbr = $this->dbLoadBalancer->getConnection( DB_REPLICA );
$res = $dbr->select(
'sites',
* @return IDatabase
*/
protected function getDB() {
- return wfGetDB( DB_SLAVE );
+ return wfGetDB( DB_REPLICA );
}
/**
* @return IDatabase
*/
function getRecacheDB() {
- return wfGetDB( DB_SLAVE, [ $this->getName(), 'QueryPage::recache', 'vslow' ] );
+ return wfGetDB( DB_REPLICA, [ $this->getName(), 'QueryPage::recache', 'vslow' ] );
}
/**
* @since 1.18
*/
public function fetchFromCache( $limit, $offset = false ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$options = [];
if ( $limit !== false ) {
$options['LIMIT'] = intval( $limit );
public function getCachedTimestamp() {
if ( is_null( $this->cachedTimestamp ) ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$fname = get_class( $this ) . '::getCachedTimestamp';
$this->cachedTimestamp = $dbr->selectField( 'querycache_info', 'qci_timestamp',
[ 'qci_type' => $this->getName() ], $fname );
// Mention the level of cache staleness...
$cacheText = '';
- $dbr = wfGetDB( DB_SLAVE, 'recentchanges' );
+ $dbr = wfGetDB( DB_REPLICA, 'recentchanges' );
$rcMax = $dbr->selectField( 'recentchanges', 'MAX(rc_timestamp)', '', __METHOD__ );
if ( $rcMax ) {
$cTime = $dbr->selectField( 'querycache_info',
list( $namespace, $fromKey, $from ) = $fromList;
list( , $toKey, $to ) = $toList;
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$filterConds = [ 'page_namespace' => $namespace ];
if ( $hideredirects ) {
$filterConds['page_is_redirect'] = 0;
case Block::TYPE_IP:
case Block::TYPE_RANGE:
list( $start, $end ) = IP::parseRange( $target );
- $conds[] = wfGetDB( DB_SLAVE )->makeList(
+ $conds[] = wfGetDB( DB_REPLICA )->makeList(
[
'ipb_address' => $target,
Block::getRangeCond( $start, $end )
} else {
$linkRenderer = $this->getLinkRenderer();
- $dbr = BotPassword::getDB( DB_SLAVE );
+ $dbr = BotPassword::getDB( DB_REPLICA );
$res = $dbr->select(
'bot_passwords',
[ 'bp_app_id' ],
}
public function getQueryInfo() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
return [
'tables' => [
if ( !$pager->getNumRows() ) {
$out->addWikiMsg( 'nocontribs', $target );
} else {
- # Show a message about slave lag, if applicable
+ # Show a message about replica DB lag, if applicable
$lag = wfGetLB()->safeGetLag( $pager->getDatabase() );
if ( $lag > 0 ) {
$out->showLagWarning( $lag );
return;
}
- # Show a message about slave lag, if applicable
+ # Show a message about replica DB lag, if applicable
$lag = wfGetLB()->safeGetLag( $pager->getDatabase() );
if ( $lag > 0 ) {
$out->showLagWarning( $lag );
function reallyGetQueryInfo( $namespace = null, $title = null ) {
$limitToTitle = !( $namespace === null && $title === null );
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$retval = [
'tables' => [
'ra' => 'redirect',
// get a little more detail about each individual entry quickly
// using the filter of reallyGetQueryInfo.
if ( $result && !isset( $result->nsb ) ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$qi = $this->reallyGetQueryInfo(
$result->namespace,
$result->title
/* Ok, let's get to it... */
if ( $history == WikiExporter::CURRENT ) {
$lb = false;
- $db = wfGetDB( DB_SLAVE );
+ $db = wfGetDB( DB_REPLICA );
$buffer = WikiExporter::BUFFER;
} else {
// Use an unbuffered query; histories may be very long!
$lb = wfGetLBFactory()->newMainLB();
- $db = $lb->getConnection( DB_SLAVE );
+ $db = $lb->getConnection( DB_REPLICA );
$buffer = WikiExporter::STREAM;
// This might take a while... :D
$name = $title->getDBkey();
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->select(
[ 'page', 'categorylinks' ],
[ 'page_namespace', 'page_title' ],
$maxPages = $this->getConfig()->get( 'ExportPagelistLimit' );
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->select(
'page',
[ 'page_namespace', 'page_title' ],
* @return array
*/
private function getLinks( $inputPages, $pageSet, $table, $fields, $join ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
foreach ( $inputPages as $page ) {
$title = Title::newFromText( $page );
*/
static function mungeQuery( $query, $prot ) {
$field = 'el_index';
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
if ( $query === '*' && $prot !== '' ) {
// Allow queries like 'ftp://*' to find all ftp links
}
public function getQueryInfo() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
// strip everything past first wildcard, so that
// index-based-only lookup would be done
list( $this->mungedQuery, $clause ) = self::mungeQuery( $this->mQuery, $this->mProt );
* Special:BrokenRedirects also rely on this.
*/
public function getQueryInfo() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$fakeTitle = $dbr->buildConcat( [
'img_media_type',
$dbr->addQuotes( ';' ),
( $oldTalk->exists()
|| ( $oldTitleTalkSubpages && $canMoveSubpage ) );
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
if ( $this->getConfig()->get( 'FixDoubleRedirects' ) ) {
$hasRedirects = $dbr->selectField( 'redirect', '1',
[
$opts['OFFSET'] = $offset;
}
- $res = wfGetDB( DB_SLAVE )->select(
+ $res = wfGetDB( DB_REPLICA )->select(
'page_props',
'pp_propname',
'',
# ## @todo FIXME: Should complain if $fromNs != $namespace
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$conds = [
'page_namespace' => $namespace,
]
];
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$minClTime = $this->getTimestampOffset( $rand );
if ( $minClTime ) {
$qi['conds'][] = 'cl_timestamp ' . $op . ' ' .
* @throws MWException If category has no entries.
*/
protected function getMinAndMaxForCat( Title $category ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->selectRow(
'categorylinks',
[
* @return array Info for the title selected.
*/
private function selectRandomPageFromDB( $rand, $offset, $up, $fname = __METHOD__ ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$query = $this->getQueryInfo( $rand, $offset, $up );
$res = $dbr->select(
}
private function selectRandomPageFromDB( $randstr, $fname = __METHOD__ ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$query = $this->getQueryInfo( $randstr );
$res = $dbr->select(
public function __construct() {
parent::__construct( 'Randomrootpage' );
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$this->extra[] = 'page_title NOT ' . $dbr->buildLike( $dbr->anyString(), '/', $dbr->anyString() );
}
}
protected function getDB() {
- return wfGetDB( DB_SLAVE, 'recentchanges' );
+ return wfGetDB( DB_REPLICA, 'recentchanges' );
}
public function outputFeedLinks() {
* expects only one result set so we use UNION instead.
*/
- $dbr = wfGetDB( DB_SLAVE, 'recentchangeslinked' );
+ $dbr = wfGetDB( DB_REPLICA, 'recentchangeslinked' );
$id = $title->getArticleID();
$ns = $title->getNamespace();
$dbkey = $title->getDBkey();
'log_user_text',
];
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
// Gets the nested SQL statement which
// returns timestamp of the log with the given log ID
// continuing with this, as the user is just going to end up getting sent
// somewhere else. Additionally, if we keep going here, we end up
// populating the memcache of tag data (see ChangeTags::listDefinedTags)
- // with out-of-date data from the slave, because the slave hasn't caught
+ // with out-of-date data from the replica DB, because the replica DB hasn't caught
// up to the fact that a new tag has been created as part of an implicit,
// as yet uncommitted transaction on master.
if ( $out->getRedirect() !== '' ) {
* @return ResultWrapper
*/
public static function listAllPages() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
return self::listPages( $dbr, '' );
}
* @return ResultWrapper
*/
public static function listPagesByPrefix( $prefix ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$title = Title::newFromText( $prefix );
if ( $title ) {
* @return ResultWrapper
*/
function listRevisions() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$tables = [ 'archive' ];
return null;
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
return $dbr->select(
'filearchive',
ArchivedFile::selectFields(),
* @return Revision|null
*/
function getRevision( $timestamp ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$fields = [
'ar_rev_id',
* @return Revision|null Null when there is no previous revision
*/
function getPreviousRevision( $timestamp ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
// Check the previous deleted revision...
$row = $dbr->selectRow( 'archive',
}
// New-style: keyed to the text storage backend.
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$text = $dbr->selectRow( 'text',
[ 'old_text', 'old_flags' ],
[ 'old_id' => $row->ar_text_id ],
* @return string|null
*/
function getLastRevisionText() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$row = $dbr->selectRow( 'archive',
[ 'ar_text', 'ar_flags', 'ar_text_id' ],
[ 'ar_namespace' => $this->title->getNamespace(),
* @return bool
*/
function isDeleted() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$n = $dbr->selectField( 'archive', 'COUNT(ar_title)',
[ 'ar_namespace' => $this->title->getNamespace(),
'ar_title' => $this->title->getDBkey() ],
$minor = $rev->isMinor() ? ChangesList::flag( 'minor' ) : '';
- $tags = wfGetDB( DB_SLAVE )->selectField(
+ $tags = wfGetDB( DB_REPLICA )->selectField(
'tag_summary',
'ts_tags',
[ 'ts_rev_id' => $rev->getId() ],
* @return string
*/
public static function softwareInformation() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
// Put the software in an array of form 'name' => 'version'. All messages should
// be loaded here, so feel free to use wfMessage in the 'name'. Raw HTML or
* @return IDatabase
*/
protected function getDB() {
- return wfGetDB( DB_SLAVE, 'watchlist' );
+ return wfGetDB( DB_REPLICA, 'watchlist' );
}
/**
$user = $this->getUser();
$output = $this->getOutput();
- # Show a message about slave lag, if applicable
+ # Show a message about replica DB lag, if applicable
$lag = wfGetLB()->safeGetLag( $dbr );
if ( $lag > 0 ) {
$output->showLagWarning( $lag );
*/
function showIndirectLinks( $level, $target, $limit, $from = 0, $back = 0 ) {
$out = $this->getOutput();
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$hidelinks = $this->opts->getValue( 'hidelinks' );
$hideredirs = $this->opts->getValue( 'hideredirs' );
'join_conds' => [ 'langlinks' => [ 'LEFT JOIN', 'll_from = page_id' ] ]
];
if ( $this->prefix ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$query['conds'][] = 'page_title ' . $dbr->buildLike( $this->prefix, $dbr->anyString() );
}
public static function getCustomisedStatuses( $messageNames, $langcode = 'en', $foreign = false ) {
// FIXME: This function should be moved to Language:: or something.
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->select( 'page',
[ 'page_namespace', 'page_title' ],
[ 'page_namespace' => [ NS_MEDIAWIKI, NS_MEDIAWIKI_TALK ] ],
$month = isset( $options['month'] ) ? $options['month'] : false;
$this->getDateCond( $year, $month );
- // Most of this code will use the 'contributions' group DB, which can map to slaves
+ // Most of this code will use the 'contributions' group DB, which can map to replica DBs
// with extra user based indexes or partioning by user. The additional metadata
- // queries should use a regular slave since the lookup pattern is not all by user.
- $this->mDbSecondary = wfGetDB( DB_SLAVE ); // any random slave
- $this->mDb = wfGetDB( DB_SLAVE, 'contributions' );
+ // queries should use a regular replica DB since the lookup pattern is not all by user.
+ $this->mDbSecondary = wfGetDB( DB_SLAVE ); // any random replica DB
+ $this->mDb = wfGetDB( DB_REPLICA, 'contributions' );
}
function getDefaultQuery() {
}
$this->target = $target;
$this->namespace = $namespace;
- $this->mDb = wfGetDB( DB_SLAVE, 'contributions' );
+ $this->mDb = wfGetDB( DB_REPLICA, 'contributions' );
}
function getDefaultQuery() {
$nt = Title::newFromText( $this->mSearch );
if ( $nt ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$this->mQueryConds[] = 'LOWER(img_name)' .
$dbr->buildLike( $dbr->anyString(),
strtolower( $nt->getDBkey() ), $dbr->anyString() );
if ( $this->mSearch !== '' ) {
$nt = Title::newFromText( $this->mSearch );
if ( $nt ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$conds[] = 'LOWER(' . $prefix . '_name)' .
$dbr->buildLike( $dbr->anyString(),
strtolower( $nt->getDBkey() ), $dbr->anyString() );
}
unset( $field );
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
if ( $dbr->implicitGroupby() ) {
$options = [ 'GROUP BY' => 'img_name' ];
} else {
$this->title = $source;
$this->articleID = $source->getArticleID();
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$maxtimestamp = $dbr->selectField(
'revision',
'MIN(rev_timestamp)',
$likeVal = $opts->getValue( 'like' );
if ( !$this->getConfig()->get( 'MiserMode' ) && $likeVal !== '' ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$likeObj = Title::newFromText( $likeVal );
if ( $likeObj instanceof Title ) {
$like = $dbr->buildLike(
* @return array
*/
function getQueryInfo() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$conds = [];
// Don't show hidden names
}
// Lookup groups for all the users
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$groupRes = $dbr->select(
'user_groups',
[ 'ug_user', 'ug_group' ],
* Helper function: do the actual database query to fetch file metadata.
*
* @param string $key
- * @param int $readFromDB Constant (default: DB_SLAVE)
+ * @param int $readFromDB Constant (default: DB_REPLICA)
* @return bool
*/
- protected function fetchFileMetadata( $key, $readFromDB = DB_SLAVE ) {
+ protected function fetchFileMetadata( $key, $readFromDB = DB_REPLICA ) {
// populate $fileMetadata[$key]
$dbr = null;
if ( $readFromDB === DB_MASTER ) {
/**
* Get a database connection for the bot passwords database
- * @param int $db Index of the connection to get, e.g. DB_MASTER or DB_SLAVE.
+ * @param int $db Index of the connection to get, e.g. DB_MASTER or DB_REPLICA.
* @return DatabaseBase
*/
public static function getDB( $db ) {
}
$audience = $this->checkAudience( $audience );
- $db = wfGetDB( ( $flags & self::READ_LATEST ) ? DB_MASTER : DB_SLAVE );
+ $db = wfGetDB( ( $flags & self::READ_LATEST ) ? DB_MASTER : DB_REPLICA );
$options = ( ( $flags & self::READ_LOCKING ) == self::READ_LOCKING )
? [ 'LOCK IN SHARE MODE' ]
: [];
}
$audience = $this->checkAudience( $audience );
- $db = wfGetDB( ( $flags & self::READ_LATEST ) ? DB_MASTER : DB_SLAVE );
+ $db = wfGetDB( ( $flags & self::READ_LATEST ) ? DB_MASTER : DB_REPLICA );
$options = ( ( $flags & self::READ_LOCKING ) == self::READ_LOCKING )
? [ 'LOCK IN SHARE MODE' ]
: [];
* @throws MWException On unexpected database errors
*/
protected function getUsersByEmail( $email ) {
- $res = wfGetDB( DB_SLAVE )->select(
+ $res = wfGetDB( DB_REPLICA )->select(
'user',
User::selectFields(),
[ 'user_email' => $email ],
$this->getCacheKey( $cache ),
$cache::TTL_HOUR,
function ( $oldValue, &$ttl, array &$setOpts ) use ( $cache ) {
- $setOpts += Database::getCacheSetOptions( wfGetDB( DB_SLAVE ) );
+ $setOpts += Database::getCacheSetOptions( wfGetDB( DB_REPLICA ) );
wfDebug( "User: cache miss for user {$this->mId}\n" );
$this->loadFromDatabase( self::READ_NORMAL );
public static function newFromConfirmationCode( $code, $flags = 0 ) {
$db = ( $flags & self::READ_LATEST ) == self::READ_LATEST
? wfGetDB( DB_MASTER )
- : wfGetDB( DB_SLAVE );
+ : wfGetDB( DB_REPLICA );
$id = $db->selectField(
'user',
$conds[] = 'ug_user > ' . (int)$after;
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$ids = $dbr->selectFieldValues(
'user_groups',
'ug_user',
if ( is_null( $this->mGroups ) ) {
$db = ( $this->queryFlagsUsed & self::READ_LATEST )
? wfGetDB( DB_MASTER )
- : wfGetDB( DB_SLAVE );
+ : wfGetDB( DB_REPLICA );
$res = $db->select( 'user_groups',
[ 'ug_group' ],
[ 'ug_user' => $this->mId ],
/**
* Get blocking information
- * @param bool $bFromSlave Whether to check the slave database first.
- * To improve performance, non-critical checks are done against slaves.
+ * @param bool $bFromSlave Whether to check the replica DB first.
+ * To improve performance, non-critical checks are done against replica DBs.
* Check when actually saving should be done against master.
*/
private function getBlockedStatus( $bFromSlave = true ) {
/**
* Check if user is blocked
*
- * @param bool $bFromSlave Whether to check the slave database instead of
+ * @param bool $bFromSlave Whether to check the replica DB instead of
* the master. Hacked from false due to horrible probs on site.
* @return bool True if blocked, false otherwise
*/
/**
* Get the block affecting the user, or null if the user is not blocked
*
- * @param bool $bFromSlave Whether to check the slave database instead of the master
+ * @param bool $bFromSlave Whether to check the replica DB instead of the master
* @return Block|null
*/
public function getBlock( $bFromSlave = true ) {
* Check if user is blocked from editing a particular article
*
* @param Title $title Title to check
- * @param bool $bFromSlave Whether to check the slave database instead of the master
+ * @param bool $bFromSlave Whether to check the replica DB instead of the master
* @return bool
*/
public function isBlockedFrom( $title, $bFromSlave = false ) {
return [];
}
$utp = $this->getTalkPage();
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
// Get the "last viewed rev" timestamp from the oldest message notification
$timestamp = $dbr->selectField( 'user_newtalk',
'MIN(user_last_timestamp)',
* @return bool True if the user has new messages
*/
protected function checkNewtalk( $field, $id ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$ok = $dbr->selectField( 'user_newtalk', $field, [ $field => $id ], __METHOD__ );
if ( is_null( $this->mFormerGroups ) ) {
$db = ( $this->queryFlagsUsed & self::READ_LATEST )
? wfGetDB( DB_MASTER )
- : wfGetDB( DB_SLAVE );
+ : wfGetDB( DB_REPLICA );
$res = $db->select( 'user_former_groups',
[ 'ufg_group' ],
[ 'ufg_user' => $this->mId ],
if ( $this->mEditCount === null ) {
/* Populate the count, if it has not been populated yet */
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
// check if the user_editcount field has been initialized
$count = $dbr->selectField(
'user', 'user_editcount',
// Only update the timestamp if the page is being watched.
// The query to find out if it is watched is cached both in memcached and per-invocation,
- // and when it does have to be executed, it can be on a slave
+ // and when it does have to be executed, it can be on a replica DB
// If this is the user's newtalk page, we always update the timestamp
$force = '';
if ( $title->getNamespace() == NS_USER_TALK && $title->getText() == $this->getName() ) {
// Get a new user_touched that is higher than the old one.
// This will be used for a CAS check as a last-resort safety
- // check against race conditions and slave lag.
+ // check against race conditions and replica DB lag.
$newTouched = $this->newTouchedTimestamp();
$dbw = wfGetDB( DB_MASTER );
// Maybe the problem was a missed cache update; clear it to be safe
$this->clearSharedCache( 'refresh' );
// User was changed in the meantime or loaded with stale data
- $from = ( $this->queryFlagsUsed & self::READ_LATEST ) ? 'master' : 'slave';
+ $from = ( $this->queryFlagsUsed & self::READ_LATEST ) ? 'master' : 'replica';
throw new MWException(
"CAS update failed on user_touched for user ID '{$this->mId}' (read from $from);" .
" the version of the user to be saved is older than the current version."
$db = ( ( $flags & self::READ_LATEST ) == self::READ_LATEST )
? wfGetDB( DB_MASTER )
- : wfGetDB( DB_SLAVE );
+ : wfGetDB( DB_REPLICA );
$options = ( ( $flags & self::READ_LOCKING ) == self::READ_LOCKING )
? [ 'LOCK IN SHARE MODE' ]
if ( $this->getId() == 0 ) {
return false; // anons
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$time = $dbr->selectField( 'revision', 'rev_timestamp',
[ 'rev_user' => $this->getId() ],
__METHOD__,
// Lazy initialization check...
if ( $dbw->affectedRows() == 0 ) {
// Now here's a goddamn hack...
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
if ( $dbr !== $dbw ) {
- // If we actually have a slave server, the count is
+ // If we actually have a replica DB server, the count is
// at least one behind because the current transaction
// has not been committed and replicated.
$this->mEditCount = $this->initEditCount( 1 );
} else {
- // But if DB_SLAVE is selecting the master, then the
+ // But if DB_REPLICA is selecting the master, then the
// count we just read includes the revision that was
// just added in the working transaction.
$this->mEditCount = $this->initEditCount();
} else {
if ( $this->mEditCount === null ) {
$this->getEditCount();
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$this->mEditCount += ( $dbr !== $dbw ) ? 1 : 0;
} else {
$this->mEditCount++;
* @return int Number of edits
*/
protected function initEditCount( $add = 0 ) {
- // Pull from a slave to be less cruel to servers
+ // Pull from a replica DB to be less cruel to servers
// Accuracy isn't the point anyway here
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$count = (int)$dbr->selectField(
'revision',
'COUNT(rev_user)',
// Load from database
$dbr = ( $this->queryFlagsUsed & self::READ_LATEST )
? wfGetDB( DB_MASTER )
- : wfGetDB( DB_SLAVE );
+ : wfGetDB( DB_REPLICA );
$res = $dbr->select(
'user_properties',
* Get a new instance of this user that was loaded from the master via a locking read
*
* Use this instead of the main context User when updating that user. This avoids races
- * where that user was loaded from a slave or even the master but without proper locks.
+ * where that user was loaded from a replica DB or even the master but without proper locks.
*
* @return User|null Returns null if the user was not found in the DB
* @since 1.27
// Database::select() doesn't like empty arrays
return new ArrayIterator( [] );
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->select(
'user',
User::selectFields(),
// Database::select() doesn't like empty arrays
return new ArrayIterator( [] );
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->select(
'user',
User::selectFields(),
public static function search( $audience, $search, $limit, $offset = 0 ) {
$user = User::newFromName( $search );
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$prefix = $user ? $user->getName() : '';
$tables = [ 'user' ];
$cond = [ 'user_name ' . $dbr->buildLike( $prefix, $dbr->anyString() ) ];
* method of batch updating rows in a database. To use create a class
* implementing the RowUpdateGenerator interface and configure the
* BatchRowIterator and BatchRowWriter for access to the correct table.
- * The components will handle reading, writing, and waiting for slaves
+ * The components will handle reading, writing, and waiting for replica DBs
* while the generator implementation handles generating update arrays
* for singular rows.
*
private $mDb = null;
/** @var float UNIX timestamp */
- private $lastSlaveWait = 0.0;
+ private $lastReplicationWait = 0.0;
/**
* Used when creating separate schema files.
* 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
}
/**
- * 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;
+ }
}
/**
$dbr = $this->forcedDb;
if ( $this->forcedDb === null ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
}
$this->maxCount = $dbr->selectField( $table, "MAX($field)", '', __METHOD__ );
$this->startTime = microtime( true );
}
$this->lb = wfGetLBFactory()->newMainLB();
- $db = $this->lb->getConnection( DB_SLAVE, 'dump' );
+ $db = $this->lb->getConnection( DB_REPLICA, 'dump' );
// Discourage the server from disconnecting us if it takes a long time
// to read out the big ol' batch query.
* @return bool|string Revision ID, or false if not found or error
*/
function getRevIdForTime( Title $title, $timestamp ) {
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$id = $dbr->selectField(
[ 'revision', 'page' ],
public function execute() {
$this->output( "Fetching redirects...\n" );
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$result = $dbr->select(
[ 'page' ],
[ 'page_namespace', 'page_title', 'page_latest' ],
public function execute() {
$start = '';
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$numImages = 0;
$numGood = 0;
}
function execute() {
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$maxUserId = 0;
do {
$this->output( "Finding spam on " . count( $wgLocalDatabases ) . " wikis\n" );
$found = false;
foreach ( $wgLocalDatabases as $wikiID ) {
- $dbr = $this->getDB( DB_SLAVE, [], $wikiID );
+ $dbr = $this->getDB( DB_REPLICA, [], $wikiID );
$count = $dbr->selectField( 'externallinks', 'COUNT(*)',
[ 'el_index' . $dbr->buildLike( $like ) ], __METHOD__ );
} else {
// Clean up spam on this wiki
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$res = $dbr->select( 'externallinks', [ 'DISTINCT el_from' ],
[ 'el_index' . $dbr->buildLike( $like ) ], __METHOD__ );
$count = $dbr->numRows( $res );
* @throws MWException
*/
public function runTable( $params ) {
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
if ( array_diff( array_keys( $params ),
[ 'table', 'conds', 'index', 'callback' ] )
protected function fileExists( $name ) {
// XXX: Doesn't actually check for file existence, just presence of image record.
// This is reasonable, since cleanupImages.php only iterates over the image table.
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$row = $dbr->selectRow( 'image', [ 'img_name' ], [ 'img_name' => $name ], __METHOD__ );
return $row !== false;
public function execute() {
global $wgLocalDatabases, $wgMemc;
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$res = $dbr->select( 'interwiki', [ 'iw_prefix' ], false );
$prefixes = [];
foreach ( $res as $row ) {
public function execute() {
$pages = $this->getOption( 'maxpages' );
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$totalsec = 0.0;
$scanned = 0;
global $wgUser;
$this->output( "Checking existence of old default messages..." );
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$res = $dbr->select( [ 'page', 'revision' ],
[ 'page_namespace', 'page_title' ],
[
}
public function execute() {
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$result = $dbr->select( [ 'pagelinks', 'page' ],
[
'page_id',
// 2. The Connection, through the load balancer.
try {
- $this->db = $this->lb->getConnection( DB_SLAVE, 'dump' );
+ $this->db = $this->lb->getConnection( DB_REPLICA, 'dump' );
} catch ( Exception $e ) {
throw new MWException( __METHOD__
. " rotating DB failed to obtain new database (" . $e->getMessage() . ")" );
* @param bool $shared True to pass shared-dir settings to hash func
*/
function fetchUsed( $shared ) {
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$image = $dbr->tableName( 'image' );
$imagelinks = $dbr->tableName( 'imagelinks' );
* @param bool $shared True to pass shared-dir settings to hash func
*/
function fetchLocal( $shared ) {
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$result = $dbr->select( 'image',
[ 'img_name' ],
'',
* note that the text string itself is *not* followed by newline
*/
public function execute() {
- $db = $this->getDB( DB_SLAVE );
+ $db = $this->getDB( DB_REPLICA );
$stdin = $this->getStdin();
while ( !feof( $stdin ) ) {
$line = fgets( $stdin );
return true;
}
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$namespaces = [
NS_MEDIAWIKI => $dbr->buildLike( $dbr->anyString(), '.json' ),
NS_USER => $dbr->buildLike( $dbr->anyString(), '/', $dbr->anyString(), '.json' ),
$title = null;
}
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
// See also SpecialDoubleRedirects
$tables = [
$this->output( "Could not find registration for #$id NULL\n" );
}
}
- $this->output( "Waiting for slaves..." );
+ $this->output( "Waiting for replica DBs..." );
wfWaitForSlaves();
$this->output( " done.\n" );
} while ( $res->numRows() >= $this->mBatchSize );
public $timestamp;
/**
- * A database slave object
+ * A database replica DB object
*
* @var object
*/
$this->identifier = $this->getOption( 'identifier', wfWikiID() );
$this->compress = $this->getOption( 'compress', 'yes' ) !== 'no';
$this->skipRedirects = $this->getOption( 'skip-redirects', false ) !== false;
- $this->dbr = $this->getDB( DB_SLAVE );
+ $this->dbr = $this->getDB( DB_REPLICA );
$this->generateNamespaces();
$this->timestamp = wfTimestamp( TS_ISO_8601, wfTimestampNow() );
$this->findex = fopen( "{$this->fspath}sitemap-index-{$this->identifier}.xml", 'wb' );
--- /dev/null
+<?php
+/**
+ * Reports the hostname of a replica DB server.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Maintenance
+ */
+
+require_once __DIR__ . '/Maintenance.php';
+
+/**
+ * Maintenance script that reports the hostname of a replica DB server.
+ *
+ * @ingroup Maintenance
+ */
+class GetSlaveServer extends Maintenance {
+ public function __construct() {
+ parent::__construct();
+ $this->addOption( "group", "Query group to check specifically" );
+ $this->addDescription( 'Report the hostname of a replica DB server' );
+ }
+
+ public function execute() {
+ global $wgAllDBsAreLocalhost;
+ if ( $wgAllDBsAreLocalhost ) {
+ $host = 'localhost';
+ } elseif ( $this->hasOption( 'group' ) ) {
+ $db = $this->getDB( DB_REPLICA, $this->getOption( 'group' ) );
+ $host = $db->getServer();
+ } else {
+ $lb = wfGetLB();
+ $i = $lb->getReaderIndex();
+ $host = $lb->getServerName( $i );
+ }
+ $this->output( "$host\n" );
+ }
+}
+
+$maintClass = "GetSlaveServer";
+require_once RUN_MAINTENANCE_IF_MAIN;
<?php
-/**
- * Reports the hostname of a slave server.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Maintenance
- */
-
-require_once __DIR__ . '/Maintenance.php';
-
-/**
- * Maintenance script that reports the hostname of a slave server.
- *
- * @ingroup Maintenance
- */
-class GetSlaveServer extends Maintenance {
- public function __construct() {
- parent::__construct();
- $this->addOption( "group", "Query group to check specifically" );
- $this->addDescription( 'Report the hostname of a slave server' );
- }
-
- public function execute() {
- global $wgAllDBsAreLocalhost;
- if ( $wgAllDBsAreLocalhost ) {
- $host = 'localhost';
- } elseif ( $this->hasOption( 'group' ) ) {
- $db = $this->getDB( DB_SLAVE, $this->getOption( 'group' ) );
- $host = $db->getServer();
- } else {
- $lb = wfGetLB();
- $i = $lb->getReaderIndex();
- $host = $lb->getServerName( $i );
- }
- $this->output( "$host\n" );
- }
-}
-
-$maintClass = "GetSlaveServer";
-require_once RUN_MAINTENANCE_IF_MAIN;
+// B/C alias
+require_once ( __DIR__ . '/getReplicaServer.php' );
if ( $doProtect ) {
# Protect the file
- echo "\nWaiting for slaves...\n";
- // Wait for slaves.
+ echo "\nWaiting for replica DBs...\n";
+ // Wait for replica DBs.
sleep( 2.0 ); # Why this sleep?
wfWaitForSlaves();
parent::__construct();
$this->addOption( 'quick', 'Force the update to be done in a single query' );
$this->addOption( 'background', 'Force replication-friendly mode; may be inefficient but
- avoids locking tables or lagging slaves with large updates;
- calculates counts on a slave if possible.
+ avoids locking tables or lagging replica DBs with large updates;
+ calculates counts on a replica DB if possible.
Background mode will be automatically used if multiple servers are listed
in the load balancer, usually indicating a replication environment.' );
if ( $backgroundMode ) {
$this->output( "Using replication-friendly background mode...\n" );
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$chunkSize = 100;
$lastUser = $dbr->selectField( 'user', 'MAX(user_id)', '', __METHOD__ );
break;
}
- // print status and let slaves catch up
+ // print status and let replica DBs catch up
$this->output( sprintf(
"id %d done (up to %d), %5.3f%% \r", $lastId, $endId, $lastId / $endId * 100 ) );
wfWaitForSlaves();
* @return int
*/
protected function doLenUpdates( $table, $idCol, $prefix, $fields ) {
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$dbw = $this->getDB( DB_MASTER );
$start = $dbw->selectField( $table, "MIN($idCol)", false, __METHOD__ );
$end = $dbw->selectField( $table, "MAX($idCol)", false, __METHOD__ );
}
// Validate the timestamps
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$this->startTimestamp = $dbr->timestamp( $this->getOption( 'starttime' ) );
$this->endTimestamp = $dbr->timestamp( $this->getOption( 'endtime' ) );
*/
protected function purgeFromLogType( $type ) {
$repo = RepoGroup::singleton()->getLocalRepo();
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
foreach ( self::$typeMappings[$type] as $logType => $logActions ) {
$this->verbose( "Scanning for {$logType}/" . implode( ',', $logActions ) . "\n" );
}
}
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$minTime = $dbr->timestamp( $this->getOption( 'starttime' ) );
$maxTime = $dbr->timestamp( $this->getOption( 'endtime' ) );
* @param int|bool $namespace
*/
private function purgeNamespace( $namespace = false ) {
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$startId = 0;
if ( $namespace === false ) {
$conds = [];
$this->output( "Building content page file cache from page {$start}!\n" );
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$overwrite = $this->getOption( 'overwrite', false );
$start = ( $start > 0 )
? $start
$this->init( $count, $table );
$this->output( "Processing $table...\n" );
- $result = $this->getDB( DB_SLAVE )->select( $table, '*', [], __METHOD__ );
+ $result = $this->getDB( DB_REPLICA )->select( $table, '*', [], __METHOD__ );
foreach ( $result as $row ) {
$update = call_user_func( $callback, $row, null );
public function execute() {
// Rebuild the text index
- if ( $this->getDB( DB_SLAVE )->getType() != 'postgres' ) {
+ if ( $this->getDB( DB_REPLICA )->getType() != 'postgres' ) {
$this->output( "** Rebuilding fulltext search index (if you abort "
. "this will break searching; run this script again to fix):\n" );
$rebuildText = $this->runChild( 'RebuildTextIndex', 'rebuildtextindex.php' );
$end = str_replace( ' ', '_', $this->getOption( 'end', '' ) ); // page on img_name
$count = 0;
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
do {
$conds = [ "img_name > {$dbr->addQuotes( $start )}" ];
if ( strlen( $end ) ) {
$end = null, $redirectsOnly = false, $oldRedirectsOnly = false
) {
$reportingInterval = 100;
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
if ( $start === null ) {
$start = 1;
) {
wfWaitForSlaves();
$this->output( "Deleting illegal entries from the links tables...\n" );
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
do {
// Find the start of the next chunk. This is based only
// on existent page_ids.
*/
private function dfnCheckInterval( $start = null, $end = null, $batchSize = 100 ) {
$dbw = $this->getDB( DB_MASTER );
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$linksTables = [ // table name => page_id field
'pagelinks' => 'pl_from',
}
public function execute() {
$this->commit = $this->hasOption( 'commit' );
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$dbw = $this->getDB( DB_MASTER );
$lastId = 0;
do {
# Do an initial scan for inactive accounts and report the result
$this->output( "Checking for unused user accounts...\n" );
$del = [];
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$res = $dbr->select( 'user', [ 'user_id', 'user_name', 'user_touched' ], '', __METHOD__ );
if ( $this->hasOption( 'ignore-groups' ) ) {
$excludedGroups = explode( ',', $this->getOption( 'ignore-groups' ) );
* @return bool
*/
private function isInactiveAccount( $id, $master = false ) {
- $dbo = $this->getDB( $master ? DB_MASTER : DB_SLAVE );
+ $dbo = $this->getDB( $master ? DB_MASTER : DB_REPLICA );
$checks = [
'revision' => 'rev',
'archive' => 'ar',
wfCountDown( 5 );
}
+ // We list user by user_id from one of the replica DBs
// We list user by user_id from one of the slave database
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$where = [];
if ( $this->nullsOnly ) {
* @return array
*/
private function getRollbackTitles( $user ) {
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$titles = [];
$results = $dbr->select(
[ 'page', 'revision' ],
<?php
/**
- * Run a database query in batches and wait for slaves. This is used on large
+ * Run a database query in batches and wait for replica DBs. This is used on large
* wikis to prevent replication lag from going through the roof when executing
* large write queries.
*
require_once __DIR__ . '/Maintenance.php';
/**
- * Maintenance script to run a database query in batches and wait for slaves.
+ * Maintenance script to run a database query in batches and wait for replica DBs.
*
* @ingroup Maintenance
*/
public function __construct() {
parent::__construct();
$this->addDescription(
- "Run a query repeatedly until it affects 0 rows, and wait for slaves in between.\n" .
+ "Run a query repeatedly until it affects 0 rows, and wait for replica DBs in between.\n" .
"NOTE: You need to set a LIMIT clause yourself." );
}
'ss_images' => 'Number of images',
];
- // Get cached stats from slave database
- $dbr = $this->getDB( DB_SLAVE );
+ // Get cached stats from a replica DB
+ $dbr = $this->getDB( DB_REPLICA );
$stats = $dbr->selectRow( 'site_stats', '*', '', __METHOD__ );
// Get maximum size for each column
parent::__construct();
$this->addDescription( 'Send SQL queries to a MediaWiki database. ' .
'Takes a file name containing SQL as argument or runs interactively.' );
- $this->addOption( 'query', 'Run a single query instead of running interactively', false, true );
+ $this->addOption( 'query',
+ 'Run a single query instead of running interactively', false, true );
$this->addOption( 'cluster', 'Use an external cluster by name', false, true );
- $this->addOption( 'wikidb', 'The database wiki ID to use if not the current one', false, true );
- $this->addOption( 'slave', 'Use a slave server (either "any" or by name)', false, true );
+ $this->addOption( 'wikidb',
+ 'The database wiki ID to use if not the current one', false, true );
+ $this->addOption( 'replicadb',
+ 'Replica DB server to use instead of the master DB (can be "any")', false, true );
}
public function execute() {
$lb = wfGetLB( $wiki );
}
// Figure out which server to use
- if ( $this->hasOption( 'slave' ) ) {
- $server = $this->getOption( 'slave' );
- if ( $server === 'any' ) {
- $index = DB_SLAVE;
- } else {
- $index = null;
- $serverCount = $lb->getServerCount();
- for ( $i = 0; $i < $serverCount; ++$i ) {
- if ( $lb->getServerName( $i ) === $server ) {
- $index = $i;
- break;
- }
- }
- if ( $index === null ) {
- $this->error( "No slave server configured with the name '$server'.", 1 );
+ $replicaDB = $this->getOption( 'replicadb', $this->getOption( 'slave', '' ) );
+ if ( $replicaDB === 'any' ) {
+ $index = DB_REPLICA;
+ } elseif ( $replicaDB != '' ) {
+ $index = null;
+ $serverCount = $lb->getServerCount();
+ for ( $i = 0; $i < $serverCount; ++$i ) {
+ if ( $lb->getServerName( $i ) === $replicaDB ) {
+ $index = $i;
+ break;
}
}
+ if ( $index === null ) {
+ $this->error( "No replica DB server configured with the name '$server'.", 1 );
+ }
} else {
$index = DB_MASTER;
}
// Get a DB handle (with this wiki's DB selected) from the appropriate load balancer
$db = $lb->getConnection( $index, [], $wiki );
- if ( $this->hasOption( 'slave' ) && $db->getLBInfo( 'master' ) !== null ) {
- $this->error( "The server selected ({$db->getServer()}) is not a slave.", 1 );
+ if ( $replicaDB != '' && $db->getLBInfo( 'master' ) !== null ) {
+ $this->error( "The server selected ({$db->getServer()}) is not a replica DB.", 1 );
}
if ( $this->hasArg( 0 ) ) {
];
function check( $fix = false, $xml = '' ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
if ( $fix ) {
print "Checking, will fix errors if possible...\n";
} else {
return;
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$dbw = wfGetDB( DB_MASTER );
$dbr->ping();
$dbw->ping();
}
// Find text row again
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$oldId = $dbr->selectField( 'revision', 'rev_text_id', [ 'rev_id' => $id ], __METHOD__ );
if ( !$oldId ) {
echo "Missing revision row for rev_id $id\n";
) {
$loadStyle = self::LS_CHUNKED;
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$dbw = $this->getDB( DB_MASTER );
# Set up external storage
}
public function execute() {
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$row = $dbr->selectRow(
[ 'text', 'revision' ],
[ 'old_flags', 'old_text' ],
}
function execute() {
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$dbw = $this->getDB( DB_MASTER );
$dryRun = $this->getOption( 'dry-run' );
unset( $this->mapCache[$key] );
}
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$map = [];
$res = $dbr->select( 'revision',
[ 'rev_id', 'rev_text_id' ],
function moveToExternal( $cluster, $maxID, $minID = 1 ) {
$fname = 'moveToExternal';
$dbw = wfGetDB( DB_MASTER );
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$count = $maxID - $minID + 1;
$blockSize = 1000;
protected function &getDB( $cluster, $groups = [], $wiki = false ) {
$lb = wfGetLBFactory()->getExternalLB( $cluster );
- return $lb->getConnection( DB_SLAVE );
+ return $lb->getConnection( DB_REPLICA );
}
public function execute() {
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
if ( !$dbr->tableExists( 'blob_orphans' ) ) {
$this->error( "blob_orphans doesn't seem to exist, need to run trackBlobs.php first", true );
}
*/
use MediaWiki\Logger\LegacyLogger;
+use MediaWiki\MediaWikiServices;
$optionsWithArgs = RecompressTracked::getOptionsWithArgs();
require __DIR__ . '/../commandLine.inc';
public $numProcs = 1;
public $numBatches = 0;
public $pageBlobClass, $orphanBlobClass;
- public $slavePipes, $slaveProcs, $prevSlaveId;
+ public $replicaPipes, $replicaProcs, $prevReplicaId;
public $copyOnly = false;
public $isChild = false;
- public $slaveId = false;
+ public $replicaId = false;
public $noCount = false;
public $debugLog, $infoLog, $criticalLog;
public $store;
private static $optionsWithArgs = [
'procs',
- 'slave-id',
+ 'replica-id',
'debug-log',
'info-log',
'critical-log'
'procs' => 'numProcs',
'copy-only' => 'copyOnly',
'child' => 'isChild',
- 'slave-id' => 'slaveId',
+ 'replica-id' => 'replicaId',
'debug-log' => 'debugLog',
'info-log' => 'infoLog',
'critical-log' => 'criticalLog',
$this->store = new ExternalStoreDB;
if ( !$this->isChild ) {
$GLOBALS['wgDebugLogPrefix'] = "RCT M: ";
- } elseif ( $this->slaveId !== false ) {
- $GLOBALS['wgDebugLogPrefix'] = "RCT {$this->slaveId}: ";
+ } elseif ( $this->replicaId !== false ) {
+ $GLOBALS['wgDebugLogPrefix'] = "RCT {$this->replicaId}: ";
}
$this->pageBlobClass = function_exists( 'xdiff_string_bdiff' ) ?
'DiffHistoryBlob' : 'ConcatenatedGzipHistoryBlob';
function logToFile( $msg, $file ) {
$header = '[' . date( 'd\TH:i:s' ) . '] ' . wfHostname() . ' ' . posix_getpid();
- if ( $this->slaveId !== false ) {
- $header .= "({$this->slaveId})";
+ if ( $this->replicaId !== false ) {
+ $header .= "({$this->replicaId})";
}
$header .= ' ' . wfWikiID();
LegacyLogger::emit( sprintf( "%-50s %s\n", $header, $msg ), $file );
}
/**
- * Wait until the selected slave has caught up to the master.
- * This allows us to use the slave for things that were committed in a
+ * Wait until the selected replica DB has caught up to the master.
+ * This allows us to use the replica DB for things that were committed in a
* previous part of this batch process.
*/
function syncDBs() {
$dbw = wfGetDB( DB_MASTER );
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$pos = $dbw->getMasterPos();
$dbr->masterPosWait( $pos, 100000 );
}
}
$this->syncDBs();
- $this->startSlaveProcs();
+ $this->startReplicaProcs();
$this->doAllPages();
$this->doAllOrphans();
- $this->killSlaveProcs();
+ $this->killReplicaProcs();
}
/**
* @return bool
*/
function checkTrackingTable() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
if ( !$dbr->tableExists( 'blob_tracking' ) ) {
$this->critical( "Error: blob_tracking table does not exist" );
* This necessary because text recompression is slow: loading, compressing and
* writing are all slow.
*/
- function startSlaveProcs() {
+ function startReplicaProcs() {
$cmd = 'php ' . wfEscapeShellArg( __FILE__ );
foreach ( self::$cmdLineOptionMap as $cmdOption => $classOption ) {
- if ( $cmdOption == 'slave-id' ) {
+ if ( $cmdOption == 'replica-id' ) {
continue;
} elseif ( in_array( $cmdOption, self::$optionsWithArgs ) && isset( $this->$classOption ) ) {
$cmd .= " --$cmdOption " . wfEscapeShellArg( $this->$classOption );
' --wiki ' . wfEscapeShellArg( wfWikiID() ) .
' ' . call_user_func_array( 'wfEscapeShellArg', $this->destClusters );
- $this->slavePipes = $this->slaveProcs = [];
+ $this->replicaPipes = $this->replicaProcs = [];
for ( $i = 0; $i < $this->numProcs; $i++ ) {
$pipes = [];
$spec = [
[ 'file', 'php://stderr', 'w' ]
];
MediaWiki\suppressWarnings();
- $proc = proc_open( "$cmd --slave-id $i", $spec, $pipes );
+ $proc = proc_open( "$cmd --replica-id $i", $spec, $pipes );
MediaWiki\restoreWarnings();
if ( !$proc ) {
- $this->critical( "Error opening slave process: $cmd" );
+ $this->critical( "Error opening replica DB process: $cmd" );
exit( 1 );
}
- $this->slaveProcs[$i] = $proc;
- $this->slavePipes[$i] = $pipes[0];
+ $this->replicaProcs[$i] = $proc;
+ $this->replicaPipes[$i] = $pipes[0];
}
- $this->prevSlaveId = -1;
+ $this->prevReplicaId = -1;
}
/**
* Gracefully terminate the child processes
*/
- function killSlaveProcs() {
- $this->info( "Waiting for slave processes to finish..." );
+ function killReplicaProcs() {
+ $this->info( "Waiting for replica DB processes to finish..." );
for ( $i = 0; $i < $this->numProcs; $i++ ) {
- $this->dispatchToSlave( $i, 'quit' );
+ $this->dispatchToReplica( $i, 'quit' );
}
for ( $i = 0; $i < $this->numProcs; $i++ ) {
- $status = proc_close( $this->slaveProcs[$i] );
+ $status = proc_close( $this->replicaProcs[$i] );
if ( $status ) {
$this->critical( "Warning: child #$i exited with status $status" );
}
}
/**
- * Dispatch a command to the next available slave.
- * This may block until a slave finishes its work and becomes available.
+ * Dispatch a command to the next available replica DB.
+ * This may block until a replica DB finishes its work and becomes available.
*/
function dispatch( /*...*/ ) {
$args = func_get_args();
- $pipes = $this->slavePipes;
+ $pipes = $this->replicaPipes;
$numPipes = stream_select( $x = [], $pipes, $y = [], 3600 );
if ( !$numPipes ) {
- $this->critical( "Error waiting to write to slaves. Aborting" );
+ $this->critical( "Error waiting to write to replica DBs. Aborting" );
exit( 1 );
}
for ( $i = 0; $i < $this->numProcs; $i++ ) {
- $slaveId = ( $i + $this->prevSlaveId + 1 ) % $this->numProcs;
- if ( isset( $pipes[$slaveId] ) ) {
- $this->prevSlaveId = $slaveId;
- $this->dispatchToSlave( $slaveId, $args );
+ $replicaId = ( $i + $this->prevReplicaId + 1 ) % $this->numProcs;
+ if ( isset( $pipes[$replicaId] ) ) {
+ $this->prevReplicaId = $replicaId;
+ $this->dispatchToReplica( $replicaId, $args );
return;
}
}
/**
- * Dispatch a command to a specified slave
- * @param int $slaveId
+ * Dispatch a command to a specified replica DB
+ * @param int $replicaId
* @param array|string $args
*/
- function dispatchToSlave( $slaveId, $args ) {
+ function dispatchToReplica( $replicaId, $args ) {
$args = (array)$args;
$cmd = implode( ' ', $args );
- fwrite( $this->slavePipes[$slaveId], "$cmd\n" );
+ fwrite( $this->replicaPipes[$replicaId], "$cmd\n" );
}
/**
* Move all tracked pages to the new clusters
*/
function doAllPages() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$i = 0;
$startId = 0;
if ( $this->noCount ) {
if ( $current == $end || $this->numBatches >= $this->reportingInterval ) {
$this->numBatches = 0;
$this->info( "$label: $current / $end" );
- wfWaitForSlaves();
+ MediaWikiServices::getInstance()->getDBLoadBalancerFactory()->waitForReplication();
}
}
* Move all orphan text to the new clusters
*/
function doAllOrphans() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$startId = 0;
$i = 0;
if ( $this->noCount ) {
case 'quit':
return;
}
- wfWaitForSlaves();
+ MediaWikiServices::getInstance()->getDBLoadBalancerFactory()->waitForReplication();
}
}
} else {
$titleText = '[deleted]';
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
// Finish any incomplete transactions
if ( !$this->copyOnly ) {
$startId = 0;
$trx = new CgzCopyTransaction( $this, $this->pageBlobClass );
+ $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
while ( true ) {
$res = $dbr->select(
[ 'blob_tracking', 'text' ],
$this->debug( "$titleText: committing blob with " . $trx->getSize() . " items" );
$trx->commit();
$trx = new CgzCopyTransaction( $this, $this->pageBlobClass );
- wfWaitForSlaves();
+ $lbFactory->waitForReplication();
}
}
}
* @param array $conds
*/
function finishIncompleteMoves( $conds ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
+ $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
$startId = 0;
$conds = array_merge( $conds, [
$startId = $row->bt_text_id;
$this->moveTextRow( $row->bt_text_id, $row->bt_new_url );
if ( $row->bt_text_id % 10 == 0 ) {
- wfWaitForSlaves();
+ $lbFactory->waitForReplication();
}
}
}
$trx = new CgzCopyTransaction( $this, $this->orphanBlobClass );
- $res = wfGetDB( DB_SLAVE )->select(
+ $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+ $res = wfGetDB( DB_REPLICA )->select(
[ 'text', 'blob_tracking' ],
[ 'old_id', 'old_text', 'old_flags' ],
[
$this->debug( "[orphan]: committing blob with " . $trx->getSize() . " rows" );
$trx->commit();
$trx = new CgzCopyTransaction( $this, $this->orphanBlobClass );
- wfWaitForSlaves();
+ $lbFactory->waitForReplication();
}
}
$this->debug( "[orphan]: committing blob with " . $trx->getSize() . " rows" );
/* Check to see if the target text_ids have been moved already.
*
- * We originally read from the slave, so this can happen when a single
+ * We originally read from the replica DB, so this can happen when a single
* text_id is shared between multiple pages. It's rare, but possible
* if a delete/move/undelete cycle splits up a null edit.
*
function resolveStubs() {
$fname = 'resolveStubs';
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$maxID = $dbr->selectField( 'text', 'MAX(old_id)', false, $fname );
$blockSize = 10000;
$numBlocks = intval( $maxID / $blockSize ) + 1;
$stub = unserialize( $stubText );
$flags = explode( ',', $flags );
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$dbw = wfGetDB( DB_MASTER );
if ( strtolower( get_class( $stub ) ) !== 'historyblobstub' ) {
class StorageTypeStats extends Maintenance {
function execute() {
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$endId = $dbr->selectField( 'text', 'MAX(old_id)', false, __METHOD__ );
if ( !$endId ) {
}
$type = isset( $options['type'] ) ? $options['type'] : 'ConcatenatedGzipHistoryBlob';
-$dbr = $this->getDB( DB_SLAVE );
+$dbr = $this->getDB( DB_REPLICA );
$res = $dbr->select(
[ 'page', 'revision', 'text' ],
'*',
function checkIntegrity() {
echo "Doing integrity check...\n";
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
// Scan for HistoryBlobStub objects in the text table (bug 20757)
function getTextClause() {
if ( !$this->textClause ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$this->textClause = '';
foreach ( $this->clusters as $cluster ) {
if ( $this->textClause != '' ) {
*/
function trackRevisions() {
$dbw = wfGetDB( DB_MASTER );
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$textClause = $this->getTextClause();
$startId = 0;
* archive table counts as orphan for our purposes.
*/
function trackOrphanText() {
- # Wait until the blob_tracking table is available in the slave
+ # Wait until the blob_tracking table is available in the replica DB
$dbw = wfGetDB( DB_MASTER );
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$pos = $dbw->getMasterPos();
$dbr->masterPosWait( $pos, 100000 );
echo "Searching for orphan blobs in $cluster...\n";
$lb = wfGetLBFactory()->getExternalLB( $cluster );
try {
- $extDB = $lb->getConnection( DB_SLAVE );
+ $extDB = $lb->getConnection( DB_REPLICA );
} catch ( DBConnectionError $e ) {
if ( strpos( $e->error, 'Unknown database' ) !== false ) {
echo "No database on $cluster\n";
class TidyUpBug37714 extends Maintenance {
public function execute() {
// Search for all log entries which are about changing the visability of other log entries.
- $result = $this->getDB( DB_SLAVE )->select(
+ $result = $this->getDB( DB_REPLICA )->select(
'logging',
[ 'log_id', 'log_params' ],
[
foreach ( $result as $row ) {
$ids = explode( ',', explode( "\n", $row->log_params )[0] );
- $result = $this->getDB( DB_SLAVE )->select( // Work out what log entries were changed here.
+ $result = $this->getDB( DB_REPLICA )->select( // Work out what log entries were changed here.
'logging',
'log_type',
[ 'log_id' => $ids ],
if ( $this->hasOption( 'use-master' ) ) {
$dbr = $this->getDB( DB_MASTER );
} else {
- $dbr = $this->getDB( DB_SLAVE, 'vslow' );
+ $dbr = $this->getDB( DB_REPLICA, 'vslow' );
}
$counter = new SiteStatsInit( $dbr );
$result = $counter->articles();
*/
class UpdateCollation extends Maintenance {
const BATCH_SIZE = 100; // Number of rows to process in one batch
- const SYNC_INTERVAL = 5; // Wait for slaves after this many batches
+ const SYNC_INTERVAL = 5; // Wait for replica DBs after this many batches
public $sizeHistogram = [];
global $wgCategoryCollation;
$dbw = $this->getDB( DB_MASTER );
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$force = $this->getOption( 'force' );
$dryRun = $this->getOption( 'dry-run' );
$verboseStats = $this->getOption( 'verbose-stats' );
$this->output( "$count done.\n" );
if ( !$dryRun && ++$batchCount % self::SYNC_INTERVAL == 0 ) {
- $this->output( "Waiting for slaves ... " );
+ $this->output( "Waiting for replica DBs ... " );
wfWaitForSlaves();
$this->output( "done\n" );
}
} while ( !wfGetLB()->pingAll() );
$this->output( "Reconnected\n\n" );
}
- # Wait for the slave to catch up
+ # Wait for the replica DB to catch up
wfWaitForSlaves();
} else {
$this->output( "cheap, skipped\n" );
$this->output( $minutes . 'm ' );
}
$this->output( sprintf( "%.2fs\n", $seconds ) );
- # Wait for the slave to catch up
+ # Wait for the replica DB to catch up
wfWaitForSlaves();
}
}
$ret = [];
$defaultOptions = User::getDefaultOptions();
- // We list user by user_id from one of the slave database
- $dbr = wfGetDB( DB_SLAVE );
+ // We list user by user_id from one of the replica DBs
+ $dbr = wfGetDB( DB_REPLICA );
$result = $dbr->select( 'user',
[ 'user_id' ],
[],
private function CHANGER() {
$this->warn();
- // We list user by user_id from one of the slave database
- $dbr = wfGetDB( DB_SLAVE );
+ // We list user by user_id from one of the replica DBs
+ $dbr = wfGetDB( DB_REPLICA );
$result = $dbr->select( 'user',
[ 'user_id' ],
[],
// must be loaded on the bottom
'position' => 'bottom',
],
+ 'mediawiki.diff.styles' => [
+ 'position' => 'top',
+ 'styles' => [
+ 'resources/src/mediawiki/mediawiki.diff.styles.css',
+ 'resources/src/mediawiki/mediawiki.diff.styles.print.css' => [
+ 'media' => 'print'
+ ],
+ ],
+ 'targets' => [ 'desktop', 'mobile' ],
+ ],
'mediawiki.feedback' => [
'scripts' => 'resources/src/mediawiki/mediawiki.feedback.js',
'styles' => 'resources/src/mediawiki/mediawiki.feedback.css',
'jquery.spinner',
'jquery.textSelection',
'mediawiki.api',
- 'mediawiki.action.history.diff',
+ 'mediawiki.diff.styles',
'mediawiki.util',
'mediawiki.jqueryMsg',
],
'position' => 'top',
'styles' => 'resources/src/mediawiki.action/mediawiki.action.history.styles.css',
],
+ // using this module is deprecated, for diff styles use mediawiki.diff.styles instead
'mediawiki.action.history.diff' => [
'position' => 'top',
'styles' => [
- 'resources/src/mediawiki.action/mediawiki.action.history.diff.css',
- 'resources/src/mediawiki.action/mediawiki.action.history.diff.print.css' => [
+ 'resources/src/mediawiki/mediawiki.diff.styles.css',
+ 'resources/src/mediawiki/mediawiki.diff.styles.print.css' => [
'media' => 'print'
],
],
+++ /dev/null
-/*!
- * Diff rendering
- */
-table.diff {
- border: none;
- border-spacing: 4px;
- margin: 0;
- width: 100%;
- /* Ensure that colums are of equal width */
- table-layout: fixed;
-}
-
-table.diff td {
- padding: 0.33em 0.5em;
-}
-
-table.diff td.diff-marker {
- /* Compensate padding for increased font-size */
- padding: 0.25em;
-}
-
-table.diff col.diff-marker {
- width: 2%;
-}
-
-table.diff col.diff-content {
- width: 48%;
-}
-
-table.diff td div {
- /* Force-wrap very long lines such as URLs or page-widening char strings */
- word-wrap: break-word;
-}
-
-td.diff-otitle,
-td.diff-ntitle {
- text-align: center;
-}
-
-td.diff-lineno {
- font-weight: bold;
-}
-
-td.diff-marker {
- text-align: right;
- font-weight: bold;
- font-size: 1.25em;
- line-height: 1.2;
-}
-
-td.diff-addedline,
-td.diff-deletedline,
-td.diff-context {
- font-size: 88%;
- line-height: 1.6;
- vertical-align: top;
- white-space: -moz-pre-wrap;
- white-space: pre-wrap;
- border-style: solid;
- border-width: 1px 1px 1px 4px;
- border-radius: 0.33em;
-}
-
-td.diff-addedline {
- border-color: #a3d3ff;
-}
-
-td.diff-deletedline {
- border-color: #ffe49c;
-}
-
-td.diff-context {
- background: #f9f9f9;
- border-color: #e6e6e6;
- color: #333;
-}
-
-.diffchange {
- font-weight: bold;
- text-decoration: none;
-}
-
-td.diff-addedline .diffchange,
-td.diff-deletedline .diffchange {
- border-radius: 0.33em;
- padding: 0.25em 0;
-}
-
-td.diff-addedline .diffchange {
- background: #d8ecff;
-}
-
-td.diff-deletedline .diffchange {
- background: #feeec8;
-}
-
-/* Correct user & content directionality when viewing a diff */
-.diff-currentversion-title,
-.diff {
- direction: ltr;
- unicode-bidi: embed;
-}
-
-/* @noflip */ .diff-contentalign-right td {
- direction: rtl;
- unicode-bidi: embed;
-}
-
-/* @noflip */ .diff-contentalign-left td {
- direction: ltr;
- unicode-bidi: embed;
-}
-
-.diff-multi,
-.diff-otitle,
-.diff-ntitle,
-.diff-lineno {
- direction: ltr !important;
- unicode-bidi: embed;
-}
+++ /dev/null
-/*!
- * Diff rendering
- */
-td.diff-context,
-td.diff-addedline .diffchange,
-td.diff-deletedline .diffchange {
- background-color: transparent;
-}
-
-td.diff-addedline .diffchange {
- text-decoration: underline;
-}
-
-td.diff-deletedline .diffchange {
- text-decoration: line-through;
-}
--- /dev/null
+/*!
+ * Diff rendering
+ */
+table.diff {
+ border: none;
+ border-spacing: 4px;
+ margin: 0;
+ width: 100%;
+ /* Ensure that colums are of equal width */
+ table-layout: fixed;
+}
+
+table.diff td {
+ padding: 0.33em 0.5em;
+}
+
+table.diff td.diff-marker {
+ /* Compensate padding for increased font-size */
+ padding: 0.25em;
+}
+
+table.diff col.diff-marker {
+ width: 2%;
+}
+
+table.diff col.diff-content {
+ width: 48%;
+}
+
+table.diff td div {
+ /* Force-wrap very long lines such as URLs or page-widening char strings */
+ word-wrap: break-word;
+}
+
+td.diff-otitle,
+td.diff-ntitle {
+ text-align: center;
+}
+
+td.diff-lineno {
+ font-weight: bold;
+}
+
+td.diff-marker {
+ text-align: right;
+ font-weight: bold;
+ font-size: 1.25em;
+ line-height: 1.2;
+}
+
+td.diff-addedline,
+td.diff-deletedline,
+td.diff-context {
+ font-size: 88%;
+ line-height: 1.6;
+ vertical-align: top;
+ white-space: -moz-pre-wrap;
+ white-space: pre-wrap;
+ border-style: solid;
+ border-width: 1px 1px 1px 4px;
+ border-radius: 0.33em;
+}
+
+td.diff-addedline {
+ border-color: #a3d3ff;
+}
+
+td.diff-deletedline {
+ border-color: #ffe49c;
+}
+
+td.diff-context {
+ background: #f9f9f9;
+ border-color: #e6e6e6;
+ color: #333;
+}
+
+.diffchange {
+ font-weight: bold;
+ text-decoration: none;
+}
+
+td.diff-addedline .diffchange,
+td.diff-deletedline .diffchange {
+ border-radius: 0.33em;
+ padding: 0.25em 0;
+}
+
+td.diff-addedline .diffchange {
+ background: #d8ecff;
+}
+
+td.diff-deletedline .diffchange {
+ background: #feeec8;
+}
+
+/* Correct user & content directionality when viewing a diff */
+.diff-currentversion-title,
+.diff {
+ direction: ltr;
+ unicode-bidi: embed;
+}
+
+/* @noflip */ .diff-contentalign-right td {
+ direction: rtl;
+ unicode-bidi: embed;
+}
+
+/* @noflip */ .diff-contentalign-left td {
+ direction: ltr;
+ unicode-bidi: embed;
+}
+
+.diff-multi,
+.diff-otitle,
+.diff-ntitle,
+.diff-lineno {
+ direction: ltr !important;
+ unicode-bidi: embed;
+}
--- /dev/null
+/*!
+ * Diff rendering
+ */
+td.diff-context,
+td.diff-addedline .diffchange,
+td.diff-deletedline .diffchange {
+ background-color: transparent;
+}
+
+td.diff-addedline .diffchange {
+ text-decoration: underline;
+}
+
+td.diff-deletedline .diffchange {
+ text-decoration: line-through;
+}
$wgDBserver, $dbw->getLBInfo( 'clusterMasterHost' ), 'cluster master set' );
$dbr = $lb->getConnection( DB_SLAVE );
- $this->assertTrue( $dbr->getLBInfo( 'slave' ), 'slave shows as slave' );
+ $this->assertTrue( $dbr->getLBInfo( 'replica' ), 'slave shows as slave' );
$this->assertEquals(
$wgDBserver, $dbr->getLBInfo( 'clusterMasterHost' ), 'cluster master set' );
$this->assertTrue( $dbw->getLBInfo( 'master' ), 'master shows as master' );
$dbr = $lb->getConnection( DB_SLAVE );
- $this->assertTrue( $dbr->getLBInfo( 'slave' ), 'slave shows as slave' );
+ $this->assertTrue( $dbr->getLBInfo( 'replica' ), 'slave shows as slave' );
$factory->shutdown();
$lb->closeAll();