/** @var callable[] */
protected $replicationWaitCallbacks = [];
+ /** @var array[] $aliases Map of (table => (dbname, schema, prefix) map) */
+ protected $tableAliases = [];
+ /** @var string[] Map of (index alias => index) */
+ protected $indexAliases = [];
+
/** @var bool Whether this PHP instance is for a CLI script */
protected $cliMode;
/** @var string Agent name for query profiling */
'IPAddress' => isset( $_SERVER[ 'REMOTE_ADDR' ] ) ? $_SERVER[ 'REMOTE_ADDR' ] : '',
'UserAgent' => isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : '',
'ChronologyProtection' => 'true',
- 'ChronologyPositionTime' => isset( $_GET['cpPosTime'] ) ? $_GET['cpPosTime'] : null
+ 'ChronologyPositionIndex' => isset( $_GET['cpPosIndex'] ) ? $_GET['cpPosIndex'] : null
];
$this->cliMode = isset( $conf['cliMode'] ) ? $conf['cliMode'] : PHP_SAPI === 'cli';
}
public function shutdown(
- $mode = self::SHUTDOWN_CHRONPROT_SYNC, callable $workCallback = null
+ $mode = self::SHUTDOWN_CHRONPROT_SYNC, callable $workCallback = null, &$cpIndex = null
) {
$chronProt = $this->getChronologyProtector();
if ( $mode === self::SHUTDOWN_CHRONPROT_SYNC ) {
- $this->shutdownChronologyProtector( $chronProt, $workCallback, 'sync' );
+ $this->shutdownChronologyProtector( $chronProt, $workCallback, 'sync', $cpIndex );
} elseif ( $mode === self::SHUTDOWN_CHRONPROT_ASYNC ) {
- $this->shutdownChronologyProtector( $chronProt, null, 'async' );
+ $this->shutdownChronologyProtector( $chronProt, null, 'async', $cpIndex );
}
$this->commitMasterChanges( __METHOD__ ); // sanity
$failed = [];
foreach ( $lbs as $i => $lb ) {
if ( $masterPositions[$i] ) {
- // The DBMS may not support getMasterPos()
+ // The RDBMS may not support getMasterPos()
if ( !$lb->waitForAll( $masterPositions[$i], $opts['timeout'] ) ) {
$failed[] = $lb->getServerName( $lb->getWriterIndex() );
}
'ip' => $this->requestInfo['IPAddress'],
'agent' => $this->requestInfo['UserAgent'],
],
- $this->requestInfo['ChronologyPositionTime']
+ $this->requestInfo['ChronologyPositionIndex']
);
$this->chronProt->setLogger( $this->replLogger );
* @param ChronologyProtector $cp
* @param callable|null $workCallback Work to do instead of waiting on syncing positions
* @param string $mode One of (sync, async); whether to wait on remote datacenters
+ * @param int|null &$cpIndex DB position key write counter; incremented on update
*/
protected function shutdownChronologyProtector(
- ChronologyProtector $cp, $workCallback, $mode
+ ChronologyProtector $cp, $workCallback, $mode, &$cpIndex = null
) {
// Record all the master positions needed
$this->forEachLB( function ( ILoadBalancer $lb ) use ( $cp ) {
} );
// Write them to the persistent stash. Try to do something useful by running $work
// while ChronologyProtector waits for the stash write to replicate to all DCs.
- $unsavedPositions = $cp->shutdown( $workCallback, $mode );
+ $unsavedPositions = $cp->shutdown( $workCallback, $mode, $cpIndex );
if ( $unsavedPositions && $workCallback ) {
// Invoke callback in case it did not cache the result yet
$workCallback(); // work now to block for less time in waitForAll()
if ( $this->trxRoundId !== false ) {
$lb->beginMasterChanges( $this->trxRoundId ); // set DBO_TRX
}
+
+ $lb->setTableAliases( $this->tableAliases );
+ $lb->setIndexAliases( $this->indexAliases );
+ }
+
+ public function setTableAliases( array $aliases ) {
+ $this->tableAliases = $aliases;
+ }
+
+ public function setIndexAliases( array $aliases ) {
+ $this->indexAliases = $aliases;
}
public function setDomainPrefix( $prefix ) {
$this->agent = $agent;
}
- public function appendPreShutdownTimeAsQuery( $url, $time ) {
+ public function appendShutdownCPIndexAsQuery( $url, $index ) {
$usedCluster = 0;
$this->forEachLB( function ( ILoadBalancer $lb ) use ( &$usedCluster ) {
$usedCluster |= ( $lb->getServerCount() > 1 );
return $url; // no master/replica clusters touched
}
- return strpos( $url, '?' ) === false ? "$url?cpPosTime=$time" : "$url&cpPosTime=$time";
+ return strpos( $url, '?' ) === false ? "$url?cpPosIndex=$index" : "$url&cpPosIndex=$index";
}
public function setRequestInfo( array $info ) {