summaryrefslogtreecommitdiff
path: root/includes/db
diff options
context:
space:
mode:
authorPierre Schmitz <pierre@archlinux.de>2009-02-22 13:37:51 +0100
committerPierre Schmitz <pierre@archlinux.de>2009-02-22 13:37:51 +0100
commitb9b85843572bf283f48285001e276ba7e61b63f6 (patch)
tree4c6f4571552ada9ccfb4030481dcf77308f8b254 /includes/db
parentd9a20acc4e789cca747ad360d87ee3f3e7aa58c1 (diff)
updated to MediaWiki 1.14.0
Diffstat (limited to 'includes/db')
-rw-r--r--includes/db/Database.php308
-rw-r--r--includes/db/DatabaseMssql.php59
-rw-r--r--includes/db/DatabaseOracle.php14
-rw-r--r--includes/db/DatabasePostgres.php89
-rw-r--r--includes/db/DatabaseSqlite.php43
-rw-r--r--includes/db/LBFactory_Multi.php14
-rw-r--r--includes/db/LoadBalancer.php77
-rw-r--r--includes/db/LoadMonitor.php3
8 files changed, 360 insertions, 247 deletions
diff --git a/includes/db/Database.php b/includes/db/Database.php
index 885ede54..84b88643 100644
--- a/includes/db/Database.php
+++ b/includes/db/Database.php
@@ -205,12 +205,17 @@ class Database {
return false;
}
- /**#@+
- * Get function
+ /**
+ * Return the last query that went through Database::query()
+ * @return String
*/
function lastQuery() { return $this->mLastQuery; }
+
+ /**
+ * Is a connection to the database open?
+ * @return Boolean
+ */
function isOpen() { return $this->mOpened; }
- /**#@-*/
function setFlag( $flag ) {
$this->mFlags |= $flag;
@@ -243,13 +248,13 @@ class Database {
# Other functions
#------------------------------------------------------------------------------
- /**@{{
+ /**
* Constructor.
- * @param string $server database server host
- * @param string $user database user name
- * @param string $password database user password
- * @param string $dbname database name
- * @param failFunction
+ * @param $server String: database server host
+ * @param $user String: database user name
+ * @param $password String: database user password
+ * @param $dbName String: database name
+ * @param $failFunction
* @param $flags
* @param $tablePrefix String: database table prefixes. By default use the prefix gave in LocalSettings.php
*/
@@ -293,7 +298,11 @@ class Database {
}
/**
- * @static
+ * Same as new Database( ... ), kept for backward compatibility
+ * @param $server String: database server host
+ * @param $user String: database user name
+ * @param $password String: database user password
+ * @param $dbName String: database name
* @param failFunction
* @param $flags
*/
@@ -305,9 +314,13 @@ class Database {
/**
* Usually aborts on failure
* If the failFunction is set to a non-zero integer, returns success
+ * @param $server String: database server host
+ * @param $user String: database user name
+ * @param $password String: database user password
+ * @param $dbName String: database name
*/
function open( $server, $user, $password, $dbName ) {
- global $wguname, $wgAllDBsAreLocalhost;
+ global $wgAllDBsAreLocalhost;
wfProfileIn( __METHOD__ );
# Test for missing mysql.so
@@ -338,13 +351,17 @@ class Database {
wfProfileIn("dbconnect-$server");
- # Try to connect up to three times
# The kernel's default SYN retransmission period is far too slow for us,
- # so we use a short timeout plus a manual retry.
+ # so we use a short timeout plus a manual retry. Retrying means that a small
+ # but finite rate of SYN packet loss won't cause user-visible errors.
$this->mConn = false;
- $max = 3;
+ if ( ini_get( 'mysql.connect_timeout' ) <= 3 ) {
+ $numAttempts = 2;
+ } else {
+ $numAttempts = 1;
+ }
$this->installErrorHandler();
- for ( $i = 0; $i < $max && !$this->mConn; $i++ ) {
+ for ( $i = 0; $i < $numAttempts && !$this->mConn; $i++ ) {
if ( $i > 1 ) {
usleep( 1000 );
}
@@ -360,23 +377,28 @@ class Database {
}
}
$phpError = $this->restoreErrorHandler();
+ # Always log connection errors
+ if ( !$this->mConn ) {
+ $error = $this->lastError();
+ if ( !$error ) {
+ $error = $phpError;
+ }
+ wfLogDBError( "Error connecting to {$this->mServer}: $error\n" );
+ wfDebug( "DB connection error\n" );
+ wfDebug( "Server: $server, User: $user, Password: " .
+ substr( $password, 0, 3 ) . "..., error: " . mysql_error() . "\n" );
+ $success = false;
+ }
wfProfileOut("dbconnect-$server");
- if ( $dbName != '' ) {
- if ( $this->mConn !== false ) {
- $success = @/**/mysql_select_db( $dbName, $this->mConn );
- if ( !$success ) {
- $error = "Error selecting database $dbName on server {$this->mServer} " .
- "from client host {$wguname['nodename']}\n";
- wfLogDBError(" Error selecting database $dbName on server {$this->mServer} \n");
- wfDebug( $error );
- }
- } else {
- wfDebug( "DB connection error\n" );
- wfDebug( "Server: $server, User: $user, Password: " .
- substr( $password, 0, 3 ) . "..., error: " . mysql_error() . "\n" );
- $success = false;
+ if ( $dbName != '' && $this->mConn !== false ) {
+ $success = @/**/mysql_select_db( $dbName, $this->mConn );
+ if ( !$success ) {
+ $error = "Error selecting database $dbName on server {$this->mServer} " .
+ "from client host " . wfHostname() . "\n";
+ wfLogDBError(" Error selecting database $dbName on server {$this->mServer} \n");
+ wfDebug( $error );
}
} else {
# Delay USE query
@@ -405,16 +427,25 @@ class Database {
wfProfileOut( __METHOD__ );
return $success;
}
- /**@}}*/
protected function installErrorHandler() {
$this->mPHPError = false;
+ $this->htmlErrors = ini_set( 'html_errors', '0' );
set_error_handler( array( $this, 'connectionErrorHandler' ) );
}
protected function restoreErrorHandler() {
restore_error_handler();
- return $this->mPHPError;
+ if ( $this->htmlErrors !== false ) {
+ ini_set( 'html_errors', $this->htmlErrors );
+ }
+ if ( $this->mPHPError ) {
+ $error = preg_replace( '!\[<a.*</a>\]!', '', $this->mPHPError );
+ $error = preg_replace( '!^.*?:(.*)$!', '$1', $error );
+ return $error;
+ } else {
+ return false;
+ }
}
protected function connectionErrorHandler( $errno, $errstr ) {
@@ -425,7 +456,7 @@ class Database {
* Closes a database connection.
* if it is open : commits any open transactions
*
- * @return bool operation success. true if already closed.
+ * @return Bool operation success. true if already closed.
*/
function close()
{
@@ -441,7 +472,7 @@ class Database {
}
/**
- * @param string $error fallback error message, used if none is given by MySQL
+ * @param $error String: fallback error message, used if none is given by MySQL
*/
function reportConnectionError( $error = 'Unknown error' ) {
$myError = $this->lastError();
@@ -457,7 +488,6 @@ class Database {
}
} else {
# New method
- wfLogDBError( "Connection error: $error\n" );
throw new DBConnectionError( $this, $error );
}
}
@@ -468,7 +498,7 @@ class Database {
* @param $sql String: SQL query
* @param $fname String: Name of the calling function, for profiling/SHOW PROCESSLIST
* comment (you can use __METHOD__ or add some extra info)
- * @param $tempIgnore Bool: Whether to avoid throwing an exception on errors...
+ * @param $tempIgnore Boolean: Whether to avoid throwing an exception on errors...
* maybe best to catch the exception instead?
* @return true for a successful write query, ResultWrapper object for a successful read query,
* or false on failure if $tempIgnore set
@@ -572,7 +602,7 @@ class Database {
* The DBMS-dependent part of query()
* @param $sql String: SQL query.
* @return Result object to feed to fetchObject, fetchRow, ...; or false on failure
- * @access private
+ * @private
*/
/*private*/ function doQuery( $sql ) {
if( $this->bufferResults() ) {
@@ -584,11 +614,11 @@ class Database {
}
/**
- * @param $error
- * @param $errno
- * @param $sql
- * @param string $fname
- * @param bool $tempIgnore
+ * @param $error String
+ * @param $errno Integer
+ * @param $sql String
+ * @param $fname String
+ * @param $tempIgnore Boolean
*/
function reportQueryError( $error, $errno, $sql, $fname, $tempIgnore = false ) {
global $wgCommandLineMode;
@@ -630,8 +660,8 @@ class Database {
/**
* Execute a prepared query with the various arguments
- * @param string $prepared the prepared sql
- * @param mixed $args Either an array here, or put scalars as varargs
+ * @param $prepared String: the prepared sql
+ * @param $args Mixed: Either an array here, or put scalars as varargs
*/
function execute( $prepared, $args = null ) {
if( !is_array( $args ) ) {
@@ -646,8 +676,8 @@ class Database {
/**
* Prepare & execute an SQL statement, quoting and inserting arguments
* in the appropriate places.
- * @param string $query
- * @param string $args ...
+ * @param $query String
+ * @param $args ...
*/
function safeQuery( $query, $args = null ) {
$prepared = $this->prepare( $query, 'Database::safeQuery' );
@@ -664,8 +694,8 @@ class Database {
/**
* For faking prepared SQL statements on DBs that don't support
* it directly.
- * @param string $preparedSql - a 'preparable' SQL statement
- * @param array $args - array of arguments to fill it with
+ * @param $preparedQuery String: a 'preparable' SQL statement
+ * @param $args Array of arguments to fill it with
* @return string executable SQL
*/
function fillPrepared( $preparedQuery, $args ) {
@@ -680,8 +710,8 @@ class Database {
* The arguments should be in $this->preparedArgs and must not be touched
* while we're doing this.
*
- * @param array $matches
- * @return string
+ * @param $matches Array
+ * @return String
* @private
*/
function fillPreparedArg( $matches ) {
@@ -702,11 +732,9 @@ class Database {
}
}
- /**#@+
- * @param mixed $res A SQL result
- */
/**
* Free a result object
+ * @param $res Mixed: A SQL result
*/
function freeResult( $res ) {
if ( $res instanceof ResultWrapper ) {
@@ -758,6 +786,7 @@ class Database {
/**
* Get the number of rows in a result object
+ * @param $res Mixed: A SQL result
*/
function numRows( $res ) {
if ( $res instanceof ResultWrapper ) {
@@ -773,6 +802,7 @@ class Database {
/**
* Get the number of fields in a result object
* See documentation for mysql_num_fields()
+ * @param $res Mixed: A SQL result
*/
function numFields( $res ) {
if ( $res instanceof ResultWrapper ) {
@@ -785,6 +815,8 @@ class Database {
* Get a field name in a result object
* See documentation for mysql_field_name():
* http://www.php.net/mysql_field_name
+ * @param $res Mixed: A SQL result
+ * @param $n Integer
*/
function fieldName( $res, $n ) {
if ( $res instanceof ResultWrapper ) {
@@ -808,6 +840,8 @@ class Database {
/**
* Change the position of the cursor in a result object
* See mysql_data_seek()
+ * @param $res Mixed: A SQL result
+ * @param $row Mixed: Either MySQL row or ResultWrapper
*/
function dataSeek( $res, $row ) {
if ( $res instanceof ResultWrapper ) {
@@ -854,7 +888,6 @@ class Database {
* See mysql_affected_rows() for more details
*/
function affectedRows() { return mysql_affected_rows( $this->mConn ); }
- /**#@-*/ // end of template : @param $result
/**
* Simple UPDATE wrapper
@@ -864,8 +897,7 @@ class Database {
* This function exists for historical reasons, Database::update() has a more standard
* calling convention and feature set
*/
- function set( $table, $var, $value, $cond, $fname = 'Database::set' )
- {
+ function set( $table, $var, $value, $cond, $fname = 'Database::set' ) {
$table = $this->tableName( $table );
$sql = "UPDATE $table SET $var = '" .
$this->strencode( $value ) . "' WHERE ($cond)";
@@ -890,7 +922,7 @@ class Database {
$row = $this->fetchRow( $res );
if ( $row !== false ) {
$this->freeResult( $res );
- return $row[0];
+ return reset( $row );
} else {
return false;
}
@@ -902,9 +934,9 @@ class Database {
*
* @private
*
- * @param array $options an associative array of options to be turned into
+ * @param $options Array: associative array of options to be turned into
* an SQL query, valid keys are listed in the function.
- * @return array
+ * @return Array
*/
function makeSelectOptions( $options ) {
$preLimitTail = $postLimitTail = '';
@@ -953,14 +985,14 @@ class Database {
/**
* SELECT wrapper
*
- * @param mixed $table Array or string, table name(s) (prefix auto-added)
- * @param mixed $vars Array or string, field name(s) to be retrieved
- * @param mixed $conds Array or string, condition(s) for WHERE
- * @param string $fname Calling function name (use __METHOD__) for logs/profiling
- * @param array $options Associative array of options (e.g. array('GROUP BY' => 'page_title')),
- * see Database::makeSelectOptions code for list of supported stuff
- * @param array $join_conds Associative array of table join conditions (optional)
- * (e.g. array( 'page' => array('LEFT JOIN','page_latest=rev_id') )
+ * @param $table Mixed: Array or string, table name(s) (prefix auto-added)
+ * @param $vars Mixed: Array or string, field name(s) to be retrieved
+ * @param $conds Mixed: Array or string, condition(s) for WHERE
+ * @param $fname String: Calling function name (use __METHOD__) for logs/profiling
+ * @param $options Array: Associative array of options (e.g. array('GROUP BY' => 'page_title')),
+ * see Database::makeSelectOptions code for list of supported stuff
+ * @param $join_conds Array: Associative array of table join conditions (optional)
+ * (e.g. array( 'page' => array('LEFT JOIN','page_latest=rev_id') )
* @return mixed Database result resource (feed to Database::fetchObject or whatever), or false on failure
*/
function select( $table, $vars, $conds='', $fname = 'Database::select', $options = array(), $join_conds = array() )
@@ -972,14 +1004,14 @@ class Database {
/**
* SELECT wrapper
*
- * @param mixed $table Array or string, table name(s) (prefix auto-added)
- * @param mixed $vars Array or string, field name(s) to be retrieved
- * @param mixed $conds Array or string, condition(s) for WHERE
- * @param string $fname Calling function name (use __METHOD__) for logs/profiling
- * @param array $options Associative array of options (e.g. array('GROUP BY' => 'page_title')),
- * see Database::makeSelectOptions code for list of supported stuff
- * @param array $join_conds Associative array of table join conditions (optional)
- * (e.g. array( 'page' => array('LEFT JOIN','page_latest=rev_id') )
+ * @param $table Mixed: Array or string, table name(s) (prefix auto-added)
+ * @param $vars Mixed: Array or string, field name(s) to be retrieved
+ * @param $conds Mixed: Array or string, condition(s) for WHERE
+ * @param $fname String: Calling function name (use __METHOD__) for logs/profiling
+ * @param $options Array: Associative array of options (e.g. array('GROUP BY' => 'page_title')),
+ * see Database::makeSelectOptions code for list of supported stuff
+ * @param $join_conds Array: Associative array of table join conditions (optional)
+ * (e.g. array( 'page' => array('LEFT JOIN','page_latest=rev_id') )
* @return string, the SQL text
*/
function selectSQLText( $table, $vars, $conds='', $fname = 'Database::select', $options = array(), $join_conds = array() ) {
@@ -1030,13 +1062,17 @@ class Database {
* Single row SELECT wrapper
* Aborts or returns FALSE on error
*
- * $vars: the selected variables
- * $conds: a condition map, terms are ANDed together.
+ * @param $table String: table name
+ * @param $vars String: the selected variables
+ * @param $conds Array: a condition map, terms are ANDed together.
* Items with numeric keys are taken to be literal conditions
* Takes an array of selected variables, and a condition map, which is ANDed
* e.g: selectRow( "page", array( "page_id" ), array( "page_namespace" =>
* NS_MAIN, "page_title" => "Astronomy" ) ) would return an object where
* $obj- >page_id is the ID of the Astronomy article
+ * @param $fname String: Calling functio name
+ * @param $options Array
+ * @param $join_conds Array
*
* @todo migrate documentation to phpdocumentor format
*/
@@ -1086,8 +1122,7 @@ class Database {
* Removes most variables from an SQL query and replaces them with X or N for numbers.
* It's only slightly flawed. Don't use for anything important.
*
- * @param string $sql A SQL Query
- * @static
+ * @param $sql String: A SQL Query
*/
static function generalizeSQL( $sql ) {
# This does the same as the regexp below would do, but in such a way
@@ -1280,7 +1315,7 @@ class Database {
* Make UPDATE options for the Database::update function
*
* @private
- * @param array $options The options passed to Database::update
+ * @param $options Array: The options passed to Database::update
* @return string
*/
function makeUpdateOptions( $options ) {
@@ -1298,14 +1333,14 @@ class Database {
/**
* UPDATE wrapper, takes a condition array and a SET array
*
- * @param string $table The table to UPDATE
- * @param array $values An array of values to SET
- * @param array $conds An array of conditions (WHERE). Use '*' to update all rows.
- * @param string $fname The Class::Function calling this function
- * (for the log)
- * @param array $options An array of UPDATE options, can be one or
+ * @param $table String: The table to UPDATE
+ * @param $values Array: An array of values to SET
+ * @param $conds Array: An array of conditions (WHERE). Use '*' to update all rows.
+ * @param $fname String: The Class::Function calling this function
+ * (for the log)
+ * @param $options Array: An array of UPDATE options, can be one or
* more of IGNORE, LOW_PRIORITY
- * @return bool
+ * @return Boolean
*/
function update( $table, $values, $conds, $fname = 'Database::update', $options = array() ) {
$table = $this->tableName( $table );
@@ -1410,8 +1445,8 @@ class Database {
* themselves. Pass the canonical name to such functions. This is only needed
* when calling query() directly.
*
- * @param string $name database table name
- * @return string full database name
+ * @param $name String: database table name
+ * @return String: full database name
*/
function tableName( $name ) {
global $wgSharedDB, $wgSharedPrefix, $wgSharedTables;
@@ -1540,8 +1575,8 @@ class Database {
/**
* Wrapper for addslashes()
- * @param string $s String to be slashed.
- * @return string slashed string.
+ * @param $s String: to be slashed.
+ * @return String: slashed string.
*/
function strencode( $s ) {
return mysql_real_escape_string( $s, $this->mConn );
@@ -1632,11 +1667,12 @@ class Database {
*
* DO NOT put the join condition in $conds
*
- * @param string $delTable The table to delete from.
- * @param string $joinTable The other table.
- * @param string $delVar The variable to join on, in the first table.
- * @param string $joinVar The variable to join on, in the second table.
- * @param array $conds Condition array of field names mapped to variables, ANDed together in the WHERE clause
+ * @param $delTable String: The table to delete from.
+ * @param $joinTable String: The other table.
+ * @param $delVar String: The variable to join on, in the first table.
+ * @param $joinVar String: The variable to join on, in the second table.
+ * @param $conds Array: Condition array of field names mapped to variables, ANDed together in the WHERE clause
+ * @param $fname String: Calling function name (use __METHOD__) for logs/profiling
*/
function deleteJoin( $delTable, $joinTable, $delVar, $joinVar, $conds, $fname = 'Database::deleteJoin' ) {
if ( !$conds ) {
@@ -1732,9 +1768,9 @@ class Database {
/**
* Construct a LIMIT query with optional offset
* This is used for query pages
- * $sql string SQL query we will append the limit too
- * $limit integer the SQL limit
- * $offset integer the SQL offset (default false)
+ * @param $sql String: SQL query we will append the limit too
+ * @param $limit Integer: the SQL limit
+ * @param $offset Integer the SQL offset (default false)
*/
function limitResult($sql, $limit, $offset=false) {
if( !is_numeric($limit) ) {
@@ -1752,10 +1788,10 @@ class Database {
* Returns an SQL expression for a simple conditional.
* Uses IF on MySQL.
*
- * @param string $cond SQL expression which will result in a boolean value
- * @param string $trueVal SQL expression to return if true
- * @param string $falseVal SQL expression to return if false
- * @return string SQL fragment
+ * @param $cond String: SQL expression which will result in a boolean value
+ * @param $trueVal String: SQL expression to return if true
+ * @param $falseVal String: SQL expression to return if false
+ * @return String: SQL fragment
*/
function conditional( $cond, $trueVal, $falseVal ) {
return " IF($cond, $trueVal, $falseVal) ";
@@ -1765,9 +1801,9 @@ class Database {
* Returns a comand for str_replace function in SQL query.
* Uses REPLACE() in MySQL
*
- * @param string $orig String or column to modify
- * @param string $old String or column to seek
- * @param string $new String or column to replace with
+ * @param $orig String: column to modify
+ * @param $old String: column to seek
+ * @param $new String: column to replace with
*/
function strreplace( $orig, $old, $new ) {
return "REPLACE({$orig}, {$old}, {$new})";
@@ -1838,9 +1874,8 @@ class Database {
/**
* Do a SELECT MASTER_POS_WAIT()
*
- * @param string $file the binlog file
- * @param string $pos the binlog position
- * @param integer $timeout the maximum number of seconds to wait for synchronisation
+ * @param $pos MySQLMasterPos object
+ * @param $timeout Integer: the maximum number of seconds to wait for synchronisation
*/
function masterPosWait( MySQLMasterPos $pos, $timeout ) {
$fname = 'Database::masterPosWait';
@@ -1896,7 +1931,8 @@ class Database {
$res = $this->query( 'SHOW SLAVE STATUS', 'Database::getSlavePos' );
$row = $this->fetchObject( $res );
if ( $row ) {
- return new MySQLMasterPos( $row->Master_Log_File, $row->Read_Master_Log_Pos );
+ $pos = isset($row->Exec_master_log_pos) ? $row->Exec_master_log_pos : $row->Exec_Master_Log_Pos;
+ return new MySQLMasterPos( $row->Relay_Master_Log_File, $pos );
} else {
return false;
}
@@ -2001,14 +2037,14 @@ class Database {
}
/**
- * @return string wikitext of a link to the server software's web site
+ * @return String: wikitext of a link to the server software's web site
*/
function getSoftwareLink() {
return "[http://www.mysql.com/ MySQL]";
}
/**
- * @return string Version information from the database
+ * @return String: Version information from the database
*/
function getServerVersion() {
return mysql_get_server_info( $this->mConn );
@@ -2106,7 +2142,7 @@ class Database {
* May be useful for very long batch queries such as
* full-wiki dumps, where a single query reads out
* over hours or days.
- * @param int $timeout in seconds
+ * @param $timeout Integer in seconds
*/
public function setTimeout( $timeout ) {
$this->query( "SET net_read_timeout=$timeout" );
@@ -2116,9 +2152,9 @@ class Database {
/**
* Read and execute SQL commands from a file.
* Returns true on success, error string or exception on failure (depending on object's error ignore settings)
- * @param string $filename File name to open
- * @param callback $lineCallback Optional function called before reading each line
- * @param callback $resultCallback Optional function called for each MySQL result
+ * @param $filename String: File name to open
+ * @param $lineCallback Callback: Optional function called before reading each line
+ * @param $resultCallback Callback: Optional function called for each MySQL result
*/
function sourceFile( $filename, $lineCallback = false, $resultCallback = false ) {
$fp = fopen( $filename, 'r' );
@@ -2133,9 +2169,9 @@ class Database {
/**
* Read and execute commands from an open file handle
* Returns true on success, error string or exception on failure (depending on object's error ignore settings)
- * @param string $fp File handle
- * @param callback $lineCallback Optional function called before reading each line
- * @param callback $resultCallback Optional function called for each MySQL result
+ * @param $fp String: File handle
+ * @param $lineCallback Callback: Optional function called before reading each line
+ * @param $resultCallback Callback: Optional function called for each MySQL result
*/
function sourceStream( $fp, $lineCallback = false, $resultCallback = false ) {
$cmd = "";
@@ -2177,7 +2213,7 @@ class Database {
$cmd = $this->replaceVars( $cmd );
$res = $this->query( $cmd, __METHOD__ );
if ( $resultCallback ) {
- call_user_func( $resultCallback, $res );
+ call_user_func( $resultCallback, $res, $this );
}
if ( false === $res ) {
@@ -2240,8 +2276,8 @@ class Database {
* Abstracted from Filestore::lock() so child classes can implement for
* their own needs.
*
- * @param string $lockName Name of lock to aquire
- * @param string $method Name of method calling us
+ * @param $lockName String: Name of lock to aquire
+ * @param $method String: Name of method calling us
* @return bool
*/
public function lock( $lockName, $method ) {
@@ -2263,14 +2299,24 @@ class Database {
* @todo fixme - Figure out a way to return a bool
* based on successful lock release.
*
- * @param string $lockName Name of lock to release
- * @param string $method Name of method calling us
+ * @param $lockName String: Name of lock to release
+ * @param $method String: Name of method calling us
*/
public function unlock( $lockName, $method ) {
$lockName = $this->addQuotes( $lockName );
$result = $this->query( "SELECT RELEASE_LOCK($lockName)", $method );
$this->freeResult( $result );
}
+
+ /**
+ * Get search engine class. All subclasses of this
+ * need to implement this if they wish to use searching.
+ *
+ * @return String
+ */
+ public function getSearchEngine() {
+ return "SearchMySQL";
+ }
}
/**
@@ -2390,8 +2436,8 @@ class DBError extends MWException {
/**
* Construct a database error
- * @param Database $db The database object which threw the error
- * @param string $error A simple error message to be used for debugging
+ * @param $db Database object which threw the error
+ * @param $error A simple error message to be used for debugging
*/
function __construct( Database &$db, $error ) {
$this->db =& $db;
@@ -2483,7 +2529,13 @@ border=\"0\" ALT=\"Google\"></A>
}
$text = str_replace( '$1', $this->error, $noconnect );
- $text .= wfGetSiteNotice();
+
+ /*
+ if ( $GLOBALS['wgShowExceptionDetails'] ) {
+ $text .= '</p><p>Backtrace:</p><p>' .
+ nl2br( htmlspecialchars( $this->getTraceAsString() ) ) .
+ "</p>\n";
+ }*/
if($wgUseFileCache) {
if($wgTitle) {
@@ -2504,13 +2556,13 @@ border=\"0\" ALT=\"Google\"></A>
$cache = new HTMLFileCache( $t );
if( $cache->isFileCached() ) {
// @todo, FIXME: $msg is not defined on the next line.
- $msg = '<p style="color: red"><b>'.$msg."<br />\n" .
+ $msg = '<p style="color: red"><b>'.$text."<br />\n" .
$cachederror . "</b></p>\n";
$tag = '<div id="article">';
$text = str_replace(
$tag,
- $tag . $msg,
+ $tag . $text,
$cache->fetchPageText() );
}
}
diff --git a/includes/db/DatabaseMssql.php b/includes/db/DatabaseMssql.php
index 32fe28b1..28ccab2d 100644
--- a/includes/db/DatabaseMssql.php
+++ b/includes/db/DatabaseMssql.php
@@ -105,7 +105,7 @@ class DatabaseMssql extends Database {
$success = @/**/mssql_select_db($dbName, $this->mConn);
if (!$success) {
$error = "Error selecting database $dbName on server {$this->mServer} " .
- "from client host {$wguname['nodename']}\n";
+ "from client host " . wfHostname() . "\n";
wfLogDBError(" Error selecting database $dbName on server {$this->mServer} \n");
wfDebug( $error );
}
@@ -154,9 +154,6 @@ class DatabaseMssql extends Database {
return $ret;
}
- /**#@+
- * @param mixed $res A SQL result
- */
/**
* Free a result object
*/
@@ -225,6 +222,7 @@ class DatabaseMssql extends Database {
/**
* Get the number of fields in a result object
* See documentation for mysql_num_fields()
+ * @param $res SQL result object as returned from Database::query(), etc.
*/
function numFields( $res ) {
if ( $res instanceof ResultWrapper ) {
@@ -237,6 +235,8 @@ class DatabaseMssql extends Database {
* Get a field name in a result object
* See documentation for mysql_field_name():
* http://www.php.net/mysql_field_name
+ * @param $res SQL result object as returned from Database::query(), etc.
+ * @param $n Int
*/
function fieldName( $res, $n ) {
if ( $res instanceof ResultWrapper ) {
@@ -263,6 +263,8 @@ class DatabaseMssql extends Database {
/**
* Change the position of the cursor in a result object
* See mysql_data_seek()
+ * @param $res SQL result object as returned from Database::query(), etc.
+ * @param $row Database row
*/
function dataSeek( $res, $row ) {
if ( $res instanceof ResultWrapper ) {
@@ -339,7 +341,7 @@ class DatabaseMssql extends Database {
*
* @private
*
- * @param array $options an associative array of options to be turned into
+ * @param $options Array: an associative array of options to be turned into
* an SQL query, valid keys are listed in the function.
* @return array
*/
@@ -390,11 +392,11 @@ class DatabaseMssql extends Database {
/**
* SELECT wrapper
*
- * @param mixed $table Array or string, table name(s) (prefix auto-added)
- * @param mixed $vars Array or string, field name(s) to be retrieved
- * @param mixed $conds Array or string, condition(s) for WHERE
- * @param string $fname Calling function name (use __METHOD__) for logs/profiling
- * @param array $options Associative array of options (e.g. array('GROUP BY' => 'page_title')),
+ * @param $table Mixed: Array or string, table name(s) (prefix auto-added)
+ * @param $vars Mixed: Array or string, field name(s) to be retrieved
+ * @param $conds Mixed: Array or string, condition(s) for WHERE
+ * @param $fname String: Calling function name (use __METHOD__) for logs/profiling
+ * @param $options Array: Associative array of options (e.g. array('GROUP BY' => 'page_title')),
* see Database::makeSelectOptions code for list of supported stuff
* @return mixed Database result resource (feed to Database::fetchObject or whatever), or false on failure
*/
@@ -643,12 +645,12 @@ class DatabaseMssql extends Database {
/**
* UPDATE wrapper, takes a condition array and a SET array
*
- * @param string $table The table to UPDATE
- * @param array $values An array of values to SET
- * @param array $conds An array of conditions (WHERE). Use '*' to update all rows.
- * @param string $fname The Class::Function calling this function
- * (for the log)
- * @param array $options An array of UPDATE options, can be one or
+ * @param $table String: The table to UPDATE
+ * @param $values Array: An array of values to SET
+ * @param $conds Array: An array of conditions (WHERE). Use '*' to update all rows.
+ * @param $fname String: The Class::Function calling this function
+ * (for the log)
+ * @param $options Array: An array of UPDATE options, can be one or
* more of IGNORE, LOW_PRIORITY
* @return bool
*/
@@ -666,7 +668,7 @@ class DatabaseMssql extends Database {
* Make UPDATE options for the Database::update function
*
* @private
- * @param array $options The options passed to Database::update
+ * @param $options Array: The options passed to Database::update
* @return string
*/
function makeUpdateOptions( $options ) {
@@ -698,7 +700,7 @@ class DatabaseMssql extends Database {
/**
* MSSQL doubles quotes instead of escaping them
- * @param string $s String to be slashed.
+ * @param $s String to be slashed.
* @return string slashed string.
*/
function strencode($s) {
@@ -755,11 +757,12 @@ class DatabaseMssql extends Database {
*
* DO NOT put the join condition in $conds
*
- * @param string $delTable The table to delete from.
- * @param string $joinTable The other table.
- * @param string $delVar The variable to join on, in the first table.
- * @param string $joinVar The variable to join on, in the second table.
- * @param array $conds Condition array of field names mapped to variables, ANDed together in the WHERE clause
+ * @param $delTable String: The table to delete from.
+ * @param $joinTable String: The other table.
+ * @param $delVar String: The variable to join on, in the first table.
+ * @param $joinVar String: The variable to join on, in the second table.
+ * @param $conds Array: Condition array of field names mapped to variables, ANDed together in the WHERE clause
+ * @param $fname String: Calling function name
*/
function deleteJoin( $delTable, $joinTable, $delVar, $joinVar, $conds, $fname = 'Database::deleteJoin' ) {
if ( !$conds ) {
@@ -857,9 +860,9 @@ class DatabaseMssql extends Database {
/**
* Returns an SQL expression for a simple conditional.
*
- * @param string $cond SQL expression which will result in a boolean value
- * @param string $trueVal SQL expression to return if true
- * @param string $falseVal SQL expression to return if false
+ * @param $cond String: SQL expression which will result in a boolean value
+ * @param $trueVal String: SQL expression to return if true
+ * @param $falseVal String: SQL expression to return if false
* @return string SQL fragment
*/
function conditional( $cond, $trueVal, $falseVal ) {
@@ -1007,6 +1010,10 @@ class DatabaseMssql extends Database {
public function unlock( $lockName, $method ) {
return true;
}
+
+ public function getSearchEngine() {
+ return "SearchEngineDummy";
+ }
}
diff --git a/includes/db/DatabaseOracle.php b/includes/db/DatabaseOracle.php
index f4dbac71..4c37a507 100644
--- a/includes/db/DatabaseOracle.php
+++ b/includes/db/DatabaseOracle.php
@@ -509,10 +509,10 @@ class DatabaseOracle extends Database {
* Returns an SQL expression for a simple conditional.
* Uses CASE on Oracle
*
- * @param string $cond SQL expression which will result in a boolean value
- * @param string $trueVal SQL expression to return if true
- * @param string $falseVal SQL expression to return if false
- * @return string SQL fragment
+ * @param $cond String: SQL expression which will result in a boolean value
+ * @param $trueVal String: SQL expression to return if true
+ * @param $falseVal String: SQL expression to return if false
+ * @return String: SQL fragment
*/
function conditional( $cond, $trueVal, $falseVal ) {
return " (CASE WHEN $cond THEN $trueVal ELSE $falseVal END) ";
@@ -640,7 +640,7 @@ echo "error!\n";
*
* @private
*
- * @param array $options an associative array of options to be turned into
+ * @param $options Array: an associative array of options to be turned into
* an SQL query, valid keys are listed in the function.
* @return array
*/
@@ -716,5 +716,9 @@ echo "error!\n";
public function unlock( $lockName, $method ) {
return true;
}
+
+ public function getSearchEngine() {
+ return "SearchOracle";
+ }
} // end DatabaseOracle class
diff --git a/includes/db/DatabasePostgres.php b/includes/db/DatabasePostgres.php
index 8fd04cb6..16a74b53 100644
--- a/includes/db/DatabasePostgres.php
+++ b/includes/db/DatabasePostgres.php
@@ -78,12 +78,6 @@ class DatabasePostgres extends Database {
$failFunction = false, $flags = 0 )
{
- global $wgOut;
- # Can't get a reference if it hasn't been set yet
- if ( !isset( $wgOut ) ) {
- $wgOut = NULL;
- }
- $this->mOut =& $wgOut;
$this->mFailFunction = $failFunction;
$this->mFlags = $flags;
$this->open( $server, $user, $password, $dbName);
@@ -138,10 +132,9 @@ class DatabasePostgres extends Database {
global $wgDBport;
- if (!strlen($user)) { ## e.g. the class is being loaded
- return;
+ if (!strlen($user)) { ## e.g. the class is being loaded
+ return;
}
-
$this->close();
$this->mServer = $server;
$this->mPort = $port = $wgDBport;
@@ -149,22 +142,31 @@ class DatabasePostgres extends Database {
$this->mPassword = $password;
$this->mDBname = $dbName;
- $hstring="";
+ $connectVars = array(
+ 'dbname' => $dbName,
+ 'user' => $user,
+ 'password' => $password );
if ($server!=false && $server!="") {
- $hstring="host=$server ";
+ $connectVars['host'] = $server;
}
if ($port!=false && $port!="") {
- $hstring .= "port=$port ";
+ $connectVars['port'] = $port;
}
+ $connectString = $this->makeConnectionString( $connectVars );
- error_reporting( E_ALL );
- @$this->mConn = pg_connect("$hstring dbname=$dbName user=$user password=$password");
+ $this->installErrorHandler();
+ $this->mConn = pg_connect( $connectString );
+ $phpError = $this->restoreErrorHandler();
if ( $this->mConn == false ) {
wfDebug( "DB connection error\n" );
wfDebug( "Server: $server, Database: $dbName, User: $user, Password: " . substr( $password, 0, 3 ) . "...\n" );
wfDebug( $this->lastError()."\n" );
- return false;
+ if ( !$this->mFailFunction ) {
+ throw new DBConnectionError( $this, $phpError );
+ } else {
+ return false;
+ }
}
$this->mOpened = true;
@@ -189,6 +191,14 @@ class DatabasePostgres extends Database {
return $this->mConn;
}
+ function makeConnectionString( $vars ) {
+ $s = '';
+ foreach ( $vars as $name => $value ) {
+ $s .= "$name='" . str_replace( "'", "\\'", $value ) . "' ";
+ }
+ return $s;
+ }
+
function initial_setup($password, $dbName) {
// If this is the initial connection, setup the schema stuff and possibly create the user
@@ -197,9 +207,8 @@ class DatabasePostgres extends Database {
print "<li>Checking the version of Postgres...";
$version = $this->getServerVersion();
$PGMINVER = '8.1';
- if ($this->numeric_version < $PGMINVER) {
- print "<b>FAILED</b>. Required version is $PGMINVER. You have " .
- htmlspecialchars( $this->numeric_version ) . " (" . htmlspecialchars( $version ) . ")</li>\n";
+ if ($version < $PGMINVER) {
+ print "<b>FAILED</b>. Required version is $PGMINVER. You have " . htmlspecialchars( $version ) . "</li>\n";
dieout("</ul>");
}
print "version " . htmlspecialchars( $this->numeric_version ) . " is OK.</li>\n";
@@ -730,10 +739,10 @@ class DatabasePostgres extends Database {
* $args may be a single associative array, or an array of these with numeric keys,
* for multi-row insert (Postgres version 8.2 and above only).
*
- * @param array $table String: Name of the table to insert to.
- * @param array $args Array: Items to insert into the table.
- * @param array $fname String: Name of the function, for profiling
- * @param mixed $options String or Array. Valid options: IGNORE
+ * @param $table String: Name of the table to insert to.
+ * @param $args Array: Items to insert into the table.
+ * @param $fname String: Name of the function, for profiling
+ * @param $options String or Array. Valid options: IGNORE
*
* @return bool Success of insert operation. IGNORE always returns true.
*/
@@ -746,8 +755,7 @@ class DatabasePostgres extends Database {
$table = $this->tableName( $table );
if (! isset( $wgDBversion ) ) {
- $this->getServerVersion();
- $wgDBversion = $this->numeric_version;
+ $wgDBversion = $this->getServerVersion();
}
if ( !is_array( $options ) )
@@ -1009,10 +1017,10 @@ class DatabasePostgres extends Database {
* Returns an SQL expression for a simple conditional.
* Uses CASE on Postgres
*
- * @param string $cond SQL expression which will result in a boolean value
- * @param string $trueVal SQL expression to return if true
- * @param string $falseVal SQL expression to return if false
- * @return string SQL fragment
+ * @param $cond String: SQL expression which will result in a boolean value
+ * @param $trueVal String: SQL expression to return if true
+ * @param $falseVal String: SQL expression to return if false
+ * @return String: SQL fragment
*/
function conditional( $cond, $trueVal, $falseVal ) {
return " (CASE WHEN $cond THEN $trueVal ELSE $falseVal END) ";
@@ -1055,7 +1063,7 @@ class DatabasePostgres extends Database {
/**
* @return string wikitext of a link to the server software's web site
*/
- function getSoftwareLink() {
+ function getSoftwareLink() {
return "[http://www.postgresql.org/ PostgreSQL]";
}
@@ -1063,16 +1071,17 @@ class DatabasePostgres extends Database {
* @return string Version information from the database
*/
function getServerVersion() {
- $version = pg_fetch_result($this->doQuery("SELECT version()"),0,0);
- $thisver = array();
- if (!preg_match('/PostgreSQL (\d+\.\d+)(\S+)/', $version, $thisver)) {
- die("Could not determine the numeric version from $version!");
+ $versionInfo = pg_version( $this->mConn );
+ if ( isset( $versionInfo['server'] ) ) {
+ $this->numeric_version = $versionInfo['server'];
+ } else {
+ // There's no way to identify the precise version before 7.4, but
+ // it doesn't matter anyway since we're just going to give an error.
+ $this->numeric_version = '7.3 or earlier';
}
- $this->numeric_version = $thisver[1];
- return $version;
+ return $this->numeric_version;
}
-
/**
* Query whether a given relation exists (in the given schema, or the
* default mw one if not given)
@@ -1319,7 +1328,7 @@ END;
*
* @private
*
- * @param string $com SQL string, read from a stream (usually tables.sql)
+ * @param $ins String: SQL string, read from a stream (usually tables.sql)
*
* @return string SQL string
*/
@@ -1344,7 +1353,7 @@ END;
*
* @private
*
- * @param array $options an associative array of options to be turned into
+ * @param $options Array: an associative array of options to be turned into
* an SQL query, valid keys are listed in the function.
* @return array
*/
@@ -1417,5 +1426,9 @@ END;
public function unlock( $lockName, $method ) {
return true;
}
+
+ public function getSearchEngine() {
+ return "SearchPostgres";
+ }
} // end DatabasePostgres class
diff --git a/includes/db/DatabaseSqlite.php b/includes/db/DatabaseSqlite.php
index 112c417b..dfc506cc 100644
--- a/includes/db/DatabaseSqlite.php
+++ b/includes/db/DatabaseSqlite.php
@@ -20,11 +20,9 @@ class DatabaseSqlite extends Database {
* Constructor
*/
function __construct($server = false, $user = false, $password = false, $dbName = false, $failFunction = false, $flags = 0) {
- global $wgOut,$wgSQLiteDataDir;
+ global $wgOut,$wgSQLiteDataDir, $wgSQLiteDataDirMode;
if ("$wgSQLiteDataDir" == '') $wgSQLiteDataDir = dirname($_SERVER['DOCUMENT_ROOT']).'/data';
- if (!is_dir($wgSQLiteDataDir)) mkdir($wgSQLiteDataDir,0700);
- if (!isset($wgOut)) $wgOut = NULL; # Can't get a reference if it hasn't been set yet
- $this->mOut =& $wgOut;
+ if (!is_dir($wgSQLiteDataDir)) wfMkdirParents( $wgSQLiteDataDir, $wgSQLiteDataDirMode );
$this->mFailFunction = $failFunction;
$this->mFlags = $flags;
$this->mDatabaseFile = "$wgSQLiteDataDir/$dbName.sqlite";
@@ -48,11 +46,28 @@ class DatabaseSqlite extends Database {
$this->mConn = false;
if ($dbName) {
$file = $this->mDatabaseFile;
- if ($this->mFlags & DBO_PERSISTENT) $this->mConn = new PDO("sqlite:$file",$user,$pass,array(PDO::ATTR_PERSISTENT => true));
- else $this->mConn = new PDO("sqlite:$file",$user,$pass);
- if ($this->mConn === false) wfDebug("DB connection error: $err\n");;
+ try {
+ if ( $this->mFlags & DBO_PERSISTENT ) {
+ $this->mConn = new PDO( "sqlite:$file", $user, $pass,
+ array( PDO::ATTR_PERSISTENT => true ) );
+ } else {
+ $this->mConn = new PDO( "sqlite:$file", $user, $pass );
+ }
+ } catch ( PDOException $e ) {
+ $err = $e->getMessage();
+ }
+ if ( $this->mConn === false ) {
+ wfDebug( "DB connection error: $err\n" );
+ if ( !$this->mFailFunction ) {
+ throw new DBConnectionError( $this, $err );
+ } else {
+ return false;
+ }
+
+ }
$this->mOpened = $this->mConn;
- $this->mConn->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_SILENT); # set error codes only, dont raise exceptions
+ # set error codes only, don't raise exceptions
+ $this->mConn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT );
}
return $this->mConn;
}
@@ -390,7 +405,19 @@ class DatabaseSqlite extends Database {
public function unlock( $lockName, $method ) {
return true;
}
+
+ public function getSearchEngine() {
+ return "SearchEngineDummy";
+ }
+ /**
+ * No-op version of deadlockLoop
+ */
+ public function deadlockLoop( /*...*/ ) {
+ $args = func_get_args();
+ $function = array_shift( $args );
+ return call_user_func_array( $function, $args );
+ }
}
/**
diff --git a/includes/db/LBFactory_Multi.php b/includes/db/LBFactory_Multi.php
index 48c2d99b..820aa2ea 100644
--- a/includes/db/LBFactory_Multi.php
+++ b/includes/db/LBFactory_Multi.php
@@ -36,6 +36,8 @@
*
* masterTemplateOverrides An override array for all master servers.
*
+ * readOnlyBySection A map of section name to read-only message. Missing or false for read/write.
+ *
* @ingroup Database
*/
class LBFactory_Multi extends LBFactory {
@@ -44,7 +46,7 @@ class LBFactory_Multi extends LBFactory {
// Optional settings
var $groupLoadsBySection = array(), $groupLoadsByDB = array(), $hostsByName = array();
var $externalLoads = array(), $externalTemplateOverrides, $templateOverridesByServer;
- var $templateOverridesByCluster, $masterTemplateOverrides;
+ var $templateOverridesByCluster, $masterTemplateOverrides, $readOnlyBySection = array();
// Other stuff
var $conf, $mainLBs = array(), $extLBs = array();
var $lastWiki, $lastSection;
@@ -55,7 +57,8 @@ class LBFactory_Multi extends LBFactory {
$required = array( 'sectionsByDB', 'sectionLoads', 'serverTemplate' );
$optional = array( 'groupLoadsBySection', 'groupLoadsByDB', 'hostsByName',
'externalLoads', 'externalTemplateOverrides', 'templateOverridesByServer',
- 'templateOverridesByCluster', 'masterTemplateOverrides' );
+ 'templateOverridesByCluster', 'masterTemplateOverrides',
+ 'readOnlyBySection' );
foreach ( $required as $key ) {
if ( !isset( $conf[$key] ) ) {
@@ -69,6 +72,13 @@ class LBFactory_Multi extends LBFactory {
$this->$key = $conf[$key];
}
}
+
+ // Check for read-only mode
+ $section = $this->getSectionForWiki();
+ if ( !empty( $this->readOnlyBySection[$section] ) ) {
+ global $wgReadOnly;
+ $wgReadOnly = $this->readOnlyBySection[$section];
+ }
}
function getSectionForWiki( $wiki = false ) {
diff --git a/includes/db/LoadBalancer.php b/includes/db/LoadBalancer.php
index 42c4044d..f847fe22 100644
--- a/includes/db/LoadBalancer.php
+++ b/includes/db/LoadBalancer.php
@@ -13,7 +13,7 @@
class LoadBalancer {
/* private */ var $mServers, $mConns, $mLoads, $mGroupLoads;
/* private */ var $mFailFunction, $mErrorConnection;
- /* private */ var $mReadIndex, $mLastIndex, $mAllowLagged;
+ /* private */ var $mReadIndex, $mAllowLagged;
/* private */ var $mWaitForPos, $mWaitTimeout;
/* private */ var $mLaggedSlaveMode, $mLastError = 'Unknown error';
/* private */ var $mParentInfo, $mLagTimes;
@@ -50,7 +50,6 @@ class LoadBalancer {
'local' => array(),
'foreignUsed' => array(),
'foreignFree' => array() );
- $this->mLastIndex = -1;
$this->mLoads = array();
$this->mWaitForPos = false;
$this->mLaggedSlaveMode = false;
@@ -399,11 +398,20 @@ class LoadBalancer {
/**
* Get a connection by index
* This is the main entry point for this class.
+ * @param int $i Database
+ * @param array $groups Query groups
+ * @param string $wiki Wiki ID
*/
public function &getConnection( $i, $groups = array(), $wiki = false ) {
global $wgDBtype;
wfProfileIn( __METHOD__ );
+ if ( $i == DB_LAST ) {
+ throw new MWException( 'Attempt to call ' . __METHOD__ . ' with deprecated server index DB_LAST' );
+ } elseif ( $i === null || $i === false ) {
+ throw new MWException( 'Attempt to call ' . __METHOD__ . ' with invalid server index' );
+ }
+
if ( $wiki === wfWikiID() ) {
$wiki = false;
}
@@ -433,19 +441,13 @@ class LoadBalancer {
# Operation-based index
if ( $i == DB_SLAVE ) {
$i = $this->getReaderIndex( false, $wiki );
- } elseif ( $i == DB_LAST ) {
- # Just use $this->mLastIndex, which should already be set
- $i = $this->mLastIndex;
- if ( $i === -1 ) {
- # Oh dear, not set, best to use the writer for safety
- wfDebug( "Warning: DB_LAST used when there was no previous index\n" );
- $i = $this->getWriterIndex();
+ # Couldn't find a working server in getReaderIndex()?
+ if ( $i === false ) {
+ $this->mLastError = 'No working slave server: ' . $this->mLastError;
+ $this->reportConnectionError( $this->mErrorConnection );
+ return false;
}
}
- # Couldn't find a working server in getReaderIndex()?
- if ( $i === false ) {
- $this->reportConnectionError( $this->mErrorConnection );
- }
# Now we have an explicit index into the servers array
$conn = $this->openConnection( $i, $wiki );
@@ -525,7 +527,7 @@ class LoadBalancer {
} else {
$server = $this->mServers[$i];
$server['serverIndex'] = $i;
- $conn = $this->reallyOpenConnection( $server );
+ $conn = $this->reallyOpenConnection( $server, false );
if ( $conn->isOpen() ) {
$this->mConns['local'][$i][0] = $conn;
} else {
@@ -534,7 +536,6 @@ class LoadBalancer {
$conn = false;
}
}
- $this->mLastIndex = $i;
wfProfileOut( __METHOD__ );
return $conn;
}
@@ -576,9 +577,8 @@ class LoadBalancer {
$oldWiki = key( $this->mConns['foreignFree'][$i] );
if ( !$conn->selectDB( $dbName ) ) {
- global $wguname;
$this->mLastError = "Error selecting database $dbName on server " .
- $conn->getServer() . " from client host {$wguname['nodename']}\n";
+ $conn->getServer() . " from client host " . wfHostname() . "\n";
$this->mErrorConnection = $conn;
$conn = false;
} else {
@@ -598,6 +598,7 @@ class LoadBalancer {
$this->mErrorConnection = $conn;
$conn = false;
} else {
+ $conn->tablePrefix( $prefix );
$this->mConns['foreignUsed'][$i][$wiki] = $conn;
wfDebug( __METHOD__.": opened new connection for $i/$wiki\n" );
}
@@ -661,31 +662,27 @@ class LoadBalancer {
function reportConnectionError( &$conn ) {
wfProfileIn( __METHOD__ );
- # Prevent infinite recursion
-
- static $reporting = false;
- if ( !$reporting ) {
- $reporting = true;
- if ( !is_object( $conn ) ) {
- // No last connection, probably due to all servers being too busy
- $conn = new Database;
- if ( $this->mFailFunction ) {
- $conn->failFunction( $this->mFailFunction );
- $conn->reportConnectionError( $this->mLastError );
- } else {
- // If all servers were busy, mLastError will contain something sensible
- throw new DBConnectionError( $conn, $this->mLastError );
- }
+
+ if ( !is_object( $conn ) ) {
+ // No last connection, probably due to all servers being too busy
+ wfLogDBError( "LB failure with no last connection\n" );
+ $conn = new Database;
+ if ( $this->mFailFunction ) {
+ $conn->failFunction( $this->mFailFunction );
+ $conn->reportConnectionError( $this->mLastError );
} else {
- if ( $this->mFailFunction ) {
- $conn->failFunction( $this->mFailFunction );
- } else {
- $conn->failFunction( false );
- }
- $server = $conn->getProperty( 'mServer' );
- $conn->reportConnectionError( "{$this->mLastError} ({$server})" );
+ // If all servers were busy, mLastError will contain something sensible
+ throw new DBConnectionError( $conn, $this->mLastError );
+ }
+ } else {
+ if ( $this->mFailFunction ) {
+ $conn->failFunction( $this->mFailFunction );
+ } else {
+ $conn->failFunction( false );
}
- $reporting = false;
+ $server = $conn->getProperty( 'mServer' );
+ wfLogDBError( "Connection error: {$this->mLastError} ({$server})\n" );
+ $conn->reportConnectionError( "{$this->mLastError} ({$server})" );
}
wfProfileOut( __METHOD__ );
}
diff --git a/includes/db/LoadMonitor.php b/includes/db/LoadMonitor.php
index 8e16f1a1..929ab2b9 100644
--- a/includes/db/LoadMonitor.php
+++ b/includes/db/LoadMonitor.php
@@ -64,6 +64,9 @@ class LoadMonitor_MySQL implements LoadMonitor {
$requestRate = 10;
global $wgMemc;
+ if ( empty( $wgMemc ) )
+ $wgMemc = wfGetMainCache();
+
$masterName = $this->parent->getServerName( 0 );
$memcKey = wfMemcKey( 'lag_times', $masterName );
$times = $wgMemc->get( $memcKey );