* @file
* @ingroup Database
*/
+use Wikimedia\Rdbms\DBMasterPos;
+use Wikimedia\Rdbms\MySQLMasterPos;
/**
* Database abstraction object for MySQL.
/**
* @return string
*/
- function getType() {
+ public function getType() {
return 'mysql';
}
* @throws Exception|DBConnectionError
* @return bool
*/
- function open( $server, $user, $password, $dbName ) {
+ public function open( $server, $user, $password, $dbName ) {
# Close/unset connection handle
$this->close();
* @param ResultWrapper|resource $res
* @throws DBUnexpectedError
*/
- function freeResult( $res ) {
+ public function freeResult( $res ) {
if ( $res instanceof ResultWrapper ) {
$res = $res->result;
}
* @return stdClass|bool
* @throws DBUnexpectedError
*/
- function fetchObject( $res ) {
+ public function fetchObject( $res ) {
if ( $res instanceof ResultWrapper ) {
$res = $res->result;
}
// Unfortunately, mysql_fetch_object does not reset the last errno.
// Only check for CR_SERVER_LOST and CR_UNKNOWN_ERROR, as
// these are the only errors mysql_fetch_object can cause.
- // See http://dev.mysql.com/doc/refman/5.0/en/mysql-fetch-row.html.
+ // See https://dev.mysql.com/doc/refman/5.0/en/mysql-fetch-row.html.
if ( $errno == 2000 || $errno == 2013 ) {
throw new DBUnexpectedError(
$this,
* @return array|bool
* @throws DBUnexpectedError
*/
- function fetchRow( $res ) {
+ public function fetchRow( $res ) {
if ( $res instanceof ResultWrapper ) {
$res = $res->result;
}
// Unfortunately, mysql_fetch_array does not reset the last errno.
// Only check for CR_SERVER_LOST and CR_UNKNOWN_ERROR, as
// these are the only errors mysql_fetch_array can cause.
- // See http://dev.mysql.com/doc/refman/5.0/en/mysql-fetch-row.html.
+ // See https://dev.mysql.com/doc/refman/5.0/en/mysql-fetch-row.html.
if ( $errno == 2000 || $errno == 2013 ) {
throw new DBUnexpectedError(
$this,
// Unfortunately, mysql_num_rows does not reset the last errno.
// We are not checking for any errors here, since
// these are no errors mysql_num_rows can cause.
- // See http://dev.mysql.com/doc/refman/5.0/en/mysql-fetch-row.html.
+ // See https://dev.mysql.com/doc/refman/5.0/en/mysql-fetch-row.html.
// See https://phabricator.wikimedia.org/T44430
return $n;
}
* @param ResultWrapper|resource $res
* @return int
*/
- function numFields( $res ) {
+ public function numFields( $res ) {
if ( $res instanceof ResultWrapper ) {
$res = $res->result;
}
* @param int $n
* @return string
*/
- function fieldName( $res, $n ) {
+ public function fieldName( $res, $n ) {
if ( $res instanceof ResultWrapper ) {
$res = $res->result;
}
* @param int $row
* @return bool
*/
- function dataSeek( $res, $row ) {
+ public function dataSeek( $res, $row ) {
if ( $res instanceof ResultWrapper ) {
$res = $res->result;
}
/**
* @return string
*/
- function lastError() {
+ public function lastError() {
if ( $this->mConn ) {
# Even if it's non-zero, it can still be invalid
MediaWiki\suppressWarnings();
* @param string $fname
* @return ResultWrapper
*/
- function replace( $table, $uniqueIndexes, $rows, $fname = __METHOD__ ) {
+ public function replace( $table, $uniqueIndexes, $rows, $fname = __METHOD__ ) {
return $this->nativeReplace( $table, $rows, $fname );
}
return (int)$rows;
}
- function tableExists( $table, $fname = __METHOD__ ) {
+ public function tableExists( $table, $fname = __METHOD__ ) {
$table = $this->tableName( $table, 'raw' );
if ( isset( $this->mSessionTempTables[$table] ) ) {
return true; // already known to exist and won't show in SHOW TABLES anyway
* @param string $field
* @return bool|MySQLField
*/
- function fieldInfo( $table, $field ) {
+ public function fieldInfo( $table, $field ) {
$table = $this->tableName( $table );
$res = $this->query( "SELECT * FROM $table LIMIT 1", __METHOD__, true );
if ( !$res ) {
* @param string $fname
* @return bool|array|null False or null on failure
*/
- function indexInfo( $table, $index, $fname = __METHOD__ ) {
+ public function indexInfo( $table, $index, $fname = __METHOD__ ) {
# SHOW INDEX works in MySQL 3.23.58, but SHOW INDEXES does not.
# SHOW INDEX should work for 3.x and up:
- # http://dev.mysql.com/doc/mysql/en/SHOW_INDEX.html
+ # https://dev.mysql.com/doc/mysql/en/SHOW_INDEX.html
$table = $this->tableName( $table );
$index = $this->indexName( $index );
* @param string $s
* @return string
*/
- function strencode( $s ) {
+ public function strencode( $s ) {
return $this->mysqlRealEscapeString( $s );
}
return strlen( $name ) && $name[0] == '`' && substr( $name, -1, 1 ) == '`';
}
- function getLag() {
+ public function getLag() {
if ( $this->getLagDetectionMethod() === 'pt-heartbeat' ) {
return $this->getLagFromPtHeartbeat();
} else {
* @see https://www.percona.com/doc/percona-toolkit/2.1/pt-heartbeat.html
*/
protected function getHeartbeatData( array $conds ) {
- $whereSQL = $this->makeList( $conds, self::LIST_AND );
- // Use ORDER BY for channel based queries since that field might not be UNIQUE.
- // Note: this would use "TIMESTAMPDIFF(MICROSECOND,ts,UTC_TIMESTAMP(6))" but the
- // percision field is not supported in MySQL <= 5.5.
- $res = $this->query(
- "SELECT ts FROM heartbeat.heartbeat WHERE $whereSQL ORDER BY ts DESC LIMIT 1"
- );
- $row = $res ? $res->fetchObject() : false;
+ // Do not bother starting implicit transactions here
+ $this->clearFlag( self::DBO_TRX, self::REMEMBER_PRIOR );
+ try {
+ $whereSQL = $this->makeList( $conds, self::LIST_AND );
+ // Use ORDER BY for channel based queries since that field might not be UNIQUE.
+ // Note: this would use "TIMESTAMPDIFF(MICROSECOND,ts,UTC_TIMESTAMP(6))" but the
+ // percision field is not supported in MySQL <= 5.5.
+ $res = $this->query(
+ "SELECT ts FROM heartbeat.heartbeat WHERE $whereSQL ORDER BY ts DESC LIMIT 1"
+ );
+ $row = $res ? $res->fetchObject() : false;
+ } finally {
+ $this->restoreFlags();
+ }
return [ $row ? $row->ts : null, microtime( true ) ];
}
- public function getApproximateLagStatus() {
+ protected function getApproximateLagStatus() {
if ( $this->getLagDetectionMethod() === 'pt-heartbeat' ) {
// Disable caching since this is fast enough and we don't wan't
// to be *too* pessimistic by having both the cache TTL and the
return $approxLag;
}
- function masterPosWait( DBMasterPos $pos, $timeout ) {
+ public function masterPosWait( DBMasterPos $pos, $timeout ) {
if ( !( $pos instanceof MySQLMasterPos ) ) {
throw new InvalidArgumentException( "Position not an instance of MySQLMasterPos" );
}
*
* @return MySQLMasterPos|bool
*/
- function getReplicaPos() {
+ public function getReplicaPos() {
$res = $this->query( 'SHOW SLAVE STATUS', __METHOD__ );
$row = $this->fetchObject( $res );
*
* @return MySQLMasterPos|bool
*/
- function getMasterPos() {
+ public function getMasterPos() {
$res = $this->query( 'SHOW MASTER STATUS', __METHOD__ );
$row = $this->fetchObject( $res );
/**
* FROM MYSQL DOCS:
- * http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_release-lock
+ * https://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_release-lock
* @param string $lockName
* @param string $method
* @return bool
}
private function makeLockName( $lockName ) {
- // http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_get-lock
+ // https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_get-lock
// Newer version enforce a 64 char length limit.
return ( strlen( $lockName ) > 64 ) ? sha1( $lockName ) : $lockName;
}
* @throws DBUnexpectedError
* @return bool|ResultWrapper
*/
- function deleteJoin( $delTable, $joinTable, $delVar, $joinVar, $conds, $fname = __METHOD__ ) {
+ public function deleteJoin(
+ $delTable, $joinTable, $delVar, $joinVar, $conds, $fname = __METHOD__
+ ) {
if ( !$conds ) {
throw new DBUnexpectedError( $this, __METHOD__ . ' called with empty $conds' );
}
*
* @return int
*/
- function getServerUptime() {
+ public function getServerUptime() {
$vars = $this->getMysqlStatus( 'Uptime' );
return (int)$vars['Uptime'];
*
* @return bool
*/
- function wasDeadlock() {
+ public function wasDeadlock() {
return $this->lastErrno() == 1213;
}
*
* @return bool
*/
- function wasLockTimeout() {
+ public function wasLockTimeout() {
return $this->lastErrno() == 1205;
}
- function wasErrorReissuable() {
+ public function wasErrorReissuable() {
return $this->lastErrno() == 2013 || $this->lastErrno() == 2006;
}
*
* @return bool
*/
- function wasReadOnlyError() {
+ public function wasReadOnlyError() {
return $this->lastErrno() == 1223 ||
( $this->lastErrno() == 1290 && strpos( $this->lastError(), '--read-only' ) !== false );
}
- function wasConnectionError( $errno ) {
+ public function wasConnectionError( $errno ) {
return $errno == 2013 || $errno == 2006;
}
* @param string $fname
* @return bool
*/
- function duplicateTableStructure( $oldName, $newName, $temporary = false, $fname = __METHOD__ ) {
+ public function duplicateTableStructure(
+ $oldName, $newName, $temporary = false, $fname = __METHOD__
+ ) {
$tmp = $temporary ? 'TEMPORARY ' : '';
$newName = $this->addIdentifierQuotes( $newName );
$oldName = $this->addIdentifierQuotes( $oldName );
* @param string $fname Calling function name
* @return array
*/
- function listTables( $prefix = null, $fname = __METHOD__ ) {
+ public function listTables( $prefix = null, $fname = __METHOD__ ) {
$result = $this->query( "SHOW TABLES", $fname );
$endArray = [];
* @param string $which
* @return array
*/
- function getMysqlStatus( $which = "%" ) {
+ private function getMysqlStatus( $which = "%" ) {
$res = $this->query( "SHOW STATUS LIKE '{$which}'" );
$status = [];
return in_array( $name, $this->listViews( $prefix ) );
}
}
-