summaryrefslogtreecommitdiff
path: root/includes/objectcache/SqlBagOStuff.php
diff options
context:
space:
mode:
Diffstat (limited to 'includes/objectcache/SqlBagOStuff.php')
-rw-r--r--includes/objectcache/SqlBagOStuff.php78
1 files changed, 22 insertions, 56 deletions
diff --git a/includes/objectcache/SqlBagOStuff.php b/includes/objectcache/SqlBagOStuff.php
index 82eeb842..e08fec99 100644
--- a/includes/objectcache/SqlBagOStuff.php
+++ b/includes/objectcache/SqlBagOStuff.php
@@ -30,6 +30,7 @@ class SqlBagOStuff extends BagOStuff {
/** @var LoadBalancer */
protected $lb;
+ /** @var array */
protected $serverInfos;
/** @var array */
@@ -53,6 +54,9 @@ class SqlBagOStuff extends BagOStuff {
/** @var string */
protected $tableName = 'objectcache';
+ /** @var bool */
+ protected $slaveOnly = false;
+
/** @var array UNIX timestamps */
protected $connFailureTimes = array();
@@ -84,6 +88,10 @@ class SqlBagOStuff extends BagOStuff {
* 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
+ * 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.
*
* @param array $params
*/
@@ -112,6 +120,7 @@ class SqlBagOStuff extends BagOStuff {
if ( isset( $params['shards'] ) ) {
$this->shards = intval( $params['shards'] );
}
+ $this->slaveOnly = !empty( $params['slaveOnly'] );
}
/**
@@ -155,12 +164,13 @@ class SqlBagOStuff extends BagOStuff {
* However, SQLite has an opposite behavior. And PostgreSQL needs to know
* if we are in transaction or no
*/
- if ( wfGetDB( DB_MASTER )->getType() == 'mysql' ) {
+ $index = $this->slaveOnly ? DB_SLAVE : DB_MASTER;
+ if ( wfGetDB( $index )->getType() == 'mysql' ) {
$this->lb = wfGetLBFactory()->newMainLB();
- $db = $this->lb->getConnection( DB_MASTER );
+ $db = $this->lb->getConnection( $index );
$db->clearFlag( DBO_TRX ); // auto-commit mode
} else {
- $db = wfGetDB( DB_MASTER );
+ $db = wfGetDB( $index );
}
}
if ( $wgDebugDBTransactions ) {
@@ -210,12 +220,7 @@ class SqlBagOStuff extends BagOStuff {
}
}
- /**
- * @param string $key
- * @param mixed $casToken [optional]
- * @return mixed
- */
- public function get( $key, &$casToken = null ) {
+ public function get( $key, &$casToken = null, $flags = 0 ) {
$values = $this->getMulti( array( $key ) );
if ( array_key_exists( $key, $values ) ) {
$casToken = $values[$key];
@@ -224,11 +229,7 @@ class SqlBagOStuff extends BagOStuff {
return false;
}
- /**
- * @param array $keys
- * @return array
- */
- public function getMulti( array $keys ) {
+ public function getMulti( array $keys, $flags = 0 ) {
$values = array(); // array of (key => value)
$keysByTable = array();
@@ -274,12 +275,7 @@ class SqlBagOStuff extends BagOStuff {
try {
$db = $this->getDB( $row->serverIndex );
if ( $this->isExpired( $db, $row->exptime ) ) { // MISS
- $this->debug( "get: key has expired, deleting" );
- # Put the expiry time in the WHERE condition to avoid deleting a
- # newly-inserted value
- $db->delete( $row->tableName,
- array( 'keyname' => $key, 'exptime' => $row->exptime ),
- __METHOD__ );
+ $this->debug( "get: key has expired" );
} else { // HIT
$values[$key] = $this->unserialize( $db->decodeBlob( $row->value ) );
}
@@ -358,8 +354,6 @@ class SqlBagOStuff extends BagOStuff {
return $result;
}
-
-
/**
* @param string $key
* @param mixed $value
@@ -367,37 +361,7 @@ class SqlBagOStuff extends BagOStuff {
* @return bool
*/
public function set( $key, $value, $exptime = 0 ) {
- list( $serverIndex, $tableName ) = $this->getTableByKey( $key );
- try {
- $db = $this->getDB( $serverIndex );
- $exptime = intval( $exptime );
-
- if ( $exptime < 0 ) {
- $exptime = 0;
- }
-
- if ( $exptime == 0 ) {
- $encExpiry = $this->getMaxDateTime( $db );
- } else {
- $exptime = $this->convertExpiry( $exptime );
- $encExpiry = $db->timestamp( $exptime );
- }
- // (bug 24425) use a replace if the db supports it instead of
- // delete/insert to avoid clashes with conflicting keynames
- $db->replace(
- $tableName,
- array( 'keyname' ),
- array(
- 'keyname' => $key,
- 'value' => $db->encodeBlob( $this->serialize( $value ) ),
- 'exptime' => $encExpiry
- ), __METHOD__ );
- } catch ( DBError $e ) {
- $this->handleWriteError( $e, $serverIndex );
- return false;
- }
-
- return true;
+ return $this->setMulti( array( $key => $value ), $exptime );
}
/**
@@ -546,7 +510,7 @@ class SqlBagOStuff extends BagOStuff {
}
protected function garbageCollect() {
- if ( !$this->purgePeriod ) {
+ if ( !$this->purgePeriod || $this->slaveOnly ) {
// Disabled
return;
}
@@ -688,9 +652,9 @@ class SqlBagOStuff extends BagOStuff {
*/
protected function unserialize( $serial ) {
if ( function_exists( 'gzinflate' ) ) {
- wfSuppressWarnings();
+ MediaWiki\suppressWarnings();
$decomp = gzinflate( $serial );
- wfRestoreWarnings();
+ MediaWiki\restoreWarnings();
if ( false !== $decomp ) {
$serial = $decomp;
@@ -758,6 +722,8 @@ class SqlBagOStuff extends BagOStuff {
* @param int $serverIndex
*/
protected function markServerDown( $exception, $serverIndex ) {
+ unset( $this->conns[$serverIndex] ); // bug T103435
+
if ( isset( $this->connFailureTimes[$serverIndex] ) ) {
if ( time() - $this->connFailureTimes[$serverIndex] >= 60 ) {
unset( $this->connFailureTimes[$serverIndex] );