Skip to content

Commit c9934b9

Browse files
authored
TOOLS-4105 Allow mongorestore to handle forceNonUnique option in collMod ops (#901)
This commit allows mongorestore to handle `forceNonUnique` option in collMod ops. The logic to handle index collMod is modified so that `forceNonUnique` don't conflict with `unique`.
1 parent 50a7efd commit c9934b9

5 files changed

Lines changed: 47 additions & 10 deletions

File tree

common/idx/index_catalog.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,9 +331,22 @@ func (i *IndexCatalog) collMod(database, collection string, indexModValue any) e
331331
continue
332332
}
333333

334-
if k == "expireAfterSeconds" || k == "hidden" || k == "prepareUnique" || k == "unique" {
334+
if k == "expireAfterSeconds" || k == "hidden" || k == "prepareUnique" {
335335
matchingIndex.Options[k] = element.Value
336+
} else if k == "unique" || k == "forceNonUnique" {
337+
v, boolOk := element.Value.(bool)
338+
if !boolOk {
339+
return errors.Errorf("cannot convert %s value to bool: %v", k, element.Value)
340+
}
341+
342+
if k == "unique" && v {
343+
delete(matchingIndex.Options, "forceNonUnique")
344+
}
336345

346+
if k == "forceNonUnique" && v {
347+
delete(matchingIndex.Options, "unique")
348+
}
349+
matchingIndex.Options[k] = v
337350
} else {
338351
return errors.Errorf("unknown index option: %v", k)
339352
}

mongodump/oplog_dump_test.go

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ func vectoredInsert(ctx context.Context) error {
136136
return nil
137137
}
138138

139-
func TestOplogDumpCollModPrepareUnique(t *testing.T) {
139+
func TestOplogDumpCollModIndexUniqueness(t *testing.T) {
140140
testtype.SkipUnlessTestType(t, testtype.IntegrationTestType)
141141
// Oplog is not available in a standalone topology.
142142
testtype.SkipUnlessTestType(t, testtype.ReplSetTestType)
@@ -157,6 +157,9 @@ func TestOplogDumpCollModPrepareUnique(t *testing.T) {
157157

158158
testCollName := testCollectionNames[0]
159159

160+
err = session.Database(testDB).Collection(testCollName).Drop(ctx)
161+
require.NoError(t, err)
162+
160163
err = session.Database(testDB).CreateCollection(ctx, testCollName)
161164
require.NoError(t, err)
162165
//nolint:errcheck
@@ -167,7 +170,7 @@ func TestOplogDumpCollModPrepareUnique(t *testing.T) {
167170

168171
md.ToolOptions.DB = ""
169172
md.OutputOptions.Oplog = true
170-
md.OutputOptions.Out = "collMod_prepareUnique"
173+
md.OutputOptions.Out = "collMod_indexUniqueness"
171174

172175
require.NoError(t, md.Init())
173176

@@ -176,7 +179,7 @@ func TestOplogDumpCollModPrepareUnique(t *testing.T) {
176179
defer failpoint.Reset()
177180

178181
go func() {
179-
require.NoError(t, createIndexesAndRunCollModPrepareUnique(ctx))
182+
require.NoError(t, createIndexesAndCollModIndexUniqueness(ctx))
180183
}()
181184

182185
//nolint:errcheck
@@ -187,7 +190,7 @@ func TestOplogDumpCollModPrepareUnique(t *testing.T) {
187190
path, err := os.Getwd()
188191
require.NoError(t, err)
189192

190-
dumpDir := util.ToUniversalPath(filepath.Join(path, "collMod_prepareUnique"))
193+
dumpDir := util.ToUniversalPath(filepath.Join(path, "collMod_indexUniqueness"))
191194
dumpDBDir := util.ToUniversalPath(filepath.Join(dumpDir, testDB))
192195
oplogFilePath := util.ToUniversalPath(filepath.Join(dumpDir, "oplog.bson"))
193196
require.True(t, fileDirExists(dumpDir))
@@ -203,28 +206,33 @@ func TestOplogDumpCollModPrepareUnique(t *testing.T) {
203206
bsonSrc := db.NewDecodedBSONSource(db.NewBufferlessBSONSource(oplogFile))
204207
prepareUniqueTrueCount := 0
205208
prepareUniqueFalseCount := 0
209+
forceNonUniqueCount := 0
206210

207211
var oplog db.Oplog
208212
for bsonSrc.Next(&oplog) {
209213
require.NoError(t, bsonSrc.Err())
210214

211215
if oplog.Namespace == testDB+".$cmd" {
212216
indexDoc, ok := bsonutil.ToMap(oplog.Object)["index"].(bson.D)
217+
indexDocMap := bsonutil.ToMap(indexDoc)
213218
if ok {
214-
if bsonutil.ToMap(indexDoc)["prepareUnique"] == true {
219+
if indexDocMap["prepareUnique"] == true {
215220
prepareUniqueTrueCount++
216-
} else {
221+
} else if indexDocMap["prepareUnique"] == false {
217222
prepareUniqueFalseCount++
223+
} else if indexDocMap["forceNonUnique"] == true {
224+
forceNonUniqueCount++
218225
}
219226
}
220227
}
221228
}
222229
require.NoError(t, oplogFile.Close())
223230
require.Equal(t, 8, prepareUniqueTrueCount)
224231
require.Equal(t, 4, prepareUniqueFalseCount)
232+
require.Equal(t, 4, forceNonUniqueCount)
225233
}
226234

227-
func createIndexesAndRunCollModPrepareUnique(ctx context.Context) error {
235+
func createIndexesAndCollModIndexUniqueness(ctx context.Context) error {
228236
client, err := testutil.GetBareSession()
229237
if err != nil {
230238
return err
@@ -274,6 +282,22 @@ func createIndexesAndRunCollModPrepareUnique(ctx context.Context) error {
274282
return res.Err()
275283
}
276284
}
285+
286+
for _, option := range []string{"unique", "forceNonUnique"} {
287+
res := client.Database(testDB).RunCommand(
288+
ctx,
289+
bson.D{
290+
{"collMod", testCollName},
291+
{"index", bson.D{
292+
{"keyPattern", index.Keys},
293+
{option, true},
294+
}},
295+
},
296+
)
297+
if res.Err() != nil {
298+
return res.Err()
299+
}
300+
}
277301
}
278302

279303
return nil

mongorestore/oplog_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -769,7 +769,7 @@ func testOplogRestoreVectoredInsert(t *testing.T, linked bool) {
769769
require.Equal(t, len(expectedDocs), i)
770770
}
771771

772-
func TestOplogRestoreCollModPrepareUnique(t *testing.T) {
772+
func TestOplogRestoreCollModIndexUniqueness(t *testing.T) {
773773
testtype.SkipUnlessTestType(t, testtype.IntegrationTestType)
774774

775775
ctx := t.Context()
@@ -793,7 +793,7 @@ func TestOplogRestoreCollModPrepareUnique(t *testing.T) {
793793
require.NoError(t, session.Database("mongodump_test_db").Drop(ctx))
794794
require.NoError(t, session.Database("mongodump_test_db").CreateCollection(ctx, "coll1"))
795795

796-
oplogFileName := "testdata/oplogs/bson/collMod_prepareUnique.bson"
796+
oplogFileName := "testdata/oplogs/bson/collMod_indexUniqueness.bson"
797797

798798
args := []string{
799799
DirectoryOption, "testdata/coll_without_index",
6.54 KB
Binary file not shown.
-4.41 KB
Binary file not shown.

0 commit comments

Comments
 (0)