X-Git-Url: http://git.cyclocoop.org/%28?a=blobdiff_plain;f=maintenance%2Fstorage%2FcheckStorage.php;h=d8a8808cc34b46173033667187e94ceb2c7bfff0;hb=e16eec8cafd0586be01aa4f0c38c7fb23f96a331;hp=26d4e797879b740c7487bae3183a948e6c3464fe;hpb=a38af7ba26579bb3004f673e44d39710887763aa;p=lhc%2Fweb%2Fwiklou.git diff --git a/maintenance/storage/checkStorage.php b/maintenance/storage/checkStorage.php index 26d4e79787..d8a8808cc3 100644 --- a/maintenance/storage/checkStorage.php +++ b/maintenance/storage/checkStorage.php @@ -22,6 +22,8 @@ */ use MediaWiki\MediaWikiServices; +use MediaWiki\Revision\RevisionRecord; +use MediaWiki\Shell\Shell; if ( !defined( 'MEDIAWIKI' ) ) { $optionsWithoutArgs = [ 'fix' ]; @@ -44,6 +46,7 @@ if ( !defined( 'MEDIAWIKI' ) ) { class CheckStorage { const CONCAT_HEADER = 'O:27:"concatenatedgziphistoryblob"'; public $oldIdMap, $errors; + /** @var ExternalStoreDB */ public $dbStore = null; public $errorDescriptions = [ @@ -55,6 +58,8 @@ class CheckStorage { ]; function check( $fix = false, $xml = '' ) { + global $wgMultiContentRevisionSchemaMigrationStage; + $dbr = wfGetDB( DB_REPLICA ); if ( $fix ) { print "Checking, will fix errors if possible...\n"; @@ -78,13 +83,40 @@ class CheckStorage { $chunkEnd = $chunkStart + $chunkSize - 1; // print "$chunkStart of $maxRevId\n"; - // Fetch revision rows $this->oldIdMap = []; $dbr->ping(); - $res = $dbr->select( 'revision', [ 'rev_id', 'rev_text_id' ], - [ "rev_id BETWEEN $chunkStart AND $chunkEnd" ], __METHOD__ ); - foreach ( $res as $row ) { - $this->oldIdMap[$row->rev_id] = $row->rev_text_id; + + // Fetch revision rows + if ( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_READ_OLD ) { + $res = $dbr->select( 'revision', [ 'rev_id', 'rev_text_id' ], + [ "rev_id BETWEEN $chunkStart AND $chunkEnd" ], __METHOD__ ); + foreach ( $res as $row ) { + if ( !isset( $this->oldIdMap[ $row->rev_text_id ] ) ) { + $this->oldIdMap[ $row->rev_text_id ] = [ $row->rev_id ]; + } elseif ( !in_array( $row->rev_id, $this->oldIdMap[ $row->rev_text_id ] ) ) { + $this->oldIdMap[ $row->rev_text_id ][] = $row->rev_id; + } + } + } else { + $res = $dbr->select( + [ 'slots', 'content' ], + [ 'slot_revision_id', 'content_address' ], + [ "slot_revision_id BETWEEN $chunkStart AND $chunkEnd" ], + __METHOD__, + [], + [ 'content' => [ 'INNER JOIN', [ 'content_id = slot_content_id' ] ] ] + ); + $blobStore = MediaWikiServices::getInstance()->getBlobStore(); + foreach ( $res as $row ) { + $textId = $blobStore->getTextIdFromAddress( $row->content_address ); + if ( $textId ) { + if ( !isset( $this->oldIdMap[$textId] ) ) { + $this->oldIdMap[ $textId ] = [ $row->slot_revision_id ]; + } elseif ( !in_array( $row->slot_revision_id, $this->oldIdMap[$textId] ) ) { + $this->oldIdMap[ $textId ][] = $row->slot_revision_id; + } + } + } } if ( !count( $this->oldIdMap ) ) { @@ -92,18 +124,18 @@ class CheckStorage { } // Fetch old_flags - $missingTextRows = array_flip( $this->oldIdMap ); + $missingTextRows = $this->oldIdMap; $externalRevs = []; $objectRevs = []; $res = $dbr->select( 'text', [ 'old_id', 'old_flags' ], - [ 'old_id' => $this->oldIdMap ], + [ 'old_id' => array_keys( $this->oldIdMap ) ], __METHOD__ ); foreach ( $res as $row ) { /** - * @var $flags int + * @var int $flags */ $flags = $row->old_flags; $id = $row->old_id; @@ -148,7 +180,7 @@ class CheckStorage { } // Output errors for any missing text rows - foreach ( $missingTextRows as $oldId => $revId ) { + foreach ( $missingTextRows as $oldId => $revIds ) { $this->addError( 'restore revision', "Error: missing text row", $oldId ); } @@ -193,7 +225,8 @@ class CheckStorage { // Check external normal blobs for existence if ( count( $externalNormalBlobs ) ) { if ( is_null( $this->dbStore ) ) { - $this->dbStore = new ExternalStoreDB; + $esFactory = MediaWikiServices::getInstance()->getExternalStoreFactory(); + $this->dbStore = $esFactory->getStore( 'DB' ); } foreach ( $externalConcatBlobs as $cluster => $xBlobIds ) { $blobIds = array_keys( $xBlobIds ); @@ -370,13 +403,13 @@ class CheckStorage { if ( is_array( $ids ) ) { $revIds = []; foreach ( $ids as $id ) { - $revIds = array_merge( $revIds, array_keys( $this->oldIdMap, $id ) ); + $revIds = array_unique( array_merge( $revIds, $this->oldIdMap[$id] ) ); } print "$msg in text rows " . implode( ', ', $ids ) . ", revisions " . implode( ', ', $revIds ) . "\n"; } else { $id = $ids; - $revIds = array_keys( $this->oldIdMap, $id ); + $revIds = $this->oldIdMap[$id]; if ( count( $revIds ) == 1 ) { print "$msg in old_id $id, rev_id {$revIds[0]}\n"; } else { @@ -392,7 +425,8 @@ class CheckStorage { } if ( is_null( $this->dbStore ) ) { - $this->dbStore = new ExternalStoreDB; + $esFactory = MediaWikiServices::getInstance()->getExternalStoreFactory(); + $this->dbStore = $esFactory->getStore( 'DB' ); } foreach ( $externalConcatBlobs as $cluster => $oldIds ) { @@ -451,7 +485,7 @@ class CheckStorage { echo "Filtering XML dump...\n"; $exitStatus = 0; passthru( 'mwdumper ' . - wfEscapeShellArg( + Shell::escape( "--output=file:$filteredXmlFileName", "--filter=revlist:$revFileName", $xml @@ -490,7 +524,7 @@ class CheckStorage { function importRevision( &$revision, &$importer ) { $id = $revision->getID(); - $content = $revision->getContent( Revision::RAW ); + $content = $revision->getContent( RevisionRecord::RAW ); $id = $id ?: ''; if ( $content === null ) {