Add IndexMode.TSDB as the preferred metrics mode#152901
Conversation
Users and docs already call time-series indices tsdb; add a new IndexMode.TSDB constant that behaves identically to TIME_SERIES so index.mode: tsdb is now also accepted, without renaming or changing anything about existing time_series indices, which keep emitting and persisting exactly as before. TSDB delegates every behavior to TIME_SERIES and is treated identically everywhere via new isTsdb()/isTsdb(IndexMode)/isTsdbName(String) helpers, replacing direct == TIME_SERIES comparisons across the codebase. Adds a transport version gating TSDB's wire serialization for mixed-version clusters, unit tests for the new alias, and a rolling upgrade test that switches a data stream from time_series to tsdb mid-upgrade and verifies both backing indices stay queryable together.
|
Hi @kkrik-es, I've created a changelog YAML for you. Note that since this PR is labelled |
Introduced `IndexMode.TSDB` as an alias for `TIME_SERIES`, added new tests, and fixed related bugs. Deferred updates to YAML REST tests for a follow-up PR.
NumberFieldType/GeoPointFieldType/ScaledFloatFieldType/ UnsignedLongFieldType all have a real (non-test-only) code path where indexMode is null, e.g. TokenCountFieldType passes null explicitly. The earlier == IndexMode.TIME_SERIES checks tolerated that; the isTsdb() instance-method replacements did not. Switch these four call sites to the null-safe IndexMode.isTsdb(IndexMode) static instead. Also gate AllSupportedFieldsTestCase's mode=tsdb parameterization on minVersion().supports(IndexMode.INDEX_MODE_TSDB_ADDED), matching the existing pattern for vectordb_document/columnar, so multi-cluster BWC runs skip creating a tsdb index against a remote that predates it.
|
Pinging @elastic/es-storage-engine (Team:StorageEngine) |
# Conflicts: # server/src/main/resources/transport/upper_bounds/9.5.csv
🔍 Preview links for changed docs⏳ Building and deploying preview... View progress This comment will be updated with preview links when the build is complete. |
ℹ️ Important: Docs version tagging👋 Thanks for updating the docs! Just a friendly reminder that our docs are now cumulative. This means all 9.x versions are documented on the same page and published off of the main branch, instead of creating separate pages for each minor version. We use applies_to tags to mark version-specific features and changes. Expand for a quick overviewWhen to use applies_to tags:✅ At the page level to indicate which products/deployments the content applies to (mandatory) What NOT to do:❌ Don't remove or replace information that applies to an older version 🤔 Need help?
|
Extend unit tests to assert IndexMode.TSDB behaves identically to IndexMode.TIME_SERIES wherever production code now uses isTsdb().
|
Instead of creating a whole new |
|
I did, this mostly works but there are cases where we invoke It's cleaner to introduce a new mode and start using it - although it's quite a change to make sure it's used and tested everywhere.. |
Fix IndexSettingsTests assertion to expect the canonical time_series message text, and add FeatureMetric TSDB coverage.
Rename TsdbAlias-style identifiers to Tsdb and reword comments, since alias has a specific meaning (index aliases) in Elasticsearch. Also add TS-command TSDB coverage in TimeSeriesIT after confirming no production bug: concrete, wildcard, and mixed-mode alias lookups all resolve correctly today.
Covers IndexMode.java's own javadoc plus test files touched by other concurrent agents that the earlier sweep missed.
IndexMode.TSDB delegated validateWithOtherSettings/validateMapping/ validateAlias straight to TIME_SERIES's method bodies, where unqualified getName()/this always resolved to TIME_SERIES. Extract shared static utilities that take the calling mode explicitly, so a tsdb-mode index's validation errors correctly say index.mode=tsdb instead of always canonicalizing to time_series. Add TSDB coverage for the sort-setting and routing-partition-size rejection paths.
Mirrors the existing logsdb/vectordb_document/columnar index mode capabilities so YAML tests can gate on cluster support for tsdb.
Renaming could be considered a breaking API change. Currently, there might be users relying on this string to detect their time series data. So, we have 2 options but they have trade-offs:
|
# Conflicts: # server/src/main/java/org/elasticsearch/index/IndexMode.java
Summary
Add
IndexMode.TSDBas a new, first-class enum value that behaves identically toTIME_SERIES(delegates every overridden method), soindex.mode: tsdbis now accepted anywhereindex.mode: time_seriesis — without renaming or changing anything about existingtime_seriesindices, which keep emitting/persisting exactly as before (time_seriesremains the canonical output string;tsdbis a preferred alias).IndexMode#isTsdb(),IndexMode.isTsdb(IndexMode)(null-safe), andIndexMode.isTsdbName(String)(for raw, un-parsedindex.modesetting strings) replace direct== IndexMode.TIME_SERIEScomparisons across the codebase, so both spellings are treated identically everywhere.Enum.valueOf(IndexMode.class, ...)/IndexMode.valueOfparse sites were deliberately left untouched — sinceTSDBis a new constant (not a rename) whose name already uppercases to match"tsdb", these already accept both spellings for free.TransportVersion(index_mode_tsdb_added) gatesTSDB's wire serialization for mixed-version clusters.TsdbIndexModeTestscoveringfromString,getName,isTsdb/isTsdbName, theindex.modesetting parser, serialization round-trip + version-gate failure, and behavior parity withTIME_SERIES.TimeSeriesToTsdbIndexModeRollingUpgradeIT— a real rolling-upgrade test that creates a data stream ontime_series, upgrades the cluster, switches the template totsdband rolls over, and verifies the old backing index staystime_series, the new one istsdb, and both remain queryable together (verified viaFROM ds METADATA _index | STATS count = COUNT(*) BY _index).Notable bugs found and fixed along the way
EsqlSession's_index_modeterm filter (used to gateTS/PROMQLcommand queries) was built from the command's fixed sentinel mode, so it only ever matched"time_series"— it would have silently excluded any concreteindex.mode: tsdbindex from aTSquery, and incorrectly rejected it as "not a time series index" on retry. Fixed with aTermsQueryBuildermatching both aliases.switch/ifstatements (FollowingEngineTests,LogsdbIndexModeSettingsProvider) with adefault/hardcoded branch would have broken onceTSDBbecame reachable viarandomFrom(IndexMode.availableModes())— not caught by the compiler since these aren't exhaustive expression switches.randomValueOtherThan(IndexMode.TIME_SERIES, ...)test patterns would let a randomly-pickedTSDBslip through as "not time series," causing spurious failures — fixed withrandomValueOtherThanMany(m -> m.isTsdb(), ...).Test plan
TsdbIndexModeTests(new) — all passIndexSettingsTests,MapperServiceTests,MappingLookupTests,IndexModeFieldTypeTests,SourceFieldMapperTests,PerFieldMapperCodecTests,TSDBDocValuesFormatSelectorTests,ResolveIndexTests— all passanalysis,optimizer,datasources,sessiontest suites — all passFollowingEngineTests(ccr),IndexCommitTimestampFieldRangeTests(stateless) — all passTimeSeriesToTsdbIndexModeRollingUpgradeIT(new) — run against real rolling upgrades from both 9.5.0 and 8.19.0spotlessJavaCheckclean across every touched moduleFollow-up (separate PR)
Updating YAML REST tests and existing Java tests to prefer/cover
tsdbalongsidetime_seriesis intentionally deferred to a follow-up PR.Related to #152902