Index: trunk/phase3/includes/db/Database.php |
— | — | @@ -343,13 +343,17 @@ |
344 | 344 | |
345 | 345 | wfProfileIn("dbconnect-$server"); |
346 | 346 | |
347 | | - # Try to connect up to three times |
348 | 347 | # The kernel's default SYN retransmission period is far too slow for us, |
349 | | - # so we use a short timeout plus a manual retry. |
| 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. |
350 | 350 | $this->mConn = false; |
351 | | - $max = 3; |
| 351 | + if ( ini_get( 'mysql.connect_timeout' ) <= 3 ) { |
| 352 | + $numAttempts = 2; |
| 353 | + } else { |
| 354 | + $numAttempts = 1; |
| 355 | + } |
352 | 356 | $this->installErrorHandler(); |
353 | | - for ( $i = 0; $i < $max && !$this->mConn; $i++ ) { |
| 357 | + for ( $i = 0; $i < $numAttempts && !$this->mConn; $i++ ) { |
354 | 358 | if ( $i > 1 ) { |
355 | 359 | usleep( 1000 ); |
356 | 360 | } |
— | — | @@ -365,30 +369,28 @@ |
366 | 370 | } |
367 | 371 | } |
368 | 372 | $phpError = $this->restoreErrorHandler(); |
| 373 | + # Always log connection errors |
369 | 374 | if ( !$this->mConn ) { |
370 | 375 | $error = $this->lastError(); |
371 | 376 | if ( !$error ) { |
372 | 377 | $error = $phpError; |
373 | 378 | } |
374 | 379 | 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; |
375 | 384 | } |
376 | 385 | |
377 | 386 | wfProfileOut("dbconnect-$server"); |
378 | 387 | |
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; |
| 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 ); |
393 | 395 | } |
394 | 396 | } else { |
395 | 397 | # Delay USE query |
— | — | @@ -2505,6 +2507,13 @@ |
2506 | 2508 | |
2507 | 2509 | $text = str_replace( '$1', $this->error, $noconnect ); |
2508 | 2510 | |
| 2511 | + /* |
| 2512 | + if ( $GLOBALS['wgShowExceptionDetails'] ) { |
| 2513 | + $text .= '</p><p>Backtrace:</p><p>' . |
| 2514 | + nl2br( htmlspecialchars( $this->getTraceAsString() ) ) . |
| 2515 | + "</p>\n"; |
| 2516 | + }*/ |
| 2517 | + |
2509 | 2518 | if($wgUseFileCache) { |
2510 | 2519 | if($wgTitle) { |
2511 | 2520 | $t =& $wgTitle; |
Index: trunk/phase3/includes/db/LoadBalancer.php |
— | — | @@ -398,11 +398,20 @@ |
399 | 399 | /** |
400 | 400 | * Get a connection by index |
401 | 401 | * 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 |
402 | 405 | */ |
403 | 406 | public function &getConnection( $i, $groups = array(), $wiki = false ) { |
404 | 407 | global $wgDBtype; |
405 | 408 | wfProfileIn( __METHOD__ ); |
406 | 409 | |
| 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 | + |
407 | 416 | if ( $wiki === wfWikiID() ) { |
408 | 417 | $wiki = false; |
409 | 418 | } |
— | — | @@ -432,13 +441,13 @@ |
433 | 442 | # Operation-based index |
434 | 443 | if ( $i == DB_SLAVE ) { |
435 | 444 | $i = $this->getReaderIndex( false, $wiki ); |
436 | | - } elseif ( $i == DB_LAST ) { |
437 | | - throw new MWException( 'Attempt to call ' . __METHOD__ . ' with deprecated server index DB_LAST' ); |
| 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 | + } |
438 | 451 | } |
439 | | - # Couldn't find a working server in getReaderIndex()? |
440 | | - if ( $i === false ) { |
441 | | - $this->reportConnectionError( $this->mErrorConnection ); |
442 | | - } |
443 | 452 | |
444 | 453 | # Now we have an explicit index into the servers array |
445 | 454 | $conn = $this->openConnection( $i, $wiki ); |
— | — | @@ -518,7 +527,7 @@ |
519 | 528 | } else { |
520 | 529 | $server = $this->mServers[$i]; |
521 | 530 | $server['serverIndex'] = $i; |
522 | | - $conn = $this->reallyOpenConnection( $server ); |
| 531 | + $conn = $this->reallyOpenConnection( $server, false ); |
523 | 532 | if ( $conn->isOpen() ) { |
524 | 533 | $this->mConns['local'][$i][0] = $conn; |
525 | 534 | } else { |
— | — | @@ -653,31 +662,27 @@ |
654 | 663 | |
655 | 664 | function reportConnectionError( &$conn ) { |
656 | 665 | wfProfileIn( __METHOD__ ); |
657 | | - # Prevent infinite recursion |
658 | 666 | |
659 | | - static $reporting = false; |
660 | | - if ( !$reporting ) { |
661 | | - $reporting = true; |
662 | | - if ( !is_object( $conn ) ) { |
663 | | - // No last connection, probably due to all servers being too busy |
664 | | - $conn = new Database; |
665 | | - if ( $this->mFailFunction ) { |
666 | | - $conn->failFunction( $this->mFailFunction ); |
667 | | - $conn->reportConnectionError( $this->mLastError ); |
668 | | - } else { |
669 | | - // If all servers were busy, mLastError will contain something sensible |
670 | | - throw new DBConnectionError( $conn, $this->mLastError ); |
671 | | - } |
| 667 | + if ( !is_object( $conn ) ) { |
| 668 | + // No last connection, probably due to all servers being too busy |
| 669 | + wfLogDBError( "LB failure with no last connection\n" ); |
| 670 | + $conn = new Database; |
| 671 | + if ( $this->mFailFunction ) { |
| 672 | + $conn->failFunction( $this->mFailFunction ); |
| 673 | + $conn->reportConnectionError( $this->mLastError ); |
672 | 674 | } else { |
673 | | - if ( $this->mFailFunction ) { |
674 | | - $conn->failFunction( $this->mFailFunction ); |
675 | | - } else { |
676 | | - $conn->failFunction( false ); |
677 | | - } |
678 | | - $server = $conn->getProperty( 'mServer' ); |
679 | | - $conn->reportConnectionError( "{$this->mLastError} ({$server})" ); |
| 675 | + // If all servers were busy, mLastError will contain something sensible |
| 676 | + throw new DBConnectionError( $conn, $this->mLastError ); |
680 | 677 | } |
681 | | - $reporting = false; |
| 678 | + } else { |
| 679 | + if ( $this->mFailFunction ) { |
| 680 | + $conn->failFunction( $this->mFailFunction ); |
| 681 | + } else { |
| 682 | + $conn->failFunction( false ); |
| 683 | + } |
| 684 | + $server = $conn->getProperty( 'mServer' ); |
| 685 | + wfLogDBError( "Connection error: {$this->mLastError} ({$server})\n" ); |
| 686 | + $conn->reportConnectionError( "{$this->mLastError} ({$server})" ); |
682 | 687 | } |
683 | 688 | wfProfileOut( __METHOD__ ); |
684 | 689 | } |
Index: trunk/phase3/includes/Revision.php |
— | — | @@ -769,10 +769,13 @@ |
770 | 770 | $flags = Revision::compressRevisionText( $data ); |
771 | 771 | |
772 | 772 | # Write to external storage if required |
773 | | - if ( $wgDefaultExternalStore ) { |
| 773 | + if( $wgDefaultExternalStore ) { |
774 | 774 | // Store and get the URL |
775 | 775 | $data = ExternalStore::insertToDefault( $data ); |
776 | | - if ( $flags ) { |
| 776 | + if( !$data ) { |
| 777 | + throw new MWException( "Unable to store text to external storage" ); |
| 778 | + } |
| 779 | + if( $flags ) { |
777 | 780 | $flags .= ','; |
778 | 781 | } |
779 | 782 | $flags .= 'external'; |
Index: trunk/phase3/includes/ExternalStoreDB.php |
— | — | @@ -123,9 +123,6 @@ |
124 | 124 | */ |
125 | 125 | function store( $cluster, $data ) { |
126 | 126 | $dbw = $this->getMaster( $cluster ); |
127 | | - if( !$dbw ) { |
128 | | - return false; |
129 | | - } |
130 | 127 | $id = $dbw->nextSequenceValue( 'blob_blob_id_seq' ); |
131 | 128 | $dbw->insert( $this->getTable( $dbw ), |
132 | 129 | array( 'blob_id' => $id, 'blob_text' => $data ), |
Property changes on: trunk/phase3/includes/specials/SpecialDeletedContributions.php |
___________________________________________________________________ |
Deleted: svn:mergeinfo |