Beispiel #1
0
 static void runDeleteFromOplogWithLock(const char* ns, BSONObj op) {
     NamespaceDetails* nsd = nsdetails(ns);
     BSONObj row = op[KEY_STR_ROW].Obj();
     BSONObj pk = row["_id"].wrap("");
     uint64_t flags = NamespaceDetails::NO_LOCKTREE;
     deleteOneObject(nsd, pk, row, flags);
 }
Beispiel #2
0
    // Special-cased helper for deleting ranges out of an index.
    long long deleteIndexRange(const string &ns,
                               const BSONObj &min,
                               const BSONObj &max,
                               const BSONObj &keyPattern,
                               const bool maxInclusive,
                               const bool fromMigrate) {
        Collection *cl = getCollection(ns);
        if (cl == NULL) {
            return 0;
        }

        IndexDetails &i = cl->idx(cl->findIndexByKeyPattern(keyPattern));
        // Extend min to get (min, MinKey, MinKey, ....)
        KeyPattern kp(keyPattern);
        BSONObj newMin = KeyPattern::toKeyFormat(kp.extendRangeBound(min, false));
        // If upper bound is included, extend max to get (max, MaxKey, MaxKey, ...)
        // If not included, extend max to get (max, MinKey, MinKey, ....)
        BSONObj newMax = KeyPattern::toKeyFormat(kp.extendRangeBound(max, maxInclusive));

        long long nDeleted = 0;
        for (shared_ptr<Cursor> c(Cursor::make(cl, i, newMin, newMax, maxInclusive, 1));
             c->ok(); c->advance()) {
            const BSONObj pk = c->currPK();
            const BSONObj obj = c->current();
            OpLogHelpers::logDelete(ns.c_str(), obj, fromMigrate);
            deleteOneObject(cl, pk, obj);
            nDeleted++;
        }
        return nDeleted;
    }
Beispiel #3
0
 void removeDataFromDocsMap() {
     Client::Transaction txn(DB_SERIALIZABLE);
     RollbackDocsMapIterator docsMap;
     size_t numDocs = 0;
     log() << "Removing documents from collections for rollback." << rsLog;
     for (RollbackDocsMapIterator it; it.ok(); it.advance()){
         numDocs++;
         DocID curr = it.current();
         LOCK_REASON(lockReason, "repl: deleting a doc during rollback");
         Client::ReadContext ctx(curr.ns, lockReason);
         Collection* cl = getCollection(curr.ns);
         verify(cl);
         BSONObj currDoc;
         LOG(2) << "Finding by pk of " << curr.pk << rsLog;
         bool found = cl->findByPK(curr.pk, currDoc);
         if (found) {
             deleteOneObject(cl, curr.pk, currDoc, Collection::NO_LOCKTREE);
         }
     }
     log() << "Done removing " << numDocs << " documents from collections for rollback." << rsLog;
     updateRollbackStatus(BSON("_id" << ROLLBACK_ID << "state" << RB_DOCS_REMOVED<< \
         "info" << "removed docs from docs map"));
     txn.commit(DB_TXN_NOSYNC);
 }
Beispiel #4
0
    long long _deleteObjects(const char *ns, BSONObj pattern, bool justOne, bool logop) {
        Collection *cl = getCollection(ns);
        if (cl == NULL) {
            return 0;
        }

        uassert(10101, "can't remove from a capped collection", !cl->isCapped());

        BSONObj obj;
        BSONObj pk = cl->getSimplePKFromQuery(pattern);

        // Fast-path for simple primary key deletes.
        if (!pk.isEmpty()) {
            if (queryByPKHack(cl, pk, pattern, obj)) {
                if (logop) {
                    OpLogHelpers::logDelete(ns, obj, false);
                }
                deleteOneObject(cl, pk, obj);
                return 1;
            }
            return 0;
        }

        long long nDeleted = 0;
        for (shared_ptr<Cursor> c = getOptimizedCursor(ns, pattern); c->ok(); ) {
            pk = c->currPK();
            if (c->getsetdup(pk)) {
                c->advance();
                continue;
            }
            if (!c->currentMatches()) {
                c->advance();
                continue;
            }

            obj = c->current();

            // justOne deletes do not intend to advance, so there's
            // no reason to do so here and potentially overlock rows.
            if (!justOne) {
                // There may be interleaved query plans that utilize multiple
                // cursors, some of which point to the same PK. We advance
                // here while those cursors point the row to be deleted.
                // 
                // Make sure to get local copies of pk/obj before advancing.
                pk = pk.getOwned();
                obj = obj.getOwned();
                while (c->ok() && c->currPK() == pk) {
                    c->advance();
                }
            }

            if (logop) {
                OpLogHelpers::logDelete(ns, obj, false);
            }
            deleteOneObject(cl, pk, obj);
            nDeleted++;

            if (justOne) {
                break;
            }
        }
        return nDeleted;
    }