* Skip COMMIT query when no write queries have been done.
* Improvement to ChronologyProtector: only record the master position if a write query was done. This should help to avoid the worst of the ChronologyProtector side-effects, such as having action=raw CSS requests block for a time equivalent to the slave lag on every page view, while maintaining the benefits, like preventing a 404 from being displayed after page creation.
This commit is contained in:
parent
fda50654b3
commit
8653947b06
3 changed files with 41 additions and 10 deletions
|
|
@ -26,6 +26,7 @@ class Database {
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
protected $mLastQuery = '';
|
protected $mLastQuery = '';
|
||||||
|
protected $mDoneWrites = false;
|
||||||
protected $mPHPError = false;
|
protected $mPHPError = false;
|
||||||
|
|
||||||
protected $mServer, $mUser, $mPassword, $mConn = null, $mDBname;
|
protected $mServer, $mUser, $mPassword, $mConn = null, $mDBname;
|
||||||
|
|
@ -210,7 +211,14 @@ class Database {
|
||||||
* @return String
|
* @return String
|
||||||
*/
|
*/
|
||||||
function lastQuery() { return $this->mLastQuery; }
|
function lastQuery() { return $this->mLastQuery; }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the connection may have been used for write queries.
|
||||||
|
* Should return true if unsure.
|
||||||
|
*/
|
||||||
|
function doneWrites() { return $this->mDoneWrites; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is a connection to the database open?
|
* Is a connection to the database open?
|
||||||
* @return Boolean
|
* @return Boolean
|
||||||
|
|
@ -492,6 +500,14 @@ class Database {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether a query writes to the DB.
|
||||||
|
* Should return true if unsure.
|
||||||
|
*/
|
||||||
|
function isWriteQuery( $sql ) {
|
||||||
|
return !preg_match( '/^(?:SELECT|BEGIN|COMMIT|SET|SHOW)\b/i', $sql );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Usually aborts on failure. If errors are explicitly ignored, returns success.
|
* Usually aborts on failure. If errors are explicitly ignored, returns success.
|
||||||
*
|
*
|
||||||
|
|
@ -527,6 +543,11 @@ class Database {
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->mLastQuery = $sql;
|
$this->mLastQuery = $sql;
|
||||||
|
if ( !$this->mDoneWrites && $this->isWriteQuery( $sql ) ) {
|
||||||
|
// Set a flag indicating that writes have been done
|
||||||
|
wfDebug( __METHOD__.": Writes done: $sql\n" );
|
||||||
|
$this->mDoneWrites = true;
|
||||||
|
}
|
||||||
|
|
||||||
# Add a comment for easy SHOW PROCESSLIST interpretation
|
# Add a comment for easy SHOW PROCESSLIST interpretation
|
||||||
#if ( $fname ) {
|
#if ( $fname ) {
|
||||||
|
|
|
||||||
|
|
@ -236,15 +236,25 @@ class ChronologyProtector {
|
||||||
* @param LoadBalancer $lb
|
* @param LoadBalancer $lb
|
||||||
*/
|
*/
|
||||||
function shutdownLB( $lb ) {
|
function shutdownLB( $lb ) {
|
||||||
if ( session_id() != '' && $lb->getServerCount() > 1 ) {
|
// Don't start a session, don't bother with non-replicated setups
|
||||||
$masterName = $lb->getServerName( 0 );
|
if ( strval( session_id() ) == '' || $lb->getServerCount() <= 1 ) {
|
||||||
if ( !isset( $this->shutdownPos[$masterName] ) ) {
|
return;
|
||||||
$pos = $lb->getMasterPos();
|
|
||||||
$info = $lb->parentInfo();
|
|
||||||
wfDebug( __METHOD__.": LB " . $info['id'] . " has master pos $pos\n" );
|
|
||||||
$this->shutdownPos[$masterName] = $pos;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
$masterName = $lb->getServerName( 0 );
|
||||||
|
if ( isset( $this->shutdownPos[$masterName] ) ) {
|
||||||
|
// Already done
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Only save the position if writes have been done on the connection
|
||||||
|
$db = $lb->getAnyOpenConnection( 0 );
|
||||||
|
$info = $lb->parentInfo();
|
||||||
|
if ( !$db || !$db->doneWrites() ) {
|
||||||
|
wfDebug( __METHOD__.": LB {$info['id']}, no writes done\n" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$pos = $db->getMasterPos();
|
||||||
|
wfDebug( __METHOD__.": LB {$info['id']} has master pos $pos\n" );
|
||||||
|
$this->shutdownPos[$masterName] = $pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -824,7 +824,7 @@ class LoadBalancer {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
foreach ( $conns2[$masterIndex] as $conn ) {
|
foreach ( $conns2[$masterIndex] as $conn ) {
|
||||||
if ( $conn->lastQuery() != '' ) {
|
if ( $conn->doneWrites() ) {
|
||||||
$conn->commit();
|
$conn->commit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue