Ladsgroup has uploaded a new change for review. (
https://gerrit.wikimedia.org/r/353478 )
Change subject: Do not update chd_seen twice and use replica for reading
......................................................................
Do not update chd_seen twice and use replica for reading
Bug: T162556
Bug: T162557
Change-Id: Ic679fae1467675a325c41ecc98ecb42263b7dfeb
---
M repo/includes/Store/Sql/SqlChangeDispatchCoordinator.php
1 file changed, 41 insertions(+), 39 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase
refs/changes/78/353478/1
diff --git a/repo/includes/Store/Sql/SqlChangeDispatchCoordinator.php
b/repo/includes/Store/Sql/SqlChangeDispatchCoordinator.php
index ce93c44..4fc5438 100644
--- a/repo/includes/Store/Sql/SqlChangeDispatchCoordinator.php
+++ b/repo/includes/Store/Sql/SqlChangeDispatchCoordinator.php
@@ -236,6 +236,13 @@
}
/**
+ * @return Database A connection to the repo's replica database
+ */
+ private function getRepoReplica() {
+ return $this->getRepoLB()->getConnection( DB_REPLICA, [],
$this->repoDB );
+ }
+
+ /**
* @param Database $db The repo database connection to release for
re-use.
*/
private function releaseRepoMaster( Database $db ) {
@@ -304,14 +311,14 @@
* @see selectClient()
*/
private function getCandidateClients() {
- $db = $this->getRepoMaster();
+ $dbr = $this->getRepoReplica();
// XXX: subject to clock skew. Use DB based "now" time?
$freshDispatchTime = wfTimestamp( TS_MW, $this->now() -
$this->dispatchInterval );
$staleLockTime = wfTimestamp( TS_MW, $this->now() -
$this->lockGraceInterval );
// TODO: pass the max change ID as a parameter!
- $row = $db->selectRow(
+ $row = $dbr->selectRow(
$this->changesTable,
'max( change_id ) as maxid',
array(),
@@ -329,16 +336,19 @@
// Limit the list to $randomness items. Candidates will be
picked
// from the resulting list at random.
- $candidates = $db->selectFieldValues(
+ $where = [
+ '( chd_lock is NULL ' . // not locked
+ ' OR chd_touched < ' . $dbr->addQuotes( $staleLockTime
) . ' ) ', // or the lock is old
+ '( chd_touched < ' . $dbr->addQuotes(
$freshDispatchTime ) . // and wasn't touched too recently or
+ ' OR ( ' . (int)$maxId. ' - chd_seen ) > ' .
(int)$this->batchSize . ') ' , // or it's lagging by more changes than batchSite
+ 'chd_seen < ' . (int)$maxId, // and not fully up to
date.
+ 'chd_disabled = 0' // and not disabled
+ ];
+
+ $candidates = $dbr->selectFieldValues(
$this->stateTable,
'chd_site',
- array( '( chd_lock is NULL ' . // not locked or...
- ' OR chd_touched < ' . $db->addQuotes(
$staleLockTime ) . ' ) ', // ...the lock is old
- '( chd_touched < ' . $db->addQuotes(
$freshDispatchTime ) . // and wasn't touched too recently or...
- ' OR ( ' . (int)$maxId. ' - chd_seen )
> ' . (int)$this->batchSize . ') ' , // or it's lagging by more changes than
batchSite
- 'chd_seen < ' . (int)$maxId, // and not fully
up to date.
- 'chd_disabled = 0' // and not disabled
- ),
+ $where,
__METHOD__,
array(
'ORDER BY' => 'chd_seen ASC',
@@ -359,9 +369,10 @@
* @throws DBUnexpectedError
*/
public function initState( array $clientWikiDBs ) {
- $db = $this->getRepoMaster();
+ $dbr = $this->getRepoReplica();
+ $dbw = $this->getRepoMaster();
- $trackedSiteIds = $db->selectFieldValues(
+ $trackedSiteIds = $dbr->selectFieldValues(
$this->stateTable,
'chd_site',
array(),
@@ -380,7 +391,7 @@
'chd_disabled' => 0,
);
- $db->insert(
+ $dbw->insert(
$this->stateTable,
$state,
__METHOD__,
@@ -390,7 +401,7 @@
$this->log( "Initialized dispatch state for $siteID" );
}
- $this->releaseRepoMaster( $db );
+ $this->releaseRepoMaster( $dbr );
}
/**
@@ -401,7 +412,7 @@
*
* @throws MWException if there are no client wikis to chose from.
* @throws Exception
- * @return array An associative array containing the state of the
selected client wiki
+ * @return bool|array An associative array containing the state of the
selected client wiki
* (see selectClient()) or false if the client wiki could
not be locked.
*
* @see selectClient()
@@ -410,14 +421,16 @@
$this->trace( "Trying $siteID" );
// start transaction
- $db = $this->getRepoMaster();
- $db->startAtomic( __METHOD__ );
+ $dbw = $this->getRepoMaster();
+ $dbr = $this->getRepoReplica();
+
+ $dbw->startAtomic( __METHOD__ );
try {
$this->trace( 'Loaded repo db master' );
// get client state
- $state = $db->selectRow(
+ $state = $dbr->selectRow(
$this->stateTable,
array( 'chd_site', 'chd_db', 'chd_seen',
'chd_touched', 'chd_lock', 'chd_disabled' ),
array( 'chd_site' => $siteID ),
@@ -440,17 +453,17 @@
if ( $state['chd_lock'] !== null ) {
// bail out if another dispatcher instance is
holding a lock for that wiki
- if ( $this->isClientLockUsed( $db, $lock ) ) {
+ if ( $this->isClientLockUsed( $dbw, $lock ) ) {
$this->trace( "$siteID is already being
handled by another process."
. " (lock: " .
$state['chd_lock'] . ")" );
- $db->rollback( __METHOD__ );
- $this->releaseRepoMaster( $db );
+ $dbw->rollback( __METHOD__ );
+ $this->releaseRepoMaster( $dbw );
return false;
}
}
- $ok = $this->engageClientLock( $db, $lock );
+ $ok = $this->engageClientLock( $dbw, $lock );
if ( !$ok ) {
// This really shouldn't happen, since we
already checked if another process has a lock.
@@ -461,31 +474,20 @@
$this->trace( "Warning: Failed to acquire lock
$lock for site $siteID!" );
- $db->rollback( __METHOD__ );
- $this->releaseRepoMaster( $db );
+ $dbw->rollback( __METHOD__ );
+ $this->releaseRepoMaster( $dbw );
return false;
}
$this->trace( "Locked client $siteID with $lock" );
-
- $state['chd_lock'] = $lock;
- $state['chd_touched'] = wfTimestamp( TS_MW,
$this->now() ); // XXX: use DB time
-
- // update state record for already known client wiki
- $db->update(
- $this->stateTable,
- $state,
- array( 'chd_site' => $state['chd_site'] ),
- __METHOD__
- );
} catch ( Exception $ex ) {
- $db->rollback( __METHOD__ );
- $this->releaseRepoMaster( $db );
+ $dbw->rollback( __METHOD__ );
+ $this->releaseRepoMaster( $dbw );
throw $ex;
}
- $db->endAtomic( __METHOD__ );
- $this->releaseRepoMaster( $db );
+ $dbw->endAtomic( __METHOD__ );
+ $this->releaseRepoMaster( $dbw );
$this->trace( "Locked site $siteID at {$state['chd_seen']}." );
--
To view, visit https://gerrit.wikimedia.org/r/353478
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic679fae1467675a325c41ecc98ecb42263b7dfeb
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Ladsgroup <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits