Page MenuHomePhabricator

Add log_id to wmf.mediawiki_history
Closed, ResolvedPublic

Description

Summary

Propagate source_log_id from PageState/UserState through MediawikiEvent.fromPageState/fromUserState into the final denormalized wmf.mediawiki_history table as a new nullable BIGINT column event_log_id.

log_id is the natural key for all page and user events in MediaWiki — every move, delete, restore, rename, block, and account-creation corresponds to exactly one row in the logging table identified by (wiki_db, log_id). It flows into the intermediate page_history/ and user_history/ Parquet files (as source_log_id on PageState/UserState) but was stripped during denormalization. This task closes that gap.

event_log_id will be NULL for revision rows, which use revision_id as their identity column.

Changes

1. analytics/refinery/source — propagate through denormalization

  • Add eventLogId: Option[Long] to MediawikiEvent (position 1 in schema, after wiki_db)
  • Populate from state.sourceLogId in fromPageState / fromUserState
  • Explicit None in both fromRevisionRow constructors

2. analytics/refinery — DDL update

  • Add event_log_id BIGINT column to create_mediawiki_history_table.hql

Validation and getting changes to prod

  • First run it myself and write to xcollazo database. Compare output to prod data at wmf, make sure it looks good.
  • If everything looks ok, then merge the changes, release refinery and refinery source.
  • Since table is EXTERNAL, then just DROP TABLLE and then CREATE again with new schema.
  • Rerun DAG for this month.

Relationship to incremental pipeline (T424350)

Once event_log_id is available in wmf.mediawiki_history, the monthly SnapshotMerger can use it as the MERGE key for page and user entity rows:

ON  t.wiki_db = s.wiki_db
AND (
      (s.revision_id  IS NOT NULL AND t.revision_id  = s.revision_id)
   OR (s.event_log_id IS NOT NULL AND t.event_log_id = s.event_log_id)
)

Full page/user entity support in the daily DeltaWriter also requires log_id in the page_change_v1 event stream — tracked on T425996: Add log_id to mediawiki page_change and user_change events.

Related Objects

Event Timeline

  1. Add log_id to mediawiki.page_change event schema

@daniel this would be very simple if we can "Include_LogEntry_objects_in_events" :) Reading that makes me think it is a difficult ask.

The priority of T424350 is quite high (this quarter). We can probably work around this somehow, but if we could easily do it then I would help get it done! What do you think?

Change #1285903 had a related patch set uploaded (by Xcollazo; author: Xcollazo):

[analytics/refinery@master] Add event_log_id to mediawiki_history DDL

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

Change #1285904 had a related patch set uploaded (by Xcollazo; author: Xcollazo):

[analytics/refinery/source@master] Add event_log_id to wmf.mediawiki_history (T425986)

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

xcollazo renamed this task from Add log_id to mediawiki.page_change event schema and wmf.mediawiki_history to Add log_id to wmf.mediawiki_history.May 11 2026, 8:47 PM
xcollazo changed the task status from Open to In Progress.
xcollazo triaged this task as High priority.
xcollazo updated the task description. (Show Details)
  1. Add log_id to mediawiki.page_change event schema

@daniel this would be very simple if we can "Include_LogEntry_objects_in_events" :) Reading that makes me think it is a difficult ask.

The priority of T424350 is quite high (this quarter). We can probably work around this somehow, but if we could easily do it then I would help get it done! What do you think?

I've moved the changes related to events to their own task at T425996: Add log_id to mediawiki page_change and user_change events.

Change #1286397 had a related patch set uploaded (by Xcollazo; author: Xcollazo):

[analytics/refinery/source@master] Refactor MediawikiEvent.fromRow to use named column access

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

event_log_id will be NULL for revision rows, which use revision_id as their identity column.

What about historical revision changes? E.g. revision visibility changes?

Change #1286481 had a related patch set uploaded (by Xcollazo; author: Xcollazo):

[analytics/refinery/source@master] Upgrade graphframes to 0.11.0 from Maven Central, drop Archiva repos

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

event_log_id will be NULL for revision rows, which use revision_id as their identity column.

What about historical revision changes? E.g. revision visibility changes?

MediaWiki History does not currently track those. Note how the only revision row below is for creates.

SELECT
  count(1) as count,
  event_entity,
  event_type
FROM wmf.mediawiki_history
WHERE
  snapshot = '2026-04'
GROUP BY event_entity, event_type
ORDER BY event_entity, event_type
countevent_entityevent_type
801,637,445pagecreate
165,765,078pagecreate-page
117,267,721pagedelete
130,719pagemerge
40,237,343pagemove
1,987,257pagerestore
8,102,997,359revisioncreate
3,496,517useralterblocks
766,153useraltergroups
307,821,921usercreate
5,097,303userrename

Change #1286397 merged by jenkins-bot:

[analytics/refinery/source@master] Refactor MediawikiEvent.fromRow to use named column access

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

Change #1286530 had a related patch set uploaded (by Xcollazo; author: Xcollazo):

[analytics/refinery/source@master] Upgrade graphframes to 0.11.0 from Maven Central, drop Archiva repos

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

Change #1286481 had a related patch set uploaded (by Xcollazo; author: Xcollazo):

[analytics/refinery/source@master] Upgrade graphframes to 0.11.0 from Maven Central, drop Archiva repos

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

Change #1286481 merged by jenkins-bot:

[analytics/refinery/source@master] Upgrade graphframes to 0.11.0 from Maven Central, drop Archiva repos

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

xcollazo opened https://gitlab.wikimedia.org/repos/wmf-packages/-/merge_requests/2

Import org.pentaho:pentaho-aggdesigner-algorithm from Archiva

Change #1286530 abandoned by Xcollazo:

[analytics/refinery/source@master] Upgrade graphframes to 0.11.0 from Maven Central, drop Archiva repos

Reason:

Superseded by 1286481

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

Change #1285903 merged by Xcollazo:

[analytics/refinery@master] Add event_log_id to mediawiki_history DDL

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

pfischer merged https://gitlab.wikimedia.org/repos/wmf-packages/-/merge_requests/2

Import org.pentaho:pentaho-aggdesigner-algorithm from Archiva

Change #1285904 merged by jenkins-bot:

[analytics/refinery/source@master] Add event_log_id to wmf.mediawiki_history

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

Verification run for this ticket's event_log_id, but also for T425735's event_user_is_cross_wiki and also recent changes from that bumped graphframes to 0.11.0 to get rid of Archiva due to T426114.

Create temp table:

CREATE EXTERNAL TABLE `xcollazo`.`mediawiki_history`(
  `wiki_db`                                       string        COMMENT 'enwiki, dewiki, eswiktionary, etc.',
  `event_log_id`                                  bigint        COMMENT 'In page/user events: id of the logging table row that caused this event. NULL for revision events.',
  `event_entity`                                  string        COMMENT 'revision, user or page',
  `event_type`                                    string        COMMENT 'create, move, delete, etc.  Detailed explanation in the docs under #Event_types',
  `event_timestamp`                               string        COMMENT 'When this event ocurred',
  --`event_timestamp`                               timestamp     COMMENT 'When this event ocurred',
  `event_comment`                                 string        COMMENT 'Comment related to this event, sourced from log_comment, rev_comment, etc.',
  `event_user_id`                                 bigint        COMMENT 'Id of the user that caused the event',
  `event_user_central_id`                         bigint        COMMENT 'Global (central) Id of the user that caused the event',
  `event_user_text_historical`                    string        COMMENT 'Historical text of the user that caused the event',
  `event_user_text`                               string        COMMENT 'Current text of the user that caused the event',
  `event_user_blocks_historical`                  array<string> COMMENT 'Historical blocks of the user that caused the event',
  `event_user_blocks`                             array<string> COMMENT 'Current blocks of the user that caused the event',
  `event_user_groups_historical`                  array<string> COMMENT 'Historical groups of the user that caused the event',
  `event_user_groups`                             array<string> COMMENT 'Current groups of the user that caused the event',
  `event_user_is_bot_by_historical`               array<string> COMMENT 'Historical bot information of the user that caused the event, can contain values name or group.',
  `event_user_is_bot_by`                          array<string> COMMENT 'Bot information of the user that caused the event, can contain values name or group.',
  `event_user_is_created_by_self`                 boolean       COMMENT 'Whether the event_user created their own account',
  `event_user_is_created_by_system`               boolean       COMMENT 'Whether the event_user account was created by mediawiki (eg. centralauth)',
  `event_user_is_created_by_peer`                 boolean       COMMENT 'Whether the event_user account was created by another user',
  `event_user_is_anonymous`                       boolean       COMMENT 'Whether the event_user is not registered',
  `event_user_is_temporary`                       boolean       COMMENT 'True if the event_user is temporary, false otherwise.',
  `event_user_is_permanent`                       boolean       COMMENT 'True if the event_user is permanent, false otherwise.',
  `event_user_is_cross_wiki`                      boolean       COMMENT 'True if the event_user is an interwiki-imported editor (usertext contains ">", is anonymous, and not temporary). NULL for user/page events.',
  `event_user_registration_timestamp`             string        COMMENT 'Registration timestamp of the user that caused the event (from the user table)',
  --`event_user_registration_timestamp`             timestamp     COMMENT 'Registration timestamp of the user that caused the event (from the user table)',
  `event_user_creation_timestamp`                 string        COMMENT 'Creation timestamp of the user that caused the event (from the logging table)',
  --`event_user_creation_timestamp`                 timestamp     COMMENT 'Creation timestamp of the user that caused the event (from the logging table)',
  `event_user_first_edit_timestamp`               string        COMMENT 'Timestamp of the first edit of the user that caused the event',
  --`event_user_first_edit_timestamp`               timestamp     COMMENT 'Timestamp of the first edit of the user that caused the event',
  `event_user_revision_count`                     bigint        COMMENT 'Cumulative revision count per user for the current event_user_id (only available in revision-create events so far)',
  `event_user_seconds_since_previous_revision`    bigint        COMMENT 'In revision events: seconds elapsed since the previous revision made by the current event_user_id (only available in revision-create events so far)',

  `page_id`                                       bigint        COMMENT 'In revision/page events: id of the page',
  `page_artificial_id`                            string        COMMENT 'In revision/page events: artificial id to track pages not having been linked back to real page-id',
  `page_title_historical`                         string        COMMENT 'In revision/page events: historical title of the page',
  `page_title`                                    string        COMMENT 'In revision/page events: current title of the page',
  `page_namespace_historical`                     int           COMMENT 'In revision/page events: historical namespace of the page.',
  `page_namespace_is_content_historical`          boolean       COMMENT 'In revision/page events: historical namespace of the page is categorized as content',
  `page_namespace`                                int           COMMENT 'In revision/page events: current namespace of the page',
  `page_namespace_is_content`                     boolean       COMMENT 'In revision/page events: current namespace of the page is categorized as content',
  `page_is_redirect`                              boolean       COMMENT 'In revision/page events: whether the page is currently a redirect',
  `page_is_deleted`                               boolean       COMMENT 'In revision/page events: Whether the page is rebuilt from a delete event',
  `page_creation_timestamp`                       string        COMMENT 'In revision/page events: create event timestamp of the page',
  --`page_creation_timestamp`                       timestamp     COMMENT 'In revision/page events: creation timestamp of the page',
  `page_first_edit_timestamp`                     string        COMMENT 'In revision/page events: first edit timestamp of the page',
  --`page_first_edit_timestamp`                     timestamp     COMMENT 'In revision/page events: first edit timestamp of the page',
  `page_revision_count`                           bigint        COMMENT 'In revision/page events: Cumulative revision count per page for the current page_id (only available in revision-create events so far)',
  `page_seconds_since_previous_revision`          bigint        COMMENT 'In revision/page events: seconds elapsed since the previous revision made on the current page_id (only available in revision-create events so far)',

  `user_id`                                       bigint        COMMENT 'In user events: id of the user',
  `user_central_id`                               bigint        COMMENT 'In user events: id of the user',
  `user_text_historical`                          string        COMMENT 'In user events: historical user text',
  `user_text`                                     string        COMMENT 'In user events: current user text',
  `user_blocks_historical`                        array<string> COMMENT 'In user events: historical user blocks',
  `user_blocks`                                   array<string> COMMENT 'In user events: current user blocks',
  `user_groups_historical`                        array<string> COMMENT 'In user events: historical user groups',
  `user_groups`                                   array<string> COMMENT 'In user events: current user groups',
  `user_is_bot_by_historical`                     array<string> COMMENT 'In user events: Historical bot information of the user, can contain values name or group.',
  `user_is_bot_by`                                array<string> COMMENT 'In user events: Bot information of the user, can contain values name or group.',
  `user_is_created_by_self`                       boolean       COMMENT 'In user events: whether the user created their own account',
  `user_is_created_by_system`                     boolean       COMMENT 'In user events: whether the user account was created by mediawiki',
  `user_is_created_by_peer`                       boolean       COMMENT 'In user events: whether the user account was created by another user',
  `user_is_anonymous`                             boolean       COMMENT 'In user events: whether the user is anonymous',
  `user_is_temporary`                             boolean       COMMENT 'In user events: whether the user is temporary',
  `user_is_permanent`                             boolean       COMMENT 'In user events: whether the user is permanent',
  `user_registration_timestamp`                   string        COMMENT 'In user events: Registration timestamp of the user (from the user table)',
  --`user_registration_timestamp`                   timestamp     COMMENT 'In user events: Registration timestamp of the user (from the user table)',
  `user_creation_timestamp`                       string        COMMENT 'In user events: Creation timestamp of the user (from the logging table)',
  --`user_creation_timestamp`                       timestamp     COMMENT 'In user events: Creation timestamp of the user (from the logging table)',
  `user_first_edit_timestamp`                     string        COMMENT 'In user events: Timestamp of the first edit of the user',
  --`user_first_edit_timestamp`                     timestamp     COMMENT 'In user events: Timestamp of the first edit of the user',

  `revision_id`                                   bigint        COMMENT 'In revision events: id of the revision',
  `revision_parent_id`                            bigint        COMMENT 'In revision events: id of the parent revision',
  `revision_minor_edit`                           boolean       COMMENT 'In revision events: whether it is a minor edit or not',
  `revision_deleted_parts`                        array<string> COMMENT 'In revision events: Deleted parts of the revision, can contain values text, comment and user',
  `revision_deleted_parts_are_suppressed`         boolean       COMMENT 'In revision events: Whether the deleted parts are deleted to admin as well (visibleonly by stewarts)',
  `revision_text_bytes`                           bigint        COMMENT 'In revision events: number of bytes of revision',
  `revision_text_bytes_diff`                      bigint        COMMENT 'In revision events: change in bytes relative to parent revision (can be negative).',
  `revision_text_sha1`                            string        COMMENT 'In revision events: sha1 hash of the revision',
  `revision_content_model`                        string        COMMENT 'In revision events: content model of revision',
  `revision_content_format`                       string        COMMENT 'In revision events: content format of revision',
  `revision_is_deleted_by_page_deletion`          boolean       COMMENT 'In revision events: whether this revision has been deleted through a page deletion (moved to archive table)',
  `revision_deleted_by_page_deletion_timestamp`   string        COMMENT 'In revision events: the timestamp when the revision was deleted',
  --`revision_deleted_by_page_deletion_timestamp`   timestamp     COMMENT 'In revision events: the timestamp when the revision was deleted',
  `revision_is_identity_reverted`                 boolean       COMMENT 'In revision events: whether this revision was reverted by another future revision',
  `revision_first_identity_reverting_revision_id` bigint        COMMENT 'In revision events: id of the revision that reverted this revision',
  `revision_seconds_to_identity_revert`           bigint        COMMENT 'In revision events: seconds elapsed between revision posting and its revert (if there was one)',
  `revision_is_identity_revert`                   boolean       COMMENT 'In revision events: whether this revision reverts other revisions',
  `revision_is_from_before_page_creation`         boolean       COMMENT 'In revision events: True if the revision timestamp is before the page creation (can happen with restore events)',
  `revision_tags`                                 array<string> COMMENT 'In revision events: Tags associated to the revision'
)
COMMENT
  'See most up to date documentation at https://wikitech.wikimedia.org/wiki/Analytics/Data_Lake/Mediawiki_history'
PARTITIONED BY (
  `snapshot` string COMMENT 'Versioning information to keep multiple datasets (YYYY-MM for regular labs imports)')
ROW FORMAT SERDE
  'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
STORED AS INPUTFORMAT
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat'
OUTPUTFORMAT
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'
LOCATION
  'hdfs://analytics-hadoop/user/xcollazo/mediawiki/history'
;

Copy snapshot artifact:

scp target/refinery-job-0.3.14-SNAPSHOT-shaded.jar stat1011.eqiad.wmnet:~/artifacts

hdfs dfs -copyFromLocal /home/xcollazo/artifacts/refinery-job-0.3.14-SNAPSHOT-shaded.jar /user/xcollazo/artifacts
hdfs dfs -chmod +rx /user/xcollazo/artifacts/refinery-job-0.3.14-SNAPSHOT-shaded.jar

Run mediawiky history. A typical run takes ~10.6h at 90 executors. We are using 128 below (~25% of cluster) thus expect more like 90/128 * ~10.6h = ~7.5h :

screen -S mwh_run

   spark3-submit \
    --driver-cores \
    2 \
    --conf \
    spark.executorEnv.SPARK_HOME=/usr/lib/spark3 \
    --conf \
    spark.executorEnv.SPARK_CONF_DIR=/etc/spark3/conf \
    --master \
    yarn \
    --conf \
    spark.dynamicAllocation.enabled=true \
    --conf \
    spark.dynamicAllocation.maxExecutors=128 \
    --conf \
    spark.shuffle.service.enabled=true \
    --conf \
    spark.yarn.maxAppAttempts=1 \
    --conf \
    spark.executor.memoryOverhead=8192 \
    --conf \
    spark.hadoop.mapreduce.fileoutputcommitter.algorithm.version=2 \
    --conf \
    spark.yarn.appMasterEnv.SPARK_CONF_DIR=/etc/spark3/conf \
    --conf \
    spark.yarn.appMasterEnv.SPARK_HOME=/usr/lib/spark3 \
    --executor-cores \
    2 \
    --executor-memory \
    32G \
    --driver-memory \
    32G \
    --name \
    xcollazo_test_of_mediawiki_history_denormalize__denormalize_history \
    --class \
    org.wikimedia.analytics.refinery.job.mediawikihistory.MediawikiHistoryRunner \
    --deploy-mode \
    client \
    hdfs:///user/xcollazo/artifacts/refinery-job-0.3.14-SNAPSHOT-shaded.jar \
    --snapshot \
    2026-04 \
    --mediawiki-base-path \
    hdfs://analytics-hadoop/wmf/data/raw/mediawiki \
    --mediawiki-private-base-path \
    hdfs://analytics-hadoop/wmf/data/raw/mediawiki_private \
    --output-base-path \
    hdfs://analytics-hadoop/user/xcollazo/mediawiki \
    --temporary-path \
    hdfs://analytics-hadoop/tmp/xcollazo/checkpoints \
    --base-num-partitions \
    64 \
    --no-stats

Run mediawiky history. A typical run takes ~10.6h at 90 executors. We are using 128 below (~25% of cluster) thus expect more like 90/128 * ~10.6h = ~7.5h :

Run failed: https://yarn.wikimedia.org/spark-history/history/application_1773845446826_1110642/jobs/

Investigating.

Run mediawiky history. A typical run takes ~10.6h at 90 executors. We are using 128 below (~25% of cluster) thus expect more like 90/128 * ~10.6h = ~7.5h :

Run failed: https://yarn.wikimedia.org/spark-history/history/application_1773845446826_1110642/jobs/

Investigating.

Things looked ok until we started getting:

FetchFailed(BlockManagerId(529, an-worker1146.eqiad.wmnet, 7337, None), shuffleId=311, mapIndex=24, mapId=469736, reduceId=0, message=                                                    
org.apache.spark.shuffle.FetchFailedException: java.lang.IllegalArgumentException: Authentication failed.                                                                                 
    at org.apache.spark.network.crypto.AuthRpcHandler.doAuthChallenge(AuthRpcHandler.java:125)                                                                                            
    at org.apache.spark.network.server.AbstractAuthRpcHandler.receive(AbstractAuthRpcHandler.java:59)                                                                                     
    at

Note this is an Authentication issue. I speculate this is because we did restart Shuffler services due to T426349: Spark 3.5.8 Shuffler not working.

Thus will rerun with same parameters as in T425986#11923202. Unfortunately, we will have to wait 13+ hours again...

Thus will rerun with same parameters as in T425986#11923202. Unfortunately, we will have to wait 13+ hours again...

Rerunning: https://yarn.wikimedia.org/proxy/application_1778834239566_7205/jobs/

Thus will rerun with same parameters as in T425986#11923202. Unfortunately, we will have to wait 13+ hours again...

Rerunning: https://yarn.wikimedia.org/proxy/application_1778834239566_7205/jobs/

Success at 8.3h. Lots of spilling and lots of GC. Given sustained evidence, opened T426510: Migrate MediawikiHistoryRunner to Spark 3.5 + AQE for later.

Next step: validate that output is good.

Table validation:

First fix metastore:

spark-sql (default)> show partitions mediawiki_history;
partition
Time taken: 0.211 seconds
spark-sql (default)> MSCK REPAIR TABLE mediawiki_history;
Response code
Time taken: 0.786 seconds
spark-sql (default)> show partitions mediawiki_history;
partition
snapshot=2026-04
Time taken: 0.142 seconds, Fetched 1 row(s)

Now a couple sanity tests:

spark-sql (default)> select count(1) from mediawiki_history where snapshot='2026-04';
count(1)
9547207038
Time taken: 52.033 seconds, Fetched 1 row(s)

spark-sql (default)> select count(1) as total_count,
                   >        count(event_log_id) as log_id_count,
                   >        count(event_user_is_cross_wiki) cross_count
                   > from xcollazo.mediawiki_history
                   > where snapshot='2026-04';
total_count	log_id_count	cross_count
9547207038	701252785	9547207038
Time taken: 55.977 seconds, Fetched 1 row(s)

spark-sql (default)> select count(1) as count,
                   >        event_user_is_cross_wiki,
                   >        wiki_db
                   > from xcollazo.mediawiki_history
                   > where snapshot='2026-04'
                   >   and wiki_db in ('enwiki', 'simplewiki', 'eswiki')
                   > group by wiki_db, event_user_is_cross_wiki
                   > order by wiki_db, event_user_is_cross_wiki;
count	event_user_is_cross_wiki	wiki_db
1533491558	false	enwiki
28165	true	enwiki
198765576	false	eswiki
3883	true	eswiki
14757207	false	simplewiki
51335	true	simplewiki
Time taken: 55.881 seconds, Fetched 6 row(s)

This all LGTM.

Steps ran in prod to get the new schema:

$ hostname -f
an-launcher1003.eqiad.wmnet

$ sudo -u analytics bash

$ hive

hive (default)> DROP TABLE wmf.mediawiki_history;
OK
Time taken: 1.111 seconds
hive (default)> quit;

$ cd /srv/deployment/analytics/refinery/hql/mediawiki/history

$ hive -f create_mediawiki_history_table.hql --database wmf -d location=hdfs://analytics-hadoop/wmf/data/wmf/mediawiki/history
...
OK
Time taken: 1.566 seconds
OK
Time taken: 0.336 seconds

$ hive

hive (default)> SHOW PARTITIONS wmf.mediawiki_history;
OK
partition
Time taken: 0.163 seconds

hive (default)> MSCK REPAIR TABLE wmf.mediawiki_history;
OK
Partitions not in metastore:	mediawiki_history:snapshot=2025-11	mediawiki_history:snapshot=2025-12	mediawiki_history:snapshot=2026-01	mediawiki_history:snapshot=2026-02	mediawiki_history:snapshot=2026-03	mediawiki_history:snapshot=2026-04
Repair: Added partition to metastore wmf.mediawiki_history:snapshot=2025-11
Repair: Added partition to metastore wmf.mediawiki_history:snapshot=2025-12
Repair: Added partition to metastore wmf.mediawiki_history:snapshot=2026-01
Repair: Added partition to metastore wmf.mediawiki_history:snapshot=2026-02
Repair: Added partition to metastore wmf.mediawiki_history:snapshot=2026-03
Repair: Added partition to metastore wmf.mediawiki_history:snapshot=2026-04
Time taken: 0.967 seconds, Fetched: 7 row(s)
hive (default)> SHOW PARTITIONS wmf.mediawiki_history;
OK
partition
snapshot=2025-11
snapshot=2025-12
snapshot=2026-01
snapshot=2026-02
snapshot=2026-03
snapshot=2026-04
Time taken: 0.151 seconds, Fetched: 6 row(s)

hive (default)> quit;

A couple quick sanity tests:

$ spark3-sql \
  --master yarn \ 
  --conf spark.executor.cores=2 \ 
  --conf spark.executor.memory=8g \ 
  --conf spark.driver.memory=8g \ 
  --conf spark.sql.shuffle.partitions=768 \ 
  --conf spark.dynamicAllocation.maxExecutors=128 \ 
  --conf spark.executor.memoryOverhead=6g

spark-sql (default)> select count(1) as count from wmf.mediawiki_history where snapshot='2026-04';
count
9547204816
Time taken: 50.637 seconds, Fetched 1 row(s)

spark-sql (default)> select wiki_db, event_log_id, event_entity event_timestamp, event_user_id, event_user_is_cross_wiki from wmf.mediawiki_history where snapshot='2026-04' and wiki_db='simplewiki' limit 10;
wiki_db	event_log_id	event_timestamp	event_user_id	event_user_is_cross_wiki
simplewiki	NULL	revision	10798	NULL
simplewiki	NULL	revision	NULL	NULL
simplewiki	NULL	revision	39678	NULL
simplewiki	NULL	revision	22027	NULL
simplewiki	NULL	revision	640235	NULL
simplewiki	NULL	revision	2133	NULL
simplewiki	NULL	revision	NULL	NULL
simplewiki	NULL	revision	18539	NULL
simplewiki	NULL	revision	209999	NULL
simplewiki	NULL	revision	2133	NULL
Time taken: 6.631 seconds, Fetched 10 row(s)

Existing data still there, with new columns marked NULL for now, as expected.

Deleted the DagProperties of the following DAGs to pickup the new refiniery-source artifact:

main/dags/mediawiki/mediawiki_history_check_denormalize_dag.py
main/dags/mediawiki/mediawiki_history_denormalize_dag.py
main/dags/mediawiki/mediawiki_history_dumps_dag.py
main/dags/mediawiki/mediawiki_history_metrics_monthly_dag.py
main/dags/mediawiki/mediawiki_history_reduced_dag.py

Confirmed that the newly generated DagProperties for all of the DAGs above are the same except for the artifact bump.

Task success in ~10.5h. Similar GC pressure profile as before in T425986#11928140.

Validating data now...

wmf.mediawiki_history's snapshot='2026-04' LGTM:

spark-sql (default)> select count(1) from wmf.mediawiki_history where snapshot='2026-04';
count(1)
9547207442
Time taken: 27.849 seconds, Fetched 1 row(s)

spark-sql (default)> select count(1) as total_count,
                   >        count(event_log_id) as log_id_count,
                   >        count(event_user_is_cross_wiki) cross_count
                   > from wmf.mediawiki_history
                   > where snapshot='2026-04';
total_count	log_id_count	cross_count
9547207442	701253189	9547207442
Time taken: 34.212 seconds, Fetched 1 row(s)

spark-sql (default)> select count(1) as count,
                   >        event_user_is_cross_wiki,
                   >        wiki_db
                   > from wmf.mediawiki_history
                   > where snapshot='2026-04'
                   >   and wiki_db in ('enwiki', 'simplewiki', 'eswiki')
                   > group by wiki_db, event_user_is_cross_wiki
                   > order by wiki_db, event_user_is_cross_wiki;
count	event_user_is_cross_wiki	wiki_db
1533491575	false	enwiki
28165	true	enwiki
198765617	false	eswiki
3883	true	eswiki
14757213	false	simplewiki
51335	true	simplewiki
Time taken: 47.243 seconds, Fetched 6 row(s)

We are done here.