Files
mongo/jstests/core/batch_write_command_insert.js
Max Hirschhorn 8302d0735b SERVER-24033 Write full index spec in oplog entry for index creation.
This ensures that the index version (aka the "v" field) is always
present in the oplog entry when creating indexes on a 3.4 primary.
We can therefore assume that if the "v" field isn't present in the
corresponding oplog entry, then a v=1 index should be built.

Changes MultiBlockIndex::init() to return the index specifications
that were actually created.

The "repairDatabase", "compact", "copydb", and "cloneCollection"
commands no longer automatically upgrade the index version to the
current default version. Instead, the only command that does so is
the "reIndex" command.
2016-09-14 20:49:17 -04:00

408 lines
10 KiB
JavaScript

//
// Ensures that mongod respects the batch write protocol for inserts
//
load("jstests/libs/get_index_helpers.js");
var coll = db.getCollection("batch_write_insert");
coll.drop();
assert(coll.getDB().getMongo().useWriteCommands(), "test is not running with write commands");
var request;
var result;
var batch;
var maxWriteBatchSize = 1000;
function resultOK(result) {
return result.ok && !('code' in result) && !('errmsg' in result) && !('errInfo' in result) &&
!('writeErrors' in result);
}
function resultNOK(result) {
return !result.ok && typeof(result.code) == 'number' && typeof(result.errmsg) == 'string';
}
// EACH TEST BELOW SHOULD BE SELF-CONTAINED, FOR EASIER DEBUGGING
//
// NO DOCS, illegal command
coll.remove({});
request = {
insert: coll.getName()
};
result = coll.runCommand(request);
assert(resultNOK(result), tojson(result));
//
// Single document insert, no write concern specified
coll.remove({});
request = {
insert: coll.getName(),
documents: [{a: 1}]
};
result = coll.runCommand(request);
assert(resultOK(result), tojson(result));
assert.eq(1, result.n);
assert.eq(coll.count(), 1);
//
// Single document insert, w:0 write concern specified, missing ordered
coll.remove({});
request = {
insert: coll.getName(),
documents: [{a: 1}],
writeConcern: {w: 0}
};
result = coll.runCommand(request);
assert(resultOK(result), tojson(result));
assert.eq(coll.count(), 1);
for (var field in result) {
assert.eq('ok', field, 'unexpected field found in result: ' + field);
}
//
// Single document insert, w:1 write concern specified, ordered:true
coll.remove({});
request = {
insert: coll.getName(),
documents: [{a: 1}],
writeConcern: {w: 1},
ordered: true
};
result = coll.runCommand(request);
assert(resultOK(result), tojson(result));
assert.eq(1, result.n);
assert.eq(coll.count(), 1);
//
// Single document insert, w:1 write concern specified, ordered:false
coll.remove({});
request = {
insert: coll.getName(),
documents: [{a: 1}],
writeConcern: {w: 1},
ordered: false
};
result = coll.runCommand(request);
assert(resultOK(result), tojson(result));
assert.eq(1, result.n);
assert.eq(coll.count(), 1);
//
// Document with illegal key should fail
coll.remove({});
request = {
insert: coll.getName(),
documents: [{$set: {a: 1}}],
writeConcern: {w: 1},
ordered: false
};
result = coll.runCommand(request);
assert(result.ok, tojson(result));
assert(result.writeErrors != null);
assert.eq(1, result.writeErrors.length);
assert.eq(0, result.n);
assert.eq(coll.count(), 0);
//
// Document with valid nested key should insert (op log format)
coll.remove({});
request = {
insert: coll.getName(),
documents: [{o: {$set: {a: 1}}}],
writeConcern: {w: 1},
ordered: false
};
result = coll.runCommand(request);
assert(resultOK(result), tojson(result));
assert.eq(1, result.n);
assert.eq(coll.count(), 1);
//
// Large batch under the size threshold should insert successfully
coll.remove({});
batch = [];
for (var i = 0; i < maxWriteBatchSize; ++i) {
batch.push({});
}
request = {
insert: coll.getName(),
documents: batch,
writeConcern: {w: 1},
ordered: false
};
result = coll.runCommand(request);
assert(resultOK(result), tojson(result));
assert.eq(batch.length, result.n);
assert.eq(coll.count(), batch.length);
//
// Large batch above the size threshold should fail to insert
coll.remove({});
batch = [];
for (var i = 0; i < maxWriteBatchSize + 1; ++i) {
batch.push({});
}
request = {
insert: coll.getName(),
documents: batch,
writeConcern: {w: 1},
ordered: false
};
result = coll.runCommand(request);
assert(resultNOK(result), tojson(result));
assert.eq(coll.count(), 0);
//
// Batch of size zero should fail to insert
coll.remove({});
request = {
insert: coll.getName(),
documents: []
};
result = coll.runCommand(request);
assert(resultNOK(result), tojson(result));
//
//
// Unique index tests
coll.remove({});
coll.ensureIndex({a: 1}, {unique: true});
//
// Should fail single insert due to duplicate key
coll.remove({});
coll.insert({a: 1});
request = {
insert: coll.getName(),
documents: [{a: 1}]
};
result = coll.runCommand(request);
assert(result.ok, tojson(result));
assert.eq(1, result.writeErrors.length);
assert.eq(0, result.n);
assert.eq(coll.count(), 1);
//
// Fail with duplicate key error on multiple document inserts, ordered false
coll.remove({});
request = {
insert: coll.getName(),
documents: [{a: 1}, {a: 1}, {a: 1}],
writeConcern: {w: 1},
ordered: false
};
result = coll.runCommand(request);
assert(result.ok, tojson(result));
assert.eq(1, result.n);
assert.eq(2, result.writeErrors.length);
assert.eq(coll.count(), 1);
assert.eq(1, result.writeErrors[0].index);
assert.eq('number', typeof result.writeErrors[0].code);
assert.eq('string', typeof result.writeErrors[0].errmsg);
assert.eq(2, result.writeErrors[1].index);
assert.eq('number', typeof result.writeErrors[1].code);
assert.eq('string', typeof result.writeErrors[1].errmsg);
assert.eq(coll.count(), 1);
//
// Fail with duplicate key error on multiple document inserts, ordered true
coll.remove({});
request = {
insert: coll.getName(),
documents: [{a: 1}, {a: 1}, {a: 1}],
writeConcern: {w: 1},
ordered: true
};
result = coll.runCommand(request);
assert(result.ok, tojson(result));
assert.eq(1, result.n);
assert.eq(1, result.writeErrors.length);
assert.eq(1, result.writeErrors[0].index);
assert.eq('number', typeof result.writeErrors[0].code);
assert.eq('string', typeof result.writeErrors[0].errmsg);
assert.eq(coll.count(), 1);
//
// Ensure _id is the first field in all documents
coll.remove({});
request = {
insert: coll.getName(),
documents: [{a: 1}, {a: 2, _id: 2}]
};
result = coll.runCommand(request);
assert.eq(2, coll.count());
coll.find().forEach(function(doc) {
var firstKey = null;
for (var key in doc) {
firstKey = key;
break;
}
assert.eq("_id", firstKey, tojson(doc));
});
//
//
// Index insertion tests - currently supported via bulk write commands
//
// Successful index creation
coll.drop();
request = {
insert: "system.indexes",
documents: [{ns: coll.toString(), key: {x: 1}, name: "x_1"}]
};
result = coll.runCommand(request);
assert(result.ok, tojson(result));
assert.eq(1, result.n);
var allIndexes = coll.getIndexes();
var spec = GetIndexHelpers.findByName(allIndexes, "x_1");
assert.neq(null, spec, "Index with name 'x_1' not found: " + tojson(allIndexes));
assert.lte(2, spec.v, tojson(spec));
// Test that a v=1 index can be created by inserting into the system.indexes collection.
coll.drop();
request = {
insert: "system.indexes",
documents: [{ns: coll.toString(), key: {x: 1}, name: "x_1", v: 1}]
};
result = coll.runCommand(request);
assert(result.ok, tojson(result));
assert.eq(1, result.n);
allIndexes = coll.getIndexes();
spec = GetIndexHelpers.findByName(allIndexes, "x_1");
assert.neq(null, spec, "Index with name 'x_1' not found: " + tojson(allIndexes));
assert.eq(1, spec.v, tojson(spec));
//
// Duplicate index insertion gives n = 0
coll.drop();
coll.ensureIndex({x: 1}, {unique: true});
request = {
insert: "system.indexes",
documents: [{ns: coll.toString(), key: {x: 1}, name: "x_1", unique: true}]
};
result = coll.runCommand(request);
assert(result.ok, tojson(result));
assert.eq(0, result.n, 'duplicate index insertion should give n = 0: ' + tojson(result));
assert(!('writeErrors' in result));
assert.eq(coll.getIndexes().length, 2);
//
// Invalid index insertion with mismatched collection db
coll.drop();
request = {
insert: "system.indexes",
documents: [{ns: "invalid." + coll.getName(), key: {x: 1}, name: "x_1", unique: true}]
};
result = coll.runCommand(request);
assert(!result.ok || (result.n == 0 && result.writeErrors.length == 1), tojson(result));
assert.eq(coll.getIndexes().length, 0);
//
// Empty index insertion
coll.drop();
request = {
insert: "system.indexes",
documents: [{}]
};
result = coll.runCommand(request);
assert(!result.ok || (result.n == 0 && result.writeErrors.length == 1), tojson(result));
assert.eq(coll.getIndexes().length, 0);
//
// Invalid index desc
coll.drop();
request = {
insert: "system.indexes",
documents: [{ns: coll.toString()}]
};
result = coll.runCommand(request);
assert(result.ok, tojson(result));
assert.eq(0, result.n);
assert.eq(0, result.writeErrors[0].index);
assert.eq(coll.getIndexes().length, 0);
//
// Invalid index desc
coll.drop();
request = {
insert: "system.indexes",
documents: [{ns: coll.toString(), key: {x: 1}}]
};
result = coll.runCommand(request);
print(tojson(result));
assert(result.ok, tojson(result));
assert.eq(0, result.n);
assert.eq(0, result.writeErrors[0].index);
assert.eq(coll.getIndexes().length, 1);
//
// Invalid index desc
coll.drop();
request = {
insert: "system.indexes",
documents: [{ns: coll.toString(), name: "x_1"}]
};
result = coll.runCommand(request);
assert(result.ok, tojson(result));
assert.eq(0, result.n);
assert.eq(0, result.writeErrors[0].index);
assert.eq(coll.getIndexes().length, 0);
//
// Cannot insert more than one index at a time through the batch writes
coll.drop();
request = {
insert: "system.indexes",
documents: [
{ns: coll.toString(), key: {x: 1}, name: "x_1"},
{ns: coll.toString(), key: {y: 1}, name: "y_1"}
]
};
result = coll.runCommand(request);
assert(!result.ok, tojson(result));
assert.eq(coll.getIndexes().length, 0);
//
// Ensure we error out correctly in the middle of a batch
coll.drop();
coll.insert({_id: 50}); // Create a document to force a duplicate key exception.
var bulk = coll.initializeOrderedBulkOp();
for (i = 1; i < 100; i++) {
bulk.insert({_id: i});
}
try {
bulk.execute();
assert(false, "should have failed due to duplicate key");
} catch (err) {
assert(coll.count() == 50, "Unexpected number inserted by bulk write: " + coll.count());
}
//
// Background index creation
// Note: due to SERVER-13304 this test is at the end of this file, and we don't drop
// the collection afterwards.
coll.drop();
coll.insert({x: 1});
request = {
insert: "system.indexes",
documents: [{ns: coll.toString(), key: {x: 1}, name: "x_1", background: true}]
};
result = coll.runCommand(request);
assert(result.ok, tojson(result));
assert.eq(1, result.n);
allIndexes = coll.getIndexes();
spec = GetIndexHelpers.findByName(allIndexes, "x_1");
assert.neq(null, spec, "Index with name 'x_1' not found: " + tojson(allIndexes));
assert.lte(2, spec.v, tojson(spec));