MediaWiki  1.31.16
LBFactory.php
Go to the documentation of this file.
1 <?php
24 namespace Wikimedia\Rdbms;
25 
26 use Psr\Log\LoggerInterface;
27 use Wikimedia\ScopedCallback;
31 use Exception;
32 use RuntimeException;
33 use LogicException;
34 
39 abstract class LBFactory implements ILBFactory {
41  protected $chronProt;
43  protected $profiler;
45  protected $trxProfiler;
47  protected $replLogger;
49  protected $connLogger;
51  protected $queryLogger;
53  protected $perfLogger;
55  protected $errorLogger;
57  protected $deprecationLogger;
59  protected $srvCache;
61  protected $memStash;
63  protected $wanCache;
64 
66  protected $localDomain;
68  protected $hostname;
70  protected $requestInfo;
71 
73  protected $ticket;
75  protected $trxRoundId = false;
77  protected $readOnlyReason = false;
79  protected $replicationWaitCallbacks = [];
80 
82  protected $tableAliases = [];
84  protected $indexAliases = [];
85 
87  protected $cliMode;
89  protected $agent;
90 
91  private static $loggerFields =
92  [ 'replLogger', 'connLogger', 'queryLogger', 'perfLogger' ];
93 
94  public function __construct( array $conf ) {
95  $this->localDomain = isset( $conf['localDomain'] )
96  ? DatabaseDomain::newFromId( $conf['localDomain'] )
98 
99  if ( isset( $conf['readOnlyReason'] ) && is_string( $conf['readOnlyReason'] ) ) {
100  $this->readOnlyReason = $conf['readOnlyReason'];
101  }
102 
103  $this->srvCache = isset( $conf['srvCache'] ) ? $conf['srvCache'] : new EmptyBagOStuff();
104  $this->memStash = isset( $conf['memStash'] ) ? $conf['memStash'] : new EmptyBagOStuff();
105  $this->wanCache = isset( $conf['wanCache'] )
106  ? $conf['wanCache']
108 
109  foreach ( self::$loggerFields as $key ) {
110  $this->$key = isset( $conf[$key] ) ? $conf[$key] : new \Psr\Log\NullLogger();
111  }
112  $this->errorLogger = isset( $conf['errorLogger'] )
113  ? $conf['errorLogger']
114  : function ( Exception $e ) {
115  trigger_error( get_class( $e ) . ': ' . $e->getMessage(), E_USER_WARNING );
116  };
117  $this->deprecationLogger = isset( $conf['deprecationLogger'] )
118  ? $conf['deprecationLogger']
119  : function ( $msg ) {
120  trigger_error( $msg, E_USER_DEPRECATED );
121  };
122 
123  $this->profiler = isset( $conf['profiler'] ) ? $conf['profiler'] : null;
124  $this->trxProfiler = isset( $conf['trxProfiler'] )
125  ? $conf['trxProfiler']
126  : new TransactionProfiler();
127 
128  $this->requestInfo = [
129  'IPAddress' => isset( $_SERVER[ 'REMOTE_ADDR' ] ) ? $_SERVER[ 'REMOTE_ADDR' ] : '',
130  'UserAgent' => isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : '',
131  'ChronologyProtection' => 'true',
132  'ChronologyPositionIndex' => isset( $_GET['cpPosIndex'] ) ? $_GET['cpPosIndex'] : null
133  ];
134 
135  $this->cliMode = isset( $conf['cliMode'] )
136  ? $conf['cliMode']
137  : ( PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg' );
138  $this->hostname = isset( $conf['hostname'] ) ? $conf['hostname'] : gethostname();
139  $this->agent = isset( $conf['agent'] ) ? $conf['agent'] : '';
140 
141  $this->ticket = mt_rand();
142  }
143 
144  public function destroy() {
145  $this->shutdown( self::SHUTDOWN_NO_CHRONPROT );
146  $this->forEachLBCallMethod( 'disable' );
147  }
148 
149  public function shutdown(
150  $mode = self::SHUTDOWN_CHRONPROT_SYNC, callable $workCallback = null, &$cpIndex = null
151  ) {
153  if ( $mode === self::SHUTDOWN_CHRONPROT_SYNC ) {
154  $this->shutdownChronologyProtector( $chronProt, $workCallback, 'sync', $cpIndex );
155  } elseif ( $mode === self::SHUTDOWN_CHRONPROT_ASYNC ) {
156  $this->shutdownChronologyProtector( $chronProt, null, 'async', $cpIndex );
157  }
158 
159  $this->commitMasterChanges( __METHOD__ ); // sanity
160  }
161 
167  abstract public function newMainLB( $domain = false );
168 
174  abstract public function getMainLB( $domain = false );
175 
181  abstract public function newExternalLB( $cluster );
182 
188  abstract public function getExternalLB( $cluster );
189 
196  protected function forEachLBCallMethod( $methodName, array $args = [] ) {
197  $this->forEachLB(
198  function ( ILoadBalancer $loadBalancer, $methodName, array $args ) {
199  call_user_func_array( [ $loadBalancer, $methodName ], $args );
200  },
201  [ $methodName, $args ]
202  );
203  }
204 
205  public function flushReplicaSnapshots( $fname = __METHOD__ ) {
206  $this->forEachLBCallMethod( 'flushReplicaSnapshots', [ $fname ] );
207  }
208 
209  public function commitAll( $fname = __METHOD__, array $options = [] ) {
211  $this->forEachLBCallMethod( 'commitAll', [ $fname ] );
212  }
213 
214  public function beginMasterChanges( $fname = __METHOD__ ) {
215  if ( $this->trxRoundId !== false ) {
216  throw new DBTransactionError(
217  null,
218  "$fname: transaction round '{$this->trxRoundId}' already started."
219  );
220  }
221  $this->trxRoundId = $fname;
222  // Set DBO_TRX flags on all appropriate DBs
223  $this->forEachLBCallMethod( 'beginMasterChanges', [ $fname ] );
224  }
225 
226  public function commitMasterChanges( $fname = __METHOD__, array $options = [] ) {
227  if ( $this->trxRoundId !== false && $this->trxRoundId !== $fname ) {
228  throw new DBTransactionError(
229  null,
230  "$fname: transaction round '{$this->trxRoundId}' still running."
231  );
232  }
234  $scope = $this->getScopedPHPBehaviorForCommit(); // try to ignore client aborts
235  // Run pre-commit callbacks and suppress post-commit callbacks, aborting on failure
236  $this->forEachLBCallMethod( 'finalizeMasterChanges' );
237  $this->trxRoundId = false;
238  // Perform pre-commit checks, aborting on failure
239  $this->forEachLBCallMethod( 'approveMasterChanges', [ $options ] );
240  // Log the DBs and methods involved in multi-DB transactions
241  $this->logIfMultiDbTransaction();
242  // Actually perform the commit on all master DB connections and revert DBO_TRX
243  $this->forEachLBCallMethod( 'commitMasterChanges', [ $fname ] );
244  // Run all post-commit callbacks
246  $e = null; // first callback exception
247  $this->forEachLB( function ( ILoadBalancer $lb ) use ( &$e ) {
248  $ex = $lb->runMasterPostTrxCallbacks( IDatabase::TRIGGER_COMMIT );
249  $e = $e ?: $ex;
250  } );
251  // Commit any dangling DBO_TRX transactions from callbacks on one DB to another DB
252  $this->forEachLBCallMethod( 'commitMasterChanges', [ $fname ] );
253  // Throw any last post-commit callback error
254  if ( $e instanceof Exception ) {
255  throw $e;
256  }
257  }
258 
259  public function rollbackMasterChanges( $fname = __METHOD__ ) {
260  $this->trxRoundId = false;
261  $this->forEachLBCallMethod( 'suppressTransactionEndCallbacks' );
262  $this->forEachLBCallMethod( 'rollbackMasterChanges', [ $fname ] );
263  // Run all post-rollback callbacks
264  $this->forEachLB( function ( ILoadBalancer $lb ) {
265  $lb->runMasterPostTrxCallbacks( IDatabase::TRIGGER_ROLLBACK );
266  } );
267  }
268 
269  public function hasTransactionRound() {
270  return ( $this->trxRoundId !== false );
271  }
272 
276  private function logIfMultiDbTransaction() {
277  $callersByDB = [];
278  $this->forEachLB( function ( ILoadBalancer $lb ) use ( &$callersByDB ) {
279  $masterName = $lb->getServerName( $lb->getWriterIndex() );
280  $callers = $lb->pendingMasterChangeCallers();
281  if ( $callers ) {
282  $callersByDB[$masterName] = $callers;
283  }
284  } );
285 
286  if ( count( $callersByDB ) >= 2 ) {
287  $dbs = implode( ', ', array_keys( $callersByDB ) );
288  $msg = "Multi-DB transaction [{$dbs}]:\n";
289  foreach ( $callersByDB as $db => $callers ) {
290  $msg .= "$db: " . implode( '; ', $callers ) . "\n";
291  }
292  $this->queryLogger->info( $msg );
293  }
294  }
295 
296  public function hasMasterChanges() {
297  $ret = false;
298  $this->forEachLB( function ( ILoadBalancer $lb ) use ( &$ret ) {
299  $ret = $ret || $lb->hasMasterChanges();
300  } );
301 
302  return $ret;
303  }
304 
305  public function laggedReplicaUsed() {
306  $ret = false;
307  $this->forEachLB( function ( ILoadBalancer $lb ) use ( &$ret ) {
308  $ret = $ret || $lb->laggedReplicaUsed();
309  } );
310 
311  return $ret;
312  }
313 
314  public function hasOrMadeRecentMasterChanges( $age = null ) {
315  $ret = false;
316  $this->forEachLB( function ( ILoadBalancer $lb ) use ( $age, &$ret ) {
317  $ret = $ret || $lb->hasOrMadeRecentMasterChanges( $age );
318  } );
319  return $ret;
320  }
321 
322  public function waitForReplication( array $opts = [] ) {
323  $opts += [
324  'domain' => false,
325  'cluster' => false,
326  'timeout' => $this->cliMode ? 60 : 10,
327  'ifWritesSince' => null
328  ];
329 
330  if ( $opts['domain'] === false && isset( $opts['wiki'] ) ) {
331  $opts['domain'] = $opts['wiki']; // b/c
332  }
333 
334  // Figure out which clusters need to be checked
336  $lbs = [];
337  if ( $opts['cluster'] !== false ) {
338  $lbs[] = $this->getExternalLB( $opts['cluster'] );
339  } elseif ( $opts['domain'] !== false ) {
340  $lbs[] = $this->getMainLB( $opts['domain'] );
341  } else {
342  $this->forEachLB( function ( ILoadBalancer $lb ) use ( &$lbs ) {
343  $lbs[] = $lb;
344  } );
345  if ( !$lbs ) {
346  return; // nothing actually used
347  }
348  }
349 
350  // Get all the master positions of applicable DBs right now.
351  // This can be faster since waiting on one cluster reduces the
352  // time needed to wait on the next clusters.
353  $masterPositions = array_fill( 0, count( $lbs ), false );
354  foreach ( $lbs as $i => $lb ) {
355  if ( $lb->getServerCount() <= 1 ) {
356  // T29975 - Don't try to wait for replica DBs if there are none
357  // Prevents permission error when getting master position
358  continue;
359  } elseif ( $opts['ifWritesSince']
360  && $lb->lastMasterChangeTimestamp() < $opts['ifWritesSince']
361  ) {
362  continue; // no writes since the last wait
363  }
364  $masterPositions[$i] = $lb->getMasterPos();
365  }
366 
367  // Run any listener callbacks *after* getting the DB positions. The more
368  // time spent in the callbacks, the less time is spent in waitForAll().
369  foreach ( $this->replicationWaitCallbacks as $callback ) {
370  $callback();
371  }
372 
373  $failed = [];
374  foreach ( $lbs as $i => $lb ) {
375  if ( $masterPositions[$i] ) {
376  // The RDBMS may not support getMasterPos()
377  if ( !$lb->waitForAll( $masterPositions[$i], $opts['timeout'] ) ) {
378  $failed[] = $lb->getServerName( $lb->getWriterIndex() );
379  }
380  }
381  }
382 
383  if ( $failed ) {
384  throw new DBReplicationWaitError(
385  null,
386  "Could not wait for replica DBs to catch up to " .
387  implode( ', ', $failed )
388  );
389  }
390  }
391 
392  public function setWaitForReplicationListener( $name, callable $callback = null ) {
393  if ( $callback ) {
394  $this->replicationWaitCallbacks[$name] = $callback;
395  } else {
396  unset( $this->replicationWaitCallbacks[$name] );
397  }
398  }
399 
400  public function getEmptyTransactionTicket( $fname ) {
401  if ( $this->hasMasterChanges() ) {
402  $this->queryLogger->error( __METHOD__ . ": $fname does not have outer scope.\n" .
403  ( new RuntimeException() )->getTraceAsString() );
404 
405  return null;
406  }
407 
408  return $this->ticket;
409  }
410 
411  public function commitAndWaitForReplication( $fname, $ticket, array $opts = [] ) {
412  if ( $ticket !== $this->ticket ) {
413  $this->perfLogger->error( __METHOD__ . ": $fname does not have outer scope.\n" .
414  ( new RuntimeException() )->getTraceAsString() );
415 
416  return;
417  }
418 
419  // The transaction owner and any caller with the empty transaction ticket can commit
420  // so that getEmptyTransactionTicket() callers don't risk seeing DBTransactionError.
421  if ( $this->trxRoundId !== false && $fname !== $this->trxRoundId ) {
422  $this->queryLogger->info( "$fname: committing on behalf of {$this->trxRoundId}." );
423  $fnameEffective = $this->trxRoundId;
424  } else {
425  $fnameEffective = $fname;
426  }
427 
428  $this->commitMasterChanges( $fnameEffective );
429  $this->waitForReplication( $opts );
430  // If a nested caller committed on behalf of $fname, start another empty $fname
431  // transaction, leaving the caller with the same empty transaction state as before.
432  if ( $fnameEffective !== $fname ) {
433  $this->beginMasterChanges( $fnameEffective );
434  }
435  }
436 
437  public function getChronologyProtectorTouched( $dbName ) {
438  return $this->getChronologyProtector()->getTouched( $dbName );
439  }
440 
441  public function disableChronologyProtection() {
442  $this->getChronologyProtector()->setEnabled( false );
443  }
444 
448  protected function getChronologyProtector() {
449  if ( $this->chronProt ) {
450  return $this->chronProt;
451  }
452 
453  $this->chronProt = new ChronologyProtector(
454  $this->memStash,
455  [
456  'ip' => $this->requestInfo['IPAddress'],
457  'agent' => $this->requestInfo['UserAgent'],
458  ],
459  $this->requestInfo['ChronologyPositionIndex']
460  );
461  $this->chronProt->setLogger( $this->replLogger );
462 
463  if ( $this->cliMode ) {
464  $this->chronProt->setEnabled( false );
465  } elseif ( $this->requestInfo['ChronologyProtection'] === 'false' ) {
466  // Request opted out of using position wait logic. This is useful for requests
467  // done by the job queue or background ETL that do not have a meaningful session.
468  $this->chronProt->setWaitEnabled( false );
469  } elseif ( $this->memStash instanceof EmptyBagOStuff ) {
470  // No where to store any DB positions and wait for them to appear
471  $this->chronProt->setEnabled( false );
472  $this->replLogger->info( 'Cannot use ChronologyProtector with EmptyBagOStuff.' );
473  }
474 
475  $this->replLogger->debug( __METHOD__ . ': using request info ' .
476  json_encode( $this->requestInfo, JSON_PRETTY_PRINT ) );
477 
478  return $this->chronProt;
479  }
480 
489  protected function shutdownChronologyProtector(
490  ChronologyProtector $cp, $workCallback, $mode, &$cpIndex = null
491  ) {
492  // Record all the master positions needed
493  $this->forEachLB( function ( ILoadBalancer $lb ) use ( $cp ) {
494  $cp->shutdownLB( $lb );
495  } );
496  // Write them to the persistent stash. Try to do something useful by running $work
497  // while ChronologyProtector waits for the stash write to replicate to all DCs.
498  $unsavedPositions = $cp->shutdown( $workCallback, $mode, $cpIndex );
499  if ( $unsavedPositions && $workCallback ) {
500  // Invoke callback in case it did not cache the result yet
501  $workCallback(); // work now to block for less time in waitForAll()
502  }
503  // If the positions failed to write to the stash, at least wait on local datacenter
504  // replica DBs to catch up before responding. Even if there are several DCs, this increases
505  // the chance that the user will see their own changes immediately afterwards. As long
506  // as the sticky DC cookie applies (same domain), this is not even an issue.
507  $this->forEachLB( function ( ILoadBalancer $lb ) use ( $unsavedPositions ) {
508  $masterName = $lb->getServerName( $lb->getWriterIndex() );
509  if ( isset( $unsavedPositions[$masterName] ) ) {
510  $lb->waitForAll( $unsavedPositions[$masterName] );
511  }
512  } );
513  }
514 
519  final protected function baseLoadBalancerParams() {
520  return [
521  'localDomain' => $this->localDomain,
522  'readOnlyReason' => $this->readOnlyReason,
523  'srvCache' => $this->srvCache,
524  'wanCache' => $this->wanCache,
525  'profiler' => $this->profiler,
526  'trxProfiler' => $this->trxProfiler,
527  'queryLogger' => $this->queryLogger,
528  'connLogger' => $this->connLogger,
529  'replLogger' => $this->replLogger,
530  'errorLogger' => $this->errorLogger,
531  'deprecationLogger' => $this->deprecationLogger,
532  'hostname' => $this->hostname,
533  'cliMode' => $this->cliMode,
534  'agent' => $this->agent,
535  'chronologyCallback' => function ( ILoadBalancer $lb ) {
536  // Defer ChronologyProtector construction in case setRequestInfo() ends up
537  // being called later (but before the first connection attempt) (T192611)
538  $this->getChronologyProtector()->initLB( $lb );
539  }
540  ];
541  }
542 
546  protected function initLoadBalancer( ILoadBalancer $lb ) {
547  if ( $this->trxRoundId !== false ) {
548  $lb->beginMasterChanges( $this->trxRoundId ); // set DBO_TRX
549  }
550 
551  $lb->setTableAliases( $this->tableAliases );
552  $lb->setIndexAliases( $this->indexAliases );
553  }
554 
555  public function setTableAliases( array $aliases ) {
556  $this->tableAliases = $aliases;
557  }
558 
559  public function setIndexAliases( array $aliases ) {
560  $this->indexAliases = $aliases;
561  }
562 
563  public function setDomainPrefix( $prefix ) {
564  $this->localDomain = new DatabaseDomain(
565  $this->localDomain->getDatabase(),
566  null,
567  $prefix
568  );
569 
570  $this->forEachLB( function ( ILoadBalancer $lb ) use ( $prefix ) {
571  $lb->setDomainPrefix( $prefix );
572  } );
573  }
574 
575  public function closeAll() {
576  $this->forEachLBCallMethod( 'closeAll', [] );
577  }
578 
579  public function setAgentName( $agent ) {
580  $this->agent = $agent;
581  }
582 
583  public function appendShutdownCPIndexAsQuery( $url, $index ) {
584  $usedCluster = 0;
585  $this->forEachLB( function ( ILoadBalancer $lb ) use ( &$usedCluster ) {
586  $usedCluster |= ( $lb->getServerCount() > 1 );
587  } );
588 
589  if ( !$usedCluster ) {
590  return $url; // no master/replica clusters touched
591  }
592 
593  return strpos( $url, '?' ) === false ? "$url?cpPosIndex=$index" : "$url&cpPosIndex=$index";
594  }
595 
596  public function setRequestInfo( array $info ) {
597  if ( $this->chronProt ) {
598  throw new LogicException( 'ChronologyProtector already initialized.' );
599  }
600 
601  $this->requestInfo = $info + $this->requestInfo;
602  }
603 
610  final protected function getScopedPHPBehaviorForCommit() {
611  if ( PHP_SAPI != 'cli' ) { // https://bugs.php.net/bug.php?id=47540
612  $old = ignore_user_abort( true ); // avoid half-finished operations
613  return new ScopedCallback( function () use ( $old ) {
614  ignore_user_abort( $old );
615  } );
616  }
617 
618  return null;
619  }
620 
621  function __destruct() {
622  $this->destroy();
623  }
624 }
625 
626 class_alias( LBFactory::class, 'LBFactory' );
Wikimedia\Rdbms\ILoadBalancer\pendingMasterChangeCallers
pendingMasterChangeCallers()
Get the list of callers that have pending master changes.
Wikimedia\Rdbms\ILoadBalancer\setDomainPrefix
setDomainPrefix( $prefix)
Set a new table prefix for the existing local domain ID for testing.
if
if($IP===false)
Definition: cleanupArchiveUserText.php:4
Wikimedia\Rdbms\LBFactory\appendShutdownCPIndexAsQuery
appendShutdownCPIndexAsQuery( $url, $index)
Append ?cpPosIndex parameter to a URL for ChronologyProtector purposes if needed.
Definition: LBFactory.php:583
Wikimedia\Rdbms\LBFactory\$replLogger
LoggerInterface $replLogger
Definition: LBFactory.php:47
Wikimedia\Rdbms\DatabaseDomain\newFromId
static newFromId( $domain)
Definition: DatabaseDomain.php:63
Wikimedia\Rdbms\LBFactory\$errorLogger
callable $errorLogger
Error logger.
Definition: LBFactory.php:55
Wikimedia\Rdbms\ILoadBalancer\waitForAll
waitForAll( $pos, $timeout=null)
Set the master wait position and wait for ALL replica DBs to catch up to it.
Wikimedia\Rdbms\ILoadBalancer\runMasterPostTrxCallbacks
runMasterPostTrxCallbacks( $type)
Issue all pending post-COMMIT/ROLLBACK callbacks.
EmptyBagOStuff
A BagOStuff object with no objects in it.
Definition: EmptyBagOStuff.php:29
Wikimedia\Rdbms\ILoadBalancer\setIndexAliases
setIndexAliases(array $aliases)
Convert certain index names to alternative names before querying the DB.
Wikimedia\Rdbms\LBFactory\$cliMode
bool $cliMode
Whether this PHP instance is for a CLI script.
Definition: LBFactory.php:87
Wikimedia\Rdbms\LBFactory\$wanCache
WANObjectCache $wanCache
Definition: LBFactory.php:63
captcha-old.count
count
Definition: captcha-old.py:249
Wikimedia\Rdbms\LBFactory\__destruct
__destruct()
Definition: LBFactory.php:621
Wikimedia\Rdbms\ChronologyProtector\shutdown
shutdown(callable $workCallback=null, $mode='sync', &$cpIndex=null)
Notify the ChronologyProtector that the LBFactory is done calling shutdownLB() for now.
Definition: ChronologyProtector.php:169
Wikimedia\Rdbms\LBFactory\$hostname
string $hostname
Local hostname of the app server.
Definition: LBFactory.php:68
Wikimedia\Rdbms\LBFactory\$connLogger
LoggerInterface $connLogger
Definition: LBFactory.php:49
Wikimedia\Rdbms\LBFactory\commitAndWaitForReplication
commitAndWaitForReplication( $fname, $ticket, array $opts=[])
Convenience method for safely running commitMasterChanges()/waitForReplication()
Definition: LBFactory.php:411
Wikimedia\Rdbms\DBReplicationWaitError
Exception class for replica DB wait timeouts.
Definition: DBReplicationWaitError.php:28
Wikimedia\Rdbms\LBFactory\initLoadBalancer
initLoadBalancer(ILoadBalancer $lb)
Definition: LBFactory.php:546
use
as see the revision history and available at free of to any person obtaining a copy of this software and associated documentation to deal in the Software without including without limitation the rights to use
Definition: MIT-LICENSE.txt:11
Wikimedia\Rdbms\LBFactory\getChronologyProtector
getChronologyProtector()
Definition: LBFactory.php:448
Wikimedia\Rdbms
Definition: ChronologyProtector.php:24
Wikimedia\Rdbms\LBFactory\forEachLBCallMethod
forEachLBCallMethod( $methodName, array $args=[])
Call a method of each tracked load balancer.
Definition: LBFactory.php:196
Wikimedia\Rdbms\ILBFactory\forEachLB
forEachLB( $callback, array $params=[])
Execute a function for each tracked load balancer The callback is called with the load balancer as th...
BagOStuff
interface is intended to be more or less compatible with the PHP memcached client.
Definition: BagOStuff.php:47
Wikimedia\Rdbms\ILoadBalancer\getServerCount
getServerCount()
Get the number of defined servers (not the number of open connections)
Wikimedia\Rdbms\LBFactory\flushReplicaSnapshots
flushReplicaSnapshots( $fname=__METHOD__)
Commit all replica DB transactions so as to flush any REPEATABLE-READ or SSI snapshot.
Definition: LBFactory.php:205
Wikimedia\Rdbms\LBFactory\$loggerFields
static $loggerFields
Definition: LBFactory.php:91
$name
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:302
Wikimedia\Rdbms\LBFactory\__construct
__construct(array $conf)
Construct a manager of ILoadBalancer objects.
Definition: LBFactory.php:94
Wikimedia\Rdbms\LBFactory\waitForReplication
waitForReplication(array $opts=[])
Waits for the replica DBs to catch up to the current master position.
Definition: LBFactory.php:322
Wikimedia\Rdbms\LBFactory\getChronologyProtectorTouched
getChronologyProtectorTouched( $dbName)
Definition: LBFactory.php:437
Wikimedia\Rdbms\LBFactory\$memStash
BagOStuff $memStash
Definition: LBFactory.php:61
Wikimedia\Rdbms\LBFactory\baseLoadBalancerParams
baseLoadBalancerParams()
Base parameters to LoadBalancer::__construct()
Definition: LBFactory.php:519
php
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
Definition: injection.txt:37
Wikimedia\Rdbms\LBFactory\setTableAliases
setTableAliases(array $aliases)
Make certain table names use their own database, schema, and table prefix when passed into SQL querie...
Definition: LBFactory.php:555
Wikimedia\Rdbms\ILoadBalancer\setTableAliases
setTableAliases(array $aliases)
Make certain table names use their own database, schema, and table prefix when passed into SQL querie...
Wikimedia\Rdbms\LBFactory\commitMasterChanges
commitMasterChanges( $fname=__METHOD__, array $options=[])
Commit changes on all master connections.
Definition: LBFactory.php:226
Wikimedia\Rdbms\LBFactory\closeAll
closeAll()
Close all open database connections on all open load balancers.
Definition: LBFactory.php:575
Wikimedia\Rdbms\DatabaseDomain\newUnspecified
static newUnspecified()
Definition: DatabaseDomain.php:97
WANObjectCache\newEmpty
static newEmpty()
Get an instance that wraps EmptyBagOStuff.
Definition: WANObjectCache.php:256
Wikimedia\Rdbms\LBFactory\$deprecationLogger
callable $deprecationLogger
Deprecation logger.
Definition: LBFactory.php:57
Wikimedia\Rdbms\LBFactory\shutdown
shutdown( $mode=self::SHUTDOWN_CHRONPROT_SYNC, callable $workCallback=null, &$cpIndex=null)
Prepare all tracked load balancers for shutdown.
Definition: LBFactory.php:149
Wikimedia\Rdbms\LBFactory\$srvCache
BagOStuff $srvCache
Definition: LBFactory.php:59
Wikimedia\Rdbms\ILoadBalancer\getServerName
getServerName( $i)
Get the host name or IP address of the server with the specified index.
Wikimedia\Rdbms\LBFactory\$queryLogger
LoggerInterface $queryLogger
Definition: LBFactory.php:51
Wikimedia\Rdbms\LBFactory\getExternalLB
getExternalLB( $cluster)
Wikimedia\Rdbms\LBFactory\$readOnlyReason
string bool $readOnlyReason
Reason all LBs are read-only or false if not.
Definition: LBFactory.php:77
Wikimedia\Rdbms\LBFactory\getMainLB
getMainLB( $domain=false)
Wikimedia\Rdbms\ILoadBalancer\getWriterIndex
getWriterIndex()
Wikimedia\Rdbms\LBFactory\shutdownChronologyProtector
shutdownChronologyProtector(ChronologyProtector $cp, $workCallback, $mode, &$cpIndex=null)
Get and record all of the staged DB positions into persistent memory storage.
Definition: LBFactory.php:489
Wikimedia\Rdbms\LBFactory\$requestInfo
array $requestInfo
Web request information about the client.
Definition: LBFactory.php:70
Wikimedia\Rdbms\LBFactory\hasMasterChanges
hasMasterChanges()
Determine if any master connection has pending changes.
Definition: LBFactory.php:296
Wikimedia\Rdbms\LBFactory\$indexAliases
string[] $indexAliases
Map of (index alias => index)
Definition: LBFactory.php:84
Wikimedia\Rdbms\LBFactory\$localDomain
DatabaseDomain $localDomain
Local domain.
Definition: LBFactory.php:66
Wikimedia\Rdbms\LBFactory\laggedReplicaUsed
laggedReplicaUsed()
Detemine if any lagged replica DB connection was used.
Definition: LBFactory.php:305
$fname
if(defined( 'MW_SETUP_CALLBACK')) $fname
Customization point after all loading (constants, functions, classes, DefaultSettings,...
Definition: Setup.php:112
Wikimedia\Rdbms\LBFactory\hasOrMadeRecentMasterChanges
hasOrMadeRecentMasterChanges( $age=null)
Determine if any master connection has pending/written changes from this request.
Definition: LBFactory.php:314
Wikimedia\Rdbms\LBFactory\commitAll
commitAll( $fname=__METHOD__, array $options=[])
Commit open transactions on all connections.
Definition: LBFactory.php:209
$e
div flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException' returning false will NOT prevent logging $e
Definition: hooks.txt:2171
Wikimedia\Rdbms\LBFactory\getEmptyTransactionTicket
getEmptyTransactionTicket( $fname)
Get a token asserting that no transaction writes are active.
Definition: LBFactory.php:400
Wikimedia\Rdbms\LBFactory\$replicationWaitCallbacks
callable[] $replicationWaitCallbacks
Definition: LBFactory.php:79
Wikimedia\Rdbms\ILoadBalancer\hasOrMadeRecentMasterChanges
hasOrMadeRecentMasterChanges( $age=null)
Check if this load balancer object had any recent or still pending writes issued against it by this P...
Wikimedia\Rdbms\ChronologyProtector\shutdownLB
shutdownLB(ILoadBalancer $lb)
Notify the ChronologyProtector that the ILoadBalancer is about to shut down.
Definition: ChronologyProtector.php:139
Wikimedia\Rdbms\LBFactory\$ticket
mixed $ticket
Definition: LBFactory.php:73
Wikimedia\Rdbms\LBFactory\setAgentName
setAgentName( $agent)
Definition: LBFactory.php:579
WANObjectCache
Multi-datacenter aware caching interface.
Definition: WANObjectCache.php:87
Wikimedia\Rdbms\ILoadBalancer\laggedReplicaUsed
laggedReplicaUsed()
Checks whether the database for generic connections this request was both:
$ret
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
Definition: hooks.txt:2005
Wikimedia\Rdbms\LBFactory\hasTransactionRound
hasTransactionRound()
Check if a transaction round is active.
Definition: LBFactory.php:269
Wikimedia\Rdbms\LBFactory\newMainLB
newMainLB( $domain=false)
Wikimedia\Rdbms\LBFactory\beginMasterChanges
beginMasterChanges( $fname=__METHOD__)
Flush any master transaction snapshots and set DBO_TRX (if DBO_DEFAULT is set)
Definition: LBFactory.php:214
$args
if( $line===false) $args
Definition: cdb.php:64
Wikimedia\Rdbms\DBTransactionError
Definition: DBTransactionError.php:27
Wikimedia\Rdbms\LBFactory\destroy
destroy()
Disables all load balancers.
Definition: LBFactory.php:144
$options
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 & $options
Definition: hooks.txt:2001
Wikimedia\Rdbms\LBFactory\rollbackMasterChanges
rollbackMasterChanges( $fname=__METHOD__)
Rollback changes on all master connections.
Definition: LBFactory.php:259
Wikimedia\Rdbms\ChronologyProtector
Class for ensuring a consistent ordering of events as seen by the user, despite replication.
Definition: ChronologyProtector.php:36
Wikimedia\Rdbms\LBFactory\disableChronologyProtection
disableChronologyProtection()
Disable the ChronologyProtector for all load balancers.
Definition: LBFactory.php:441
Wikimedia\Rdbms\LBFactory
An interface for generating database load balancers.
Definition: LBFactory.php:39
as
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
Definition: distributors.txt:22
Wikimedia\Rdbms\LBFactory\$perfLogger
LoggerInterface $perfLogger
Definition: LBFactory.php:53
Wikimedia\Rdbms\LBFactory\$trxProfiler
TransactionProfiler $trxProfiler
Definition: LBFactory.php:45
Wikimedia\Rdbms\LBFactory\$trxRoundId
string bool $trxRoundId
String if a requested DBO_TRX transaction round is active.
Definition: LBFactory.php:75
Wikimedia\Rdbms\LBFactory\setIndexAliases
setIndexAliases(array $aliases)
Convert certain index names to alternative names before querying the DB.
Definition: LBFactory.php:559
Wikimedia\Rdbms\ILoadBalancer\hasMasterChanges
hasMasterChanges()
Determine if there are pending changes in a transaction by this thread.
class
you have access to all of the normal MediaWiki so you can get a DB use the etc For full docs on the Maintenance class
Definition: maintenance.txt:56
Wikimedia\Rdbms\LBFactory\logIfMultiDbTransaction
logIfMultiDbTransaction()
Log query info if multi DB transactions are going to be committed now.
Definition: LBFactory.php:276
Wikimedia\Rdbms\LBFactory\setDomainPrefix
setDomainPrefix( $prefix)
Set a new table prefix for the existing local domain ID for testing.
Definition: LBFactory.php:563
Wikimedia\Rdbms\LBFactory\$chronProt
ChronologyProtector $chronProt
Definition: LBFactory.php:41
Wikimedia\Rdbms\DatabaseDomain
Class to handle database/prefix specification for IDatabase domains.
Definition: DatabaseDomain.php:28
Wikimedia\Rdbms\TransactionProfiler
Helper class that detects high-contention DB queries via profiling calls.
Definition: TransactionProfiler.php:38
Wikimedia\Rdbms\LBFactory\$tableAliases
$tableAliases
Definition: LBFactory.php:82
Wikimedia\Rdbms\LBFactory\$profiler
object string $profiler
Class name or object With profileIn/profileOut methods.
Definition: LBFactory.php:43
Wikimedia\Rdbms\ILoadBalancer\beginMasterChanges
beginMasterChanges( $fname=__METHOD__)
Flush any master transaction snapshots and set DBO_TRX (if DBO_DEFAULT is set)
Wikimedia\Rdbms\LBFactory\$agent
string $agent
Agent name for query profiling.
Definition: LBFactory.php:89
Wikimedia\Rdbms\ILoadBalancer
Database cluster connection, tracking, load balancing, and transaction manager interface.
Definition: ILoadBalancer.php:78
Wikimedia\Rdbms\LBFactory\getScopedPHPBehaviorForCommit
getScopedPHPBehaviorForCommit()
Make PHP ignore user aborts/disconnects until the returned value leaves scope.
Definition: LBFactory.php:610
Wikimedia\Rdbms\LBFactory\newExternalLB
newExternalLB( $cluster)
Wikimedia\Rdbms\LBFactory\setWaitForReplicationListener
setWaitForReplicationListener( $name, callable $callback=null)
Add a callback to be run in every call to waitForReplication() before waiting.
Definition: LBFactory.php:392
array
the array() calling protocol came about after MediaWiki 1.4rc1.
Wikimedia\Rdbms\ILBFactory
An interface for generating database load balancers.
Definition: ILBFactory.php:33
Wikimedia\Rdbms\LBFactory\setRequestInfo
setRequestInfo(array $info)
Definition: LBFactory.php:596