Rename DB primary position interfaces to DBPrimaryPos and MySQLPrimaryPos
And replace all uses. Bug: T282894 Change-Id: I5222a8568255ac9fa5e2350e2264b8d2ee5eb968
This commit is contained in:
parent
e82c5e52d5
commit
d11c59538a
18 changed files with 149 additions and 130 deletions
|
|
@ -419,6 +419,9 @@ because of Phabricator reports.
|
||||||
* The 'getMasterDB()' methods for LocalRepo (and so ForeignDBRepo), JobQueueDB,
|
* The 'getMasterDB()' methods for LocalRepo (and so ForeignDBRepo), JobQueueDB,
|
||||||
ForeignDBViaLBRepo, and DBFileJournal have been deprecated in favour of a new
|
ForeignDBViaLBRepo, and DBFileJournal have been deprecated in favour of a new
|
||||||
method, getPrimaryDB().
|
method, getPrimaryDB().
|
||||||
|
* DBMasterPos and MySQLMasterPos have been respectively renamed to DBPrimaryPos
|
||||||
|
and MySQLPrimaryPos. The former names are left as deprecated, temporary class
|
||||||
|
aliases.
|
||||||
* wfIncrStats(), deprecated in 1.36, now emits deprecation warnings.
|
* wfIncrStats(), deprecated in 1.36, now emits deprecation warnings.
|
||||||
* wfCanIPUseHTTPS() is now deprecated, and always returns true.
|
* wfCanIPUseHTTPS() is now deprecated, and always returns true.
|
||||||
* The UserLoadFromDatabase hook has been deprecated. It had no known uses.
|
* The UserLoadFromDatabase hook has been deprecated. It had no known uses.
|
||||||
|
|
|
||||||
|
|
@ -1806,7 +1806,8 @@ $wgAutoloadLocalClasses = [
|
||||||
'Wikimedia\\Rdbms\\DBConnectionError' => __DIR__ . '/includes/libs/rdbms/exception/DBConnectionError.php',
|
'Wikimedia\\Rdbms\\DBConnectionError' => __DIR__ . '/includes/libs/rdbms/exception/DBConnectionError.php',
|
||||||
'Wikimedia\\Rdbms\\DBError' => __DIR__ . '/includes/libs/rdbms/exception/DBError.php',
|
'Wikimedia\\Rdbms\\DBError' => __DIR__ . '/includes/libs/rdbms/exception/DBError.php',
|
||||||
'Wikimedia\\Rdbms\\DBExpectedError' => __DIR__ . '/includes/libs/rdbms/exception/DBExpectedError.php',
|
'Wikimedia\\Rdbms\\DBExpectedError' => __DIR__ . '/includes/libs/rdbms/exception/DBExpectedError.php',
|
||||||
'Wikimedia\\Rdbms\\DBMasterPos' => __DIR__ . '/includes/libs/rdbms/database/position/DBMasterPos.php',
|
'Wikimedia\\Rdbms\\DBMasterPos' => __DIR__ . '/includes/libs/rdbms/database/position/DBPrimaryPos.php',
|
||||||
|
'Wikimedia\\Rdbms\\DBPrimaryPos' => __DIR__ . '/includes/libs/rdbms/database/position/DBPrimaryPos.php',
|
||||||
'Wikimedia\\Rdbms\\DBQueryDisconnectedError' => __DIR__ . '/includes/libs/rdbms/exception/DBQueryDisconnectedError.php',
|
'Wikimedia\\Rdbms\\DBQueryDisconnectedError' => __DIR__ . '/includes/libs/rdbms/exception/DBQueryDisconnectedError.php',
|
||||||
'Wikimedia\\Rdbms\\DBQueryError' => __DIR__ . '/includes/libs/rdbms/exception/DBQueryError.php',
|
'Wikimedia\\Rdbms\\DBQueryError' => __DIR__ . '/includes/libs/rdbms/exception/DBQueryError.php',
|
||||||
'Wikimedia\\Rdbms\\DBQueryTimeoutError' => __DIR__ . '/includes/libs/rdbms/exception/DBQueryTimeoutError.php',
|
'Wikimedia\\Rdbms\\DBQueryTimeoutError' => __DIR__ . '/includes/libs/rdbms/exception/DBQueryTimeoutError.php',
|
||||||
|
|
@ -1856,7 +1857,8 @@ $wgAutoloadLocalClasses = [
|
||||||
'Wikimedia\\Rdbms\\MWPostgreSqlPlatformCompat' => __DIR__ . '/includes/libs/rdbms/dbal/MWPostgreSqlPlatformCompat.php',
|
'Wikimedia\\Rdbms\\MWPostgreSqlPlatformCompat' => __DIR__ . '/includes/libs/rdbms/dbal/MWPostgreSqlPlatformCompat.php',
|
||||||
'Wikimedia\\Rdbms\\MaintainableDBConnRef' => __DIR__ . '/includes/libs/rdbms/database/MaintainableDBConnRef.php',
|
'Wikimedia\\Rdbms\\MaintainableDBConnRef' => __DIR__ . '/includes/libs/rdbms/database/MaintainableDBConnRef.php',
|
||||||
'Wikimedia\\Rdbms\\MySQLField' => __DIR__ . '/includes/libs/rdbms/field/MySQLField.php',
|
'Wikimedia\\Rdbms\\MySQLField' => __DIR__ . '/includes/libs/rdbms/field/MySQLField.php',
|
||||||
'Wikimedia\\Rdbms\\MySQLMasterPos' => __DIR__ . '/includes/libs/rdbms/database/position/MySQLMasterPos.php',
|
'Wikimedia\\Rdbms\\MySQLMasterPos' => __DIR__ . '/includes/libs/rdbms/database/position/MySQLPrimaryPos.php',
|
||||||
|
'Wikimedia\\Rdbms\\MySQLPrimaryPos' => __DIR__ . '/includes/libs/rdbms/database/position/MySQLPrimaryPos.php',
|
||||||
'Wikimedia\\Rdbms\\MysqliResultWrapper' => __DIR__ . '/includes/libs/rdbms/database/resultwrapper/MysqliResultWrapper.php',
|
'Wikimedia\\Rdbms\\MysqliResultWrapper' => __DIR__ . '/includes/libs/rdbms/database/resultwrapper/MysqliResultWrapper.php',
|
||||||
'Wikimedia\\Rdbms\\NextSequenceValue' => __DIR__ . '/includes/libs/rdbms/database/utils/NextSequenceValue.php',
|
'Wikimedia\\Rdbms\\NextSequenceValue' => __DIR__ . '/includes/libs/rdbms/database/utils/NextSequenceValue.php',
|
||||||
'Wikimedia\\Rdbms\\PostgresBlob' => __DIR__ . '/includes/libs/rdbms/encasing/PostgresBlob.php',
|
'Wikimedia\\Rdbms\\PostgresBlob' => __DIR__ . '/includes/libs/rdbms/encasing/PostgresBlob.php',
|
||||||
|
|
|
||||||
|
|
@ -451,7 +451,7 @@ abstract class JobQueue {
|
||||||
* spawned when a template is edited. One can think of the task as "update links
|
* spawned when a template is edited. One can think of the task as "update links
|
||||||
* of pages that use template X" and an instance of that task as a "root job".
|
* of pages that use template X" and an instance of that task as a "root job".
|
||||||
* However, what actually goes into the queue are range and leaf job subtypes.
|
* However, what actually goes into the queue are range and leaf job subtypes.
|
||||||
* Since these jobs include things like page ID ranges and DB master positions,
|
* Since these jobs include things like page ID ranges and DB primary positions,
|
||||||
* and can morph into smaller jobs recursively, simple duplicate detection
|
* and can morph into smaller jobs recursively, simple duplicate detection
|
||||||
* for individual jobs being identical (like that of job_sha1) is not useful.
|
* for individual jobs being identical (like that of job_sha1) is not useful.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -681,7 +681,7 @@ class JobRunner implements LoggerAwareInterface {
|
||||||
$lb->waitForAll( $pos );
|
$lb->waitForAll( $pos );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actually commit the DB master changes
|
// Actually commit the DB primary changes
|
||||||
$this->lbFactory->commitMasterChanges(
|
$this->lbFactory->commitMasterChanges(
|
||||||
$fnameTrxOwner,
|
$fnameTrxOwner,
|
||||||
// Abort if any transaction was too big
|
// Abort if any transaction was too big
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ use Wikimedia\LightweightObjectStore\StorageAwareness;
|
||||||
* should query the new value and backfill the cache using set().
|
* should query the new value and backfill the cache using set().
|
||||||
* The preferred way to do this logic is through getWithSetCallback().
|
* The preferred way to do this logic is through getWithSetCallback().
|
||||||
* When querying the store on cache miss, the closest DB replica
|
* When querying the store on cache miss, the closest DB replica
|
||||||
* should be used. Try to avoid heavyweight DB master or quorum reads.
|
* should be used. Try to avoid heavyweight DB primary or quorum reads.
|
||||||
*
|
*
|
||||||
* To ensure consumers of the cache see new values in a timely manner,
|
* To ensure consumers of the cache see new values in a timely manner,
|
||||||
* you either need to follow either the validation strategy, or the
|
* you either need to follow either the validation strategy, or the
|
||||||
|
|
|
||||||
|
|
@ -155,9 +155,9 @@ class ChronologyProtector implements LoggerAwareInterface {
|
||||||
/** @var float|null UNIX timestamp when the client data was loaded */
|
/** @var float|null UNIX timestamp when the client data was loaded */
|
||||||
protected $startupTimestamp;
|
protected $startupTimestamp;
|
||||||
|
|
||||||
/** @var array<string,DBMasterPos> Map of (DB master name => position) */
|
/** @var array<string,DBPrimaryPos> Map of (DB primary name => position) */
|
||||||
protected $startupPositionsByMaster = [];
|
protected $startupPositionsByMaster = [];
|
||||||
/** @var array<string,DBMasterPos> Map of (DB master name => position) */
|
/** @var array<string,DBPrimaryPos> Map of (DB primary name => position) */
|
||||||
protected $shutdownPositionsByMaster = [];
|
protected $shutdownPositionsByMaster = [];
|
||||||
/** @var array<string,float> Map of (DB cluster name => UNIX timestamp) */
|
/** @var array<string,float> Map of (DB cluster name => UNIX timestamp) */
|
||||||
protected $startupTimestampsByCluster = [];
|
protected $startupTimestampsByCluster = [];
|
||||||
|
|
@ -267,7 +267,7 @@ class ChronologyProtector implements LoggerAwareInterface {
|
||||||
$masterName = $lb->getServerName( $lb->getWriterIndex() );
|
$masterName = $lb->getServerName( $lb->getWriterIndex() );
|
||||||
|
|
||||||
$pos = $this->getStartupSessionPositions()[$masterName] ?? null;
|
$pos = $this->getStartupSessionPositions()[$masterName] ?? null;
|
||||||
if ( $pos instanceof DBMasterPos ) {
|
if ( $pos instanceof DBPrimaryPos ) {
|
||||||
$this->logger->debug( __METHOD__ . ": $cluster ($masterName) position is '$pos'" );
|
$this->logger->debug( __METHOD__ . ": $cluster ($masterName) position is '$pos'" );
|
||||||
$lb->waitFor( $pos );
|
$lb->waitFor( $pos );
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -316,7 +316,7 @@ class ChronologyProtector implements LoggerAwareInterface {
|
||||||
* @internal This method should only be called from LBFactory.
|
* @internal This method should only be called from LBFactory.
|
||||||
*
|
*
|
||||||
* @param int|null &$clientPosIndex DB position key write counter; incremented on update
|
* @param int|null &$clientPosIndex DB position key write counter; incremented on update
|
||||||
* @return DBMasterPos[] Empty on success; map of (db name => unsaved position) on failure
|
* @return DBPrimaryPos[] Empty on success; map of (db name => unsaved position) on failure
|
||||||
*/
|
*/
|
||||||
public function persistSessionReplicationPositions( &$clientPosIndex = null ) {
|
public function persistSessionReplicationPositions( &$clientPosIndex = null ) {
|
||||||
if ( !$this->enabled ) {
|
if ( !$this->enabled ) {
|
||||||
|
|
@ -402,7 +402,7 @@ class ChronologyProtector implements LoggerAwareInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array<string,DBMasterPos>
|
* @return array<string,DBPrimaryPos>
|
||||||
*/
|
*/
|
||||||
protected function getStartupSessionPositions() {
|
protected function getStartupSessionPositions() {
|
||||||
$this->lazyStartup();
|
$this->lazyStartup();
|
||||||
|
|
@ -499,7 +499,7 @@ class ChronologyProtector implements LoggerAwareInterface {
|
||||||
* Merge the new replication positions with the currently stored ones (highest wins)
|
* Merge the new replication positions with the currently stored ones (highest wins)
|
||||||
*
|
*
|
||||||
* @param array<string,mixed>|false $storedValue Current replication position data
|
* @param array<string,mixed>|false $storedValue Current replication position data
|
||||||
* @param array<string,DBMasterPos> $shutdownPositions New replication positions
|
* @param array<string,DBPrimaryPos> $shutdownPositions New replication positions
|
||||||
* @param array<string,float> $shutdownTimestamps New DB post-commit shutdown timestamps
|
* @param array<string,float> $shutdownTimestamps New DB post-commit shutdown timestamps
|
||||||
* @param int|null &$clientPosIndex New position write index
|
* @param int|null &$clientPosIndex New position write index
|
||||||
* @return array<string,mixed> Combined replication position data
|
* @return array<string,mixed> Combined replication position data
|
||||||
|
|
@ -510,13 +510,13 @@ class ChronologyProtector implements LoggerAwareInterface {
|
||||||
array $shutdownTimestamps,
|
array $shutdownTimestamps,
|
||||||
?int &$clientPosIndex = null
|
?int &$clientPosIndex = null
|
||||||
) {
|
) {
|
||||||
/** @var array<string,DBMasterPos> $mergedPositions */
|
/** @var array<string,DBPrimaryPos> $mergedPositions */
|
||||||
$mergedPositions = $storedValue[self::FLD_POSITIONS] ?? [];
|
$mergedPositions = $storedValue[self::FLD_POSITIONS] ?? [];
|
||||||
// Use the newest positions for each DB master
|
// Use the newest positions for each DB primary
|
||||||
foreach ( $shutdownPositions as $masterName => $pos ) {
|
foreach ( $shutdownPositions as $masterName => $pos ) {
|
||||||
if (
|
if (
|
||||||
!isset( $mergedPositions[$masterName] ) ||
|
!isset( $mergedPositions[$masterName] ) ||
|
||||||
!( $mergedPositions[$masterName] instanceof DBMasterPos ) ||
|
!( $mergedPositions[$masterName] instanceof DBPrimaryPos ) ||
|
||||||
$pos->asOfTime() > $mergedPositions[$masterName]->asOfTime()
|
$pos->asOfTime() > $mergedPositions[$masterName]->asOfTime()
|
||||||
) {
|
) {
|
||||||
$mergedPositions[$masterName] = $pos;
|
$mergedPositions[$masterName] = $pos;
|
||||||
|
|
@ -525,7 +525,7 @@ class ChronologyProtector implements LoggerAwareInterface {
|
||||||
|
|
||||||
/** @var array<string,float> $mergedTimestamps */
|
/** @var array<string,float> $mergedTimestamps */
|
||||||
$mergedTimestamps = $storedValue[self::FLD_TIMESTAMPS] ?? [];
|
$mergedTimestamps = $storedValue[self::FLD_TIMESTAMPS] ?? [];
|
||||||
// Use the newest touch timestamp for each DB master
|
// Use the newest touch timestamp for each DB primary
|
||||||
foreach ( $shutdownTimestamps as $cluster => $timestamp ) {
|
foreach ( $shutdownTimestamps as $cluster => $timestamp ) {
|
||||||
if (
|
if (
|
||||||
!isset( $mergedTimestamps[$cluster] ) ||
|
!isset( $mergedTimestamps[$cluster] ) ||
|
||||||
|
|
|
||||||
|
|
@ -582,7 +582,7 @@ class DBConnRef implements IDatabase {
|
||||||
return $this->__call( __FUNCTION__, func_get_args() );
|
return $this->__call( __FUNCTION__, func_get_args() );
|
||||||
}
|
}
|
||||||
|
|
||||||
public function masterPosWait( DBMasterPos $pos, $timeout ) {
|
public function masterPosWait( DBPrimaryPos $pos, $timeout ) {
|
||||||
return $this->__call( __FUNCTION__, func_get_args() );
|
return $this->__call( __FUNCTION__, func_get_args() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3980,7 +3980,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
* @stable to override
|
* @stable to override
|
||||||
*/
|
*/
|
||||||
public function masterPosWait( DBMasterPos $pos, $timeout ) {
|
public function masterPosWait( DBPrimaryPos $pos, $timeout ) {
|
||||||
# Real waits are implemented in the subclass.
|
# Real waits are implemented in the subclass.
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ use Wikimedia\AtEase\AtEase;
|
||||||
* @see Database
|
* @see Database
|
||||||
*/
|
*/
|
||||||
abstract class DatabaseMysqlBase extends Database {
|
abstract class DatabaseMysqlBase extends Database {
|
||||||
/** @var MySQLMasterPos */
|
/** @var MySQLPrimaryPos */
|
||||||
protected $lastKnownReplicaPos;
|
protected $lastKnownReplicaPos;
|
||||||
/** @var string Method to detect replica DB lag */
|
/** @var string Method to detect replica DB lag */
|
||||||
protected $lagDetectionMethod;
|
protected $lagDetectionMethod;
|
||||||
|
|
@ -672,9 +672,9 @@ abstract class DatabaseMysqlBase extends Database {
|
||||||
return $approxLag;
|
return $approxLag;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function masterPosWait( DBMasterPos $pos, $timeout ) {
|
public function masterPosWait( DBPrimaryPos $pos, $timeout ) {
|
||||||
if ( !( $pos instanceof MySQLMasterPos ) ) {
|
if ( !( $pos instanceof MySQLPrimaryPos ) ) {
|
||||||
throw new InvalidArgumentException( "Position not an instance of MySQLMasterPos" );
|
throw new InvalidArgumentException( "Position not an instance of MySQLPrimaryPos" );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $this->topologyRole === self::ROLE_STATIC_CLONE ) {
|
if ( $this->topologyRole === self::ROLE_STATIC_CLONE ) {
|
||||||
|
|
@ -788,7 +788,7 @@ abstract class DatabaseMysqlBase extends Database {
|
||||||
/**
|
/**
|
||||||
* Get the position of the master from SHOW SLAVE STATUS
|
* Get the position of the master from SHOW SLAVE STATUS
|
||||||
*
|
*
|
||||||
* @return MySQLMasterPos|bool
|
* @return MySQLPrimaryPos|bool
|
||||||
*/
|
*/
|
||||||
public function getReplicaPos() {
|
public function getReplicaPos() {
|
||||||
$now = microtime( true ); // as-of-time *before* fetching GTID variables
|
$now = microtime( true ); // as-of-time *before* fetching GTID variables
|
||||||
|
|
@ -799,14 +799,14 @@ abstract class DatabaseMysqlBase extends Database {
|
||||||
// Use gtid_slave_pos for MariaDB and gtid_executed for MySQL
|
// Use gtid_slave_pos for MariaDB and gtid_executed for MySQL
|
||||||
foreach ( [ 'gtid_slave_pos', 'gtid_executed' ] as $name ) {
|
foreach ( [ 'gtid_slave_pos', 'gtid_executed' ] as $name ) {
|
||||||
if ( isset( $data[$name] ) && strlen( $data[$name] ) ) {
|
if ( isset( $data[$name] ) && strlen( $data[$name] ) ) {
|
||||||
return new MySQLMasterPos( $data[$name], $now );
|
return new MySQLPrimaryPos( $data[$name], $now );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = $this->getServerRoleStatus( 'SLAVE', __METHOD__ );
|
$data = $this->getServerRoleStatus( 'SLAVE', __METHOD__ );
|
||||||
if ( $data && strlen( $data['Relay_Master_Log_File'] ) ) {
|
if ( $data && strlen( $data['Relay_Master_Log_File'] ) ) {
|
||||||
return new MySQLMasterPos(
|
return new MySQLPrimaryPos(
|
||||||
"{$data['Relay_Master_Log_File']}/{$data['Exec_Master_Log_Pos']}",
|
"{$data['Relay_Master_Log_File']}/{$data['Exec_Master_Log_Pos']}",
|
||||||
$now
|
$now
|
||||||
);
|
);
|
||||||
|
|
@ -818,7 +818,7 @@ abstract class DatabaseMysqlBase extends Database {
|
||||||
/**
|
/**
|
||||||
* Get the position of the master from SHOW MASTER STATUS
|
* Get the position of the master from SHOW MASTER STATUS
|
||||||
*
|
*
|
||||||
* @return MySQLMasterPos|bool
|
* @return MySQLPrimaryPos|bool
|
||||||
*/
|
*/
|
||||||
public function getMasterPos() {
|
public function getMasterPos() {
|
||||||
$now = microtime( true ); // as-of-time *before* fetching GTID variables
|
$now = microtime( true ); // as-of-time *before* fetching GTID variables
|
||||||
|
|
@ -830,7 +830,7 @@ abstract class DatabaseMysqlBase extends Database {
|
||||||
// Use gtid_binlog_pos for MariaDB and gtid_executed for MySQL
|
// Use gtid_binlog_pos for MariaDB and gtid_executed for MySQL
|
||||||
foreach ( [ 'gtid_binlog_pos', 'gtid_executed' ] as $name ) {
|
foreach ( [ 'gtid_binlog_pos', 'gtid_executed' ] as $name ) {
|
||||||
if ( isset( $data[$name] ) && strlen( $data[$name] ) ) {
|
if ( isset( $data[$name] ) && strlen( $data[$name] ) ) {
|
||||||
$pos = new MySQLMasterPos( $data[$name], $now );
|
$pos = new MySQLPrimaryPos( $data[$name], $now );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -847,7 +847,7 @@ abstract class DatabaseMysqlBase extends Database {
|
||||||
if ( !$pos ) {
|
if ( !$pos ) {
|
||||||
$data = $this->getServerRoleStatus( 'MASTER', __METHOD__ );
|
$data = $this->getServerRoleStatus( 'MASTER', __METHOD__ );
|
||||||
if ( $data && strlen( $data['File'] ) ) {
|
if ( $data && strlen( $data['File'] ) ) {
|
||||||
$pos = new MySQLMasterPos( "{$data['File']}/{$data['Position']}", $now );
|
$pos = new MySQLPrimaryPos( "{$data['File']}/{$data['Position']}", $now );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1641,19 +1641,19 @@ interface IDatabase {
|
||||||
* is flushed, and this is called, then queries will reflect the point the DB was synced
|
* is flushed, and this is called, then queries will reflect the point the DB was synced
|
||||||
* up to (on success) without interference from REPEATABLE-READ snapshots.
|
* up to (on success) without interference from REPEATABLE-READ snapshots.
|
||||||
*
|
*
|
||||||
* @param DBMasterPos $pos
|
* @param DBPrimaryPos $pos
|
||||||
* @param int $timeout The maximum number of seconds to wait for synchronisation
|
* @param int $timeout The maximum number of seconds to wait for synchronisation
|
||||||
* @return int|null Zero if the replica DB was past that position already,
|
* @return int|null Zero if the replica DB was past that position already,
|
||||||
* greater than zero if we waited for some period of time, less than
|
* greater than zero if we waited for some period of time, less than
|
||||||
* zero if it timed out, and null on error
|
* zero if it timed out, and null on error
|
||||||
* @throws DBError If an error occurs, {@see query}
|
* @throws DBError If an error occurs, {@see query}
|
||||||
*/
|
*/
|
||||||
public function masterPosWait( DBMasterPos $pos, $timeout );
|
public function masterPosWait( DBPrimaryPos $pos, $timeout );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the replication position of this replica DB
|
* Get the replication position of this replica DB
|
||||||
*
|
*
|
||||||
* @return DBMasterPos|bool False if this is not a replica DB
|
* @return DBPrimaryPos|bool False if this is not a replica DB
|
||||||
* @throws DBError If an error occurs, {@see query}
|
* @throws DBError If an error occurs, {@see query}
|
||||||
*/
|
*/
|
||||||
public function getReplicaPos();
|
public function getReplicaPos();
|
||||||
|
|
@ -1661,7 +1661,7 @@ interface IDatabase {
|
||||||
/**
|
/**
|
||||||
* Get the position of this master
|
* Get the position of this master
|
||||||
*
|
*
|
||||||
* @return DBMasterPos|bool False if this is not a master
|
* @return DBPrimaryPos|bool False if this is not a master
|
||||||
* @throws DBError If an error occurs, {@see query}
|
* @throws DBError If an error occurs, {@see query}
|
||||||
*/
|
*/
|
||||||
public function getMasterPos();
|
public function getMasterPos();
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,13 @@ namespace Wikimedia\Rdbms;
|
||||||
use Serializable;
|
use Serializable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An object representing a master or replica DB position in a replicated setup.
|
* An object representing a primary or replica DB position in a replicated setup.
|
||||||
*
|
*
|
||||||
* The implementation details of this opaque type are up to the database subclass.
|
* The implementation details of this opaque type are up to the database subclass.
|
||||||
*
|
*
|
||||||
* @stable to implement
|
* @stable to implement
|
||||||
*/
|
*/
|
||||||
interface DBMasterPos extends Serializable {
|
interface DBPrimaryPos extends Serializable {
|
||||||
/**
|
/**
|
||||||
* @return float UNIX timestamp
|
* @return float UNIX timestamp
|
||||||
* @since 1.25
|
* @since 1.25
|
||||||
|
|
@ -19,18 +19,18 @@ interface DBMasterPos extends Serializable {
|
||||||
public function asOfTime();
|
public function asOfTime();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param DBMasterPos $pos
|
* @param DBPrimaryPos $pos
|
||||||
* @return bool Whether this position is at or higher than $pos
|
* @return bool Whether this position is at or higher than $pos
|
||||||
* @since 1.27
|
* @since 1.27
|
||||||
*/
|
*/
|
||||||
public function hasReached( DBMasterPos $pos );
|
public function hasReached( DBPrimaryPos $pos );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param DBMasterPos $pos
|
* @param DBPrimaryPos $pos
|
||||||
* @return bool Whether this position appears to be for the same channel as another
|
* @return bool Whether this position appears to be for the same channel as another
|
||||||
* @since 1.27
|
* @since 1.27
|
||||||
*/
|
*/
|
||||||
public function channelsMatch( DBMasterPos $pos );
|
public function channelsMatch( DBPrimaryPos $pos );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
|
|
@ -38,3 +38,10 @@ interface DBMasterPos extends Serializable {
|
||||||
*/
|
*/
|
||||||
public function __toString();
|
public function __toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deprecated alias, renamed as of MediaWiki 1.37
|
||||||
|
*
|
||||||
|
* @deprecated since 1.37
|
||||||
|
*/
|
||||||
|
class_alias( DBPrimaryPos::class, 'Wikimedia\\Rdbms\\DBMasterPos' );
|
||||||
|
|
@ -6,9 +6,9 @@ use InvalidArgumentException;
|
||||||
use UnexpectedValueException;
|
use UnexpectedValueException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DBMasterPos class for MySQL/MariaDB
|
* DBPrimaryPos class for MySQL/MariaDB
|
||||||
*
|
*
|
||||||
* Note that master positions and sync logic here make some assumptions:
|
* Note that primary positions and sync logic here make some assumptions:
|
||||||
* - Binlog-based usage assumes single-source replication and non-hierarchical replication.
|
* - Binlog-based usage assumes single-source replication and non-hierarchical replication.
|
||||||
* - GTID-based usage allows getting/syncing with multi-source replication. It is assumed
|
* - GTID-based usage allows getting/syncing with multi-source replication. It is assumed
|
||||||
* that GTID sets are complete (e.g. include all domains on the server).
|
* that GTID sets are complete (e.g. include all domains on the server).
|
||||||
|
|
@ -16,7 +16,7 @@ use UnexpectedValueException;
|
||||||
* @see https://mariadb.com/kb/en/library/gtid/
|
* @see https://mariadb.com/kb/en/library/gtid/
|
||||||
* @see https://dev.mysql.com/doc/refman/5.6/en/replication-gtids-concepts.html
|
* @see https://dev.mysql.com/doc/refman/5.6/en/replication-gtids-concepts.html
|
||||||
*/
|
*/
|
||||||
class MySQLMasterPos implements DBMasterPos {
|
class MySQLPrimaryPos implements DBPrimaryPos {
|
||||||
/** @var string One of (BINARY_LOG, GTID_MYSQL, GTID_MARIA) */
|
/** @var string One of (BINARY_LOG, GTID_MYSQL, GTID_MARIA) */
|
||||||
private $style;
|
private $style;
|
||||||
/** @var string|null Base name of all Binary Log files */
|
/** @var string|null Base name of all Binary Log files */
|
||||||
|
|
@ -100,7 +100,7 @@ class MySQLMasterPos implements DBMasterPos {
|
||||||
return $this->asOfTime;
|
return $this->asOfTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function hasReached( DBMasterPos $pos ) {
|
public function hasReached( DBPrimaryPos $pos ) {
|
||||||
if ( !( $pos instanceof self ) ) {
|
if ( !( $pos instanceof self ) ) {
|
||||||
throw new InvalidArgumentException( "Position not an instance of " . __CLASS__ );
|
throw new InvalidArgumentException( "Position not an instance of " . __CLASS__ );
|
||||||
}
|
}
|
||||||
|
|
@ -117,7 +117,7 @@ class MySQLMasterPos implements DBMasterPos {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check that $this has a GTID for at least one domain also in $pos; due to MariaDB
|
// Check that $this has a GTID for at least one domain also in $pos; due to MariaDB
|
||||||
// quirks, prior master switch-overs may result in inactive garbage GTIDs that cannot
|
// quirks, prior primary switch-overs may result in inactive garbage GTIDs that cannot
|
||||||
// be cleaned up. Assume that the domains in both this and $pos cover the relevant
|
// be cleaned up. Assume that the domains in both this and $pos cover the relevant
|
||||||
// active channels.
|
// active channels.
|
||||||
return ( $comparisons && !in_array( false, $comparisons, true ) );
|
return ( $comparisons && !in_array( false, $comparisons, true ) );
|
||||||
|
|
@ -134,7 +134,7 @@ class MySQLMasterPos implements DBMasterPos {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function channelsMatch( DBMasterPos $pos ) {
|
public function channelsMatch( DBPrimaryPos $pos ) {
|
||||||
if ( !( $pos instanceof self ) ) {
|
if ( !( $pos instanceof self ) ) {
|
||||||
throw new InvalidArgumentException( "Position not an instance of " . __CLASS__ );
|
throw new InvalidArgumentException( "Position not an instance of " . __CLASS__ );
|
||||||
}
|
}
|
||||||
|
|
@ -144,7 +144,7 @@ class MySQLMasterPos implements DBMasterPos {
|
||||||
$thatPosDomains = array_keys( $pos->getActiveGtidCoordinates() );
|
$thatPosDomains = array_keys( $pos->getActiveGtidCoordinates() );
|
||||||
if ( $thisPosDomains && $thatPosDomains ) {
|
if ( $thisPosDomains && $thatPosDomains ) {
|
||||||
// Check that $this has a GTID for at least one domain also in $pos; due to MariaDB
|
// Check that $this has a GTID for at least one domain also in $pos; due to MariaDB
|
||||||
// quirks, prior master switch-overs may result in inactive garbage GTIDs that cannot
|
// quirks, prior primary switch-overs may result in inactive garbage GTIDs that cannot
|
||||||
// easily be cleaned up. Assume that the domains in both this and $pos cover the
|
// easily be cleaned up. Assume that the domains in both this and $pos cover the
|
||||||
// relevant active channels.
|
// relevant active channels.
|
||||||
return array_intersect( $thatPosDomains, $thisPosDomains ) ? true : false;
|
return array_intersect( $thatPosDomains, $thisPosDomains ) ? true : false;
|
||||||
|
|
@ -195,11 +195,11 @@ class MySQLMasterPos implements DBMasterPos {
|
||||||
*
|
*
|
||||||
* This makes getRelevantActiveGTIDs() filter out GTIDs from other domains
|
* This makes getRelevantActiveGTIDs() filter out GTIDs from other domains
|
||||||
*
|
*
|
||||||
* @see MySQLMasterPos::getRelevantActiveGTIDs()
|
* @see MySQLPrimaryPos::getRelevantActiveGTIDs()
|
||||||
* @see https://mariadb.com/kb/en/library/gtid/#gtid_domain_id
|
* @see https://mariadb.com/kb/en/library/gtid/#gtid_domain_id
|
||||||
*
|
*
|
||||||
* @param string|int|null $id @@gtid_domain_id of the active replication stream
|
* @param string|int|null $id @@gtid_domain_id of the active replication stream
|
||||||
* @return MySQLMasterPos This instance (since 1.34)
|
* @return MySQLPrimaryPos This instance (since 1.34)
|
||||||
* @since 1.31
|
* @since 1.31
|
||||||
*/
|
*/
|
||||||
public function setActiveDomain( $id ) {
|
public function setActiveDomain( $id ) {
|
||||||
|
|
@ -213,10 +213,10 @@ class MySQLMasterPos implements DBMasterPos {
|
||||||
*
|
*
|
||||||
* This makes getRelevantActiveGTIDs() filter out GTIDs from other origin servers
|
* This makes getRelevantActiveGTIDs() filter out GTIDs from other origin servers
|
||||||
*
|
*
|
||||||
* @see MySQLMasterPos::getRelevantActiveGTIDs()
|
* @see MySQLPrimaryPos::getRelevantActiveGTIDs()
|
||||||
*
|
*
|
||||||
* @param string|int|null $id @@server_id of the server were writes originate
|
* @param string|int|null $id @@server_id of the server were writes originate
|
||||||
* @return MySQLMasterPos This instance (since 1.34)
|
* @return MySQLPrimaryPos This instance (since 1.34)
|
||||||
* @since 1.31
|
* @since 1.31
|
||||||
*/
|
*/
|
||||||
public function setActiveOriginServerId( $id ) {
|
public function setActiveOriginServerId( $id ) {
|
||||||
|
|
@ -230,10 +230,10 @@ class MySQLMasterPos implements DBMasterPos {
|
||||||
*
|
*
|
||||||
* This makes getRelevantActiveGTIDs() filter out GTIDs from other origin servers
|
* This makes getRelevantActiveGTIDs() filter out GTIDs from other origin servers
|
||||||
*
|
*
|
||||||
* @see MySQLMasterPos::getRelevantActiveGTIDs()
|
* @see MySQLPrimaryPos::getRelevantActiveGTIDs()
|
||||||
*
|
*
|
||||||
* @param string|null $id @@server_uuid of the server were writes originate
|
* @param string|null $id @@server_uuid of the server were writes originate
|
||||||
* @return MySQLMasterPos This instance (since 1.34)
|
* @return MySQLPrimaryPos This instance (since 1.34)
|
||||||
* @since 1.31
|
* @since 1.31
|
||||||
*/
|
*/
|
||||||
public function setActiveOriginServerUUID( $id ) {
|
public function setActiveOriginServerUUID( $id ) {
|
||||||
|
|
@ -243,12 +243,12 @@ class MySQLMasterPos implements DBMasterPos {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param MySQLMasterPos $pos
|
* @param MySQLPrimaryPos $pos
|
||||||
* @param MySQLMasterPos $refPos
|
* @param MySQLPrimaryPos $refPos
|
||||||
* @return string[] List of active GTIDs from $pos that have domains in $refPos
|
* @return string[] List of active GTIDs from $pos that have domains in $refPos
|
||||||
* @since 1.34
|
* @since 1.34
|
||||||
*/
|
*/
|
||||||
public static function getRelevantActiveGTIDs( MySQLMasterPos $pos, MySQLMasterPos $refPos ) {
|
public static function getRelevantActiveGTIDs( MySQLPrimaryPos $pos, MySQLPrimaryPos $refPos ) {
|
||||||
return array_values( array_intersect_key(
|
return array_values( array_intersect_key(
|
||||||
$pos->gtids,
|
$pos->gtids,
|
||||||
$pos->getActiveGtidCoordinates(),
|
$pos->getActiveGtidCoordinates(),
|
||||||
|
|
@ -363,3 +363,10 @@ class MySQLMasterPos implements DBMasterPos {
|
||||||
: $this->getLogFile() . "/{$this->logPos[self::CORD_EVENT]}";
|
: $this->getLogFile() . "/{$this->logPos[self::CORD_EVENT]}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deprecated alias, renamed as of MediaWiki 1.37
|
||||||
|
*
|
||||||
|
* @deprecated since 1.37
|
||||||
|
*/
|
||||||
|
class_alias( MySQLPrimaryPos::class, 'Wikimedia\\Rdbms\\MySQLMasterPos' );
|
||||||
|
|
@ -595,7 +595,7 @@ abstract class LBFactory implements ILBFactory {
|
||||||
protected function shutdownChronologyProtector(
|
protected function shutdownChronologyProtector(
|
||||||
ChronologyProtector $cp, $workCallback, &$cpIndex = null
|
ChronologyProtector $cp, $workCallback, &$cpIndex = null
|
||||||
) {
|
) {
|
||||||
// Remark all of the relevant DB master positions
|
// Remark all of the relevant DB primary positions
|
||||||
$this->forEachLB( static function ( ILoadBalancer $lb ) use ( $cp ) {
|
$this->forEachLB( static function ( ILoadBalancer $lb ) use ( $cp ) {
|
||||||
$cp->stageSessionReplicationPosition( $lb );
|
$cp->stageSessionReplicationPosition( $lb );
|
||||||
} );
|
} );
|
||||||
|
|
@ -607,8 +607,8 @@ abstract class LBFactory implements ILBFactory {
|
||||||
}
|
}
|
||||||
// If the positions failed to write to the stash, then wait on the local datacenter
|
// If the positions failed to write to the stash, then wait on the local datacenter
|
||||||
// replica DBs to catch up before sending an HTTP response. As long as the request that
|
// replica DBs to catch up before sending an HTTP response. As long as the request that
|
||||||
// caused such DB writes occurred in the master datacenter, and clients are temporarily
|
// caused such DB writes occurred in the primary datacenter, and clients are temporarily
|
||||||
// pinned to the master datacenter after causing DB writes, then this should suffice.
|
// pinned to the primary datacenter after causing DB writes, then this should suffice.
|
||||||
$this->forEachLB( static function ( ILoadBalancer $lb ) use ( $unsavedPositions ) {
|
$this->forEachLB( static function ( ILoadBalancer $lb ) use ( $unsavedPositions ) {
|
||||||
$masterName = $lb->getServerName( $lb->getWriterIndex() );
|
$masterName = $lb->getServerName( $lb->getWriterIndex() );
|
||||||
if ( isset( $unsavedPositions[$masterName] ) ) {
|
if ( isset( $unsavedPositions[$masterName] ) ) {
|
||||||
|
|
|
||||||
|
|
@ -225,7 +225,7 @@ interface ILoadBalancer {
|
||||||
* will return true. This is useful for discouraging clients from taking further actions
|
* will return true. This is useful for discouraging clients from taking further actions
|
||||||
* if session consistency could not be maintained with respect to their last actions.
|
* if session consistency could not be maintained with respect to their last actions.
|
||||||
*
|
*
|
||||||
* @param DBMasterPos|bool $pos Primary position or false
|
* @param DBPrimaryPos|bool $pos Primary position or false
|
||||||
*/
|
*/
|
||||||
public function waitFor( $pos );
|
public function waitFor( $pos );
|
||||||
|
|
||||||
|
|
@ -237,7 +237,7 @@ interface ILoadBalancer {
|
||||||
*
|
*
|
||||||
* This can be used a faster proxy for waitForAll()
|
* This can be used a faster proxy for waitForAll()
|
||||||
*
|
*
|
||||||
* @param DBMasterPos|bool $pos Primary position or false
|
* @param DBPrimaryPos|bool $pos Primary position or false
|
||||||
* @param int|null $timeout Max seconds to wait; default is mWaitTimeout
|
* @param int|null $timeout Max seconds to wait; default is mWaitTimeout
|
||||||
* @return bool Success (able to connect and no timeouts reached)
|
* @return bool Success (able to connect and no timeouts reached)
|
||||||
*/
|
*/
|
||||||
|
|
@ -249,7 +249,7 @@ interface ILoadBalancer {
|
||||||
* This method is only intented for use a throttling mechanism for high-volume updates.
|
* This method is only intented for use a throttling mechanism for high-volume updates.
|
||||||
* Unlike waitFor(), failure does not effect getLaggedReplicaMode()/laggedReplicaUsed().
|
* Unlike waitFor(), failure does not effect getLaggedReplicaMode()/laggedReplicaUsed().
|
||||||
*
|
*
|
||||||
* @param DBMasterPos|bool $pos Primary position or false
|
* @param DBPrimaryPos|bool $pos Primary position or false
|
||||||
* @param int|null $timeout Max seconds to wait; default is mWaitTimeout
|
* @param int|null $timeout Max seconds to wait; default is mWaitTimeout
|
||||||
* @return bool Success (able to connect and no timeouts reached)
|
* @return bool Success (able to connect and no timeouts reached)
|
||||||
*/
|
*/
|
||||||
|
|
@ -515,7 +515,7 @@ interface ILoadBalancer {
|
||||||
/**
|
/**
|
||||||
* Get the current primary replication position
|
* Get the current primary replication position
|
||||||
*
|
*
|
||||||
* @return DBMasterPos|bool Returns false if not applicable
|
* @return DBPrimaryPos|bool Returns false if not applicable
|
||||||
* @throws DBError
|
* @throws DBError
|
||||||
*/
|
*/
|
||||||
public function getMasterPos();
|
public function getMasterPos();
|
||||||
|
|
@ -532,7 +532,7 @@ interface ILoadBalancer {
|
||||||
* This can be useful for implementing session consistency, where the session
|
* This can be useful for implementing session consistency, where the session
|
||||||
* will be resumed accross multiple HTTP requests or CLI script instances.
|
* will be resumed accross multiple HTTP requests or CLI script instances.
|
||||||
*
|
*
|
||||||
* @return DBMasterPos|bool Replication position or false if not applicable
|
* @return DBPrimaryPos|bool Replication position or false if not applicable
|
||||||
* @since 1.34
|
* @since 1.34
|
||||||
*/
|
*/
|
||||||
public function getReplicaResumePos();
|
public function getReplicaResumePos();
|
||||||
|
|
@ -786,7 +786,7 @@ interface ILoadBalancer {
|
||||||
* to get an accurate position.
|
* to get an accurate position.
|
||||||
*
|
*
|
||||||
* @param IDatabase $conn Replica DB
|
* @param IDatabase $conn Replica DB
|
||||||
* @param DBMasterPos|bool $pos Primary position; default: current position
|
* @param DBPrimaryPos|bool $pos Primary position; default: current position
|
||||||
* @param int $timeout Timeout in seconds [optional]
|
* @param int $timeout Timeout in seconds [optional]
|
||||||
* @return bool Success
|
* @return bool Success
|
||||||
* @since 1.34
|
* @since 1.34
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,7 @@ class LoadBalancer implements ILoadBalancer {
|
||||||
private $errorConnection;
|
private $errorConnection;
|
||||||
/** @var int[] The group replica server indexes keyed by group */
|
/** @var int[] The group replica server indexes keyed by group */
|
||||||
private $readIndexByGroup = [];
|
private $readIndexByGroup = [];
|
||||||
/** @var bool|DBMasterPos Replication sync position or false if not set */
|
/** @var bool|DBPrimaryPos Replication sync position or false if not set */
|
||||||
private $waitForPos;
|
private $waitForPos;
|
||||||
/** @var bool Whether to disregard replica DB lag as a factor in replica DB selection */
|
/** @var bool Whether to disregard replica DB lag as a factor in replica DB selection */
|
||||||
private $allowLagged = false;
|
private $allowLagged = false;
|
||||||
|
|
@ -792,7 +792,7 @@ class LoadBalancer implements ILoadBalancer {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param DBMasterPos|bool $pos
|
* @param DBPrimaryPos|bool $pos
|
||||||
*/
|
*/
|
||||||
private function setWaitForPositionIfHigher( $pos ) {
|
private function setWaitForPositionIfHigher( $pos ) {
|
||||||
if ( !$pos ) {
|
if ( !$pos ) {
|
||||||
|
|
@ -893,10 +893,10 @@ class LoadBalancer implements ILoadBalancer {
|
||||||
// Check if we already know that the DB has reached this point
|
// Check if we already know that the DB has reached this point
|
||||||
$srvName = $this->getServerName( $index );
|
$srvName = $this->getServerName( $index );
|
||||||
$key = $this->srvCache->makeGlobalKey( __CLASS__, 'last-known-pos', $srvName, 'v1' );
|
$key = $this->srvCache->makeGlobalKey( __CLASS__, 'last-known-pos', $srvName, 'v1' );
|
||||||
/** @var DBMasterPos $knownReachedPos */
|
/** @var DBPrimaryPos $knownReachedPos */
|
||||||
$knownReachedPos = $this->srvCache->get( $key );
|
$knownReachedPos = $this->srvCache->get( $key );
|
||||||
if (
|
if (
|
||||||
$knownReachedPos instanceof DBMasterPos &&
|
$knownReachedPos instanceof DBPrimaryPos &&
|
||||||
$knownReachedPos->hasReached( $this->waitForPos )
|
$knownReachedPos->hasReached( $this->waitForPos )
|
||||||
) {
|
) {
|
||||||
$this->replLogger->debug(
|
$this->replLogger->debug(
|
||||||
|
|
@ -2383,7 +2383,7 @@ class LoadBalancer implements ILoadBalancer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $pos instanceof DBMasterPos ) {
|
if ( $pos instanceof DBPrimaryPos ) {
|
||||||
$this->replLogger->debug( __METHOD__ . ': waiting' );
|
$this->replLogger->debug( __METHOD__ . ': waiting' );
|
||||||
$result = $conn->masterPosWait( $pos, $timeout );
|
$result = $conn->masterPosWait( $pos, $timeout );
|
||||||
$ok = ( $result !== null && $result != -1 );
|
$ok = ( $result !== null && $result != -1 );
|
||||||
|
|
|
||||||
|
|
@ -653,7 +653,7 @@ class RecompressTracked {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a DB master connection for the given external cluster name
|
* Gets a DB primary connection for the given external cluster name
|
||||||
* @param string $cluster
|
* @param string $cluster
|
||||||
* @return IMaintainableDatabase
|
* @return IMaintainableDatabase
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ use Wikimedia\Rdbms\LBFactoryMulti;
|
||||||
use Wikimedia\Rdbms\LBFactorySimple;
|
use Wikimedia\Rdbms\LBFactorySimple;
|
||||||
use Wikimedia\Rdbms\LoadBalancer;
|
use Wikimedia\Rdbms\LoadBalancer;
|
||||||
use Wikimedia\Rdbms\LoadMonitorNull;
|
use Wikimedia\Rdbms\LoadMonitorNull;
|
||||||
use Wikimedia\Rdbms\MySQLMasterPos;
|
use Wikimedia\Rdbms\MySQLPrimaryPos;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @group Database
|
* @group Database
|
||||||
|
|
@ -257,8 +257,8 @@ class LBFactoryTest extends MediaWikiIntegrationTestCase {
|
||||||
$now = microtime( true );
|
$now = microtime( true );
|
||||||
|
|
||||||
// (a) First HTTP request
|
// (a) First HTTP request
|
||||||
$m1Pos = new MySQLMasterPos( 'db1034-bin.000976/843431247', $now );
|
$m1Pos = new MySQLPrimaryPos( 'db1034-bin.000976/843431247', $now );
|
||||||
$m2Pos = new MySQLMasterPos( 'db1064-bin.002400/794074907', $now );
|
$m2Pos = new MySQLPrimaryPos( 'db1064-bin.002400/794074907', $now );
|
||||||
|
|
||||||
// Primary DB 1
|
// Primary DB 1
|
||||||
/** @var IDatabase|\PHPUnit\Framework\MockObject\MockObject $mockDB1 */
|
/** @var IDatabase|\PHPUnit\Framework\MockObject\MockObject $mockDB1 */
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
use Wikimedia\Rdbms\DatabaseMysqli;
|
use Wikimedia\Rdbms\DatabaseMysqli;
|
||||||
use Wikimedia\Rdbms\IDatabase;
|
use Wikimedia\Rdbms\IDatabase;
|
||||||
use Wikimedia\Rdbms\IMaintainableDatabase;
|
use Wikimedia\Rdbms\IMaintainableDatabase;
|
||||||
use Wikimedia\Rdbms\MySQLMasterPos;
|
use Wikimedia\Rdbms\MySQLPrimaryPos;
|
||||||
use Wikimedia\TestingAccessWrapper;
|
use Wikimedia\TestingAccessWrapper;
|
||||||
|
|
||||||
class DatabaseMysqlBaseTest extends PHPUnit\Framework\TestCase {
|
class DatabaseMysqlBaseTest extends PHPUnit\Framework\TestCase {
|
||||||
|
|
@ -139,10 +139,10 @@ class DatabaseMysqlBaseTest extends PHPUnit\Framework\TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers \Wikimedia\Rdbms\MySQLMasterPos
|
* @covers \Wikimedia\Rdbms\MySQLPrimaryPos
|
||||||
*/
|
*/
|
||||||
public function testBinLogName() {
|
public function testBinLogName() {
|
||||||
$pos = new MySQLMasterPos( "db1052.2424/4643", 1 );
|
$pos = new MySQLPrimaryPos( "db1052.2424/4643", 1 );
|
||||||
|
|
||||||
$this->assertEquals( "db1052", $pos->getLogName() );
|
$this->assertEquals( "db1052", $pos->getLogName() );
|
||||||
$this->assertEquals( "db1052.2424", $pos->getLogFile() );
|
$this->assertEquals( "db1052.2424", $pos->getLogFile() );
|
||||||
|
|
@ -151,10 +151,10 @@ class DatabaseMysqlBaseTest extends PHPUnit\Framework\TestCase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider provideComparePositions
|
* @dataProvider provideComparePositions
|
||||||
* @covers \Wikimedia\Rdbms\MySQLMasterPos
|
* @covers \Wikimedia\Rdbms\MySQLPrimaryPos
|
||||||
*/
|
*/
|
||||||
public function testHasReached(
|
public function testHasReached(
|
||||||
MySQLMasterPos $lowerPos, MySQLMasterPos $higherPos, $match, $hetero
|
MySQLPrimaryPos $lowerPos, MySQLPrimaryPos $higherPos, $match, $hetero
|
||||||
) {
|
) {
|
||||||
if ( $match ) {
|
if ( $match ) {
|
||||||
$this->assertTrue( $lowerPos->channelsMatch( $higherPos ) );
|
$this->assertTrue( $lowerPos->channelsMatch( $higherPos ) );
|
||||||
|
|
@ -182,94 +182,94 @@ class DatabaseMysqlBaseTest extends PHPUnit\Framework\TestCase {
|
||||||
return [
|
return [
|
||||||
// Binlog style
|
// Binlog style
|
||||||
[
|
[
|
||||||
new MySQLMasterPos( 'db1034-bin.000976/843431247', $now ),
|
new MySQLPrimaryPos( 'db1034-bin.000976/843431247', $now ),
|
||||||
new MySQLMasterPos( 'db1034-bin.000976/843431248', $now ),
|
new MySQLPrimaryPos( 'db1034-bin.000976/843431248', $now ),
|
||||||
true,
|
true,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
new MySQLMasterPos( 'db1034-bin.000976/999', $now ),
|
new MySQLPrimaryPos( 'db1034-bin.000976/999', $now ),
|
||||||
new MySQLMasterPos( 'db1034-bin.000976/1000', $now ),
|
new MySQLPrimaryPos( 'db1034-bin.000976/1000', $now ),
|
||||||
true,
|
true,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
new MySQLMasterPos( 'db1034-bin.000976/999', $now ),
|
new MySQLPrimaryPos( 'db1034-bin.000976/999', $now ),
|
||||||
new MySQLMasterPos( 'db1035-bin.000976/1000', $now ),
|
new MySQLPrimaryPos( 'db1035-bin.000976/1000', $now ),
|
||||||
false,
|
false,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
// MySQL GTID style
|
// MySQL GTID style
|
||||||
[
|
[
|
||||||
new MySQLMasterPos( '3E11FA47-71CA-11E1-9E33-C80AA9429562:1-23', $now ),
|
new MySQLPrimaryPos( '3E11FA47-71CA-11E1-9E33-C80AA9429562:1-23', $now ),
|
||||||
new MySQLMasterPos( '3E11FA47-71CA-11E1-9E33-C80AA9429562:5-24', $now ),
|
new MySQLPrimaryPos( '3E11FA47-71CA-11E1-9E33-C80AA9429562:5-24', $now ),
|
||||||
true,
|
true,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
new MySQLMasterPos( '3E11FA47-71CA-11E1-9E33-C80AA9429562:5-99', $now ),
|
new MySQLPrimaryPos( '3E11FA47-71CA-11E1-9E33-C80AA9429562:5-99', $now ),
|
||||||
new MySQLMasterPos( '3E11FA47-71CA-11E1-9E33-C80AA9429562:1-100', $now ),
|
new MySQLPrimaryPos( '3E11FA47-71CA-11E1-9E33-C80AA9429562:1-100', $now ),
|
||||||
true,
|
true,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
new MySQLMasterPos( '3E11FA47-71CA-11E1-9E33-C80AA9429562:1-99', $now ),
|
new MySQLPrimaryPos( '3E11FA47-71CA-11E1-9E33-C80AA9429562:1-99', $now ),
|
||||||
new MySQLMasterPos( '1E11FA47-71CA-11E1-9E33-C80AA9429562:1-100', $now ),
|
new MySQLPrimaryPos( '1E11FA47-71CA-11E1-9E33-C80AA9429562:1-100', $now ),
|
||||||
false,
|
false,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
// MariaDB GTID style
|
// MariaDB GTID style
|
||||||
[
|
[
|
||||||
new MySQLMasterPos( '255-11-23', $now ),
|
new MySQLPrimaryPos( '255-11-23', $now ),
|
||||||
new MySQLMasterPos( '255-11-24', $now ),
|
new MySQLPrimaryPos( '255-11-24', $now ),
|
||||||
true,
|
true,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
new MySQLMasterPos( '255-11-99', $now ),
|
new MySQLPrimaryPos( '255-11-99', $now ),
|
||||||
new MySQLMasterPos( '255-11-100', $now ),
|
new MySQLPrimaryPos( '255-11-100', $now ),
|
||||||
true,
|
true,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
new MySQLMasterPos( '255-11-999', $now ),
|
new MySQLPrimaryPos( '255-11-999', $now ),
|
||||||
new MySQLMasterPos( '254-11-1000', $now ),
|
new MySQLPrimaryPos( '254-11-1000', $now ),
|
||||||
false,
|
false,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
new MySQLMasterPos( '255-11-23,256-12-50', $now ),
|
new MySQLPrimaryPos( '255-11-23,256-12-50', $now ),
|
||||||
new MySQLMasterPos( '255-11-24', $now ),
|
new MySQLPrimaryPos( '255-11-24', $now ),
|
||||||
true,
|
true,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
new MySQLMasterPos( '255-11-99,256-12-50,257-12-50', $now ),
|
new MySQLPrimaryPos( '255-11-99,256-12-50,257-12-50', $now ),
|
||||||
new MySQLMasterPos( '255-11-1000', $now ),
|
new MySQLPrimaryPos( '255-11-1000', $now ),
|
||||||
true,
|
true,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
new MySQLMasterPos( '255-11-23,256-12-50', $now ),
|
new MySQLPrimaryPos( '255-11-23,256-12-50', $now ),
|
||||||
new MySQLMasterPos( '255-11-24,155-52-63', $now ),
|
new MySQLPrimaryPos( '255-11-24,155-52-63', $now ),
|
||||||
true,
|
true,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
new MySQLMasterPos( '255-11-99,256-12-50,257-12-50', $now ),
|
new MySQLPrimaryPos( '255-11-99,256-12-50,257-12-50', $now ),
|
||||||
new MySQLMasterPos( '255-11-1000,256-12-51', $now ),
|
new MySQLPrimaryPos( '255-11-1000,256-12-51', $now ),
|
||||||
true,
|
true,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
new MySQLMasterPos( '255-11-99,256-12-50', $now ),
|
new MySQLPrimaryPos( '255-11-99,256-12-50', $now ),
|
||||||
new MySQLMasterPos( '255-13-1000,256-14-49', $now ),
|
new MySQLPrimaryPos( '255-13-1000,256-14-49', $now ),
|
||||||
true,
|
true,
|
||||||
true
|
true
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
new MySQLMasterPos( '253-11-999,255-11-999', $now ),
|
new MySQLPrimaryPos( '253-11-999,255-11-999', $now ),
|
||||||
new MySQLMasterPos( '254-11-1000', $now ),
|
new MySQLPrimaryPos( '254-11-1000', $now ),
|
||||||
false,
|
false,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
|
|
@ -278,13 +278,13 @@ class DatabaseMysqlBaseTest extends PHPUnit\Framework\TestCase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider provideChannelPositions
|
* @dataProvider provideChannelPositions
|
||||||
* @covers \Wikimedia\Rdbms\MySQLMasterPos
|
* @covers \Wikimedia\Rdbms\MySQLPrimaryPos
|
||||||
*/
|
*/
|
||||||
public function testChannelsMatch( MySQLMasterPos $pos1, MySQLMasterPos $pos2, $matches ) {
|
public function testChannelsMatch( MySQLPrimaryPos $pos1, MySQLPrimaryPos $pos2, $matches ) {
|
||||||
$this->assertEquals( $matches, $pos1->channelsMatch( $pos2 ) );
|
$this->assertEquals( $matches, $pos1->channelsMatch( $pos2 ) );
|
||||||
$this->assertEquals( $matches, $pos2->channelsMatch( $pos1 ) );
|
$this->assertEquals( $matches, $pos2->channelsMatch( $pos1 ) );
|
||||||
|
|
||||||
$roundtripPos = new MySQLMasterPos( (string)$pos1, 1 );
|
$roundtripPos = new MySQLPrimaryPos( (string)$pos1, 1 );
|
||||||
$this->assertEquals( (string)$pos1, (string)$roundtripPos );
|
$this->assertEquals( (string)$pos1, (string)$roundtripPos );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -293,23 +293,23 @@ class DatabaseMysqlBaseTest extends PHPUnit\Framework\TestCase {
|
||||||
|
|
||||||
return [
|
return [
|
||||||
[
|
[
|
||||||
new MySQLMasterPos( 'db1034-bin.000876/44', $now ),
|
new MySQLPrimaryPos( 'db1034-bin.000876/44', $now ),
|
||||||
new MySQLMasterPos( 'db1034-bin.000976/74', $now ),
|
new MySQLPrimaryPos( 'db1034-bin.000976/74', $now ),
|
||||||
true
|
true
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
new MySQLMasterPos( 'db1052-bin.000976/999', $now ),
|
new MySQLPrimaryPos( 'db1052-bin.000976/999', $now ),
|
||||||
new MySQLMasterPos( 'db1052-bin.000976/1000', $now ),
|
new MySQLPrimaryPos( 'db1052-bin.000976/1000', $now ),
|
||||||
true
|
true
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
new MySQLMasterPos( 'db1066-bin.000976/9999', $now ),
|
new MySQLPrimaryPos( 'db1066-bin.000976/9999', $now ),
|
||||||
new MySQLMasterPos( 'db1035-bin.000976/10000', $now ),
|
new MySQLPrimaryPos( 'db1035-bin.000976/10000', $now ),
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
new MySQLMasterPos( 'db1066-bin.000976/9999', $now ),
|
new MySQLPrimaryPos( 'db1066-bin.000976/9999', $now ),
|
||||||
new MySQLMasterPos( 'trump2016.000976/10000', $now ),
|
new MySQLPrimaryPos( 'trump2016.000976/10000', $now ),
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
@ -317,33 +317,33 @@ class DatabaseMysqlBaseTest extends PHPUnit\Framework\TestCase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider provideCommonDomainGTIDs
|
* @dataProvider provideCommonDomainGTIDs
|
||||||
* @covers \Wikimedia\Rdbms\MySQLMasterPos
|
* @covers \Wikimedia\Rdbms\MySQLPrimaryPos
|
||||||
*/
|
*/
|
||||||
public function testGetRelevantActiveGTIDs( MySQLMasterPos $pos, MySQLMasterPos $ref, $gtids ) {
|
public function testGetRelevantActiveGTIDs( MySQLPrimaryPos $pos, MySQLPrimaryPos $ref, $gtids ) {
|
||||||
$this->assertEquals( $gtids, MySQLMasterPos::getRelevantActiveGTIDs( $pos, $ref ) );
|
$this->assertEquals( $gtids, MySQLPrimaryPos::getRelevantActiveGTIDs( $pos, $ref ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function provideCommonDomainGTIDs() {
|
public static function provideCommonDomainGTIDs() {
|
||||||
return [
|
return [
|
||||||
[
|
[
|
||||||
new MySQLMasterPos( '255-13-99,256-12-50,257-14-50', 1 ),
|
new MySQLPrimaryPos( '255-13-99,256-12-50,257-14-50', 1 ),
|
||||||
new MySQLMasterPos( '255-11-1000', 1 ),
|
new MySQLPrimaryPos( '255-11-1000', 1 ),
|
||||||
[ '255-13-99' ]
|
[ '255-13-99' ]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
( new MySQLMasterPos( '255-13-99,256-12-50,257-14-50', 1 ) )
|
( new MySQLPrimaryPos( '255-13-99,256-12-50,257-14-50', 1 ) )
|
||||||
->setActiveDomain( 257 ),
|
->setActiveDomain( 257 ),
|
||||||
new MySQLMasterPos( '255-11-1000,257-14-30', 1 ),
|
new MySQLPrimaryPos( '255-11-1000,257-14-30', 1 ),
|
||||||
[ '257-14-50' ]
|
[ '257-14-50' ]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
new MySQLMasterPos(
|
new MySQLPrimaryPos(
|
||||||
'2E11FA47-71CA-11E1-9E33-C80AA9429562:1-5,' .
|
'2E11FA47-71CA-11E1-9E33-C80AA9429562:1-5,' .
|
||||||
'3E11FA47-71CA-11E1-9E33-C80AA9429562:20-99,' .
|
'3E11FA47-71CA-11E1-9E33-C80AA9429562:20-99,' .
|
||||||
'7E11FA47-71CA-11E1-9E33-C80AA9429562:1-30',
|
'7E11FA47-71CA-11E1-9E33-C80AA9429562:1-30',
|
||||||
1
|
1
|
||||||
),
|
),
|
||||||
new MySQLMasterPos(
|
new MySQLPrimaryPos(
|
||||||
'1E11FA47-71CA-11E1-9E33-C80AA9429562:30-100,' .
|
'1E11FA47-71CA-11E1-9E33-C80AA9429562:30-100,' .
|
||||||
'3E11FA47-71CA-11E1-9E33-C80AA9429562:30-66',
|
'3E11FA47-71CA-11E1-9E33-C80AA9429562:30-66',
|
||||||
1
|
1
|
||||||
|
|
@ -400,7 +400,7 @@ class DatabaseMysqlBaseTest extends PHPUnit\Framework\TestCase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider provideGtidData
|
* @dataProvider provideGtidData
|
||||||
* @covers \Wikimedia\Rdbms\MySQLMasterPos
|
* @covers \Wikimedia\Rdbms\MySQLPrimaryPos
|
||||||
* @covers \Wikimedia\Rdbms\DatabaseMysqlBase::getReplicaPos
|
* @covers \Wikimedia\Rdbms\DatabaseMysqlBase::getReplicaPos
|
||||||
* @covers \Wikimedia\Rdbms\DatabaseMysqlBase::getMasterPos
|
* @covers \Wikimedia\Rdbms\DatabaseMysqlBase::getMasterPos
|
||||||
*/
|
*/
|
||||||
|
|
@ -554,15 +554,15 @@ class DatabaseMysqlBaseTest extends PHPUnit\Framework\TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers \Wikimedia\Rdbms\MySQLMasterPos
|
* @covers \Wikimedia\Rdbms\MySQLPrimaryPos
|
||||||
*/
|
*/
|
||||||
public function testSerialize() {
|
public function testSerialize() {
|
||||||
$pos = new MySQLMasterPos( '3E11FA47-71CA-11E1-9E33-C80AA9429562:99', 53636363 );
|
$pos = new MySQLPrimaryPos( '3E11FA47-71CA-11E1-9E33-C80AA9429562:99', 53636363 );
|
||||||
$roundtripPos = unserialize( serialize( $pos ) );
|
$roundtripPos = unserialize( serialize( $pos ) );
|
||||||
|
|
||||||
$this->assertEquals( $pos, $roundtripPos );
|
$this->assertEquals( $pos, $roundtripPos );
|
||||||
|
|
||||||
$pos = new MySQLMasterPos( '255-11-23', 53636363 );
|
$pos = new MySQLPrimaryPos( '255-11-23', 53636363 );
|
||||||
$roundtripPos = unserialize( serialize( $pos ) );
|
$roundtripPos = unserialize( serialize( $pos ) );
|
||||||
|
|
||||||
$this->assertEquals( $pos, $roundtripPos );
|
$this->assertEquals( $pos, $roundtripPos );
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue