* @since 1.32
* @var int One of the MIGRATION_* constants
*/
-$wgChangeTagsSchemaMigrationStage = MIGRATION_OLD;
+$wgChangeTagsSchemaMigrationStage = MIGRATION_WRITE_BOTH;
/**
* Temporarily flag to use change_tag_def table as backend of change tag statistics.
[ 'addIndex', 'site_identifiers', 'PRIMARY', 'patch-site_identifiers-pk.sql' ],
[ 'addIndex', 'recentchanges', 'rc_this_oldid', 'patch-recentchanges-rc_this_oldid-index.sql' ],
[ 'dropTable', 'transcache' ],
+ [ 'runMaintenance', PopulateChangeTagDef::class, 'maintenance/populateChangeTagDef.php' ],
+ [ 'addIndex', 'change_tag', 'change_tag_rc_tag_id',
+ 'patch-change_tag-change_tag_rc_tag_id.sql' ],
];
}
[ 'doLogUsertextPopulation' ],
[ 'doLogSearchPopulation' ],
[ 'addTable', 'l10n_cache', 'patch-l10n_cache.sql' ],
- [ 'addIndex', 'change_tag', 'change_tag_rc_tag', 'patch-change_tag-indexes.sql' ],
+ [ 'addIndex', 'tag_summary', 'tag_summary_rc_id', 'patch-change_tag-indexes.sql' ],
[ 'addField', 'redirect', 'rd_interwiki', 'patch-rd_interwiki.sql' ],
[ 'doUpdateMimeMinorField' ],
'patch-site_identifiers-fix-pk.sql' ],
[ 'addIndex', 'recentchanges', 'rc_this_oldid', 'patch-recentchanges-rc_this_oldid-index.sql' ],
[ 'dropTable', 'transcache' ],
+ [ 'runMaintenance', PopulateChangeTagDef::class, 'maintenance/populateChangeTagDef.php' ],
+ [ 'addIndex', 'change_tag', 'change_tag_rc_tag_id',
+ 'patch-change_tag-change_tag_rc_tag_id.sql' ],
];
}
[ 'populateContentTables' ],
[ 'addIndex', 'recentchanges', 'rc_this_oldid', 'patch-recentchanges-rc_this_oldid-index.sql' ],
[ 'dropTable', 'transcache' ],
+ [ 'runMaintenance', PopulateChangeTagDef::class, 'maintenance/populateChangeTagDef.php' ],
+ [ 'addIndex', 'change_tag', 'change_tag_i03',
+ 'patch-change_tag-change_tag_rc_tag_id.sql' ],
// KEEP THIS AT THE BOTTOM!!
[ 'doRebuildDuplicateFunction' ],
[ 'addIndex', 'site_identifiers', 'site_identifiers_pkey', 'patch-site_identifiers-pk.sql' ],
[ 'addPgIndex', 'recentchanges', 'rc_this_oldid', '(rc_this_oldid)' ],
[ 'dropTable', 'transcache' ],
+ [ 'runMaintenance', PopulateChangeTagDef::class, 'maintenance/populateChangeTagDef.php' ],
+ [ 'addIndex', 'change_tag', 'change_tag_rc_tag_id',
+ 'patch-change_tag-change_tag_rc_tag_id.sql' ],
];
}
[ 'doLogUsertextPopulation' ],
[ 'doLogSearchPopulation' ],
[ 'addTable', 'l10n_cache', 'patch-l10n_cache.sql' ],
- [ 'addIndex', 'change_tag', 'change_tag_rc_tag', 'patch-change_tag-indexes.sql' ],
+ [ 'addIndex', 'tag_summary', 'tag_summary_rc_id', 'patch-change_tag-indexes.sql' ],
[ 'addField', 'redirect', 'rd_interwiki', 'patch-rd_interwiki.sql' ],
[ 'sqliteSetupSearchindex' ],
'patch-site_identifiers-fix-pk.sql' ],
[ 'addIndex', 'recentchanges', 'rc_this_oldid', 'patch-recentchanges-rc_this_oldid-index.sql' ],
[ 'dropTable', 'transcache' ],
+ [ 'runMaintenance', PopulateChangeTagDef::class, 'maintenance/populateChangeTagDef.php' ],
+ [ 'addIndex', 'change_tag', 'change_tag_rc_tag_id',
+ 'patch-change_tag-change_tag_rc_tag_id.sql' ],
];
}
--- /dev/null
+-- T193874: Add new indexes to change_tag table using ct_tag_id instead of ct_tag
+
+CREATE UNIQUE INDEX /*i*/change_tag_rc_tag_id ON /*_*/change_tag (ct_rc_id,ct_tag_id);
+CREATE UNIQUE INDEX /*i*/change_tag_log_tag_id ON /*_*/change_tag (ct_log_id,ct_tag_id);
+CREATE UNIQUE INDEX /*i*/change_tag_rev_tag_id ON /*_*/change_tag (ct_rev_id,ct_tag_id);
+
+CREATE INDEX /*i*/change_tag_rc_tag_nonuniq ON /*_*/change_tag (ct_rc_id,ct_tag);
+CREATE INDEX /*i*/change_tag_log_tag_nonuniq ON /*_*/change_tag (ct_log_id,ct_tag);
+CREATE INDEX /*i*/change_tag_rev_tag_nonuniq ON /*_*/change_tag (ct_rev_id,ct_tag);
+
+DROP INDEX /*i*/change_tag_rc_tag ON /*_*/change_tag;
+DROP INDEX /*i*/change_tag_log_tag ON /*_*/change_tag;
+DROP INDEX /*i*/change_tag_rev_tag ON /*_*/change_tag;
+
+ALTER TABLE /*i*/change_tag
+ ALTER COLUMN ct_tag SET DEFAULT '';
\ No newline at end of file
--- /dev/null
+-- T193874: Add new indexes to change_tag table using ct_tag_id instead of ct_tag
+
+CREATE UNIQUE INDEX /*i*/change_tag_rc_tag_id ON /*_*/change_tag (ct_rc_id,ct_tag_id);
+CREATE UNIQUE INDEX /*i*/change_tag_log_tag_id ON /*_*/change_tag (ct_log_id,ct_tag_id);
+CREATE UNIQUE INDEX /*i*/change_tag_rev_tag_id ON /*_*/change_tag (ct_rev_id,ct_tag_id);
+
+CREATE INDEX /*i*/change_tag_rc_tag_nonuniq ON /*_*/change_tag (ct_rc_id,ct_tag);
+CREATE INDEX /*i*/change_tag_log_tag_nonuniq ON /*_*/change_tag (ct_log_id,ct_tag);
+CREATE INDEX /*i*/change_tag_rev_tag_nonuniq ON /*_*/change_tag (ct_rev_id,ct_tag);
+
+DROP INDEX /*i*/change_tag_rc_tag ON /*_*/change_tag;
+DROP INDEX /*i*/change_tag_log_tag ON /*_*/change_tag;
+DROP INDEX /*i*/change_tag_rev_tag ON /*_*/change_tag;
+
+ALTER TABLE /*i*/change_tag
+ ADD CONSTRAINT DF_ct_tag DEFAULT '' FOR ct_tag;
\ No newline at end of file
-- REVID for the change
ct_rev_id int NULL REFERENCES /*_*/revision(rev_id),
-- Tag applied
- ct_tag nvarchar(255) NOT NULL,
+ ct_tag nvarchar(255) NOT NULL default '',
-- Parameters for the tag, presently unused
ct_params nvarchar(max) NULL,
-- Foreign key to change_tag_def row
ct_tag_id int NULL CONSTRAINT ctd_tag_id__fk FOREIGN KEY REFERENCES /*_*/change_tag_def(ctd_id)
);
-CREATE UNIQUE INDEX /*i*/change_tag_rc_tag ON /*_*/change_tag (ct_rc_id,ct_tag);
-CREATE UNIQUE INDEX /*i*/change_tag_log_tag ON /*_*/change_tag (ct_log_id,ct_tag);
-CREATE UNIQUE INDEX /*i*/change_tag_rev_tag ON /*_*/change_tag (ct_rev_id,ct_tag);
+CREATE INDEX /*i*/change_tag_rc_tag_nonuniq ON /*_*/change_tag (ct_rc_id,ct_tag);
+CREATE INDEX /*i*/change_tag_log_tag_nonuniq ON /*_*/change_tag (ct_log_id,ct_tag);
+CREATE INDEX /*i*/change_tag_rev_tag_nonuniq ON /*_*/change_tag (ct_rev_id,ct_tag);
+
+CREATE UNIQUE INDEX /*i*/change_tag_rc_tag_id ON /*_*/change_tag (ct_rc_id,ct_tag_id);
+CREATE UNIQUE INDEX /*i*/change_tag_log_tag_id ON /*_*/change_tag (ct_log_id,ct_tag_id);
+CREATE UNIQUE INDEX /*i*/change_tag_rev_tag_id ON /*_*/change_tag (ct_rev_id,ct_tag_id);
+
-- Covering index, so we can pull all the info only out of the index.
CREATE INDEX /*i*/change_tag_tag_id ON /*_*/change_tag (ct_tag,ct_rc_id,ct_rev_id,ct_log_id);
CREATE INDEX /*i*/change_tag_tag_id_id ON /*_*/change_tag (ct_tag_id,ct_rc_id,ct_rev_id,ct_log_id);
--- /dev/null
+-- T193874: Add new indexes to change_tag table using ct_tag_id instead of ct_tag
+
+define mw_prefix='{$wgDBprefix}';
+
+CREATE UNIQUE INDEX &mw_prefix.change_tag_u04 ON &mw_prefix.change_tag (ct_rc_id,ct_tag_id);
+CREATE UNIQUE INDEX &mw_prefix.change_tag_u05 ON &mw_prefix.change_tag (ct_log_id,ct_tag_id);
+CREATE UNIQUE INDEX &mw_prefix.change_tag_u06 ON &mw_prefix.change_tag (ct_rev_id,ct_tag_id);
+
+CREATE INDEX &mw_prefix.change_tag_i03 ON &mw_prefix.change_tag (ct_rc_id,ct_tag);
+CREATE INDEX &mw_prefix.change_tag_i04 ON &mw_prefix.change_tag (ct_log_id,ct_tag);
+CREATE INDEX &mw_prefix.change_tag_i05 ON &mw_prefix.change_tag (ct_rev_id,ct_tag);
+
+DROP INDEX &mw_prefix.change_tag_u01;
+DROP INDEX &mw_prefix.change_tag_u02;
+DROP INDEX &mw_prefix.change_tag_u03;
+
+ALTER TABLE &mw_prefix.change_tag
+ MODIFY ct_tag DEFAULT '///invalid///';
\ No newline at end of file
ct_rc_id NUMBER NULL,
ct_log_id NUMBER NULL,
ct_rev_id NUMBER NULL,
- ct_tag VARCHAR2(255) NOT NULL,
+ ct_tag VARCHAR2(255) DEFAULT '///invalid///' NOT NULL,
ct_params BLOB NULL,
- ct_tag_id NUMBER NULL,
+ ct_tag_id NUMBER NULL
);
ALTER TABLE &mw_prefix.change_tag ADD CONSTRAINT &mw_prefix.change_tag_pk PRIMARY KEY (ct_id);
-CREATE UNIQUE INDEX &mw_prefix.change_tag_u01 ON &mw_prefix.change_tag (ct_rc_id,ct_tag);
-CREATE UNIQUE INDEX &mw_prefix.change_tag_u02 ON &mw_prefix.change_tag (ct_log_id,ct_tag);
-CREATE UNIQUE INDEX &mw_prefix.change_tag_u03 ON &mw_prefix.change_tag (ct_rev_id,ct_tag);
+
+CREATE INDEX &mw_prefix.change_tag_i03 ON &mw_prefix.change_tag (ct_rc_id,ct_tag);
+CREATE INDEX &mw_prefix.change_tag_i04 ON &mw_prefix.change_tag (ct_log_id,ct_tag);
+CREATE INDEX &mw_prefix.change_tag_i05 ON &mw_prefix.change_tag (ct_rev_id,ct_tag);
+
+CREATE UNIQUE INDEX &mw_prefix.change_tag_u04 ON &mw_prefix.change_tag (ct_rc_id,ct_tag_id);
+CREATE UNIQUE INDEX &mw_prefix.change_tag_u05 ON &mw_prefix.change_tag (ct_log_id,ct_tag_id);
+CREATE UNIQUE INDEX &mw_prefix.change_tag_u06 ON &mw_prefix.change_tag (ct_rev_id,ct_tag_id);
+
CREATE INDEX &mw_prefix.change_tag_i01 ON &mw_prefix.change_tag (ct_tag,ct_rc_id,ct_rev_id,ct_log_id);
CREATE INDEX &mw_prefix.change_tag_i02 ON &mw_prefix.change_tag (ct_tag_id,ct_rc_id,ct_rev_id,ct_log_id);
*
* @ingroup Maintenance
*/
-class PopulateChangeTagDef extends Maintenance {
+class PopulateChangeTagDef extends LoggedUpdateMaintenance {
/** @var Wikimedia\Rdbms\ILBFactory */
protected $lbFactory;
public function execute() {
global $wgChangeTagsSchemaMigrationStage;
+ if ( $wgChangeTagsSchemaMigrationStage === MIGRATION_OLD ) {
+ // Return "success", but don't flag it as done so the next run will retry
+ $this->output( '... Not run, $wgChangeTagsSchemaMigrationStage === MIGRATION_OLD' . "\n" );
+ return true;
+ }
+ return parent::execute();
+ }
+
+ protected function doDBUpdates() {
$this->lbFactory = MediaWiki\MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
$this->setBatchSize( $this->getOption( 'batch-size', $this->getBatchSize() ) );
- $this->countDown( 5 );
- if ( $wgChangeTagsSchemaMigrationStage < MIGRATION_NEW ) {
+ if ( $this->lbFactory->getMainLB()->getConnection( DB_REPLICA )->fieldExists(
+ 'change_tag',
+ 'ct_tag',
+ __METHOD__
+ )
+ ) {
if ( !$this->hasOption( 'populate-only' ) ) {
$this->updateCountTag();
}
// TODO: Implement
// $this->cleanZeroCountRows();
+
+ return true;
}
private function updateCountTagId() {
$this->output( "Finished adding ct_tag_id = {$tagId} for ct_tag = {$tagName}\n" );
}
+ protected function getUpdateKey() {
+ return __CLASS__;
+ }
}
$maintClass = PopulateChangeTagDef::class;
--- /dev/null
+-- T193874: Add new indexes to change_tag table using ct_tag_id instead of ct_tag
+
+CREATE UNIQUE INDEX /*i*/change_tag_rc_tag_id ON /*_*/change_tag (ct_rc_id,ct_tag_id);
+CREATE UNIQUE INDEX /*i*/change_tag_log_tag_id ON /*_*/change_tag (ct_log_id,ct_tag_id);
+CREATE UNIQUE INDEX /*i*/change_tag_rev_tag_id ON /*_*/change_tag (ct_rev_id,ct_tag_id);
+
+CREATE INDEX /*i*/change_tag_rc_tag_nonuniq ON /*_*/change_tag (ct_rc_id,ct_tag);
+CREATE INDEX /*i*/change_tag_log_tag_nonuniq ON /*_*/change_tag (ct_log_id,ct_tag);
+CREATE INDEX /*i*/change_tag_rev_tag_nonuniq ON /*_*/change_tag (ct_rev_id,ct_tag);
+
+DROP INDEX /*i*/change_tag_rc_tag;
+DROP INDEX /*i*/change_tag_log_tag;
+DROP INDEX /*i*/change_tag_rev_tag;
+
+ALTER TABLE /*i*/change_tag
+ ALTER COLUMN ct_tag SET DEFAULT '';
\ No newline at end of file
ct_rc_id INTEGER NULL,
ct_log_id INTEGER NULL,
ct_rev_id INTEGER NULL,
- ct_tag TEXT NOT NULL,
+ ct_tag TEXT NOT NULL DEFAULT '',
ct_params TEXT NULL,
ct_tag_id INTEGER NULL
);
ALTER SEQUENCE change_tag_ct_id_seq OWNED BY change_tag.ct_id;
-CREATE UNIQUE INDEX change_tag_rc_tag ON change_tag(ct_rc_id,ct_tag);
-CREATE UNIQUE INDEX change_tag_log_tag ON change_tag(ct_log_id,ct_tag);
-CREATE UNIQUE INDEX change_tag_rev_tag ON change_tag(ct_rev_id,ct_tag);
+
+CREATE INDEX change_tag_rc_tag_nonuniq ON change_tag(ct_rc_id,ct_tag);
+CREATE INDEX change_tag_log_tag_nonuniq ON change_tag(ct_log_id,ct_tag);
+CREATE INDEX change_tag_rev_tag_nonuniq ON change_tag(ct_rev_id,ct_tag);
+
+CREATE UNIQUE INDEX change_tag_rc_tag_id ON change_tag(ct_rc_id,ct_tag_id);
+CREATE UNIQUE INDEX change_tag_log_tag_id ON change_tag(ct_log_id,ct_tag_id);
+CREATE UNIQUE INDEX change_tag_rev_tag_id ON change_tag(ct_rev_id,ct_tag_id);
+
CREATE INDEX change_tag_tag_id ON change_tag(ct_tag,ct_rc_id,ct_rev_id,ct_log_id);
CREATE INDEX change_tag_tag_id_id ON change_tag(ct_tag_id,ct_rc_id,ct_rev_id,ct_log_id);
--- /dev/null
+-- T193874: Add new indexes to change_tag table using ct_tag_id instead of ct_tag
+BEGIN TRANSACTION;
+
+DROP TABLE IF EXISTS /*_*/change_tag_tmp;
+
+CREATE TABLE /*_*/change_tag_tmp (
+ ct_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ ct_rc_id int NULL,
+ ct_log_id int unsigned NULL,
+ ct_rev_id int unsigned NULL,
+ ct_tag varchar(255) NOT NULL default '',
+ ct_params blob NULL,
+ ct_tag_id int unsigned NULL
+) /*$wgDBTableOptions*/ MAX_ROWS=10000000 AVG_ROW_LENGTH=1024;
+
+INSERT OR IGNORE INTO /*_*/change_tag_tmp (ct_id, ct_rc_id, ct_log_id, ct_rev_id, ct_tag, ct_params, ct_tag_id)
+ SELECT
+ ct_id, ct_rc_id, ct_log_id, ct_rev_id, ct_tag, ct_params, ct_tag_id
+ FROM /*_*/change_tag;
+
+DROP TABLE /*_*/change_tag;
+
+ALTER TABLE /*_*/change_tag_tmp RENAME TO /*_*/change_tag;
+
+CREATE INDEX /*i*/change_tag_rc_tag_nonuniq ON /*_*/change_tag (ct_rc_id,ct_tag);
+CREATE INDEX /*i*/change_tag_log_tag_nonuniq ON /*_*/change_tag (ct_log_id,ct_tag);
+CREATE INDEX /*i*/change_tag_rev_tag_nonuniq ON /*_*/change_tag (ct_rev_id,ct_tag);
+CREATE UNIQUE INDEX /*i*/change_tag_rc_tag_id ON /*_*/change_tag (ct_rc_id,ct_tag_id);
+CREATE UNIQUE INDEX /*i*/change_tag_log_tag_id ON /*_*/change_tag (ct_log_id,ct_tag_id);
+CREATE UNIQUE INDEX /*i*/change_tag_rev_tag_id ON /*_*/change_tag (ct_rev_id,ct_tag_id);
+CREATE INDEX /*i*/change_tag_tag_id ON /*_*/change_tag (ct_tag,ct_rc_id,ct_rev_id,ct_log_id);
+CREATE INDEX /*i*/change_tag_tag_id_id ON /*_*/change_tag (ct_tag_id,ct_rc_id,ct_rev_id,ct_log_id);
+
+COMMIT;
\ No newline at end of file
-- REVID for the change
ct_rev_id int unsigned NULL,
-- Tag applied, this will go away and be replaced with ct_tag_id
- ct_tag varchar(255) NOT NULL,
+ ct_tag varchar(255) NOT NULL default '',
-- Parameters for the tag; used by some extensions
ct_params blob NULL,
-- Foreign key to change_tag_def row, this will be "NOT NULL" once populated
ct_tag_id int unsigned NULL
) /*$wgDBTableOptions*/;
-CREATE UNIQUE INDEX /*i*/change_tag_rc_tag ON /*_*/change_tag (ct_rc_id,ct_tag);
-CREATE UNIQUE INDEX /*i*/change_tag_log_tag ON /*_*/change_tag (ct_log_id,ct_tag);
-CREATE UNIQUE INDEX /*i*/change_tag_rev_tag ON /*_*/change_tag (ct_rev_id,ct_tag);
+CREATE INDEX /*i*/change_tag_rc_tag_nonuniq ON /*_*/change_tag (ct_rc_id,ct_tag);
+CREATE INDEX /*i*/change_tag_log_tag_nonuniq ON /*_*/change_tag (ct_log_id,ct_tag);
+CREATE INDEX /*i*/change_tag_rev_tag_nonuniq ON /*_*/change_tag (ct_rev_id,ct_tag);
+
+CREATE UNIQUE INDEX /*i*/change_tag_rc_tag_id ON /*_*/change_tag (ct_rc_id,ct_tag_id);
+CREATE UNIQUE INDEX /*i*/change_tag_log_tag_id ON /*_*/change_tag (ct_log_id,ct_tag_id);
+CREATE UNIQUE INDEX /*i*/change_tag_rev_tag_id ON /*_*/change_tag (ct_rev_id,ct_tag_id);
-- Covering index, so we can pull all the info only out of the index.
CREATE INDEX /*i*/change_tag_tag_id ON /*_*/change_tag (ct_tag,ct_rc_id,ct_rev_id,ct_log_id);
CREATE INDEX /*i*/change_tag_tag_id_id ON /*_*/change_tag (ct_tag_id,ct_rc_id,ct_rev_id,ct_log_id);
public function setUp() {
parent::setUp();
- $this->tablesUsed = [ 'change_tag', 'change_tag_def' ];
+ $this->tablesUsed = [ 'change_tag', 'change_tag_def', 'updatelog' ];
$this->cleanChangeTagTables();
$this->insertChangeTagData();
private function cleanChangeTagTables() {
wfGetDB( DB_MASTER )->delete( 'change_tag', '*' );
wfGetDB( DB_MASTER )->delete( 'change_tag_def', '*' );
+ wfGetDB( DB_MASTER )->delete( 'updatelog', '*' );
}
private function insertChangeTagData() {