SERVER-117870 Fix aggregation view resolution concurrent to viewless timeseries upgrade (#47026)
GitOrigin-RevId: 7a9e77287614a2b91db9b6e1700761883c724f42
This commit is contained in:
parent
f74364871c
commit
c0ba541999
3
.github/CODEOWNERS
vendored
3
.github/CODEOWNERS
vendored
@ -1198,6 +1198,9 @@ WORKSPACE.bazel @10gen/devprod-build @svc-auto-approve-bot
|
||||
# The following patterns are parsed from ./jstests/multiVersion/genericSetFCVUsage/index_builds/OWNERS.yml
|
||||
/jstests/multiVersion/genericSetFCVUsage/index_builds/**/* @10gen/server-index-builds @svc-auto-approve-bot
|
||||
|
||||
# The following patterns are parsed from ./jstests/multiVersion/genericSetFCVUsage/query-optimization/OWNERS.yml
|
||||
/jstests/multiVersion/genericSetFCVUsage/query-optimization/**/* @10gen/query-optimization @svc-auto-approve-bot
|
||||
|
||||
# The following patterns are parsed from ./jstests/multiVersion/genericSetFCVUsage/shard_catalog/OWNERS.yml
|
||||
/jstests/multiVersion/genericSetFCVUsage/shard_catalog/**/* @10gen/server-catalog-and-routing-shard-catalog @svc-auto-approve-bot
|
||||
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
load("//bazel:mongo_js_rules.bzl", "all_subpackage_javascript_files", "mongo_js_library")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
mongo_js_library(
|
||||
name = "all_javascript_files",
|
||||
srcs = glob([
|
||||
"*.js",
|
||||
]),
|
||||
)
|
||||
|
||||
all_subpackage_javascript_files()
|
||||
@ -0,0 +1,5 @@
|
||||
version: 1.0.0
|
||||
filters:
|
||||
- "*":
|
||||
approvers:
|
||||
- 10gen/query-optimization
|
||||
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Tests that aggregations return correct results when a timeseries collection is upgraded from
|
||||
* viewful to viewless format mid-query. In particular, if the aggregation resolves the timeseries
|
||||
* view but the buckets collection is transformed to viewless timeseries before it can be acquired.
|
||||
*
|
||||
* @tags: [
|
||||
* requires_timeseries,
|
||||
* featureFlagCreateViewlessTimeseriesCollections,
|
||||
* ]
|
||||
*/
|
||||
|
||||
import {configureFailPoint} from "jstests/libs/fail_point_util.js";
|
||||
import {Thread} from "jstests/libs/parallelTester.js";
|
||||
import {ReplSetTest} from "jstests/libs/replsettest.js";
|
||||
|
||||
// TODO(SERVER-114573): Remove this test once 9.0 becomes lastLTS.
|
||||
if (lastLTSFCV != "8.0") {
|
||||
quit();
|
||||
}
|
||||
|
||||
const rst = new ReplSetTest({nodes: 1});
|
||||
rst.startSet();
|
||||
rst.initiate();
|
||||
|
||||
const primary = rst.getPrimary();
|
||||
const dbName = jsTestName();
|
||||
const collName = jsTestName();
|
||||
const testDB = primary.getDB(dbName);
|
||||
const coll = testDB[collName];
|
||||
|
||||
// Create timeseries in viewful format.
|
||||
assert.commandWorked(testDB.adminCommand({setFeatureCompatibilityVersion: lastLTSFCV, confirm: true}));
|
||||
assert.commandWorked(testDB.createCollection(collName, {timeseries: {timeField: "t"}}));
|
||||
assert.commandWorked(coll.insertOne({t: ISODate()}));
|
||||
|
||||
// Pause aggregation after resolving the view but before acquiring buckets.
|
||||
const fp = configureFailPoint(primary, "hangAfterAcquiringCollectionCatalog", {collection: collName});
|
||||
|
||||
const aggThread = new Thread(
|
||||
function (host, dbName, collName) {
|
||||
const conn = new Mongo(host);
|
||||
const result = conn.getDB(dbName).runCommand({aggregate: collName, pipeline: [], cursor: {}});
|
||||
assert.commandWorked(result);
|
||||
assert.eq(1, result.cursor.firstBatch.length);
|
||||
},
|
||||
primary.host,
|
||||
dbName,
|
||||
collName,
|
||||
);
|
||||
|
||||
aggThread.start();
|
||||
fp.wait();
|
||||
|
||||
// Upgrade FCV while aggregation is paused - converts viewful to viewless.
|
||||
assert.commandWorked(testDB.adminCommand({setFeatureCompatibilityVersion: latestFCV, confirm: true}));
|
||||
|
||||
// Release aggregation. We expect non-empty results.
|
||||
fp.off();
|
||||
aggThread.join();
|
||||
|
||||
rst.stopSet();
|
||||
@ -242,6 +242,30 @@ private:
|
||||
[&](const BSONObj& data) {
|
||||
return _aggExState.getExecutionNss().coll() == data["collection"].valueStringData();
|
||||
});
|
||||
|
||||
// TODO SERVER-111172: Remove this test once view-ful timeseries are removed and 9.0 is LTS.
|
||||
if (_aggExState.isView() && !_mainAcq->collectionExists() &&
|
||||
executionNss.isTimeseriesBucketsCollection()) {
|
||||
// We resolved a timeseries view, but didn't later find the targeted buckets collection.
|
||||
// If we continue execution, we will return no documents.
|
||||
//
|
||||
// This can happen in multiple ways, such as:
|
||||
// 1. Because the timeseries collection is being converted to viewless timeseries.
|
||||
// 2. Due to the timeseries collection (buckets + view) being concurrently dropped.
|
||||
// 3. Due to a 'orphaned' timeseries view (e.g. because of a stepdown during a drop).
|
||||
//
|
||||
// In scenario (1), it is incorrect to return empty results. Throw CollectionBecameView
|
||||
// to re-resolve the aggregation over the now viewless timeseries collection.
|
||||
//
|
||||
// In scenarios like (2) or (3), preserve the existing (v8.0) behavior of returning
|
||||
// empty results on queries over dropped or incomplete viewful timeseries collections.
|
||||
auto originalNssColl = CollectionCatalog::get(opCtx)->establishConsistentCollection(
|
||||
opCtx, _aggExState.getOriginalNss(), boost::none /* readTimestamp */);
|
||||
if (originalNssColl && originalNssColl->isTimeseriesCollection()) {
|
||||
uasserted(ErrorCodes::CollectionBecameView,
|
||||
"Timeseries collection upgraded to viewless format while resolving view");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user