MediaWiki master
fixInconsistentRedirects.php
Go to the documentation of this file.
1<?php
21// @codeCoverageIgnoreStart
22require_once __DIR__ . '/Maintenance.php';
23// @codeCoverageIgnoreEnd
24
32
33 public function __construct() {
34 parent::__construct();
35 $this->addDescription( 'Fix redirect pages with missing or incomplete row in the redirect table' );
36 $this->setBatchSize( 100 );
37 }
38
39 protected function getUpdateKey() {
40 return __CLASS__;
41 }
42
43 protected function doDBUpdates() {
44 $dbr = $this->getReplicaDB();
45
46 $builder = $dbr->newSelectQueryBuilder()
47 ->caller( __METHOD__ )
48 ->from( 'page' )
49 ->where( [ 'page_is_redirect' => 1 ] );
50
51 $this->output( "Fixing inconsistent redirects ...\n" );
52
53 $estimateCount = $builder->estimateRowCount();
54 $this->output( "Estimated redirect page count: $estimateCount\n" );
55
56 $builder
57 ->limit( $this->getBatchSize() )
58 ->leftJoin( 'redirect', null, 'page_id=rd_from' )
59 ->select( [ 'rd_from', 'rd_interwiki', 'rd_fragment' ] );
60
61 // Using the page_redirect_namespace_len index to skip non-redirects
62 $index = [ 'page_is_redirect', 'page_namespace', 'page_len', 'page_id' ];
63 $builder->select( $index )->orderBy( $index );
64 $prevRow = [];
65
66 $total = 0;
67 $updated = 0;
68 do {
69 $res = ( clone $builder )
70 ->where( $prevRow ? [ $dbr->buildComparison( '>', $prevRow ) ] : [] )
71 ->caller( __METHOD__ )->fetchResultSet();
72
73 foreach ( $res as $row ) {
74 // Only attempt write queries if the row or rd_interwiki/rd_fragment fields are missing
75 // (we don't include this condition in the query to avoid slow queries and bad estimates)
76 if ( $row->rd_from === null || $row->rd_interwiki === null || $row->rd_fragment === null ) {
77 RefreshLinks::fixRedirect( $this, $row->page_id );
78 $updated++;
79 }
80 }
81 if ( isset( $row ) ) {
82 // Update the conditions to select the next batch
83 foreach ( $index as $field ) {
84 $prevRow[ $field ] = $row->$field;
85 }
86 }
87
88 $this->waitForReplication();
89 $total += $res->numRows();
90 $this->output( "$updated/$total\n" );
91
92 } while ( $res->numRows() == $this->getBatchSize() );
93
94 $this->output( "Done, updated $updated of $total rows.\n" );
95 return true;
96 }
97}
98
99// @codeCoverageIgnoreStart
100$maintClass = FixInconsistentRedirects::class;
101require_once RUN_MAINTENANCE_IF_MAIN;
102// @codeCoverageIgnoreEnd
Fix redirect pages with missing or incomplete row in the redirect table.
getUpdateKey()
Get the update key name to go in the update log table.
Class for scripts that perform database maintenance and want to log the update in updatelog so we can...
output( $out, $channel=null)
Throw some output to the user.
waitForReplication()
Wait for replica DBs to catch up.
getBatchSize()
Returns batch size.
addDescription( $text)
Set the description text.
setBatchSize( $s=0)