MediaWiki  master
runBatchedQuery.php
Go to the documentation of this file.
1 <?php
26 require_once __DIR__ . '/Maintenance.php';
27 
30 
37  public function __construct() {
38  parent::__construct();
39  $this->addDescription(
40  "Run an update query on all rows of a table. " .
41  "Waits for replicas at appropriate intervals." );
42  $this->addOption( 'table', 'The table name', true, true );
43  $this->addOption( 'set', 'The SET clause', true, true );
44  $this->addOption( 'where', 'The WHERE clause', false, true );
45  $this->addOption( 'key', 'A column name, the values of which are unique', true, true );
46  $this->addOption( 'batch-size', 'The batch size (default 1000)', false, true );
47  $this->addOption( 'db', 'The database name, or omit to use the current wiki.', false, true );
48  }
49 
50  public function execute() {
51  $table = $this->getOption( 'table' );
52  $key = $this->getOption( 'key' );
53  $set = $this->getOption( 'set' );
54  $where = $this->getOption( 'where', null );
55  $where = $where === null ? [] : [ $where ];
56  $batchSize = $this->getOption( 'batch-size', 1000 );
57 
58  $dbName = $this->getOption( 'db', null );
59  if ( $dbName === null ) {
60  $dbw = $this->getDB( DB_MASTER );
61  } else {
62  $lbf = MediaWiki\MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
63  $lb = $lbf->getMainLB( $dbName );
64  $dbw = $lb->getConnection( DB_MASTER, [], $dbName );
65  }
66 
67  $selectConds = $where;
68  $prevEnd = false;
69  $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
70 
71  $n = 1;
72  do {
73  $this->output( "Batch $n: " );
74  $n++;
75 
76  // Note that the update conditions do not rely on atomicity of the
77  // SELECT query in order to guarantee that all rows are updated. The
78  // results of the SELECT are merely a partitioning hint. Simultaneous
79  // updates merely result in the wrong number of rows being updated
80  // in a batch.
81 
82  $res = $dbw->select( $table, $key, $selectConds, __METHOD__,
83  [ 'ORDER BY' => $key, 'LIMIT' => $batchSize ] );
84  if ( $res->numRows() ) {
85  $res->seek( $res->numRows() - 1 );
86  $row = $res->fetchObject();
87  $end = $dbw->addQuotes( $row->$key );
88  $selectConds = array_merge( $where, [ "$key > $end" ] );
89  $updateConds = array_merge( $where, [ "$key <= $end" ] );
90  } else {
91  $updateConds = $where;
92  $end = false;
93  }
94  if ( $prevEnd !== false ) {
95  $updateConds = array_merge( [ "$key > $prevEnd" ], $updateConds );
96  }
97 
98  $query = "UPDATE " . $dbw->tableName( $table ) .
99  " SET " . $set .
100  " WHERE " . $dbw->makeList( $updateConds, IDatabase::LIST_AND );
101 
102  $dbw->query( $query, __METHOD__ );
103 
104  $prevEnd = $end;
105 
106  $affected = $dbw->affectedRows();
107  $this->output( "$affected rows affected\n" );
108  $lbFactory->waitForReplication();
109  } while ( $res->numRows() );
110  }
111 
112  public function getDbType() {
113  return Maintenance::DB_ADMIN;
114  }
115 }
116 
117 $maintClass = RunBatchedQuery::class;
118 require_once RUN_MAINTENANCE_IF_MAIN;
RUN_MAINTENANCE_IF_MAIN
const RUN_MAINTENANCE_IF_MAIN
Definition: Maintenance.php:38
$maintClass
$maintClass
Definition: runBatchedQuery.php:117
RunBatchedQuery\execute
execute()
Do the actual work.
Definition: runBatchedQuery.php:50
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:163
Maintenance\addDescription
addDescription( $text)
Set the description text.
Definition: Maintenance.php:327
RunBatchedQuery
Maintenance script to run a database query in batches and wait for replica DBs.
Definition: runBatchedQuery.php:36
Maintenance
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
Definition: Maintenance.php:55
$res
$res
Definition: testCompression.php:57
LIST_AND
const LIST_AND
Definition: Defines.php:48
Wikimedia\Rdbms\IDatabase
Basic database interface for live and lazy-loaded relation database handles.
Definition: IDatabase.php:38
MediaWiki\MediaWikiServices\getInstance
static getInstance()
Returns the global default instance of the top level service locator.
Definition: MediaWikiServices.php:195
RunBatchedQuery\getDbType
getDbType()
Does the script need different DB access? By default, we give Maintenance scripts normal rights to th...
Definition: runBatchedQuery.php:112
Maintenance\addOption
addOption( $name, $description, $required=false, $withArg=false, $shortName=false, $multiOccurrence=false)
Add a parameter to the script.
Definition: Maintenance.php:245
DB_MASTER
const DB_MASTER
Definition: defines.php:26
Maintenance\DB_ADMIN
const DB_ADMIN
Definition: Maintenance.php:62
Maintenance\getDB
getDB( $db, $groups=[], $dbDomain=false)
Returns a database to be used by current maintenance script.
Definition: Maintenance.php:1369
RunBatchedQuery\__construct
__construct()
Default constructor.
Definition: runBatchedQuery.php:37
Maintenance\getOption
getOption( $name, $default=null)
Get an option, or return the default.
Definition: Maintenance.php:281
Maintenance\output
output( $out, $channel=null)
Throw some output to the user.
Definition: Maintenance.php:433