summaryrefslogtreecommitdiff
path: root/includes/db/DatabaseMysqlBase.php
diff options
context:
space:
mode:
Diffstat (limited to 'includes/db/DatabaseMysqlBase.php')
-rw-r--r--includes/db/DatabaseMysqlBase.php125
1 files changed, 93 insertions, 32 deletions
diff --git a/includes/db/DatabaseMysqlBase.php b/includes/db/DatabaseMysqlBase.php
index ba0f39ff..aac95a8c 100644
--- a/includes/db/DatabaseMysqlBase.php
+++ b/includes/db/DatabaseMysqlBase.php
@@ -38,6 +38,9 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
protected $mFakeMaster = false;
+ /** @var string|null */
+ private $serverVersion = null;
+
/**
* @return string
*/
@@ -55,7 +58,6 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
*/
function open( $server, $user, $password, $dbName ) {
global $wgAllDBsAreLocalhost, $wgSQLMode;
- wfProfileIn( __METHOD__ );
# Debugging hack -- fake cluster
if ( $wgAllDBsAreLocalhost ) {
@@ -69,8 +71,6 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
$this->mPassword = $password;
$this->mDBname = $dbName;
- wfProfileIn( "dbconnect-$server" );
-
# The kernel's default SYN retransmission period is far too slow for us,
# 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.
@@ -79,27 +79,27 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
try {
$this->mConn = $this->mysqlConnect( $realServer );
} catch ( Exception $ex ) {
- wfProfileOut( "dbconnect-$server" );
- wfProfileOut( __METHOD__ );
$this->restoreErrorHandler();
throw $ex;
}
$error = $this->restoreErrorHandler();
- wfProfileOut( "dbconnect-$server" );
-
# Always log connection errors
if ( !$this->mConn ) {
if ( !$error ) {
$error = $this->lastError();
}
- wfLogDBError( "Error connecting to {$this->mServer}: $error" );
+ wfLogDBError(
+ "Error connecting to {db_server}: {error}",
+ $this->getLogContext( array(
+ 'method' => __METHOD__,
+ 'error' => $error,
+ ) )
+ );
wfDebug( "DB connection error\n" .
"Server: $server, User: $user, Password: " .
substr( $password, 0, 3 ) . "..., error: " . $error . "\n" );
- wfProfileOut( __METHOD__ );
-
$this->reportConnectionError( $error );
}
@@ -108,12 +108,15 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
$success = $this->selectDB( $dbName );
wfRestoreWarnings();
if ( !$success ) {
- wfLogDBError( "Error selecting database $dbName on server {$this->mServer}" );
+ wfLogDBError(
+ "Error selecting database {db_name} on server {db_server}",
+ $this->getLogContext( array(
+ 'method' => __METHOD__,
+ ) )
+ );
wfDebug( "Error selecting database $dbName on server {$this->mServer} " .
"from client host " . wfHostname() . "\n" );
- wfProfileOut( __METHOD__ );
-
$this->reportConnectionError( "Error selecting database $dbName" );
}
}
@@ -123,20 +126,29 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
$this->reportConnectionError( "Error setting character set" );
}
+ // Abstract over any insane MySQL defaults
+ $set = array( 'group_concat_max_len = 262144' );
// Set SQL mode, default is turning them all off, can be overridden or skipped with null
if ( is_string( $wgSQLMode ) ) {
- $mode = $this->addQuotes( $wgSQLMode );
+ $set[] = 'sql_mode = ' . $this->addQuotes( $wgSQLMode );
+ }
+
+ if ( $set ) {
// Use doQuery() to avoid opening implicit transactions (DBO_TRX)
- $success = $this->doQuery( "SET sql_mode = $mode", __METHOD__ );
+ $success = $this->doQuery( 'SET ' . implode( ', ', $set ), __METHOD__ );
if ( !$success ) {
- wfLogDBError( "Error setting sql_mode to $mode on server {$this->mServer}" );
- wfProfileOut( __METHOD__ );
- $this->reportConnectionError( "Error setting sql_mode to $mode" );
+ wfLogDBError(
+ 'Error setting MySQL variables on server {db_server} (check $wgSQLMode)',
+ $this->getLogContext( array(
+ 'method' => __METHOD__,
+ ) )
+ );
+ $this->reportConnectionError(
+ 'Error setting MySQL variables on server {db_server} (check $wgSQLMode)' );
}
}
$this->mOpened = true;
- wfProfileOut( __METHOD__ );
return true;
}
@@ -456,7 +468,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
$rows *= $plan->rows > 0 ? $plan->rows : 1; // avoid resetting to zero
}
- return $rows;
+ return (int)$rows;
}
/**
@@ -652,7 +664,6 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
return '0'; // http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html
}
- wfProfileIn( __METHOD__ );
# Commit any open transactions
$this->commit( __METHOD__, 'flush' );
@@ -661,18 +672,15 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
if ( $wait > $timeout * 1e6 ) {
wfDebug( "Fake slave timed out waiting for $pos ($wait us)\n" );
- wfProfileOut( __METHOD__ );
return -1;
} elseif ( $wait > 0 ) {
wfDebug( "Fake slave waiting $wait us\n" );
usleep( $wait );
- wfProfileOut( __METHOD__ );
return 1;
} else {
wfDebug( "Fake slave up to date ($wait us)\n" );
- wfProfileOut( __METHOD__ );
return 0;
}
@@ -692,8 +700,6 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
}
}
- wfProfileOut( __METHOD__ );
-
return $status;
}
@@ -763,9 +769,9 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
* @return string
*/
public function getSoftwareLink() {
- // MariaDB includes its name in its version string (sent when the connection is opened),
- // and this is how MariaDB's version of the mysql command-line client identifies MariaDB
- // servers (see the mariadb_connection() function in libmysql/libmysql.c).
+ // MariaDB includes its name in its version string; this is how MariaDB's version of
+ // the mysql command-line client identifies MariaDB servers (see mariadb_connection()
+ // in libmysql/libmysql.c).
$version = $this->getServerVersion();
if ( strpos( $version, 'MariaDB' ) !== false || strpos( $version, '-maria-' ) !== false ) {
return '[{{int:version-db-mariadb-url}} MariaDB]';
@@ -778,6 +784,19 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
}
/**
+ * @return string
+ */
+ public function getServerVersion() {
+ // Not using mysql_get_server_info() or similar for consistency: in the handshake,
+ // MariaDB 10 adds the prefix "5.5.5-", and only some newer client libraries strip
+ // it off (see RPL_VERSION_HACK in include/mysql_com.h).
+ if ( $this->serverVersion === null ) {
+ $this->serverVersion = $this->selectField( '', 'VERSION()', '', __METHOD__ );
+ }
+ return $this->serverVersion;
+ }
+
+ /**
* @param array $options
*/
public function setSessionOptions( array $options ) {
@@ -1169,7 +1188,8 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
*/
class MySQLField implements Field {
private $name, $tablename, $default, $max_length, $nullable,
- $is_pk, $is_unique, $is_multiple, $is_key, $type, $binary;
+ $is_pk, $is_unique, $is_multiple, $is_key, $type, $binary,
+ $is_numeric, $is_blob, $is_unsigned, $is_zerofill;
function __construct( $info ) {
$this->name = $info->name;
@@ -1183,6 +1203,10 @@ class MySQLField implements Field {
$this->is_key = ( $this->is_pk || $this->is_unique || $this->is_multiple );
$this->type = $info->type;
$this->binary = isset( $info->binary ) ? $info->binary : false;
+ $this->is_numeric = isset( $info->numeric ) ? $info->numeric : false;
+ $this->is_blob = isset( $info->blob ) ? $info->blob : false;
+ $this->is_unsigned = isset( $info->unsigned ) ? $info->unsigned : false;
+ $this->is_zerofill = isset( $info->zerofill ) ? $info->zerofill : false;
}
/**
@@ -1231,21 +1255,54 @@ class MySQLField implements Field {
return $this->is_multiple;
}
+ /**
+ * @return bool
+ */
function isBinary() {
return $this->binary;
}
+
+ /**
+ * @return bool
+ */
+ function isNumeric() {
+ return $this->is_numeric;
+ }
+
+ /**
+ * @return bool
+ */
+ function isBlob() {
+ return $this->is_blob;
+ }
+
+ /**
+ * @return bool
+ */
+ function isUnsigned() {
+ return $this->is_unsigned;
+ }
+
+ /**
+ * @return bool
+ */
+ function isZerofill() {
+ return $this->is_zerofill;
+ }
}
class MySQLMasterPos implements DBMasterPos {
/** @var string */
public $file;
-
- /** @var int Timestamp */
+ /** @var int Position */
public $pos;
+ /** @var float UNIX timestamp */
+ public $asOfTime = 0.0;
function __construct( $file, $pos ) {
$this->file = $file;
$this->pos = $pos;
+ $this->asOfTime = microtime( true );
}
function __toString() {
@@ -1271,4 +1328,8 @@ class MySQLMasterPos implements DBMasterPos {
return ( $thisPos && $thatPos && $thisPos >= $thatPos );
}
+
+ function asOfTime() {
+ return $this->asOfTime;
+ }
}