Exemple #1
0
    void IndexRebuilder::checkNS(const std::list<std::string>& nsToCheck) {
        bool firstTime = true;
        for (std::list<std::string>::const_iterator it = nsToCheck.begin();
                it != nsToCheck.end();
                ++it) {

            // This write lock is held throughout the index building process
            // for this namespace.
            Client::WriteContext ctx(*it);
            Collection* collection = ctx.ctx().db()->getCollection( *it );
            if ( collection == NULL )
                continue;

            IndexCatalog* indexCatalog = collection->getIndexCatalog();

            if ( indexCatalog->numIndexesInProgress() == 0 ) {
                continue;
            }

            log() << "found interrupted index build(s) on " << *it << endl;

            if (firstTime) {
                log() << "note: restart the server with --noIndexBuildRetry to skip index rebuilds";
                firstTime = false;
            }

            // If the indexBuildRetry flag isn't set, just clear the inProg flag
            if (!serverGlobalParams.indexBuildRetry) {
                // If we crash between unsetting the inProg flag and cleaning up the index, the
                // index space will be lost.
                Status s = indexCatalog->blowAwayInProgressIndexEntries();
                if ( !s.isOK() ) {
                    log() << "failed to blowAwayInProgressIndexEntries: " << s;
                    fassertFailed( 17201 );
                }
                continue;
            }

            // We go from right to left building these indexes, so that indexBuildInProgress-- has
            // the correct effect of "popping" an index off the list.
            while ( indexCatalog->numIndexesInProgress() > 0 ) {
                // First, clean up the in progress index build.  Save the system.indexes entry so that we
                // can add it again afterwards.
                BSONObj indexObj = indexCatalog->prepOneUnfinishedIndex();

                // The index has now been removed from system.indexes, so the only record of it is
                // in-memory. If there is a journal commit between now and when insert() rewrites
                // the entry and the db crashes before the new system.indexes entry is journalled,
                // the index will be lost forever.  Thus, we're assuming no journaling will happen
                // between now and the entry being re-written.

                try {
                    // TODO
                    const std::string ns = collection->ns().getSystemIndexesCollection();
                    theDataFileMgr.insert(ns.c_str(), indexObj.objdata(), indexObj.objsize(), false, true);
                }
                catch (const DBException& e) {
                    log() << "building index failed: " << e.what() << " (" << e.getCode() << ")";
                }
            }
        }
    }