示例#1
0
文件: insert.cpp 项目: aberg001/mongo
    void insertObjects(const char *ns, const vector<BSONObj> &objs, bool keepGoing, uint64_t flags, bool logop ) {
        StringData _ns(ns);
        if (NamespaceString::isSystem(_ns)) {
            massert(16748, "need transaction to run insertObjects", cc().txnStackSize() > 0);
            uassert(10095, "attempt to insert in reserved database name 'system'", nsToDatabaseSubstring(_ns) != "system");
            massert(16750, "attempted to insert multiple objects into a system namspace at once", objs.size() == 1);

            // Trying to insert into a system collection.  Fancy side-effects go here:
            if (nsToCollectionSubstring(ns) == "system.indexes") {
                BSONObj obj = stripDropDups(objs[0]);
                NamespaceDetails *d = getAndMaybeCreateNS(obj["ns"].Stringdata(), logop);
                bool ok = d->ensureIndex(obj);
                if (!ok) {
                    // Already had that index
                    return;
                }

                // Now we have to actually insert that document into system.indexes, we may have
                // modified it with stripDropDups.
                vector<BSONObj> newObjs;
                newObjs.push_back(obj);
                _insertObjects(ns, newObjs, keepGoing, flags, logop);
                return;
            } else if (!legalClientSystemNS(ns, true)) {
                uasserted(16459, str::stream() << "attempt to insert in system namespace '" << ns << "'");
            }
        }
        _insertObjects(ns, objs, keepGoing, flags, logop);
    }
示例#2
0
    static void _buildHotIndex(const char *ns, Message &m, const vector<BSONObj> objs) {
        uassert(16905, "Can only build one index at a time.", objs.size() == 1);

        DEV {
            // System.indexes cannot be sharded.
            Client::ShardedOperationScope sc;
            verify(!sc.handlePossibleShardedMessage(m, 0));
        }

        LOCK_REASON(lockReason, "building hot index");
        scoped_ptr<Lock::DBWrite> lk(new Lock::DBWrite(ns, lockReason));

        uassert(16902, "not master", isMasterNs(ns));

        const BSONObj &info = objs[0];
        const StringData &coll = info["ns"].Stringdata();

        scoped_ptr<Client::Transaction> transaction(new Client::Transaction(DB_SERIALIZABLE));
        shared_ptr<Collection::Indexer> indexer;

        // Prepare the index build. Performs index validation and marks
        // the collection as having an index build in progress.
        {
            Client::Context ctx(ns);
            Collection *cl = getOrCreateCollection(coll, true);
            if (cl->findIndexByKeyPattern(info["key"].Obj()) >= 0) {
                // No error or action if the index already exists. We need to commit
                // the transaction in case this is an ensure index on the _id field
                // and the ns was created by getOrCreateCollection()
                transaction->commit();
                return;
            }

            _insertObjects(ns, objs, false, 0, true);
            indexer = cl->newIndexer(info, true);
            indexer->prepare();
        }

        // Perform the index build
        {
            Lock::DBWrite::Downgrade dg(lk);
            uassert(16906, "not master: after indexer setup but before build", isMasterNs(ns));

            Client::Context ctx(ns);
            indexer->build();
        }

        uassert(16907, "not master: after indexer build but before commit", isMasterNs(ns));

        // Commit the index build
        {
            Client::Context ctx(ns);
            indexer->commit();
        }
        transaction->commit();
    }