r41234 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r41233‎ | r41234 | r41235 >
Date:18:09, 24 September 2008
Author:brion
Status:old
Tags:
Comment:
Revert some recent ES-related changes -- they made behavior much worse when we encountered problems with site_stats updates hanging and stacking up extra open ES connections.
r41230
r41229
r41093
r41091
r41092
r41086
r41063
r40696

Also reverted r41231 which no longer applies
Modified paths:
  • /trunk/phase3/includes/ExternalStore.php (modified) (history)
  • /trunk/phase3/includes/ExternalStoreDB.php (modified) (history)
  • /trunk/phase3/includes/Revision.php (modified) (history)
  • /trunk/phase3/includes/db/Database.php (modified) (history)
  • /trunk/phase3/includes/db/LoadBalancer.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/db/Database.php
@@ -343,17 +343,13 @@
344344
345345 wfProfileIn("dbconnect-$server");
346346
 347+ # Try to connect up to three times
347348 # The kernel's default SYN retransmission period is far too slow for us,
348 - # so we use a short timeout plus a manual retry. Retrying means that a small
349 - # but finite rate of SYN packet loss won't cause user-visible errors.
 349+ # so we use a short timeout plus a manual retry.
350350 $this->mConn = false;
351 - if ( ini_get( 'mysql.connect_timeout' ) <= 3 ) {
352 - $numAttempts = 2;
353 - } else {
354 - $numAttempts = 1;
355 - }
 351+ $max = 3;
356352 $this->installErrorHandler();
357 - for ( $i = 0; $i < $numAttempts && !$this->mConn; $i++ ) {
 353+ for ( $i = 0; $i < $max && !$this->mConn; $i++ ) {
358354 if ( $i > 1 ) {
359355 usleep( 1000 );
360356 }
@@ -369,28 +365,30 @@
370366 }
371367 }
372368 $phpError = $this->restoreErrorHandler();
373 - # Always log connection errors
374369 if ( !$this->mConn ) {
375370 $error = $this->lastError();
376371 if ( !$error ) {
377372 $error = $phpError;
378373 }
379374 wfLogDBError( "Error connecting to {$this->mServer}: $error\n" );
380 - wfDebug( "DB connection error\n" );
381 - wfDebug( "Server: $server, User: $user, Password: " .
382 - substr( $password, 0, 3 ) . "..., error: " . mysql_error() . "\n" );
383 - $success = false;
384375 }
385376
386377 wfProfileOut("dbconnect-$server");
387378
388 - if ( $dbName != '' && $this->mConn !== false ) {
389 - $success = @/**/mysql_select_db( $dbName, $this->mConn );
390 - if ( !$success ) {
391 - $error = "Error selecting database $dbName on server {$this->mServer} " .
392 - "from client host {$wguname['nodename']}\n";
393 - wfLogDBError(" Error selecting database $dbName on server {$this->mServer} \n");
394 - wfDebug( $error );
 379+ if ( $dbName != '' ) {
 380+ if ( $this->mConn !== false ) {
 381+ $success = @/**/mysql_select_db( $dbName, $this->mConn );
 382+ if ( !$success ) {
 383+ $error = "Error selecting database $dbName on server {$this->mServer} " .
 384+ "from client host {$wguname['nodename']}\n";
 385+ wfLogDBError(" Error selecting database $dbName on server {$this->mServer} \n");
 386+ wfDebug( $error );
 387+ }
 388+ } else {
 389+ wfDebug( "DB connection error\n" );
 390+ wfDebug( "Server: $server, User: $user, Password: " .
 391+ substr( $password, 0, 3 ) . "..., error: " . mysql_error() . "\n" );
 392+ $success = false;
395393 }
396394 } else {
397395 # Delay USE query
@@ -2507,13 +2505,6 @@
25082506
25092507 $text = str_replace( '$1', $this->error, $noconnect );
25102508
2511 - /*
2512 - if ( $GLOBALS['wgShowExceptionDetails'] ) {
2513 - $text .= '</p><p>Backtrace:</p><p>' .
2514 - nl2br( htmlspecialchars( $this->getTraceAsString() ) ) .
2515 - "</p>\n";
2516 - }*/
2517 -
25182509 if($wgUseFileCache) {
25192510 if($wgTitle) {
25202511 $t =& $wgTitle;
Index: trunk/phase3/includes/db/LoadBalancer.php
@@ -398,20 +398,11 @@
399399 /**
400400 * Get a connection by index
401401 * This is the main entry point for this class.
402 - * @param int $i Database
403 - * @param array $groups Query groups
404 - * @param string $wiki Wiki ID
405402 */
406403 public function &getConnection( $i, $groups = array(), $wiki = false ) {
407404 global $wgDBtype;
408405 wfProfileIn( __METHOD__ );
409406
410 - if ( $i == DB_LAST ) {
411 - throw new MWException( 'Attempt to call ' . __METHOD__ . ' with deprecated server index DB_LAST' );
412 - } elseif ( $i === null || $i === false ) {
413 - throw new MWException( 'Attempt to call ' . __METHOD__ . ' with invalid server index' );
414 - }
415 -
416407 if ( $wiki === wfWikiID() ) {
417408 $wiki = false;
418409 }
@@ -441,13 +432,13 @@
442433 # Operation-based index
443434 if ( $i == DB_SLAVE ) {
444435 $i = $this->getReaderIndex( false, $wiki );
445 - # Couldn't find a working server in getReaderIndex()?
446 - if ( $i === false ) {
447 - $this->mLastError = 'No working slave server: ' . $this->mLastError;
448 - $this->reportConnectionError( $this->mErrorConnection );
449 - return false;
450 - }
 436+ } elseif ( $i == DB_LAST ) {
 437+ throw new MWException( 'Attempt to call ' . __METHOD__ . ' with deprecated server index DB_LAST' );
451438 }
 439+ # Couldn't find a working server in getReaderIndex()?
 440+ if ( $i === false ) {
 441+ $this->reportConnectionError( $this->mErrorConnection );
 442+ }
452443
453444 # Now we have an explicit index into the servers array
454445 $conn = $this->openConnection( $i, $wiki );
@@ -527,7 +518,7 @@
528519 } else {
529520 $server = $this->mServers[$i];
530521 $server['serverIndex'] = $i;
531 - $conn = $this->reallyOpenConnection( $server, false );
 522+ $conn = $this->reallyOpenConnection( $server );
532523 if ( $conn->isOpen() ) {
533524 $this->mConns['local'][$i][0] = $conn;
534525 } else {
@@ -669,7 +660,6 @@
670661 $reporting = true;
671662 if ( !is_object( $conn ) ) {
672663 // No last connection, probably due to all servers being too busy
673 - wfLogDBError( "LB failure with no last connection\n" );
674664 $conn = new Database;
675665 if ( $this->mFailFunction ) {
676666 $conn->failFunction( $this->mFailFunction );
@@ -685,7 +675,6 @@
686676 $conn->failFunction( false );
687677 }
688678 $server = $conn->getProperty( 'mServer' );
689 - wfLogDBError( "Connection error: {$this->mLastError} ({$server})\n" );
690679 $conn->reportConnectionError( "{$this->mLastError} ({$server})" );
691680 }
692681 $reporting = false;
Index: trunk/phase3/includes/Revision.php
@@ -761,13 +761,20 @@
762762 $flags = Revision::compressRevisionText( $data );
763763
764764 # Write to external storage if required
765 - if( $wgDefaultExternalStore ) {
 765+ if ( $wgDefaultExternalStore ) {
 766+ if ( is_array( $wgDefaultExternalStore ) ) {
 767+ // Distribute storage across multiple clusters
 768+ $store = $wgDefaultExternalStore[mt_rand(0, count( $wgDefaultExternalStore ) - 1)];
 769+ } else {
 770+ $store = $wgDefaultExternalStore;
 771+ }
766772 // Store and get the URL
767 - $data = ExternalStore::randomInsert( $data );
768 - if( !$data ) {
769 - throw new MWException( "Unable to store text to external storage" );
 773+ $data = ExternalStore::insert( $store, $data );
 774+ if ( !$data ) {
 775+ # This should only happen in the case of a configuration error, where the external store is not valid
 776+ throw new MWException( "Unable to store text to external storage $store" );
770777 }
771 - if( $flags ) {
 778+ if ( $flags ) {
772779 $flags .= ',';
773780 }
774781 $flags .= 'external';
Index: trunk/phase3/includes/ExternalStore.php
@@ -14,7 +14,7 @@
1515 */
1616 class ExternalStore {
1717 /* Fetch data from given URL */
18 - static function fetchFromURL( $url ) {
 18+ static function fetchFromURL($url) {
1919 global $wgExternalStores;
2020
2121 if( !$wgExternalStores )
@@ -44,7 +44,7 @@
4545
4646 $class = 'ExternalStore' . ucfirst( $proto );
4747 /* Any custom modules should be added to $wgAutoLoadClasses for on-demand loading */
48 - if( !class_exists( $class ) ) {
 48+ if( !class_exists( $class ) ){
4949 return false;
5050 }
5151
@@ -66,47 +66,4 @@
6767 return $store->store( $params, $data );
6868 }
6969 }
70 -
71 - /**
72 - * Like insert() above, but does more of the work for us.
73 - * This function does not need a url param, it builds it by
74 - * itself. It also fails-over to the next possible clusters.
75 - *
76 - * @param string $data
77 - * Returns the URL of the stored data item, or false on error
78 - */
79 - public static function randomInsert( $data ) {
80 - global $wgDefaultExternalStore;
81 - $tryStores = (array)$wgDefaultExternalStore;
82 - $error = false;
83 - while ( count( $tryStores ) > 0 ) {
84 - $index = mt_rand(0, count( $tryStores ) - 1);
85 - $storeUrl = $tryStores[$index];
86 - wfDebug( __METHOD__.": trying $storeUrl\n" );
87 - list( $proto, $params ) = explode( '://', $storeUrl, 2 );
88 - $store = self::getStoreObject( $proto );
89 - if ( $store === false ) {
90 - throw new MWException( "Invalid external storage protocol - $storeUrl" );
91 - }
92 - try {
93 - $url = $store->store( $params, $data ); // Try to save the object
94 - } catch ( DBConnectionError $error ) {
95 - $url = false;
96 - }
97 - if ( $url ) {
98 - return $url; // Done!
99 - } else {
100 - unset( $tryStores[$index] ); // Don't try this one again!
101 - $tryStores = array_values( $tryStores ); // Must have consecutive keys
102 - wfDebugLog( 'ExternalStorage', "Unable to store text to external storage $storeUrl" );
103 - }
104 - }
105 - // All stores failed
106 - if ( $error ) {
107 - // Rethrow the last connection error
108 - throw $error;
109 - } else {
110 - throw new MWException( "Unable to store text to external storage" );
111 - }
112 - }
11370 }
Index: trunk/phase3/includes/ExternalStoreDB.php
@@ -40,7 +40,7 @@
4141 /** @todo Document.*/
4242 function &getMaster( $cluster ) {
4343 $lb =& $this->getLoadBalancer( $cluster );
44 - return $lb->getConnection( DB_MASTER, array() );
 44+ return $lb->getConnection( DB_MASTER );
4545 }
4646
4747 /** @todo Document.*/
@@ -56,7 +56,7 @@
5757 * Fetch data from given URL
5858 * @param string $url An url of the form DB://cluster/id or DB://cluster/id/itemid for concatened storage.
5959 */
60 - function fetchFromURL( $url ) {
 60+ function fetchFromURL($url) {
6161 $path = explode( '/', $url );
6262 $cluster = $path[2];
6363 $id = $path[3];
@@ -122,14 +122,12 @@
123123 * @return string URL
124124 */
125125 function store( $cluster, $data ) {
126 - $dbw = $this->getMaster( $cluster );
127 - if( !$dbw ) {
128 - return false;
129 - }
 126+ $fname = 'ExternalStoreDB::store';
 127+
 128+ $dbw =& $this->getMaster( $cluster );
 129+
130130 $id = $dbw->nextSequenceValue( 'blob_blob_id_seq' );
131 - $dbw->insert( $this->getTable( $dbw ),
132 - array( 'blob_id' => $id, 'blob_text' => $data ),
133 - __METHOD__ );
 131+ $dbw->insert( $this->getTable( $dbw ), array( 'blob_id' => $id, 'blob_text' => $data ), $fname );
134132 $id = $dbw->insertId();
135133 if ( $dbw->getFlag( DBO_TRX ) ) {
136134 $dbw->immediateCommit();

Follow-up revisions

RevisionCommit summaryAuthorDate
r41329* Revert revert r41234 of ES-related changes. The site_stats complaint should...tstarling01:42, 28 September 2008

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r40696ExternalStore tweaks:...aaron12:07, 10 September 2008
r41063Use normal, more patient, connection attempts for master connection hereaaron08:40, 20 September 2008
r41086Revert/rewrite of r40696....tstarling06:42, 21 September 2008
r41091Logging tweakststarling08:28, 21 September 2008
r41092wfGetDB() needs a parameter.tstarling08:44, 21 September 2008
r41093More specific error messageststarling09:06, 21 September 2008
r41229Revert untested code change from r41086. Don't call methods on non-objects, t...aaron16:09, 24 September 2008
r41230Uncomment out needed code, PN2 not wanting to save :/aaron16:13, 24 September 2008
r41231Another fix for r41086. Don't keep retrying server if connection fails.aaron17:28, 24 September 2008