@@ -82,6 +82,8 @@ var selectedNSSupportedCommands = map[string]struct{}{
82
82
}
83
83
84
84
var cloningNSSupportedCommands = map [string ]struct {}{
85
+ "create" : {},
86
+ "drop" : {},
85
87
"createIndexes" : {},
86
88
"deleteIndex" : {},
87
89
"deleteIndexes" : {},
@@ -103,11 +105,17 @@ var ErrNoCloningNamespace = errors.New("cloning namespace desn't exist")
103
105
// cloneNS has all data related to cloning namespace within oplog
104
106
type cloneNS struct {
105
107
snapshot.CloneNS
106
- toUUID primitive.Binary
108
+ fromDB string
109
+ fromColl string
110
+ toDB string
111
+ toColl string
112
+ toUUID primitive.Binary
107
113
}
108
114
109
115
func (c * cloneNS ) SetNSPair (nsPair snapshot.CloneNS ) {
110
116
c .CloneNS = nsPair
117
+ c .fromDB , c .fromColl , _ = strings .Cut (nsPair .FromNS , "." )
118
+ c .toDB , c .toColl , _ = strings .Cut (nsPair .ToNS , "." )
111
119
}
112
120
113
121
// OplogRestore is the oplog applyer
@@ -381,16 +389,15 @@ func (o *OplogRestore) isOpForCloning(oe *db.Oplog) bool {
381
389
return true // internal ops of applyOps are checked one by one later
382
390
}
383
391
384
- cloneFromDB , cloneFromColl , _ := strings .Cut (o .cloneNS .FromNS , "." )
385
- if db != cloneFromDB {
392
+ if db != o .cloneNS .fromDB {
386
393
// it's command not relevant for db to clone from
387
394
return false
388
395
}
389
396
390
397
if _ , ok := cloningNSSupportedCommands [cmd ]; ok {
391
398
// check if command targets collection
392
399
collForCmd , _ := oe .Object [0 ].Value .(string )
393
- if collForCmd == cloneFromColl {
400
+ if collForCmd == o . cloneNS . fromColl {
394
401
return true
395
402
}
396
403
}
@@ -769,10 +776,37 @@ func (o *OplogRestore) cloneEntry(op *db.Oplog) {
769
776
if ! o .cloneNS .IsSpecified () {
770
777
return
771
778
}
779
+
780
+ // op: i, u, d
772
781
if op .Namespace == o .cloneNS .FromNS {
773
- * op .UI = o . cloneNS . toUUID
782
+ op .UI = nil
774
783
op .Namespace = o .cloneNS .ToNS
784
+ return
785
+ }
786
+
787
+ if op .Operation != "c" || len (op .Object ) == 0 {
788
+ return
789
+ }
790
+
791
+ dbName , _ , _ := strings .Cut (op .Namespace , "." )
792
+ if dbName != o .cloneNS .fromDB {
793
+ return
794
+ }
795
+
796
+ cmdName := op .Object [0 ].Key
797
+ if cmdName != "create" && cmdName != "drop" {
798
+ return
775
799
}
800
+
801
+ collName , _ := op .Object [0 ].Value .(string )
802
+ if collName != o .cloneNS .fromColl {
803
+ return
804
+ }
805
+
806
+ // op: create/drop
807
+ op .Namespace = fmt .Sprintf ("%s.$cmd" , o .cloneNS .toDB )
808
+ op .Object [0 ].Value = o .cloneNS .toColl
809
+ op .UI = nil
776
810
}
777
811
778
812
func (o * OplogRestore ) handleNonTxnOp (op db.Oplog ) error {
0 commit comments