Skip to content

SOLR-18562: Don't overwrite other aliases when fixing a time routed alias's start - #5191

Open
SpookyJumpyBeans wants to merge 2 commits into
apache:mainfrom
SpookyJumpyBeans:tra-start-stale-aliases
Open

SpookyJumpyBeans wants to merge 2 commits into
apache:mainfrom
SpookyJumpyBeans:tra-start-stale-aliases

Conversation

@SpookyJumpyBeans

@SpookyJumpyBeans SpookyJumpyBeans commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

https://issues.apache.org/jira/browse/SOLR-18562

Description

When the first document arrives for a time routed alias with date math in router.start, TimeRoutedAlias.validateRouteValue() fixes the start and writes it to aliases.json asynchronously. The modification function passed to applyModificationAndExportToZk() ignores its argument and returns a clone of the aliases snapshot taken earlier. If aliases.json changed in between, the CAS fails, the retry reads the current version, and the function returns the old snapshot again, which then gets written. Any alias created after the snapshot is lost.

Solution

Build the change on the aliases passed to the function (like every other caller of applyModificationAndExportToZk), and set only router.start:

(a) ->
    a.hasAlias(aliasName)
        ? a.cloneWithCollectionAliasProperties(aliasName, ROUTER_START, fixedStart)
        : a

Notes:

  • Before, the whole property map of the alias was copied from the snapshot, so a concurrent change to another property of the same alias could also be reverted. Setting only router.start avoids that.
  • If the alias itself is deleted before the asynchronous write runs, the function returns the aliases unchanged, so nothing is written. Before, the snapshot was written back, which would have recreated the deleted alias.
  • Two nodes fixing the start at the same time can still pick slightly different instants (the existing comment about who wins); this PR doesn't change that.

Tests

Added CreateRoutedAliasTest.testFixingStartKeepsOtherAliases: it creates a time routed alias with start=NOW/DAY, creates a second alias, puts the hosting node's cached aliases back to before the second alias existed (with reflection, under @SuppressForbidden, since there is no hook to delay a watch event), and sends the first document to that node. It then checks that router.start was fixed and the second alias still exists.

The test fails on main (the second alias is gone: expected:<...> but was:<null>) and passes with the fix (also 5 more runs with different seeds). CreateRoutedAliasTest and AliasIntegrationTest pass, and so does ./gradlew :solr:core:check -x test. I didn't put it in TimeRoutedAliasUpdateProcessorTest because that class is @AwaitsFix (SOLR-13059), and so is its testDateMathInStart (SOLR-13943).

Checklist

  • I have reviewed the guidelines for How to Contribute and my code conforms to the standards described there to the best of my ability.
  • I have created a Jira issue and added the issue ID to my pull request title.
  • I have given Solr maintainers access to contribute to my PR branch. (optional but recommended, not available for branches on forks living under an organisation)
  • I have developed this patch against the main branch.
  • I have run ./gradlew check.
  • I have added tests for my changes.
  • I have added documentation for the Reference Guide
  • I have added a changelog entry for my change

…lias's start

When the first document arrives for a time routed alias with date math
in router.start, the fixed start is written to aliases.json
asynchronously. The modification function ignored the current aliases it
was given and returned a clone of an earlier snapshot, so if
aliases.json changed in between, the retry wrote the old snapshot over
it and any alias created since was lost. Apply the change to the current
aliases and set only router.start.
SpookyJumpyBeans added a commit to SpookyJumpyBeans/boyidai that referenced this pull request Oct 22, 2026
If the alias is deleted before the asynchronous write runs, return the
aliases unchanged instead of throwing from the background task.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant