mirror of https://github.com/mongodb/mongo
116 lines
3.6 KiB
JavaScript
116 lines
3.6 KiB
JavaScript
/**
|
|
* Initial sync runs in several phases - the first 3 are as follows:
|
|
* 1) fetches the last oplog entry (op_start1) on the source;
|
|
* 2) copies all non-local databases from the source; and
|
|
* 3) fetches and applies operations from the source after op_start1.
|
|
*
|
|
* Between phases 1 and 2, this test updates array fields and subdocument fields with both the
|
|
* "update" and "applyOps" commands on the source, then replaces the array/subdoc fields with
|
|
* strings. The secondary will fail to apply the update operation in phase 3 but initial sync
|
|
* completes nevertheless. The absence of the array/subdoc on the source indicates that a later
|
|
* operation has replaced the field, so the target is free to ignore the failed update operation.
|
|
*/
|
|
|
|
import {ReplSetTest} from "jstests/libs/replsettest.js";
|
|
import {finishAndValidate, reInitiateSetWithSecondary} from "jstests/replsets/libs/initial_sync_update_missing_doc.js";
|
|
|
|
const replSet = new ReplSetTest({nodes: 1});
|
|
|
|
replSet.startSet();
|
|
replSet.initiate();
|
|
|
|
const primary = replSet.getPrimary();
|
|
const dbName = "test";
|
|
const collectionName = jsTestName();
|
|
|
|
const db = primary.getDB(dbName);
|
|
const coll = db.getCollection(collectionName);
|
|
|
|
jsTestLog("Insert some documents with array and subdocument fields");
|
|
|
|
for (let i = 0; i < 8; ++i) {
|
|
assert.commandWorked(coll.insertOne({_id: i, array: [0], doc: {field: 0}}));
|
|
}
|
|
|
|
jsTestLog("Add a secondary");
|
|
|
|
const secondaryConfig = {
|
|
rsConfig: {votes: 0, priority: 0},
|
|
};
|
|
const secondary = reInitiateSetWithSecondary(replSet, secondaryConfig);
|
|
|
|
jsTestLog("Use both 'update' and 'applyOps' to update docs on primary");
|
|
|
|
coll.updateMany({}, {$set: {scalar: 0}});
|
|
|
|
// Update the 8 documents in different ways:
|
|
// * use updateOne or applyOps
|
|
// * update the subdocument or array field
|
|
// * also update the scalar field, or don't
|
|
assert.commandWorked(coll.updateOne({_id: 1}, {$set: {"doc.field": 1, "scalar": 1}}));
|
|
assert.commandWorked(coll.updateOne({_id: 0}, {$set: {"doc.field": 1}}));
|
|
|
|
assert.commandWorked(coll.updateOne({_id: 3}, {$set: {"array.0": 1, "scalar": 1}}));
|
|
assert.commandWorked(coll.updateOne({_id: 2}, {$set: {"array.0": 1}}));
|
|
|
|
assert.commandWorked(
|
|
primary.adminCommand({
|
|
applyOps: [
|
|
{
|
|
op: "u",
|
|
ns: coll.getFullName(),
|
|
o2: {_id: 5},
|
|
o: {$v: 2, diff: {u: {"scalar": 1}, sdoc: {u: {field: 1}}}},
|
|
},
|
|
],
|
|
}),
|
|
);
|
|
|
|
assert.commandWorked(
|
|
primary.adminCommand({
|
|
applyOps: [{op: "u", ns: coll.getFullName(), o2: {_id: 4}, o: {$v: 2, diff: {sdoc: {u: {field: 1}}}}}],
|
|
}),
|
|
);
|
|
|
|
assert.commandWorked(
|
|
primary.adminCommand({
|
|
applyOps: [
|
|
{
|
|
op: "u",
|
|
ns: coll.getFullName(),
|
|
o2: {_id: 7},
|
|
o: {$v: 2, diff: {u: {"scalar": 1}, sarray: {a: true, u0: 1}}},
|
|
},
|
|
],
|
|
}),
|
|
);
|
|
|
|
assert.commandWorked(
|
|
primary.adminCommand({
|
|
applyOps: [
|
|
{
|
|
op: "u",
|
|
ns: coll.getFullName(),
|
|
o2: {_id: 6},
|
|
o: {$v: 2, diff: {sarray: {a: true, u0: 1}}},
|
|
},
|
|
],
|
|
}),
|
|
);
|
|
|
|
jsTestLog("Set array and subdoc fields to strings on primary");
|
|
|
|
assert.commandWorked(coll.updateMany({}, {$set: {array: "string", doc: "string"}}));
|
|
|
|
jsTestLog("Allow initial sync to finish");
|
|
|
|
assert.commandWorked(
|
|
secondary.getDB("admin").runCommand({configureFailPoint: "initialSyncHangBeforeCopyingDatabases", mode: "off"}),
|
|
);
|
|
|
|
jsTestLog(`Collection on primary: ${tojson(coll.find().toArray())}`);
|
|
|
|
finishAndValidate(replSet, collectionName, 8);
|
|
|
|
replSet.stopSet();
|