From 3b13196c8a4d77617438e37f9ca29e8eee416317 Mon Sep 17 00:00:00 2001 From: Tim Starling Date: Thu, 28 Sep 2006 09:05:28 +0000 Subject: [PATCH] various improvements --- maintenance/fixSlaveDesync.php | 133 ++++++++++++++++++++++++++++----- 1 file changed, 114 insertions(+), 19 deletions(-) diff --git a/maintenance/fixSlaveDesync.php b/maintenance/fixSlaveDesync.php index e97f96c9a8..d2dffe543f 100644 --- a/maintenance/fixSlaveDesync.php +++ b/maintenance/fixSlaveDesync.php @@ -22,12 +22,50 @@ if ( isset( $args[0] ) ) { } else { $dbw =& wfGetDB( DB_MASTER ); $maxPage = $dbw->selectField( 'page', 'MAX(page_id)', false, 'fixDesync.php' ); + $corrupt = findPageLatestCorruption(); + foreach ( $corrupt as $id => $dummy ) { + desyncFixPage( $id ); + } + /* for ( $i=1; $i <= $maxPage; $i++ ) { desyncFixPage( $i ); if ( !($i % $reportingInterval) ) { print "$i\n"; } + }*/ +} + +function findPageLatestCorruption() { + $desync = array(); + $n = 0; + $dbw =& wfGetDB( DB_MASTER ); + $masterIDs = array(); + $res = $dbw->select( 'page', array( 'page_id', 'page_latest' ), array( 'page_id<6054123' ), __METHOD__ ); + print "Number of pages: " . $dbw->numRows( $res ) . "\n"; + while ( $row = $dbw->fetchObject( $res ) ) { + $masterIDs[$row->page_id] = $row->page_latest; + if ( !( ++$n % 10000 ) ) { + print "$n\r"; + } } + print "\n"; + $dbw->freeResult( $res ); + + global $slaveIndexes; + foreach ( $slaveIndexes as $i ) { + $slaveIDs = array(); + $db =& wfGetDB( $i ); + $res = $db->select( 'page', array( 'page_id', 'page_latest' ), array( 'page_id<6054123' ), __METHOD__ ); + while ( $row = $db->fetchObject( $res ) ) { + if ( isset( $masterIDs[$row->page_id] ) && $masterIDs[$row->page_id] != $row->page_latest ) { + $desync[$row->page_id] = true; + print $row->page_id . "\t"; + } + } + $db->freeResult( $res ); + } + print "\n"; + return $desync; } function desyncFixPage( $pageID ) { @@ -36,10 +74,20 @@ function desyncFixPage( $pageID ) { # Check for a corrupted page_latest $dbw =& wfGetDB( DB_MASTER ); - $realLatest = $dbw->selectField( 'page', 'page_latest', array( 'page_id' => $pageID ), $fname ); + $dbw->begin(); + $realLatest = $dbw->selectField( 'page', 'page_latest', array( 'page_id' => $pageID ), + $fname, 'FOR UPDATE' ); + #list( $masterFile, $masterPos ) = $dbw->getMasterPos(); $found = false; foreach ( $slaveIndexes as $i ) { $db =& wfGetDB( $i ); + /* + if ( !$db->masterPosWait( $masterFile, $masterPos, 10 ) ) { + echo "Slave is too lagged, aborting\n"; + $dbw->commit(); + sleep(10); + return; + }*/ $latest = $db->selectField( 'page', 'page_latest', array( 'page_id' => $pageID ), $fname ); $max = $db->selectField( 'revision', 'MAX(rev_id)', false, $fname ); if ( $latest != $realLatest && $realLatest < $max ) { @@ -49,11 +97,14 @@ function desyncFixPage( $pageID ) { } } if ( !$found ) { + print "page_id $pageID seems fine\n"; + $dbw->commit(); return; } - # Find the missing revision - $res = $dbw->select( 'revision', array( 'rev_id' ), array( 'rev_page' => $pageID ), $fname ); + # Find the missing revisions + $res = $dbw->select( 'revision', array( 'rev_id' ), array( 'rev_page' => $pageID ), + $fname, 'FOR UPDATE' ); $masterIDs = array(); while ( $row = $dbw->fetchObject( $res ) ) { $masterIDs[] = $row->rev_id; @@ -66,35 +117,79 @@ function desyncFixPage( $pageID ) { $slaveIDs[] = $row->rev_id; } $db->freeResult( $res ); - $missingIDs = array_diff( $masterIDs, $slaveIDs ); + if ( count( $masterIDs ) < count( $slaveIDs ) ) { + $missingIDs = array_diff( $slaveIDs, $masterIDs ); + if ( count( $missingIDs ) ) { + print "Found " . count( $missingIDs ) . " lost in master, copying from slave... "; + $dbFrom = $db; + $dbTo = $dbw; + $found = true; + $toMaster = true; + } else { + $found = false; + } + } else { + $missingIDs = array_diff( $masterIDs, $slaveIDs ); + if ( count( $missingIDs ) ) { + print "Found " . count( $missingIDs ) . " missing revision(s), copying from master... "; + $dbFrom = $dbw; + $dbTo = $db; + $found = true; + $toMaster = false; + } else { + $found = false; + } + } - if ( count( $missingIDs ) ) { - print "Found " . count( $missingIDs ) . " missing revision(s), copying from master... "; + if ( $found ) { foreach ( $missingIDs as $rid ) { print "$rid "; # Revision - $row = $dbw->selectRow( 'revision', '*', array( 'rev_id' => $rid ), $fname ); - foreach ( $slaveIndexes as $i ) { - $db =& wfGetDB( $i ); - $db->insert( 'revision', get_object_vars( $row ), $fname, 'IGNORE' ); + $row = $dbFrom->selectRow( 'revision', '*', array( 'rev_id' => $rid ), $fname ); + if ( $toMaster ) { + $id = $dbw->selectField( 'revision', 'rev_id', array( 'rev_id' => $rid ), + $fname, 'FOR UPDATE' ); + if ( $id ) { + echo "Revision already exists\n"; + $found = false; + break; + } else { + $dbw->insert( 'revision', get_object_vars( $row ), $fname, 'IGNORE' ); + } + } else { + foreach ( $slaveIndexes as $i ) { + $db =& wfGetDB( $i ); + $db->insert( 'revision', get_object_vars( $row ), $fname, 'IGNORE' ); + } } # Text - $row = $dbw->selectRow( 'text', '*', array( 'old_id' => $row->rev_text_id ), $fname ); - foreach ( $slaveIndexes as $i ) { - $db =& wfGetDB( $i ); - $db->insert( 'text', get_object_vars( $row ), $fname, 'IGNORE' ); + $row = $dbFrom->selectRow( 'text', '*', array( 'old_id' => $row->rev_text_id ), $fname ); + if ( $toMaster ) { + $dbw->insert( 'text', get_object_vars( $row ), $fname, 'IGNORE' ); + } else { + foreach ( $slaveIndexes as $i ) { + $db =& wfGetDB( $i ); + $db->insert( 'text', get_object_vars( $row ), $fname, 'IGNORE' ); + } } } print "done\n"; } - print "Fixing page_latest... "; - foreach ( $slaveIndexes as $i ) { - $db =& wfGetDB( $i ); - $db->update( 'page', array( 'page_latest' => $realLatest ), array( 'page_id' => $pageID ), $fname ); + if ( $found ) { + print "Fixing page_latest... "; + if ( $toMaster ) { + #$dbw->update( 'page', array( 'page_latest' => $realLatest ), array( 'page_id' => $pageID ), $fname ); + } else { + foreach ( $slaveIndexes as $i ) { + $db =& wfGetDB( $i ); + $db->update( 'page', array( 'page_latest' => $realLatest ), array( 'page_id' => $pageID ), $fname ); + } + } + print "done\n"; } - print "done\n"; + $dbw->commit(); } ?> -- 2.20.1