From: Aaron Schulz Date: Tue, 10 Jun 2014 22:13:41 +0000 (-0700) Subject: Improved DB handling in LCStoreDB X-Git-Tag: 1.31.0-rc.0~15150 X-Git-Url: http://git.cyclocoop.org//%22%22.str_replace%28%27%22%27%2C?a=commitdiff_plain;h=8d6c724ade57c776588a885b2aa5b74720bc67fa;p=lhc%2Fweb%2Fwiklou.git Improved DB handling in LCStoreDB * Only do the DB inserts in finishWrite(). Previously this would COMMIT there but would spread out queries throughout the set() calls. This pushes all the contention down to the last step. Change-Id: Ia8afb79a8328c18a7d8a386bcd15a5074007d52e --- diff --git a/includes/cache/LocalisationCache.php b/includes/cache/LocalisationCache.php index 1153fd2962..ec36cfb5ab 100644 --- a/includes/cache/LocalisationCache.php +++ b/includes/cache/LocalisationCache.php @@ -1155,11 +1155,11 @@ class LCStoreDB implements LCStore { private $currentLang; private $writesDone = false; - /** - * @var DatabaseBase - */ + /** @var DatabaseBase */ private $dbw; - private $batch; + /** @var Array */ + private $batch = array(); + private $readOnly = false; public function get( $code, $key ) { @@ -1180,26 +1180,11 @@ class LCStoreDB implements LCStore { public function startWrite( $code ) { if ( $this->readOnly ) { return; - } - - if ( !$code ) { + } elseif ( !$code ) { throw new MWException( __METHOD__ . ": Invalid language \"$code\"" ); } $this->dbw = wfGetDB( DB_MASTER ); - try { - $this->dbw->begin( __METHOD__ ); - $this->dbw->delete( 'l10n_cache', array( 'lc_lang' => $code ), __METHOD__ ); - } catch ( DBQueryError $e ) { - if ( $this->dbw->wasReadOnlyError() ) { - $this->readOnly = true; - $this->dbw->rollback( __METHOD__ ); - - return; - } else { - throw $e; - } - } $this->currentLang = $code; $this->batch = array(); @@ -1208,37 +1193,42 @@ class LCStoreDB implements LCStore { public function finishWrite() { if ( $this->readOnly ) { return; + } elseif ( is_null( $this->currentLang ) ) { + throw new MWException( __CLASS__ . ': must call startWrite() before finishWrite()' ); } - if ( $this->batch ) { - $this->dbw->insert( 'l10n_cache', $this->batch, __METHOD__ ); + $this->dbw->begin( __METHOD__ ); + try { + $this->dbw->delete( 'l10n_cache', + array( 'lc_lang' => $this->currentLang ), __METHOD__ ); + foreach ( array_chunk( $this->batch, 500 ) as $rows ) { + $this->dbw->insert( 'l10n_cache', $rows, __METHOD__ ); + } + $this->writesDone = true; + } catch ( DBQueryError $e ) { + if ( $this->dbw->wasReadOnlyError() ) { + $this->readOnly = true; // just avoid site down time + } else { + throw $e; + } } - $this->dbw->commit( __METHOD__ ); + $this->currentLang = null; - $this->dbw = null; $this->batch = array(); - $this->writesDone = true; } public function set( $key, $value ) { if ( $this->readOnly ) { return; - } - - if ( is_null( $this->currentLang ) ) { - throw new MWException( __CLASS__ . ': must call startWrite() before calling set()' ); + } elseif ( is_null( $this->currentLang ) ) { + throw new MWException( __CLASS__ . ': must call startWrite() before set()' ); } $this->batch[] = array( 'lc_lang' => $this->currentLang, 'lc_key' => $key, 'lc_value' => $this->dbw->encodeBlob( serialize( $value ) ) ); - - if ( count( $this->batch ) >= 100 ) { - $this->dbw->insert( 'l10n_cache', $this->batch, __METHOD__ ); - $this->batch = array(); - } } }