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); }
// 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; }
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); }
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; }