From 108956c981b37e5b81b2372ac351a3a0cf02c73f Mon Sep 17 00:00:00 2001 From: David Percy Date: Fri, 25 Mar 2022 18:30:08 +0000 Subject: SERVER-65081 Enable Time-series Metric Indexes --- src/mongo/db/catalog/multi_index_block.cpp | 5 +- src/mongo/db/storage/storage_parameters.idl | 3 +- ...ries_index_schema_conversion_functions_test.cpp | 77 ++++++++++++---------- 3 files changed, 49 insertions(+), 36 deletions(-) diff --git a/src/mongo/db/catalog/multi_index_block.cpp b/src/mongo/db/catalog/multi_index_block.cpp index 9c6d897c591..16e4c00231b 100644 --- a/src/mongo/db/catalog/multi_index_block.cpp +++ b/src/mongo/db/catalog/multi_index_block.cpp @@ -52,6 +52,7 @@ #include "mongo/db/repl/replication_coordinator.h" #include "mongo/db/repl/tenant_migration_conflict_info.h" #include "mongo/db/storage/storage_options.h" +#include "mongo/db/storage/storage_parameters_gen.h" #include "mongo/db/storage/write_unit_of_work.h" #include "mongo/db/timeseries/timeseries_constants.h" #include "mongo/db/timeseries/timeseries_index_schema_conversion_functions.h" @@ -271,10 +272,10 @@ StatusWith> MultiIndexBlock::init( info = statusWithInfo.getValue(); indexInfoObjs.push_back(info); - // TODO SERVER-54592: Remove FCV check once feature flag is enabled. boost::optional options = collection->getTimeseriesOptions(); if (options && - serverGlobalParams.featureCompatibility.isFCVUpgradingToOrAlreadyLatest() && + feature_flags::gTimeseriesMetricIndexes.isEnabled( + serverGlobalParams.featureCompatibility) && timeseries::doesBucketsIndexIncludeMeasurement( opCtx, collection->ns(), *options, info)) { invariant(collection->getTimeseriesBucketsMayHaveMixedSchemaData()); diff --git a/src/mongo/db/storage/storage_parameters.idl b/src/mongo/db/storage/storage_parameters.idl index dd1c5083a61..ed4153148e4 100644 --- a/src/mongo/db/storage/storage_parameters.idl +++ b/src/mongo/db/storage/storage_parameters.idl @@ -128,7 +128,8 @@ feature_flags: featureFlagTimeseriesMetricIndexes: description: "When enabled, support secondary indexes on time-series measurements" cpp_varname: feature_flags::gTimeseriesMetricIndexes - default: false + default: true + version: 6.0 featureFlagTimeseriesBucketCompression: description: "Enable bucket compression on time-series collections" cpp_varname: feature_flags::gTimeseriesBucketCompression diff --git a/src/mongo/db/timeseries/timeseries_index_schema_conversion_functions_test.cpp b/src/mongo/db/timeseries/timeseries_index_schema_conversion_functions_test.cpp index 49b08dc4fc6..88a2fd76b7d 100644 --- a/src/mongo/db/timeseries/timeseries_index_schema_conversion_functions_test.cpp +++ b/src/mongo/db/timeseries/timeseries_index_schema_conversion_functions_test.cpp @@ -49,8 +49,10 @@ const std::string kControlMinTimeFieldName(timeseries::kControlMinFieldNamePrefi const std::string kControlMaxTimeFieldName(timeseries::kControlMaxFieldNamePrefix + kTimeseriesTimeFieldName); const std::string kTimeseriesSomeDataFieldName("somedatafield"); -const std::string kBucketsSomeDataFieldName(timeseries::kBucketDataFieldName + "." + - kTimeseriesSomeDataFieldName); +const std::string kControlMinSomeDataFieldName(timeseries::kControlMinFieldNamePrefix + + kTimeseriesSomeDataFieldName); +const std::string kControlMaxSomeDataFieldName(timeseries::kControlMaxFieldNamePrefix + + kTimeseriesSomeDataFieldName); /** * Constructs a TimeseriesOptions object for testing. @@ -153,14 +155,16 @@ TEST(TimeseriesIndexSchemaConversionTest, DescendingTimeIndexSpecConversion) { testBothWaysIndexSpecConversion(timeseriesOptions, timeseriesIndexSpec, bucketsIndexSpec); } -// {tm.subfield1: 1} <=> {tm.subfield1: 1} -TEST(TimeseriesIndexSchemaConversionTest, TimeSubFieldIndexSpecConversionFails) { +// {tm.subfield1: 1} <=> {control.min.tm.subfield1: 1, control.max.tm.subfield1: 1} +// This case is probably not useful, because 'tm' is always a Date, which can't have subfields. +// Presumably it works because we treat 'tm' similarly to other non-metadata fields. +TEST(TimeseriesIndexSchemaConversionTest, TimeSubFieldIndexSpecConversion) { TimeseriesOptions timeseriesOptions = makeTimeseriesOptions(); BSONObj timeseriesIndexSpec = BSON(kTimeseriesTimeFieldName + kSubField1Name << 1); - BSONObj bucketsIndexSpec = BSON(kTimeseriesTimeFieldName + kSubField1Name << 1); + BSONObj bucketsIndexSpec = BSON(kControlMinTimeFieldName + kSubField1Name + << 1 << kControlMaxTimeFieldName + kSubField1Name << 1); - testBothWaysIndexSpecConversion( - timeseriesOptions, timeseriesIndexSpec, bucketsIndexSpec, false /* testShouldSucceed */); + testBothWaysIndexSpecConversion(timeseriesOptions, timeseriesIndexSpec, bucketsIndexSpec); } // {mm: 1} <=> {meta: 1} @@ -216,62 +220,69 @@ TEST(TimeseriesIndexSchemaConversionTest, MetadataAndTimeCompoundIndexSpecConver testBothWaysIndexSpecConversion(timeseriesOptions, timeseriesIndexSpec, bucketsIndexSpec); } -// {somedatafield: 1} <=> {data.somedatafield: 1} -TEST(TimeseriesIndexSchemaConversionTest, DataIndexSpecConversionFails) { +// {somedatafield: 1} <=> {control.min.somedatafield: 1, control.max.somedatafield: 1} +TEST(TimeseriesIndexSchemaConversionTest, DataIndexSpecConversion) { TimeseriesOptions timeseriesOptions = makeTimeseriesOptions(); BSONObj timeseriesIndexSpec = BSON(kTimeseriesSomeDataFieldName << 1); - BSONObj bucketsIndexSpec = BSON(kBucketsSomeDataFieldName << 1); + BSONObj bucketsIndexSpec = + BSON(kControlMinSomeDataFieldName << 1 << kControlMaxSomeDataFieldName << 1); - testBothWaysIndexSpecConversion( - timeseriesOptions, timeseriesIndexSpec, bucketsIndexSpec, false /* testShouldSucceed */); + testBothWaysIndexSpecConversion(timeseriesOptions, timeseriesIndexSpec, bucketsIndexSpec); } -// {tm: 1, somedatafield: 1} <=> {control.min.tm: 1, control.max.tm: 1, data.somedatafield: 1} -TEST(TimeseriesIndexSchemaConversionTest, TimeAndDataCompoundIndexSpecConversionFails) { +// {tm: 1, somedatafield: 1} <=> +// {control.min.tm: 1, control.max.tm: 1, +// control.min.somedatafield: 1, control.max.somedatafield: 1} +TEST(TimeseriesIndexSchemaConversionTest, TimeAndDataCompoundIndexSpecConversion) { TimeseriesOptions timeseriesOptions = makeTimeseriesOptions(); BSONObj timeseriesIndexSpec = BSON(kTimeseriesTimeFieldName << 1 << kTimeseriesSomeDataFieldName << 1); BSONObj bucketsIndexSpec = BSON(kControlMinTimeFieldName << 1 << kControlMaxTimeFieldName << 1 - << kBucketsSomeDataFieldName << 1); + << kControlMinSomeDataFieldName << 1 + << kControlMaxSomeDataFieldName << 1); - testBothWaysIndexSpecConversion( - timeseriesOptions, timeseriesIndexSpec, bucketsIndexSpec, false /* testShouldSucceed */); + testBothWaysIndexSpecConversion(timeseriesOptions, timeseriesIndexSpec, bucketsIndexSpec); } -// {somedatafield: 1, tm: 1} <=> {data.somedatafield: 1, control.min.tm: 1, control.max.tm: 1} -TEST(TimeseriesIndexSchemaConversionTest, DataAndTimeCompoundIndexSpecConversionFails) { +// {somedatafield: 1, tm: 1} <=> +// {control.min.somedatafield: 1, control.max.somedatafield: 1, +// control.min.tm: 1, control.max.tm: 1} +TEST(TimeseriesIndexSchemaConversionTest, DataAndTimeCompoundIndexSpecConversion) { TimeseriesOptions timeseriesOptions = makeTimeseriesOptions(); BSONObj timeseriesIndexSpec = BSON(kTimeseriesSomeDataFieldName << 1 << kTimeseriesTimeFieldName << 1); - BSONObj bucketsIndexSpec = BSON(kBucketsSomeDataFieldName << 1 << kControlMinTimeFieldName << 1 - << kControlMaxTimeFieldName << 1); + BSONObj bucketsIndexSpec = + BSON(kControlMinSomeDataFieldName << 1 << kControlMaxSomeDataFieldName << 1 + << kControlMinTimeFieldName << 1 + << kControlMaxTimeFieldName << 1); - testBothWaysIndexSpecConversion( - timeseriesOptions, timeseriesIndexSpec, bucketsIndexSpec, false /* testShouldSucceed */); + testBothWaysIndexSpecConversion(timeseriesOptions, timeseriesIndexSpec, bucketsIndexSpec); } -// {mm: 1, somedatafield: 1} <=> {meta: 1, data.somedatafield: 1} -TEST(TimeseriesIndexSchemaConversionTest, MetadataAndDataCompoundIndexSpecConversionFails) { +// {mm: 1, somedatafield: 1} <=> {meta: 1, control.min.somedatafield: 1, control.max.somedatafield: +// 1} +TEST(TimeseriesIndexSchemaConversionTest, MetadataAndDataCompoundIndexSpecConversion) { TimeseriesOptions timeseriesOptions = makeTimeseriesOptions(); BSONObj timeseriesIndexSpec = BSON(kTimeseriesMetaFieldName << 1 << kTimeseriesSomeDataFieldName << 1); BSONObj bucketsIndexSpec = - BSON(timeseries::kBucketMetaFieldName << 1 << kBucketsSomeDataFieldName << 1); + BSON(timeseries::kBucketMetaFieldName << 1 << kControlMinSomeDataFieldName << 1 + << kControlMaxSomeDataFieldName << 1); - testBothWaysIndexSpecConversion( - timeseriesOptions, timeseriesIndexSpec, bucketsIndexSpec, false /* testShouldSucceed */); + testBothWaysIndexSpecConversion(timeseriesOptions, timeseriesIndexSpec, bucketsIndexSpec); } -// {somedatafield: 1, mm: 1} <=> {data.somedatafield: 1, meta: 1} -TEST(TimeseriesIndexSchemaConversionTest, DataAndMetadataCompoundIndexSpecConversionFails) { +// {somedatafield: 1, mm: 1} <=> +// {control.min.somedatafield: 1, control.max.somedatafield: 1, meta: 1} +TEST(TimeseriesIndexSchemaConversionTest, DataAndMetadataCompoundIndexSpecConversion) { TimeseriesOptions timeseriesOptions = makeTimeseriesOptions(); BSONObj timeseriesIndexSpec = BSON(kTimeseriesSomeDataFieldName << 1 << kTimeseriesMetaFieldName << 1); BSONObj bucketsIndexSpec = - BSON(kBucketsSomeDataFieldName << 1 << timeseries::kBucketMetaFieldName << 1); + BSON(kControlMinSomeDataFieldName << 1 << kControlMaxSomeDataFieldName << 1 + << timeseries::kBucketMetaFieldName << 1); - testBothWaysIndexSpecConversion( - timeseriesOptions, timeseriesIndexSpec, bucketsIndexSpec, false /* testShouldSucceed */); + testBothWaysIndexSpecConversion(timeseriesOptions, timeseriesIndexSpec, bucketsIndexSpec); } // {mm.subfield1: 1, mm.subfield2: 1, mm.foo:1, mm.bar: 1, mm.baz: 1, tm: 1} <=> -- cgit v1.2.1