[SERVER-48397] Make collMod no-op behaviour consistent Created: 25/May/20  Updated: 06/Dec/22

Status: Backlog
Project: Core Server
Component/s: Index Maintenance
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major - P3
Reporter: Bernard Gorman Assignee: Backlog - Query Execution
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
is duplicated by SERVER-48191 Consider making collMod for index opt... Closed
Related
is related to SERVER-48047 Do not generate "hidden" field in opl... Closed
Assigned Teams:
Query Execution
Participants:

 Description   

As of SERVER-48047, a collMod command which attempts to set an index's hidden field to the same value as it already has in the index catalog results in a no-op. The hidden field will be omitted in the collMod oplog entry, and the command response will not include any information about the hidden field. This was necessary in order to support hidden indexes in multiversion scenarios.

However, the same is not currently true of the expireAfterSeconds field. If the user attempts to set this to the same value it already has, then the corresponding oplog entry will redundantly include the expireAfterSeconds field, and the command response will explicitly list the (identical) old and new values of the parameter.

We should decide which behaviour we want, both in terms of the oplog entry and the command response, and make sure that both fields are handled consistently. This may involve pushing the no-op detection down to the replication system here.



 Comments   
Comment by Bernard Gorman [ 26/May/20 ]

daniel.gottlieb, judah.schvimer, for clarity: we do still generate an oplog entry if collMod's hidden value is a "no-op", i.e. the same as the existing value. But this oplog entry does not contain the hidden field - it is effectively the same as if the user had issued an empty collMod command.

replset:PRIMARY> db.runCommand({collMod: "testing", index: {name: "a_1", hidden: false}})
{
	"ok" : 1,
	"$clusterTime" : {
		"clusterTime" : Timestamp(1590518288, 1),
		"signature" : {
			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
			"keyId" : NumberLong(0)
		}
	},
	"operationTime" : Timestamp(1590518288, 1)
}
replset:PRIMARY> use local
switched to db local
replset:PRIMARY> db.oplog.rs.find()
...
{ "op" : "c", "ns" : "test.$cmd", "ui" : UUID("66005930-6300-4b6c-bfb8-96744ec1b4c1"), "o" : { "collMod" : "testing" }, "o2" : { "collectionOptions_old" : { "uuid" : UUID("66005930-6300-4b6c-bfb8-96744ec1b4c1") } }, "ts" : Timestamp(1590518288, 1), "t" : NumberLong(1), "wall" : ISODate("2020-05-26T18:38:08.436Z"), "v" : NumberLong(2) }

Comment by Judah Schvimer [ 26/May/20 ]

collmod should be able to accept a write concern.

I'm not familiar enough to know whether all of commands buy into this, or if they each have to instrument the logic.

All commands are expected to buy into "noop writes still wait for write concern". collmod should have this behavior. If we have any concern though, we should test this. It doesn't look like we already have a test.

Comment by Daniel Gottlieb (Inactive) [ 26/May/20 ]

Not necessarily related, but this ticket mentioned two keywords (no-op and user) that trigger me to communicate some subtle, but intended MongoDB behavior. Apologies if I've assumed the ticket is going somewhere that it's not.

Can collmod accept a write concern (e.g: "majority")?

One of behavior's we've converged on (with "normal" updates) is not assuming a no-op update means the intended update has satisfied its write concern. Consider the following:

| Writer 1                        | Writer 2                                      |
|---------------------------------+-----------------------------------------------|
| Insert {_id: 1, a: 1}           |                                               |
| Update {_id: 1}, {$set: {a: 2}} |                                               |
|                                 | Update {_id: 1}, {$set: {a: 2}} w: "majority" |

Even though the second update is a no-op (in the oplog), we have code that makes sure the response doesn't return to the client until the version of the document that was read is guaranteed to be majority committed. I'm not familiar enough to know whether all of commands buy into this, or if they each have to instrument the logic.

Generated at Thu Feb 08 05:17:00 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.