Skip to content

fix: compare Keeper replica versions numerically, not lexicographically#260

Open
nahuel11500 wants to merge 1 commit into
ClickHouse:mainfrom
nahuel11500:fix/keeper-observed-version-compare
Open

fix: compare Keeper replica versions numerically, not lexicographically#260
nahuel11500 wants to merge 1 commit into
ClickHouse:mainfrom
nahuel11500:fix/keeper-observed-version-compare

Conversation

@nahuel11500

Copy link
Copy Markdown

Why

keeperReconciler.evaluateVersionConditions picks the cluster's observed version by comparing the replicas' reported version strings with Go's < operator, which is lexicographic. Whenever a component crosses a digit-count boundary (e.g. 25.925.10), the older version compares as "greater": "25.9.1.100" > "25.10.2.5".

During a rolling upgrade across such a boundary this means:

  • KeeperCluster.Status.Version keeps reporting the old version even after replicas have upgraded, and
  • GetVersionSyncCondition uses the old version as the reference, so the VersionInSync condition flags the already-upgraded replicas as mismatched instead of the pending ones.

The impact is limited to status/condition reporting, but ClickHouse crosses a .9 → .10 minor boundary every year, so any Keeper upgrade over that boundary hits it.

What

Replaced the string comparison with a small newerVersion helper that reuses the existing upgrade.ParseBareVersion/upgrade.CompareVersions (already used for the same purpose elsewhere, e.g. in the upgrade checker and fetcher), falling back to the previous lexicographic behavior if a version doesn't parse.

Added a unit test in the existing Keeper version status spec that reproduces the bug with two replicas on 25.9.1.100 and 25.10.2.5: before the fix Status.Version reports 25.9.1.100, after the fix it correctly reports 25.10.2.5.

The ClickHouse controller is not affected — it takes Status.Version from the version probe result directly rather than from a max over replica versions.

Related Issues

None — found while reading the reconciler code.

The observed cluster version was picked with a plain string comparison,
so across a digit-count boundary (e.g. 25.9 -> 25.10) the older version
won and Status.Version and the VersionInSync condition reported the
already-upgraded replicas as out of sync.

Reuse upgrade.ParseBareVersion/CompareVersions to pick the newest
reported version, falling back to the previous behavior if a version
does not parse.
@CLAassistant

CLAassistant commented Jul 8, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@nahuel11500 nahuel11500 marked this pull request as ready for review July 8, 2026 15:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants