Page MenuHomePhabricator

mediawiki.page_change.v1 event - Add revision revert details
Open, Needs TriagePublic

Description

In 2019 in T216297: Develop method for identifying reverts in EventBus data, we added revert info into MediaWiki state change events.

But, in 2021 in T215001: Revisions missing from mediawiki_revision_create (T215001#6942373), EventBus was modified to use a MediaWiki hook that did not give us access to information about whether a revision was created because of a UI revert action.

In 2025 in T390970: EventBus: replace PageSaveCompleteHook with PageRevisionUpdateListener, mediawiki.page_change.v1 was switched to using DomainEvents. The Domain event used does have access to revert info.

This information is very useful, especially for T418032: Weekly delivery cadence of core contributor metrics.

Done is

  • mediawiki.page_change.v1 event stream has a revision.revert details

Details

Related Changes in Gerrit:
Related Changes in GitLab:
TitleReferenceAuthorSource BranchDest Branch
mediawiki/page/change - add rev_reverted_oldest_id and rev_reverted_newest_idrepos/data-engineering/schemas-event-primary!68ottopage_change_revert_infomaster
Remove rev_reverted_ids from all schema versions that referenced itrepos/data-engineering/schemas-event-primary!67ottoT423583_page_change_remove_rev_reverted_idsmaster
mediawiki/page/change - add revision.revert detailsrepos/data-engineering/schemas-event-primary!44ottopage_change_revert_infomaster
Customize query in GitLab

Event Timeline

Restricted Application added a subscriber: Aklapper. · View Herald Transcript

If feasible, there are other revert related information that would be useful:

  • Which revision is reverted?
  • The timestamp-diff between current revision (revert) and the reverted-revision.

Note: Joseph also would like it if we could get the list of revisions in between the current rev and the reverted-to-revision. This may be possible, but maybe also difficult / expensive in MW. TBD!

@xcollazo @Milimetric I was wrong about only UI revert info being available. It looks like we have a lot more!

@xcollazo @Milimetric I was wrong about only UI revert info being available. It looks like we have a lot more!

Looked at the draft MR, looks like we can mine that for DPE-MediaWiki-Incremental-History for sure!

Well, that is just a TBD schema right now! We'll see what MW let's me get, but I think all of that?

@xcollazo I'm not 100% sure, but my brief understanding is:

  • if a revert was done via a supported UI feature (undo, rollback, etc?) then MW knows about the revert and it doesn't matter how old the revision is.
  • if not, we can ask MW to detect if a revision is a revert, but it will only look back $wgManualRevertSearchRadius revisions. This defaults to 15, and I don't see a obvious WMF override.
  • Additionally, MediaWiki will only let us max $wgRevertedTagMaxDepth revision ids in between reverted-to and new reverting (are my terms correct?) revisions. So, if the reverted-to revision is very old, the rev_reverted_ids list will be incomplete, or we can't set it. We'll have to decide what to do there.

I'll need to verify this with some experts.

Alternatively, perhaps this info is in the existent mediawiki.revisions-tags-change stream? Maybe it is just tags so it isn't rich enough? Need to investigate.

Ottomata renamed this task from mediawiki.page_change.v1 event - Add revision is revert field to mediawiki.page_change.v1 event - Add revision revert details.May 11 2026, 2:33 AM
Ottomata updated the task description. (Show Details)

Mentioned in SAL (#wikimedia-operations) [2026-05-11T18:12:03Z] <ottomata> roll restarting eventgate-main to pick up changes for T423583

Mentioned in SAL (#wikimedia-operations) [2026-05-12T13:48:25Z] <ottomata> roll restart eventgate main to pick up mediawiki/page/change/1.4.0 schema version for T423583

It looks like in the effort of moving fast for T418032: Weekly delivery cadence of core contributor metrics, I merged mediawiki/page/change - add revision.revert details too quickly.

https://wikimedia.slack.com/archives/C05RHK7PS6Q/p1778598896610319?thread_ts=1778523101.461819&cid=C05RHK7PS6Q

rev_reverted_ids is both probably too expensive to get in page_change from MW, as well as it probably not being that useful for Incremental MediaWiki History, since there is a limit to the number of reverted rev ids that MW will detect.

I really don't want to introduce a vestigial field for a feature we'll never use. I'd like to make a backwards incompatible change to mediawiki/page/change schema. Nothing has set this field in prod yet except for canary events. I will have to:

  • merged incompatible schema change that removes revision.revert.rev_reverted_ids field
  • Manually alter Hive tables to remove revision.revert.rev_reverted_ids field for the tables downstream of these streams:
curl 'https://meta.wikimedia.org/w/api.php?action=streamconfigs&constraints=schema_title=mediawiki/page/change' | jq .streams[].stream
"mediawiki.page_change.v1"
"mediawiki.page_change.private.v1"
"mediawiki.page_content_change.v1"
"mediawiki.content_history_reconcile.v1"
"mediawiki.content_history_reconcile_enriched.v1"

I am pretty sure that I can remove revision.revert.rev_reverted_ids from the schema in a 1.5.0 version and nothing will break outright:

  • nothing is producing revision.revert yet; not even canary events because the explicit schema examples does not have this.
  • Nothing is producing any event data with mediawiki/page/change/1.4.0 (except for canary events).
  • The rev_reverted_ids field will remain in the hive tables until we remove but it will just be NULL.

So I can do the first steps and then manually alter Hive tables to remove vestigial stuff without urgency.

I'm considering adding a rev_reverted_oldest_id and rev_reverted_newest_id field since I have those ones explicitly via EditResult.

It looks like that without a full list of rev_reverted_ids, revision.revert info is not useful for T424350: Incremental MediaWiki History Phase I. Putting this on hold.

I will still resolve the vestigial field somehow...

Discussed with @tchin today. We considered

  • A. Do nothing. rev_reverted_ids remains vestigial and null forvever.
  • B. make a major version bump, or a backwards incompatible minor version bump. Upgrade all producers that use state/change/page fragment.
  • C. Rewrite versions in place to remove rev_reverted_ids field.

We think C. is actually the easiest and least fragile in this case. The procedure should be:

  1. remove rev_reverted_ids from all versioned and latest schema files. Merge.
  2. Restart all eventgate's that might have cached this field.
  3. ALTER all Hive tables with rev_reverted_ids to remove the field.

That should be it.

  • Hive tables should be the only place this field exists, and it should be null for all records.
  • Flink apps do use a schema version with rev_reverted_ids, but since they serialize null values by omitting the field, they won't ever output events that have this field. Until the next time the Flink app is restarted, it will use a cached version of the schema with rev_reverted_ids but there shouldn't be any noticeable effect.
  • The schemas will be outdated in any CDN caches, e.g. in https://schema.wikimedia.org/#!/, but we don't use the public endpoints in production, so the CDN is not in the read path.

I ran a dry_run EvolveHiveTable command with mediawiki/page/change/latest from MR !67 which removes rev_reverted_ids.

spark3-submit \
--class org.wikimedia.analytics.refinery.job.refine.cli.EvolveHiveTable \
/srv/deployment/analytics/refinery/artifacts/refinery-job-shaded.jar \
--table=event.mediawiki_page_change_v1 \
--schema_uri=/mediawiki/page/change/latest \
--dry_run=true \
--schema_base_uris=file:///home/otto/primary/jsonschema \
--timestamps_as_strings=true \
--location=hdfs:///wmf/data/event/mediawiki_page_change_v1 \
--partition_columns=datacenter:string,year:long,month:long,day:long,hour:long \
--transform_functions=org.wikimedia.analytics.refinery.job.refine.event_transforms

[...]
Table schema:
[...]
    |-- revert: struct (nullable = true)
    |    |-- is_exact: boolean (nullable = true)
    |    |-- method: string (nullable = true)
    |    |-- rev_original_dt: string (nullable = true)
    |    |-- rev_original_id: long (nullable = true)
    |    |-- rev_reverted_ids: array (nullable = true)
    |    |    |-- element: long (containsNull = true)




[...]
Input schema:
[...]
    |-- revert: struct (nullable = true)
    |    |-- is_exact: boolean (nullable = true)
    |    |-- method: string (nullable = true)
    |    |-- rev_original_dt: string (nullable = true)
    |    |-- rev_original_id: long (nullable = true)

FYI, it did say:

Alter statements:
ALTER TABLE event.mediawiki_page_change_v1
ADD COLUMNS (
`$schema` STRING
)

But I think that is unrelated and a consequence of me running EvolveHiveTable manually? The table schema has _schema and the event schema has $schema. In practice this should get normalized out? Anyway...I'm pretty sure this is unrelated.

The good news is that removing the field in the event schema will cause no changes to the Hive table, as expected.

Mentioned in SAL (#wikimedia-operations) [2026-06-30T14:54:21Z] <ottomata> roll restart eventgates to re-cache page_change related schemas - T423583#12067516

Schema is merged, eventgates restarted. So far so good.

Since we bumped schema versions for T421237: `mediawiki.page_change.v1`: negative namespace_id schema validation errors, there are now more Hive tables that will need altered:

event.mediawiki_page_change_v1
event.mediawiki_page_change_private_v1
event.mediawiki_page_content_change_v1
event.mediawiki_content_history_reconcile_enriched_v1
event.mediawiki_article_country_prediction_change_v1
event.mediawiki_page_revert_risk_prediction_change_v1
event.mediawiki_page_html_content_change_v1
event.mediawiki_page_html_feature_counts_change_v1

The HQL DDL to remove the rev_reverted_ids for tables that use mediawiki/page/change related field is

CHANGE COLUMN `revision` `revision` struct<
  comment:string,
  content_slots:map<string,struct<content_body:string,content_format:string,content_model:string,content_sha1:string,content_size:bigint,origin_rev_id:bigint,slot_role:string>>,
  editor:struct<edit_count:bigint,groups:array<string>,is_bot:boolean,is_system:boolean,is_temp:boolean,registration_dt:string,user_id:bigint,user_text:string,user_central_id:bigint,wiki_id:string,first_edit_dt:string>,
  is_comment_visible:boolean,
  is_content_visible:boolean,
  is_editor_visible:boolean,
  is_minor_edit:boolean,
  rev_dt:string,
  rev_id:bigint,
  rev_parent_id:bigint,
  rev_sha1:string,
  rev_size:bigint,
  revert:struct<is_exact:boolean,method:string,rev_original_dt:string,rev_original_id:bigint>
>;

The DDL will be slightly different for different schemas...

@tchin and I ran the following ALTERs for these tables:




--- feature counts change alters

ALTER TABLE `event.mediawiki_page_html_feature_counts_change_v1`
CHANGE COLUMN `revision` `revision` struct<
  comment:string,
  content_slots:map<string,struct<content_format:string,content_model:string,content_sha1:string,content_size:bigint,origin_rev_id:bigint,slot_role:string>>,
  editor:struct<edit_count:bigint,groups:array<string>,is_bot:boolean,is_system:boolean,is_temp:boolean,registration_dt:string,user_central_id:bigint,user_id:bigint,user_text:string,wiki_id:string>,
  is_comment_visible:boolean,
  is_content_visible:boolean,
  is_editor_visible:boolean,
  is_minor_edit:boolean,
  rendering:struct<content:struct<content_language:string,content_length:bigint,content_type:string,content_uri:string>,render_dt:string,render_flavor:string,render_id:string>,
  rev_dt:string,
  rev_id:bigint,
  rev_parent_id:bigint,
  rev_sha1:string,
  rev_size:bigint,
  revert:struct<is_exact:boolean,method:string,rev_original_dt:string,rev_original_id:bigint>
>;




--- rendering content change alters

ALTER TABLE `event.mediawiki_page_html_content_change_v1`
CHANGE COLUMN `revision` `revision` struct<
  comment:string,
  content_slots:map<string,struct<content_format:string,content_model:string,content_sha1:string,content_size:bigint,origin_rev_id:bigint,slot_role:string>>,
  editor:struct<edit_count:bigint,groups:array<string>,is_bot:boolean,is_system:boolean,is_temp:boolean,registration_dt:string,user_central_id:bigint,user_id:bigint,user_text:string,wiki_id:string>,
  is_comment_visible:boolean,
  is_content_visible:boolean,
  is_editor_visible:boolean,
  is_minor_edit:boolean,
  rendering:struct<content:struct<content_body:string,content_language:string,content_length:bigint,content_type:string,content_uri:string>,render_dt:string,render_flavor:string,render_id:string>,
  rev_dt:string,
  rev_id:bigint,
  rev_parent_id:bigint,
  rev_sha1:string,
  rev_size:bigint,
  revert:struct<is_exact:boolean,method:string,rev_original_dt:string,rev_original_id:bigint>
>;


--- mediawiki/page/change alters

ALTER TABLE `event.mediawiki_page_change_v1`
CHANGE COLUMN `revision` `revision` struct<
  comment:string,
  content_slots:map<string,struct<content_body:string,content_format:string,content_model:string,content_sha1:string,content_size:bigint,origin_rev_id:bigint,slot_role:string>>,
  editor:struct<edit_count:bigint,groups:array<string>,is_bot:boolean,is_system:boolean,is_temp:boolean,registration_dt:string,user_id:bigint,user_text:string,user_central_id:bigint,wiki_id:string,first_edit_dt:string>,
  is_comment_visible:boolean,
  is_content_visible:boolean,
  is_editor_visible:boolean,
  is_minor_edit:boolean,
  rev_dt:string,
  rev_id:bigint,
  rev_parent_id:bigint,
  rev_sha1:string,
  rev_size:bigint,
  revert:struct<is_exact:boolean,method:string,rev_original_dt:string,rev_original_id:bigint>
>;


ALTER TABLE `event.mediawiki_page_change_private_v1`
CHANGE COLUMN `revision` `revision` struct<
  comment:string,
  content_slots:map<string,struct<content_body:string,content_format:string,content_model:string,content_sha1:string,content_size:bigint,origin_rev_id:bigint,slot_role:string>>,
  editor:struct<edit_count:bigint,groups:array<string>,is_bot:boolean,is_system:boolean,is_temp:boolean,registration_dt:string,user_id:bigint,user_text:string,user_central_id:bigint,wiki_id:string,first_edit_dt:string>,
  is_comment_visible:boolean,
  is_content_visible:boolean,
  is_editor_visible:boolean,
  is_minor_edit:boolean,
  rev_dt:string,
  rev_id:bigint,
  rev_parent_id:bigint,
  rev_sha1:string,
  rev_size:bigint,
  revert:struct<is_exact:boolean,method:string,rev_original_dt:string,rev_original_id:bigint>
>;


ALTER TABLE `event.mediawiki_page_content_change_v1`
CHANGE COLUMN `revision` `revision` struct<
  comment:string,
  content_slots:map<string,struct<content_body:string,content_format:string,content_model:string,content_sha1:string,content_size:bigint,origin_rev_id:bigint,slot_role:string>>,
  editor:struct<edit_count:bigint,groups:array<string>,is_bot:boolean,is_system:boolean,is_temp:boolean,registration_dt:string,user_id:bigint,user_text:string,user_central_id:bigint,wiki_id:string,first_edit_dt:string>,
  is_comment_visible:boolean,
  is_content_visible:boolean,
  is_editor_visible:boolean,
  is_minor_edit:boolean,
  rev_dt:string,
  rev_id:bigint,
  rev_parent_id:bigint,
  rev_sha1:string,
  rev_size:bigint,
  revert:struct<is_exact:boolean,method:string,rev_original_dt:string,rev_original_id:bigint>
>;


ALTER TABLE `event.mediawiki_content_history_reconcile_enriched_v1`
CHANGE COLUMN `revision` `revision` struct<
  comment:string,
  content_slots:map<string,struct<content_body:string,content_format:string,content_model:string,content_sha1:string,content_size:bigint,origin_rev_id:bigint,slot_role:string>>,
  editor:struct<edit_count:bigint,groups:array<string>,is_bot:boolean,is_system:boolean,is_temp:boolean,registration_dt:string,user_id:bigint,user_text:string,user_central_id:bigint,wiki_id:string,first_edit_dt:string>,
  is_comment_visible:boolean,
  is_content_visible:boolean,
  is_editor_visible:boolean,
  is_minor_edit:boolean,
  rev_dt:string,
  rev_id:bigint,
  rev_parent_id:bigint,
  rev_sha1:string,
  rev_size:bigint,
  revert:struct<is_exact:boolean,method:string,rev_original_dt:string,rev_original_id:bigint>
>;


--- prediction classification change alters


ALTER TABLE `event.mediawiki_article_country_prediction_change_v1`
CHANGE COLUMN `revision` `revision` struct<
  comment:string,
  editor:struct<edit_count:bigint,groups:array<string>,is_bot:boolean,is_system:boolean,is_temp:boolean,registration_dt:string,user_id:bigint,user_text:string,user_central_id:bigint,wiki_id:string>,
  is_comment_visible:boolean,
  is_content_visible:boolean,
  is_editor_visible:boolean,
  is_minor_edit:boolean,
  rev_dt:string,
  rev_id:bigint,
  rev_parent_id:bigint,
  rev_sha1:string,
  rev_size:bigint,
  revert:struct<is_exact:boolean,method:string,rev_original_dt:string,rev_original_id:bigint>
>;

ALTER TABLE `event.mediawiki_page_revert_risk_prediction_change_v1`
CHANGE COLUMN `revision` `revision` struct<
  comment:string,
  editor:struct<edit_count:bigint,groups:array<string>,is_bot:boolean,is_system:boolean,is_temp:boolean,registration_dt:string,user_id:bigint,user_text:string,user_central_id:bigint,wiki_id:string>,
  is_comment_visible:boolean,
  is_content_visible:boolean,
  is_editor_visible:boolean,
  is_minor_edit:boolean,
  rev_dt:string,
  rev_id:bigint,
  rev_parent_id:bigint,
  rev_sha1:string,
  rev_size:bigint,
  revert:struct<is_exact:boolean,method:string,rev_original_dt:string,rev_original_id:bigint>
>;

Change #1306748 had a related patch set uploaded (by Ottomata; author: Ottomata):

[mediawiki/extensions/EventBus@master] page_change - add revision.revert info

https://gerrit.wikimedia.org/r/1306748

Change #1306748 merged by jenkins-bot:

[mediawiki/extensions/EventBus@master] page_change - add revision.revert info

https://gerrit.wikimedia.org/r/1306748

Change #1307000 had a related patch set uploaded (by Ottomata; author: Ottomata):

[mediawiki/extensions/EventBus@master] page_change - add rev_reverted_oldest_id and rev_reverted_newest_id

https://gerrit.wikimedia.org/r/1307000

@tchin

T423583#11914122

I forgot I wanted to add oldest and newest reverted rev ids. Done in the patches I just added you as reviewer to. Thank you!

Change #1307000 merged by jenkins-bot:

[mediawiki/extensions/EventBus@master] page_change - add rev_reverted_oldest_id and rev_reverted_newest_id

https://gerrit.wikimedia.org/r/1307000

Tested and works in beta!
Did some manual edits and a manual revert and the rev_reverted_*id values are as expected.

revert:
  method: manual
  is_exact: true
  rev_original_id: 4085
  rev_original_dt: 2026-07-02T17:02:10Z
  rev_reverted_oldest_id: 4086
  rev_reverted_newest_id: 4088

Presto is erroring on some of these tables when reading partitions where rev_reverted_ids existed.
E.g.

presto error: There is a mismatch between the table and partition schemas. The types are incompatible and cannot be coerced. The column 'revision' in table 'event.mediawiki_article_country_prediction_change_v1' is declared as type 'struct<comment:string,editor:struct<edit_count:bigint,groups:array<string>,is_bot:boolean,is_system:boolean,is_temp:boolean,registration_dt:string,user_id:bigint,user_text:string,user_central_id:bigint,wiki_id:string>,is_comment_visible:boolean,is_content_visible:boolean,is_editor_visible:boolean,is_minor_edit:boolean,rev_dt:string,rev_id:bigint,rev_parent_id:bigint,rev_sha1:string,rev_size:bigint,revert:struct<is_exact:boolean,method:string,rev_original_dt:string,rev_original_id:bigint>>', but partition 'datacenter=eqiad/year=2026/month=6/day=30/hour=15' declared column 'revision' as type 'struct<comment:string,content_slots:map<string,struct<content_body:string,content_format:string,content_model:string,content_sha1:string,content_size:bigint,origin_rev_id:bigint,slot_role:string>>,editor:struct<edit_count:bigint,groups:array<string>,is_bot:boolean,is_system:boolean,is_temp:boolean,registration_dt:string,user_id:bigint,user_text:string,user_central_id:bigint,wiki_id:string,first_edit_dt:string>,is_comment_visible:boolean,is_content_visible:boolean,is_editor_visible:boolean,is_minor_edit:boolean,rev_dt:string,rev_id:bigint,rev_parent_id:bigint,rev_sha1:string,rev_size:bigint,revert:struct<is_exact:boolean,method:string,rev_original_dt:string,rev_original_id:bigint>>'.

I tried few things to fix, including rerunning the ALTER statements with CASCADE, but I think it is quite likely I messed something up along the way. A blunter and more complete approach is to DROP the relevant partitions and re-add them. This causes those old partitions to be recreated with the current table schema version.

These tables had presto errors:

  • event.mediawiki_page_change_v1
  • event.mediawiki_page_change_private_v1
  • event.mediawiki_page_content_change_v1
  • event.mediawiki_article_country_prediction_change_v1
  • event.mediawiki_content_history_reconcile_enriched_v1

I tried to drop the partitions and then run MSCK REPAIR TABLE, but got an error there too:

FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask

I'm short on time so I didn't investigate why MSCK REPAIR TABLE didn't work.

Instead, I generated ADD PARTITION statements for each dropped partition in months 5 and 6. I've attached the 5 HQL files I used to do this.
I ran each with a command like hive --service cli -f <file.hql>

Presto is working for month=6 now.

Slack thread link.