web-dev-qa-db-fra.com

MongoDB - Erreur: échec de la commande getMore: curseur introuvable

Je dois créer un nouveau champ sid sur chaque document dans une collection d'environ 500 000 documents. Chaque sid est unique et basé sur les champs roundedDate et stream existants de cet enregistrement.

Je le fais avec le code suivant:

var cursor = db.getCollection('snapshots').find();
var iterated = 0;
var updated = 0;

while (cursor.hasNext()) {
    var doc = cursor.next();

    if (doc.stream && doc.roundedDate && !doc.sid) {
        db.getCollection('snapshots').update({ "_id": doc['_id'] }, {
            $set: {
                sid: doc.stream.valueOf() + '-' + doc.roundedDate,
            }
        });

        updated++;
    }

    iterated++;
}; 

print('total ' + cursor.count() + ' iterated through ' + iterated + ' updated ' + updated);

Cela fonctionne bien au début, mais après quelques heures et environ 100K enregistre les erreurs avec:

Error: getMore command failed: {
    "ok" : 0,
    "errmsg": "Cursor not found, cursor id: ###",
    "code": 43,
}: ...

 mongo error

14
Chava Sobreyra

C'est un bogue dans la gestion de la session du serveur mongodb. Correction en cours, devrait être corrigé dans 4.0+

SERVER-34810: l'actualisation du cache de session peut tuer par erreur des curseurs toujours utilisés

(reproduit dans MongoDB 3.6.5)

l'ajout de collection.find().batchSize(20) m'a aidé avec une performance réduite.

2
Vladimir Ishenko

J'ai également rencontré ce problème, mais pour moi, il était causé par un bogue dans le pilote MongDB.

Cela s'est passé dans la version 3.0.x du paquet npm mongodb, qui est par exemple. utilisé dans Meteor 1.7.0.x, où j’ai également enregistré ce problème. Il est décrit plus en détail dans ce commentaire et le fil de discussion contient un exemple de projet confirmant le bogue: https://github.com/meteor/meteor/issues/9944#issuecomment-420542042

La mise à jour du paquet npm vers 3.1.x a corrigé le problème, car j'avais déjà pris en compte les bons conseils donnés ici par @Danziger.

1
SimonSimCity

Lors de l'utilisation du pilote Java v3, noCursorTimeout doit être défini dans FindOptions.

DBCollectionFindOptions options =
                    new DBCollectionFindOptions()
                        .maxTime(90, TimeUnit.MINUTES)
                        .noCursorTimeout(true)
                        .batchSize(batchSize)
                        .projection(projectionQuery);        
cursor = collection.find(filterQuery, options);
0
user1240792