Vastly increase how long wfWaitForSlaves() can block in CLI mode
* All maintenance scripts pretty much assumed this behavior, but it was not actually the case. This can avoid some massive lag problems. Change-Id: I5894409d6abade16afd8144f6689c2aff3fa7327
This commit is contained in:
parent
5c74148ba3
commit
cafcb6b225
3 changed files with 21 additions and 10 deletions
|
|
@ -3752,6 +3752,7 @@ function wfGetNull() {
|
|||
* @param float|null $ifWritesSince Only wait if writes were done since this UNIX timestamp
|
||||
* @param string|bool $wiki Wiki identifier accepted by wfGetLB
|
||||
* @param string|bool $cluster Cluster name accepted by LBFactory. Default: false.
|
||||
* @return bool Success (able to connect and no timeouts reached)
|
||||
*/
|
||||
function wfWaitForSlaves( $ifWritesSince = false, $wiki = false, $cluster = false ) {
|
||||
// B/C: first argument used to be "max seconds of lag"; ignore such values
|
||||
|
|
@ -3767,19 +3768,21 @@ function wfWaitForSlaves( $ifWritesSince = false, $wiki = false, $cluster = fals
|
|||
// Prevents permission error when getting master position
|
||||
if ( $lb->getServerCount() > 1 ) {
|
||||
if ( $ifWritesSince && !$lb->hasMasterConnection() ) {
|
||||
return; // assume no writes done
|
||||
return true; // assume no writes done
|
||||
}
|
||||
$dbw = $lb->getConnection( DB_MASTER, array(), $wiki );
|
||||
if ( $ifWritesSince && $dbw->lastDoneWrites() < $ifWritesSince ) {
|
||||
return; // no writes since the last wait
|
||||
return true; // no writes since the last wait
|
||||
}
|
||||
$pos = $dbw->getMasterPos();
|
||||
// The DBMS may not support getMasterPos() or the whole
|
||||
// load balancer might be fake (e.g. $wgAllDBsAreLocalhost).
|
||||
if ( $pos !== false ) {
|
||||
$lb->waitForAll( $pos );
|
||||
return $lb->waitForAll( $pos, PHP_SAPI === 'cli' ? 86400 : null );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3211,7 +3211,7 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
|
|||
* @param DBMasterPos $pos
|
||||
* @param int $timeout The maximum number of seconds to wait for
|
||||
* synchronisation
|
||||
* @return int Zzero if the slave was past that position already,
|
||||
* @return int Zero if the slave was past that position already,
|
||||
* greater than zero if we waited for some period of time, less than
|
||||
* zero if we timed out.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -331,17 +331,23 @@ class LoadBalancer {
|
|||
/**
|
||||
* Set the master wait position and wait for ALL slaves to catch up to it
|
||||
* @param DBMasterPos $pos
|
||||
* @param int $timeout Max seconds to wait; default is mWaitTimeout
|
||||
* @return bool Success (able to connect and no timeouts reached)
|
||||
*/
|
||||
public function waitForAll( $pos ) {
|
||||
public function waitForAll( $pos, $timeout = null ) {
|
||||
wfProfileIn( __METHOD__ );
|
||||
$this->mWaitForPos = $pos;
|
||||
$serverCount = count( $this->mServers );
|
||||
|
||||
$ok = true;
|
||||
for ( $i = 1; $i < $serverCount; $i++ ) {
|
||||
if ( $this->mLoads[$i] > 0 ) {
|
||||
$this->doWait( $i, true );
|
||||
$ok = $this->doWait( $i, true, $timeout ) && $ok;
|
||||
}
|
||||
}
|
||||
wfProfileOut( __METHOD__ );
|
||||
|
||||
return $ok;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -363,11 +369,12 @@ class LoadBalancer {
|
|||
|
||||
/**
|
||||
* Wait for a given slave to catch up to the master pos stored in $this
|
||||
* @param int $index
|
||||
* @param bool $open
|
||||
* @param int $index Server index
|
||||
* @param bool $open Check the server even if a new connection has to be made
|
||||
* @param int $timeout Max seconds to wait; default is mWaitTimeout
|
||||
* @return bool
|
||||
*/
|
||||
protected function doWait( $index, $open = false ) {
|
||||
protected function doWait( $index, $open = false, $timeout = null ) {
|
||||
# Find a connection to wait on
|
||||
$conn = $this->getAnyOpenConnection( $index );
|
||||
if ( !$conn ) {
|
||||
|
|
@ -386,7 +393,8 @@ class LoadBalancer {
|
|||
}
|
||||
|
||||
wfDebug( __METHOD__ . ": Waiting for slave #$index to catch up...\n" );
|
||||
$result = $conn->masterPosWait( $this->mWaitForPos, $this->mWaitTimeout );
|
||||
$timeout = $timeout ?: $this->mWaitTimeout;
|
||||
$result = $conn->masterPosWait( $this->mWaitForPos, $timeout );
|
||||
|
||||
if ( $result == -1 || is_null( $result ) ) {
|
||||
# Timed out waiting for slave, use master instead
|
||||
|
|
|
|||
Loading…
Reference in a new issue