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