MediaWiki  1.29.1
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 
38 abstract class LBFactory implements ILBFactory {
40  protected $chronProt;
42  protected $profiler;
44  protected $trxProfiler;
46  protected $replLogger;
48  protected $connLogger;
50  protected $queryLogger;
52  protected $perfLogger;
54  protected $errorLogger;
56  protected $srvCache;
58  protected $memCache;
60  protected $wanCache;
61 
63  protected $localDomain;
65  protected $hostname;
67  protected $requestInfo;
68 
70  protected $ticket;
72  protected $trxRoundId = false;
74  protected $readOnlyReason = false;
76  protected $replicationWaitCallbacks = [];
77 
79  protected $cliMode;
81  protected $agent;
82 
83  private static $loggerFields =
84  [ 'replLogger', 'connLogger', 'queryLogger', 'perfLogger' ];
85 
86  public function __construct( array $conf ) {
87  $this->localDomain = isset( $conf['localDomain'] )
88  ? DatabaseDomain::newFromId( $conf['localDomain'] )
90 
91  if ( isset( $conf['readOnlyReason'] ) && is_string( $conf['readOnlyReason'] ) ) {
92  $this->readOnlyReason = $conf['readOnlyReason'];
93  }
94 
95  $this->srvCache = isset( $conf['srvCache'] ) ? $conf['srvCache'] : new EmptyBagOStuff();
96  $this->memCache = isset( $conf['memCache'] ) ? $conf['memCache'] : new EmptyBagOStuff();
97  $this->wanCache = isset( $conf['wanCache'] )
98  ? $conf['wanCache']
100 
101  foreach ( self::$loggerFields as $key ) {
102  $this->$key = isset( $conf[$key] ) ? $conf[$key] : new \Psr\Log\NullLogger();
103  }
104  $this->errorLogger = isset( $conf['errorLogger'] )
105  ? $conf['errorLogger']
106  : function ( Exception $e ) {
107  trigger_error( E_USER_WARNING, get_class( $e ) . ': ' . $e->getMessage() );
108  };
109 
110  $this->profiler = isset( $conf['profiler'] ) ? $conf['profiler'] : null;
111  $this->trxProfiler = isset( $conf['trxProfiler'] )
112  ? $conf['trxProfiler']
113  : new TransactionProfiler();
114 
115  $this->requestInfo = [
116  'IPAddress' => isset( $_SERVER[ 'REMOTE_ADDR' ] ) ? $_SERVER[ 'REMOTE_ADDR' ] : '',
117  'UserAgent' => isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : '',
118  'ChronologyProtection' => 'true'
119  ];
120 
121  $this->cliMode = isset( $conf['cliMode'] ) ? $conf['cliMode'] : PHP_SAPI === 'cli';
122  $this->hostname = isset( $conf['hostname'] ) ? $conf['hostname'] : gethostname();
123  $this->agent = isset( $conf['agent'] ) ? $conf['agent'] : '';
124 
125  $this->ticket = mt_rand();
126  }
127 
128  public function destroy() {
129  $this->shutdown( self::SHUTDOWN_NO_CHRONPROT );
130  $this->forEachLBCallMethod( 'disable' );
131  }
132 
133  public function shutdown(
134  $mode = self::SHUTDOWN_CHRONPROT_SYNC, callable $workCallback = null
135  ) {
137  if ( $mode === self::SHUTDOWN_CHRONPROT_SYNC ) {
138  $this->shutdownChronologyProtector( $chronProt, $workCallback, 'sync' );
139  } elseif ( $mode === self::SHUTDOWN_CHRONPROT_ASYNC ) {
140  $this->shutdownChronologyProtector( $chronProt, null, 'async' );
141  }
142 
143  $this->commitMasterChanges( __METHOD__ ); // sanity
144  }
145 
151  abstract public function newMainLB( $domain = false );
152 
158  abstract public function getMainLB( $domain = false );
159 
165  abstract public function newExternalLB( $cluster );
166 
172  abstract public function getExternalLB( $cluster );
173 
180  protected function forEachLBCallMethod( $methodName, array $args = [] ) {
181  $this->forEachLB(
182  function ( ILoadBalancer $loadBalancer, $methodName, array $args ) {
183  call_user_func_array( [ $loadBalancer, $methodName ], $args );
184  },
185  [ $methodName, $args ]
186  );
187  }
188 
189  public function flushReplicaSnapshots( $fname = __METHOD__ ) {
190  $this->forEachLBCallMethod( 'flushReplicaSnapshots', [ $fname ] );
191  }
192 
193  public function commitAll( $fname = __METHOD__, array $options = [] ) {
195  $this->forEachLBCallMethod( 'commitAll', [ $fname ] );
196  }
197 
198  public function beginMasterChanges( $fname = __METHOD__ ) {
199  if ( $this->trxRoundId !== false ) {
200  throw new DBTransactionError(
201  null,
202  "$fname: transaction round '{$this->trxRoundId}' already started."
203  );
204  }
205  $this->trxRoundId = $fname;
206  // Set DBO_TRX flags on all appropriate DBs
207  $this->forEachLBCallMethod( 'beginMasterChanges', [ $fname ] );
208  }
209 
210  public function commitMasterChanges( $fname = __METHOD__, array $options = [] ) {
211  if ( $this->trxRoundId !== false && $this->trxRoundId !== $fname ) {
212  throw new DBTransactionError(
213  null,
214  "$fname: transaction round '{$this->trxRoundId}' still running."
215  );
216  }
218  $scope = $this->getScopedPHPBehaviorForCommit(); // try to ignore client aborts
219  // Run pre-commit callbacks and suppress post-commit callbacks, aborting on failure
220  $this->forEachLBCallMethod( 'finalizeMasterChanges' );
221  $this->trxRoundId = false;
222  // Perform pre-commit checks, aborting on failure
223  $this->forEachLBCallMethod( 'approveMasterChanges', [ $options ] );
224  // Log the DBs and methods involved in multi-DB transactions
225  $this->logIfMultiDbTransaction();
226  // Actually perform the commit on all master DB connections and revert DBO_TRX
227  $this->forEachLBCallMethod( 'commitMasterChanges', [ $fname ] );
228  // Run all post-commit callbacks
230  $e = null; // first callback exception
231  $this->forEachLB( function ( ILoadBalancer $lb ) use ( &$e ) {
232  $ex = $lb->runMasterPostTrxCallbacks( IDatabase::TRIGGER_COMMIT );
233  $e = $e ?: $ex;
234  } );
235  // Commit any dangling DBO_TRX transactions from callbacks on one DB to another DB
236  $this->forEachLBCallMethod( 'commitMasterChanges', [ $fname ] );
237  // Throw any last post-commit callback error
238  if ( $e instanceof Exception ) {
239  throw $e;
240  }
241  }
242 
243  public function rollbackMasterChanges( $fname = __METHOD__ ) {
244  $this->trxRoundId = false;
245  $this->forEachLBCallMethod( 'suppressTransactionEndCallbacks' );
246  $this->forEachLBCallMethod( 'rollbackMasterChanges', [ $fname ] );
247  // Run all post-rollback callbacks
248  $this->forEachLB( function ( ILoadBalancer $lb ) {
249  $lb->runMasterPostTrxCallbacks( IDatabase::TRIGGER_ROLLBACK );
250  } );
251  }
252 
253  public function hasTransactionRound() {
254  return ( $this->trxRoundId !== false );
255  }
256 
260  private function logIfMultiDbTransaction() {
261  $callersByDB = [];
262  $this->forEachLB( function ( ILoadBalancer $lb ) use ( &$callersByDB ) {
263  $masterName = $lb->getServerName( $lb->getWriterIndex() );
264  $callers = $lb->pendingMasterChangeCallers();
265  if ( $callers ) {
266  $callersByDB[$masterName] = $callers;
267  }
268  } );
269 
270  if ( count( $callersByDB ) >= 2 ) {
271  $dbs = implode( ', ', array_keys( $callersByDB ) );
272  $msg = "Multi-DB transaction [{$dbs}]:\n";
273  foreach ( $callersByDB as $db => $callers ) {
274  $msg .= "$db: " . implode( '; ', $callers ) . "\n";
275  }
276  $this->queryLogger->info( $msg );
277  }
278  }
279 
280  public function hasMasterChanges() {
281  $ret = false;
282  $this->forEachLB( function ( ILoadBalancer $lb ) use ( &$ret ) {
283  $ret = $ret || $lb->hasMasterChanges();
284  } );
285 
286  return $ret;
287  }
288 
289  public function laggedReplicaUsed() {
290  $ret = false;
291  $this->forEachLB( function ( ILoadBalancer $lb ) use ( &$ret ) {
292  $ret = $ret || $lb->laggedReplicaUsed();
293  } );
294 
295  return $ret;
296  }
297 
298  public function hasOrMadeRecentMasterChanges( $age = null ) {
299  $ret = false;
300  $this->forEachLB( function ( ILoadBalancer $lb ) use ( $age, &$ret ) {
301  $ret = $ret || $lb->hasOrMadeRecentMasterChanges( $age );
302  } );
303  return $ret;
304  }
305 
306  public function waitForReplication( array $opts = [] ) {
307  $opts += [
308  'domain' => false,
309  'cluster' => false,
310  'timeout' => 60,
311  'ifWritesSince' => null
312  ];
313 
314  if ( $opts['domain'] === false && isset( $opts['wiki'] ) ) {
315  $opts['domain'] = $opts['wiki']; // b/c
316  }
317 
318  // Figure out which clusters need to be checked
320  $lbs = [];
321  if ( $opts['cluster'] !== false ) {
322  $lbs[] = $this->getExternalLB( $opts['cluster'] );
323  } elseif ( $opts['domain'] !== false ) {
324  $lbs[] = $this->getMainLB( $opts['domain'] );
325  } else {
326  $this->forEachLB( function ( ILoadBalancer $lb ) use ( &$lbs ) {
327  $lbs[] = $lb;
328  } );
329  if ( !$lbs ) {
330  return; // nothing actually used
331  }
332  }
333 
334  // Get all the master positions of applicable DBs right now.
335  // This can be faster since waiting on one cluster reduces the
336  // time needed to wait on the next clusters.
337  $masterPositions = array_fill( 0, count( $lbs ), false );
338  foreach ( $lbs as $i => $lb ) {
339  if ( $lb->getServerCount() <= 1 ) {
340  // T29975 - Don't try to wait for replica DBs if there are none
341  // Prevents permission error when getting master position
342  continue;
343  } elseif ( $opts['ifWritesSince']
344  && $lb->lastMasterChangeTimestamp() < $opts['ifWritesSince']
345  ) {
346  continue; // no writes since the last wait
347  }
348  $masterPositions[$i] = $lb->getMasterPos();
349  }
350 
351  // Run any listener callbacks *after* getting the DB positions. The more
352  // time spent in the callbacks, the less time is spent in waitForAll().
353  foreach ( $this->replicationWaitCallbacks as $callback ) {
354  $callback();
355  }
356 
357  $failed = [];
358  foreach ( $lbs as $i => $lb ) {
359  if ( $masterPositions[$i] ) {
360  // The DBMS may not support getMasterPos()
361  if ( !$lb->waitForAll( $masterPositions[$i], $opts['timeout'] ) ) {
362  $failed[] = $lb->getServerName( $lb->getWriterIndex() );
363  }
364  }
365  }
366 
367  if ( $failed ) {
368  throw new DBReplicationWaitError(
369  null,
370  "Could not wait for replica DBs to catch up to " .
371  implode( ', ', $failed )
372  );
373  }
374  }
375 
376  public function setWaitForReplicationListener( $name, callable $callback = null ) {
377  if ( $callback ) {
378  $this->replicationWaitCallbacks[$name] = $callback;
379  } else {
380  unset( $this->replicationWaitCallbacks[$name] );
381  }
382  }
383 
384  public function getEmptyTransactionTicket( $fname ) {
385  if ( $this->hasMasterChanges() ) {
386  $this->queryLogger->error( __METHOD__ . ": $fname does not have outer scope.\n" .
387  ( new RuntimeException() )->getTraceAsString() );
388 
389  return null;
390  }
391 
392  return $this->ticket;
393  }
394 
395  public function commitAndWaitForReplication( $fname, $ticket, array $opts = [] ) {
396  if ( $ticket !== $this->ticket ) {
397  $this->perfLogger->error( __METHOD__ . ": $fname does not have outer scope.\n" .
398  ( new RuntimeException() )->getTraceAsString() );
399 
400  return;
401  }
402 
403  // The transaction owner and any caller with the empty transaction ticket can commit
404  // so that getEmptyTransactionTicket() callers don't risk seeing DBTransactionError.
405  if ( $this->trxRoundId !== false && $fname !== $this->trxRoundId ) {
406  $this->queryLogger->info( "$fname: committing on behalf of {$this->trxRoundId}." );
407  $fnameEffective = $this->trxRoundId;
408  } else {
409  $fnameEffective = $fname;
410  }
411 
412  $this->commitMasterChanges( $fnameEffective );
413  $this->waitForReplication( $opts );
414  // If a nested caller committed on behalf of $fname, start another empty $fname
415  // transaction, leaving the caller with the same empty transaction state as before.
416  if ( $fnameEffective !== $fname ) {
417  $this->beginMasterChanges( $fnameEffective );
418  }
419  }
420 
421  public function getChronologyProtectorTouched( $dbName ) {
422  return $this->getChronologyProtector()->getTouched( $dbName );
423  }
424 
425  public function disableChronologyProtection() {
426  $this->getChronologyProtector()->setEnabled( false );
427  }
428 
432  protected function getChronologyProtector() {
433  if ( $this->chronProt ) {
434  return $this->chronProt;
435  }
436 
437  $this->chronProt = new ChronologyProtector(
438  $this->memCache,
439  [
440  'ip' => $this->requestInfo['IPAddress'],
441  'agent' => $this->requestInfo['UserAgent'],
442  ],
443  isset( $_GET['cpPosTime'] ) ? $_GET['cpPosTime'] : null
444  );
445  $this->chronProt->setLogger( $this->replLogger );
446 
447  if ( $this->cliMode ) {
448  $this->chronProt->setEnabled( false );
449  } elseif ( $this->requestInfo['ChronologyProtection'] === 'false' ) {
450  // Request opted out of using position wait logic. This is useful for requests
451  // done by the job queue or background ETL that do not have a meaningful session.
452  $this->chronProt->setWaitEnabled( false );
453  }
454 
455  $this->replLogger->debug( __METHOD__ . ': using request info ' .
456  json_encode( $this->requestInfo, JSON_PRETTY_PRINT ) );
457 
458  return $this->chronProt;
459  }
460 
468  protected function shutdownChronologyProtector(
469  ChronologyProtector $cp, $workCallback, $mode
470  ) {
471  // Record all the master positions needed
472  $this->forEachLB( function ( ILoadBalancer $lb ) use ( $cp ) {
473  $cp->shutdownLB( $lb );
474  } );
475  // Write them to the persistent stash. Try to do something useful by running $work
476  // while ChronologyProtector waits for the stash write to replicate to all DCs.
477  $unsavedPositions = $cp->shutdown( $workCallback, $mode );
478  if ( $unsavedPositions && $workCallback ) {
479  // Invoke callback in case it did not cache the result yet
480  $workCallback(); // work now to block for less time in waitForAll()
481  }
482  // If the positions failed to write to the stash, at least wait on local datacenter
483  // replica DBs to catch up before responding. Even if there are several DCs, this increases
484  // the chance that the user will see their own changes immediately afterwards. As long
485  // as the sticky DC cookie applies (same domain), this is not even an issue.
486  $this->forEachLB( function ( ILoadBalancer $lb ) use ( $unsavedPositions ) {
487  $masterName = $lb->getServerName( $lb->getWriterIndex() );
488  if ( isset( $unsavedPositions[$masterName] ) ) {
489  $lb->waitForAll( $unsavedPositions[$masterName] );
490  }
491  } );
492  }
493 
498  final protected function baseLoadBalancerParams() {
499  return [
500  'localDomain' => $this->localDomain,
501  'readOnlyReason' => $this->readOnlyReason,
502  'srvCache' => $this->srvCache,
503  'wanCache' => $this->wanCache,
504  'profiler' => $this->profiler,
505  'trxProfiler' => $this->trxProfiler,
506  'queryLogger' => $this->queryLogger,
507  'connLogger' => $this->connLogger,
508  'replLogger' => $this->replLogger,
509  'errorLogger' => $this->errorLogger,
510  'hostname' => $this->hostname,
511  'cliMode' => $this->cliMode,
512  'agent' => $this->agent,
513  'chronologyProtector' => $this->getChronologyProtector()
514  ];
515  }
516 
520  protected function initLoadBalancer( ILoadBalancer $lb ) {
521  if ( $this->trxRoundId !== false ) {
522  $lb->beginMasterChanges( $this->trxRoundId ); // set DBO_TRX
523  }
524  }
525 
526  public function setDomainPrefix( $prefix ) {
527  $this->localDomain = new DatabaseDomain(
528  $this->localDomain->getDatabase(),
529  null,
530  $prefix
531  );
532 
533  $this->forEachLB( function( ILoadBalancer $lb ) use ( $prefix ) {
534  $lb->setDomainPrefix( $prefix );
535  } );
536  }
537 
538  public function closeAll() {
539  $this->forEachLBCallMethod( 'closeAll', [] );
540  }
541 
542  public function setAgentName( $agent ) {
543  $this->agent = $agent;
544  }
545 
546  public function appendPreShutdownTimeAsQuery( $url, $time ) {
547  $usedCluster = 0;
548  $this->forEachLB( function ( ILoadBalancer $lb ) use ( &$usedCluster ) {
549  $usedCluster |= ( $lb->getServerCount() > 1 );
550  } );
551 
552  if ( !$usedCluster ) {
553  return $url; // no master/replica clusters touched
554  }
555 
556  return strpos( $url, '?' ) === false ? "$url?cpPosTime=$time" : "$url&cpPosTime=$time";
557  }
558 
559  public function setRequestInfo( array $info ) {
560  $this->requestInfo = $info + $this->requestInfo;
561  }
562 
569  final protected function getScopedPHPBehaviorForCommit() {
570  if ( PHP_SAPI != 'cli' ) { // https://bugs.php.net/bug.php?id=47540
571  $old = ignore_user_abort( true ); // avoid half-finished operations
572  return new ScopedCallback( function () use ( $old ) {
573  ignore_user_abort( $old );
574  } );
575  }
576 
577  return null;
578  }
579 
580  function __destruct() {
581  $this->destroy();
582  }
583 }
584 
585 class_alias( LBFactory::class, 'LBFactory' );
Wikimedia\Rdbms\LBFactory\$memCache
BagOStuff $memCache
Definition: LBFactory.php:58
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.
Wikimedia\Rdbms\LBFactory\$replLogger
LoggerInterface $replLogger
Definition: LBFactory.php:46
Wikimedia\Rdbms\DatabaseDomain\newFromId
static newFromId( $domain)
Definition: DatabaseDomain.php:63
Wikimedia\Rdbms\LBFactory\$errorLogger
callable $errorLogger
Error logger.
Definition: LBFactory.php:54
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\LBFactory\$cliMode
bool $cliMode
Whether this PHP instance is for a CLI script.
Definition: LBFactory.php:79
Wikimedia\Rdbms\LBFactory\$wanCache
WANObjectCache $wanCache
Definition: LBFactory.php:60
captcha-old.count
count
Definition: captcha-old.py:225
Wikimedia\Rdbms\LBFactory\__destruct
__destruct()
Definition: LBFactory.php:580
Wikimedia\Rdbms\LBFactory\$hostname
string $hostname
Local hostname of the app server.
Definition: LBFactory.php:65
Wikimedia\Rdbms\LBFactory\$connLogger
LoggerInterface $connLogger
Definition: LBFactory.php:48
Wikimedia\Rdbms\LBFactory\commitAndWaitForReplication
commitAndWaitForReplication( $fname, $ticket, array $opts=[])
Convenience method for safely running commitMasterChanges()/waitForReplication()
Definition: LBFactory.php:395
Wikimedia\Rdbms\DBReplicationWaitError
Exception class for replica DB wait timeouts.
Definition: DBReplicationWaitError.php:28
Wikimedia\Rdbms\LBFactory\initLoadBalancer
initLoadBalancer(ILoadBalancer $lb)
Definition: LBFactory.php:520
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:10
Wikimedia\Rdbms\LBFactory\getChronologyProtector
getChronologyProtector()
Definition: LBFactory.php:432
Wikimedia\Rdbms
Definition: ChronologyProtector.php:24
$fname
if(!defined( 'MEDIAWIKI')) $fname
This file is not a valid entry point, perform no further processing unless MEDIAWIKI is defined.
Definition: Setup.php:36
Wikimedia\Rdbms\LBFactory\forEachLBCallMethod
forEachLBCallMethod( $methodName, array $args=[])
Call a method of each tracked load balancer.
Definition: LBFactory.php:180
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:189
Wikimedia\Rdbms\LBFactory\$loggerFields
static $loggerFields
Definition: LBFactory.php:83
Wikimedia\Rdbms\LBFactory\appendPreShutdownTimeAsQuery
appendPreShutdownTimeAsQuery( $url, $time)
Append ?cpPosTime parameter to a URL for ChronologyProtector purposes if needed.
Definition: LBFactory.php:546
$name
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:304
Wikimedia\Rdbms\LBFactory\__construct
__construct(array $conf)
Construct a manager of ILoadBalancer objects.
Definition: LBFactory.php:86
Wikimedia\Rdbms\LBFactory\waitForReplication
waitForReplication(array $opts=[])
Waits for the replica DBs to catch up to the current master position.
Definition: LBFactory.php:306
Wikimedia\Rdbms\LBFactory\getChronologyProtectorTouched
getChronologyProtectorTouched( $dbName)
Definition: LBFactory.php:421
Wikimedia\Rdbms\LBFactory\baseLoadBalancerParams
baseLoadBalancerParams()
Base parameters to LoadBalancer::__construct()
Definition: LBFactory.php:498
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:35
Wikimedia\Rdbms\LBFactory\commitMasterChanges
commitMasterChanges( $fname=__METHOD__, array $options=[])
Commit changes on all master connections.
Definition: LBFactory.php:210
Wikimedia\Rdbms\LBFactory\closeAll
closeAll()
Close all open database connections on all open load balancers.
Definition: LBFactory.php:538
Wikimedia\Rdbms\DatabaseDomain\newUnspecified
static newUnspecified()
Definition: DatabaseDomain.php:93
WANObjectCache\newEmpty
static newEmpty()
Get an instance that wraps EmptyBagOStuff.
Definition: WANObjectCache.php:200
Wikimedia\Rdbms\LBFactory\$srvCache
BagOStuff $srvCache
Definition: LBFactory.php:56
Wikimedia\Rdbms\ILoadBalancer\getServerName
getServerName( $i)
Get the host name or IP address of the server with the specified index Prefer a readable name if avai...
Wikimedia\Rdbms\LBFactory\$queryLogger
LoggerInterface $queryLogger
Definition: LBFactory.php:50
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:74
Wikimedia\Rdbms\LBFactory\getMainLB
getMainLB( $domain=false)
Wikimedia\Rdbms\ILoadBalancer\getWriterIndex
getWriterIndex()
$time
see documentation in includes Linker php for Linker::makeImageLink & $time
Definition: hooks.txt:1769
Wikimedia\Rdbms\LBFactory\$requestInfo
array $requestInfo
Web request information about the client.
Definition: LBFactory.php:67
Wikimedia\Rdbms\LBFactory\hasMasterChanges
hasMasterChanges()
Determine if any master connection has pending changes.
Definition: LBFactory.php:280
Wikimedia\Rdbms\LBFactory\$localDomain
DatabaseDomain $localDomain
Local domain.
Definition: LBFactory.php:63
Wikimedia\Rdbms\LBFactory\laggedReplicaUsed
laggedReplicaUsed()
Detemine if any lagged replica DB connection was used.
Definition: LBFactory.php:289
Wikimedia\Rdbms\LBFactory\hasOrMadeRecentMasterChanges
hasOrMadeRecentMasterChanges( $age=null)
Determine if any master connection has pending/written changes from this request.
Definition: LBFactory.php:298
Wikimedia\Rdbms\LBFactory\commitAll
commitAll( $fname=__METHOD__, array $options=[])
Commit open transactions on all connections.
Definition: LBFactory.php:193
$e
div flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException' returning false will NOT prevent logging $e
Definition: hooks.txt:2122
Wikimedia\Rdbms\LBFactory\getEmptyTransactionTicket
getEmptyTransactionTicket( $fname)
Get a token asserting that no transaction writes are active.
Definition: LBFactory.php:384
Wikimedia\Rdbms\LBFactory\$replicationWaitCallbacks
callable[] $replicationWaitCallbacks
Definition: LBFactory.php:76
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:70
Wikimedia\Rdbms\LBFactory\setAgentName
setAgentName( $agent)
Definition: LBFactory.php:542
WANObjectCache
Multi-datacenter aware caching interface.
Definition: WANObjectCache.php:81
Wikimedia\Rdbms\LBFactory\shutdownChronologyProtector
shutdownChronologyProtector(ChronologyProtector $cp, $workCallback, $mode)
Get and record all of the staged DB positions into persistent memory storage.
Definition: LBFactory.php:468
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:1956
Wikimedia\Rdbms\LBFactory\hasTransactionRound
hasTransactionRound()
Check if a transaction round is active.
Definition: LBFactory.php:253
Wikimedia\Rdbms\LBFactory\newMainLB
newMainLB( $domain=false)
Wikimedia\Rdbms\ChronologyProtector\shutdown
shutdown(callable $workCallback=null, $mode='sync')
Notify the ChronologyProtector that the LBFactory is done calling shutdownLB() for now.
Definition: ChronologyProtector.php:166
Wikimedia\Rdbms\LBFactory\beginMasterChanges
beginMasterChanges( $fname=__METHOD__)
Flush any master transaction snapshots and set DBO_TRX (if DBO_DEFAULT is set)
Definition: LBFactory.php:198
$args
if( $line===false) $args
Definition: cdb.php:63
Wikimedia\Rdbms\DBTransactionError
Definition: DBTransactionError.php:27
Wikimedia\Rdbms\LBFactory\destroy
destroy()
Disables all load balancers.
Definition: LBFactory.php:128
Wikimedia\Rdbms\LBFactory\rollbackMasterChanges
rollbackMasterChanges( $fname=__METHOD__)
Rollback changes on all master connections.
Definition: LBFactory.php:243
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:425
Wikimedia\Rdbms\LBFactory
An interface for generating database load balancers.
Definition: LBFactory.php:38
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:9
Wikimedia\Rdbms\LBFactory\$perfLogger
LoggerInterface $perfLogger
Definition: LBFactory.php:52
Wikimedia\Rdbms\LBFactory\$trxProfiler
TransactionProfiler $trxProfiler
Definition: LBFactory.php:44
Wikimedia\Rdbms\LBFactory\$trxRoundId
string bool $trxRoundId
String if a requested DBO_TRX transaction round is active.
Definition: LBFactory.php:72
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:52
Wikimedia\Rdbms\LBFactory\logIfMultiDbTransaction
logIfMultiDbTransaction()
Log query info if multi DB transactions are going to be committed now.
Definition: LBFactory.php:260
Wikimedia\Rdbms\LBFactory\setDomainPrefix
setDomainPrefix( $prefix)
Set a new table prefix for the existing local domain ID for testing.
Definition: LBFactory.php:526
Wikimedia\Rdbms\LBFactory\$chronProt
ChronologyProtector $chronProt
Definition: LBFactory.php:40
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:39
Wikimedia\Rdbms\LBFactory\$profiler
object string $profiler
Class name or object With profileIn/profileOut methods.
Definition: LBFactory.php:42
Wikimedia\Rdbms\ILoadBalancer\beginMasterChanges
beginMasterChanges( $fname=__METHOD__)
Flush any master transaction snapshots and set DBO_TRX (if DBO_DEFAULT is set)
$options
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist Do not use this to implement individual filters if they are compatible with the ChangesListFilter and ChangesListFilterGroup structure use sub classes of those in conjunction with the ChangesListSpecialPageStructuredFilters hook This hook can be used to implement filters that do not implement that or custom behavior that is not an individual filter e g Watchlist and Watchlist you will want to construct new ChangesListBooleanFilter or ChangesListStringOptionsFilter objects When constructing you specify which group they belong to You can reuse existing or create your you must register them with $special registerFilterGroup 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
Definition: hooks.txt:1049
Wikimedia\Rdbms\LBFactory\$agent
string $agent
Agent name for query profiling.
Definition: LBFactory.php:81
Wikimedia\Rdbms\ILoadBalancer
Database cluster connection, tracking, load balancing, and transaction manager interface.
Definition: ILoadBalancer.php:79
Wikimedia\Rdbms\LBFactory\getScopedPHPBehaviorForCommit
getScopedPHPBehaviorForCommit()
Make PHP ignore user aborts/disconnects until the returned value leaves scope.
Definition: LBFactory.php:569
Wikimedia\Rdbms\LBFactory\shutdown
shutdown( $mode=self::SHUTDOWN_CHRONPROT_SYNC, callable $workCallback=null)
Prepare all tracked load balancers for shutdown.
Definition: LBFactory.php:133
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:376
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:559