77 [
'replLogger',
'connLogger',
'queryLogger',
'perfLogger' ];
80 $this->localDomain = isset( $conf[
'localDomain'] )
84 if ( isset( $conf[
'readOnlyReason'] ) && is_string( $conf[
'readOnlyReason'] ) ) {
85 $this->readOnlyReason = $conf[
'readOnlyReason'];
88 $this->srvCache = isset( $conf[
'srvCache'] ) ? $conf[
'srvCache'] :
new EmptyBagOStuff();
89 $this->memCache = isset( $conf[
'memCache'] ) ? $conf[
'memCache'] :
new EmptyBagOStuff();
90 $this->wanCache = isset( $conf[
'wanCache'] )
94 foreach ( self::$loggerFields
as $key ) {
95 $this->$key = isset( $conf[$key] ) ? $conf[$key] : new \Psr\Log\NullLogger();
97 $this->errorLogger = isset( $conf[
'errorLogger'] )
98 ? $conf[
'errorLogger']
100 trigger_error( E_USER_WARNING, get_class(
$e ) .
': ' .
$e->getMessage() );
103 $this->profiler = isset(
$params[
'profiler'] ) ?
$params[
'profiler'] : null;
104 $this->trxProfiler = isset( $conf[
'trxProfiler'] )
105 ? $conf[
'trxProfiler']
108 $this->requestInfo = [
109 'IPAddress' => isset( $_SERVER[
'REMOTE_ADDR' ] ) ? $_SERVER[
'REMOTE_ADDR' ] :
'',
110 'UserAgent' => isset( $_SERVER[
'HTTP_USER_AGENT'] ) ? $_SERVER[
'HTTP_USER_AGENT'] :
'',
111 'ChronologyProtection' =>
'true'
114 $this->cliMode = isset(
$params[
'cliMode'] ) ?
$params[
'cliMode'] : PHP_SAPI ===
'cli';
115 $this->hostname = isset( $conf[
'hostname'] ) ? $conf[
'hostname'] : gethostname();
118 $this->ticket = mt_rand();
122 $this->
shutdown( self::SHUTDOWN_NO_CHRONPROT );
127 $mode = self::SHUTDOWN_CHRONPROT_SYNC, callable $workCallback = null
130 if ( $mode === self::SHUTDOWN_CHRONPROT_SYNC ) {
132 } elseif ( $mode === self::SHUTDOWN_CHRONPROT_ASYNC ) {
144 abstract public function newMainLB( $domain =
false );
151 abstract public function getMainLB( $domain =
false );
176 call_user_func_array( [ $loadBalancer, $methodName ], $args );
178 [ $methodName,
$args ]
192 if ( $this->trxRoundId !==
false ) {
195 "$fname: transaction round '{$this->trxRoundId}' already started."
198 $this->trxRoundId =
$fname;
204 if ( $this->trxRoundId !==
false && $this->trxRoundId !==
$fname ) {
207 "$fname: transaction round '{$this->trxRoundId}' still running."
214 $this->trxRoundId =
false;
237 $this->trxRoundId =
false;
255 $callersByDB[$masterName] = $callers;
259 if ( count( $callersByDB ) >= 2 ) {
260 $dbs = implode(
', ', array_keys( $callersByDB ) );
261 $msg =
"Multi-DB transaction [{$dbs}]:\n";
262 foreach ( $callersByDB
as $db => $callers ) {
263 $msg .=
"$db: " . implode(
'; ', $callers ) .
"\n";
265 $this->queryLogger->info( $msg );
300 'ifWritesSince' => null
303 if ( $opts[
'domain'] ===
false && isset( $opts[
'wiki'] ) ) {
304 $opts[
'domain'] = $opts[
'wiki'];
310 if ( $opts[
'cluster'] !==
false ) {
312 } elseif ( $opts[
'domain'] !==
false ) {
313 $lbs[] = $this->
getMainLB( $opts[
'domain'] );
326 $masterPositions = array_fill( 0, count( $lbs ),
false );
327 foreach ( $lbs
as $i => $lb ) {
328 if ( $lb->getServerCount() <= 1 ) {
332 } elseif ( $opts[
'ifWritesSince']
333 && $lb->lastMasterChangeTimestamp() < $opts[
'ifWritesSince']
337 $masterPositions[$i] = $lb->getMasterPos();
342 foreach ( $this->replicationWaitCallbacks
as $callback ) {
347 foreach ( $lbs
as $i => $lb ) {
348 if ( $masterPositions[$i] ) {
350 if ( !$lb->waitForAll( $masterPositions[$i], $opts[
'timeout'] ) ) {
351 $failed[] = $lb->getServerName( $lb->getWriterIndex() );
358 "Could not wait for replica DBs to catch up to " .
359 implode(
', ', $failed )
366 $this->replicationWaitCallbacks[
$name] = $callback;
368 unset( $this->replicationWaitCallbacks[
$name] );
374 $this->queryLogger->error( __METHOD__ .
": $fname does not have outer scope.\n" .
384 if (
$ticket !== $this->ticket ) {
385 $this->perfLogger->error( __METHOD__ .
": $fname does not have outer scope.\n" .
393 if ( $this->trxRoundId !==
false &&
$fname !== $this->trxRoundId ) {
394 $this->queryLogger->info(
"$fname: committing on behalf of {$this->trxRoundId}." );
404 if ( $fnameEffective !==
$fname ) {
421 if ( $this->chronProt ) {
428 'ip' => $this->requestInfo[
'IPAddress'],
429 'agent' => $this->requestInfo[
'UserAgent'],
431 isset( $_GET[
'cpPosTime'] ) ? $_GET[
'cpPosTime'] : null
433 $this->chronProt->setLogger( $this->replLogger );
435 if ( $this->cliMode ) {
436 $this->chronProt->setEnabled(
false );
437 } elseif ( $this->requestInfo[
'ChronologyProtection'] ===
'false' ) {
440 $this->chronProt->setWaitEnabled(
false );
443 $this->replLogger->debug( __METHOD__ .
': using request info ' .
444 json_encode( $this->requestInfo, JSON_PRETTY_PRINT ) );
465 $unsavedPositions = $cp->
shutdown( $workCallback, $mode );
466 if ( $unsavedPositions && $workCallback ) {
476 if ( isset( $unsavedPositions[$masterName] ) ) {
477 $lb->
waitForAll( $unsavedPositions[$masterName] );
508 if ( $this->trxRoundId !==
false ) {
515 $this->localDomain->getDatabase(),
539 if ( !$usedCluster ) {
543 return strpos( $url,
'?' ) ===
false ?
"$url?cpPosTime=$time" :
"$url&cpPosTime=$time";
557 if ( PHP_SAPI !=
'cli' ) {
558 $old = ignore_user_abort(
true );
559 return new ScopedCallback(
function ()
use ( $old ) {
560 ignore_user_abort( $old );
beginMasterChanges($fname=__METHOD__)
Flush any master transaction snapshots and set DBO_TRX (if DBO_DEFAULT is set)
runMasterPostTrxCallbacks($type)
Issue all pending post-COMMIT/ROLLBACK callbacks.
the array() calling protocol came about after MediaWiki 1.4rc1.
LoggerInterface $perfLogger
LoggerInterface $queryLogger
baseLoadBalancerParams()
Base parameters to LoadBalancer::__construct()
beginMasterChanges($fname=__METHOD__)
Flush any master transaction snapshots and set DBO_TRX (if DBO_DEFAULT is set)
bool $cliMode
Whether this PHP instance is for a CLI script.
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses & $ret
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
div flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException'returning false will NOT prevent logging $e
__construct(array $conf)
Construct a manager of ILoadBalancer objects.
An interface for generating database load balancers.
callable[] $replicationWaitCallbacks
commitAll($fname=__METHOD__, array $options=[])
Commit open transactions on all connections.
shutdownLB(ILoadBalancer $lb)
Notify the ChronologyProtector that the ILoadBalancer is about to shut down.
forEachLB($callback, array $params=[])
Execute a function for each tracked load balancer The callback is called with the load balancer as th...
getChronologyProtectorTouched($dbName)
object string $profiler
Class name or object With profileIn/profileOut methods.
laggedReplicaUsed()
Detemine if any lagged replica DB connection was used.
shutdownChronologyProtector(ChronologyProtector $cp, $workCallback, $mode)
Get and record all of the staged DB positions into persistent memory storage.
commitMasterChanges($fname=__METHOD__, array $options=[])
Commit changes on all master connections.
Class to handle database/prefix specification for IDatabase domains.
shutdown(callable $workCallback=null, $mode= 'sync')
Notify the ChronologyProtector that the LBFactory is done calling shutdownLB() for now...
shutdown($mode=self::SHUTDOWN_CHRONPROT_SYNC, callable $workCallback=null)
Prepare all tracked load balancers for shutdown.
static newEmpty()
Get an instance that wraps EmptyBagOStuff.
initLoadBalancer(ILoadBalancer $lb)
array $requestInfo
Web request information about the client.
waitForAll($pos, $timeout=null)
Set the master wait position and wait for ALL replica DBs to catch up to it.
rollbackMasterChanges($fname=__METHOD__)
Rollback changes on all master connections.
DatabaseDomain $localDomain
Local domain.
Exception class for replica DB wait timeouts.
callable $errorLogger
Error logger.
hasMasterChanges()
Determine if there are pending changes in a transaction by this thread.
appendPreShutdownTimeAsQuery($url, $time)
Append ?cpPosTime parameter to a URL for ChronologyProtector purposes if needed.
waitForReplication(array $opts=[])
Waits for the replica DBs to catch up to the current master position.
string $agent
Agent name for query profiling.
Database cluster connection, tracking, load balancing, and transaction manager interface.
Helper class that detects high-contention DB queries via profiling calls.
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set and then return false from the hook function Ensure you consume the ChangeTagAfterDelete hook to carry out custom deletion actions as context called by AbstractContent::getParserOutput May be used to override the normal model specific rendering of page content as context as context $options
hasMasterChanges()
Determine if any master connection has pending changes.
string bool $trxRoundId
String if a requested DBO_TRX transaction round is active.
string bool $readOnlyReason
Reason all LBs are read-only or false if not.
pendingMasterChangeCallers()
Get the list of callers that have pending master changes.
closeAll()
Close all open database connections on all open load balancers.
A BagOStuff object with no objects in it.
disableChronologyProtection()
Disable the ChronologyProtector for all load balancers.
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
setDomainPrefix($prefix)
Set a new table prefix for the existing local domain ID for testing.
getServerCount()
Get the number of defined servers (not the number of open connections)
LoggerInterface $replLogger
forEachLBCallMethod($methodName, array $args=[])
Call a method of each tracked load balancer.
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
commitAndWaitForReplication($fname, $ticket, array $opts=[])
Convenience method for safely running commitMasterChanges()/waitForReplication()
Class for ensuring a consistent ordering of events as seen by the user, despite replication.
if(!defined( 'MEDIAWIKI')) $fname
This file is not a valid entry point, perform no further processing unless MEDIAWIKI is defined...
hasOrMadeRecentMasterChanges($age=null)
Check if this load balancer object had any recent or still pending writes issued against it by this P...
hasOrMadeRecentMasterChanges($age=null)
Determine if any master connection has pending/written changes from this request. ...
static newFromId($domain)
setWaitForReplicationListener($name, callable $callback=null)
Add a callback to be run in every call to waitForReplication() before waiting.
destroy()
Disables all load balancers.
setDomainPrefix($prefix)
Set a new table prefix for the existing local domain ID for testing.
getScopedPHPBehaviorForCommit()
Make PHP ignore user aborts/disconnects until the returned value leaves scope.
string $hostname
Local hostname of the app server.
LoggerInterface $connLogger
TransactionProfiler $trxProfiler
getServerName($i)
Get the host name or IP address of the server with the specified index Prefer a readable name if avai...
setRequestInfo(array $info)
flushReplicaSnapshots($fname=__METHOD__)
Commit all replica DB transactions so as to flush any REPEATABLE-READ or SSI snapshot.
logIfMultiDbTransaction()
Log query info if multi DB transactions are going to be committed now.
see documentation in includes Linker php for Linker::makeImageLink & $time
getEmptyTransactionTicket($fname)
Get a token asserting that no transaction writes are active.
ChronologyProtector $chronProt
Allows to change the fields on the form that will be generated $name