X-Git-Url: https://git.cyclocoop.org/%27.WWW_URL.%27admin/?a=blobdiff_plain;f=includes%2FRevision.php;h=6acc528f76bcde938da16cabfb024d5df1cab6cc;hb=8585cc9ffb75cda2f923d3c16760f357aff074d0;hp=bc760a3609f7d4dd8784bb046a73aad0463176d4;hpb=544561106282ea6cfcd472d460c879fe92f40007;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/Revision.php b/includes/Revision.php index bc760a3609..6acc528f76 100644 --- a/includes/Revision.php +++ b/includes/Revision.php @@ -92,6 +92,8 @@ class Revision implements IDBAccessObject { const FOR_THIS_USER = 2; const RAW = 3; + const TEXT_CACHE_GROUP = 'revisiontext:10'; // process cache name and max key count + /** * Load a page revision from a given revision ID number. * Returns null if no such revision can be found. @@ -1575,33 +1577,25 @@ class Revision implements IDBAccessObject { * @return string|bool The revision's text, or false on failure */ private function loadText() { - // Caching may be beneficial for massive use of external storage global $wgRevisionCacheExpiry; - static $processCache = null; - - if ( !$wgRevisionCacheExpiry ) { - return $this->fetchText(); - } - - if ( !$processCache ) { - $processCache = new MapCacheLRU( 10 ); - } $cache = ObjectCache::getMainWANInstance(); - $key = $cache->makeKey( 'revisiontext', 'textid', $this->getTextId() ); + if ( $cache->getQoS( $cache::ATTR_EMULATION ) <= $cache::QOS_EMULATION_SQL ) { + // Do not cache RDBMs blobs in...the RDBMs store + $ttl = $cache::TTL_UNCACHEABLE; + } else { + $ttl = $wgRevisionCacheExpiry ?: $cache::TTL_UNCACHEABLE; + } // No negative caching; negative hits on text rows may be due to corrupted replica DBs - return $processCache->getWithSetCallback( $key, function () use ( $cache, $key ) { - global $wgRevisionCacheExpiry; - - return $cache->getWithSetCallback( - $key, - $wgRevisionCacheExpiry, - function () { - return $this->fetchText(); - } - ); - } ); + return $cache->getWithSetCallback( + $cache->makeKey( 'revisiontext', 'textid', $this->getTextId() ), + $ttl, + function () { + return $this->fetchText(); + }, + [ 'pcGroup' => self::TEXT_CACHE_GROUP, 'pcTTL' => $cache::TTL_PROC_LONG ] + ); } private function fetchText() { @@ -1615,25 +1609,38 @@ class Revision implements IDBAccessObject { $row = null; } + // Callers doing updates will pass in READ_LATEST as usual. Since the text/blob tables + // do not normally get rows changed around, set READ_LATEST_IMMUTABLE in those cases. + $flags = $this->mQueryFlags; + $flags |= DBAccessObjectUtils::hasFlags( $flags, self::READ_LATEST ) + ? self::READ_LATEST_IMMUTABLE + : 0; + + list( $index, $options, $fallbackIndex, $fallbackOptions ) = + DBAccessObjectUtils::getDBOptions( $flags ); + if ( !$row ) { // Text data is immutable; check replica DBs first. - $dbr = wfGetDB( DB_REPLICA ); - $row = $dbr->selectRow( 'text', + $row = wfGetDB( $index )->selectRow( + 'text', [ 'old_text', 'old_flags' ], [ 'old_id' => $textId ], - __METHOD__ ); + __METHOD__, + $options + ); } - // 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 ) ) { - $dbw = wfGetDB( DB_MASTER ); - $row = $dbw->selectRow( 'text', + // Fallback to DB_MASTER in some cases if the row was not found + if ( !$row && $fallbackIndex !== null ) { + // Use FOR UPDATE if it was used to fetch this revision. This avoids missing the row + // due to REPEATABLE-READ. Also fallback to the master if READ_LATEST is provided. + $row = wfGetDB( $fallbackIndex )->selectRow( + 'text', [ 'old_text', 'old_flags' ], [ 'old_id' => $textId ], __METHOD__, - $forUpdate ? [ 'FOR UPDATE' ] : [] ); + $fallbackOptions + ); } if ( !$row ) {