Exemple #1
0
    bool compact(const string& ns, string &errmsg, bool validate, BSONObjBuilder& result, double pf, int pb) {
        massert( 14028, "bad ns", NamespaceString::normal(ns.c_str()) );
        massert( 14027, "can't compact a system namespace", !str::contains(ns, ".system.") ); // items in system.indexes cannot be moved there are pointers to those disklocs in NamespaceDetails

        bool ok;
        {
            writelock lk;
            BackgroundOperation::assertNoBgOpInProgForNs(ns.c_str());
            Client::Context ctx(ns);
            NamespaceDetails *d = nsdetails(ns.c_str());
            massert( 13660, str::stream() << "namespace " << ns << " does not exist", d );
            massert( 13661, "cannot compact capped collection", !d->capped );
            log() << "compact " << ns << " begin" << endl;
            if( pf != 0 || pb != 0 ) { 
                log() << "paddingFactor:" << pf << " paddingBytes:" << pb << endl;
            } 
            try { 
                ok = _compact(ns.c_str(), d, errmsg, validate, result, pf, pb);
            }
            catch(...) { 
                log() << "compact " << ns << " end (with error)" << endl;
                throw;
            }
            log() << "compact " << ns << " end" << endl;
        }
        return ok;
    }
Exemple #2
0
Command& CommandCache::alloc( NodePtr node, LocalNodePtr localNode, 
                              const uint64_t size )
{
    EQ_TS_THREAD( _thread );

    const Cache which = (size > Packet::minSize) ? CACHE_BIG : CACHE_SMALL;

    _compact( which );
    Command& command = _newCommand( which );
    command._alloc( node, localNode, size );
    return command;
}
Command& CommandCache::alloc( NodePtr node, LocalNodePtr localNode, 
                              const uint64_t size )
{
    EQ_TS_THREAD( _thread );
    EQASSERTINFO( size < EQ_BIT48,
                  "Out-of-sync network stream: packet size " << size << "?" );

    const Cache which = (size > Packet::minSize) ? CACHE_BIG : CACHE_SMALL;

    _compact( which );
    Command& command = _newCommand( which );
    command.alloc_( node, localNode, size );
    return command;
}
Exemple #4
0
        virtual bool run(const string& db, BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) {
            string coll = cmdObj.firstElement().valuestr();
            if( coll.empty() || db.empty() ) {
                errmsg = "no collection name specified";
                return false;
            }

            if( isCurrentlyAReplSetPrimary() && !cmdObj["force"].trueValue() ) { 
                errmsg = "will not run compact on an active replica set primary as this is a slow blocking operation. use force:true to force";
                return false;
            }
            
            string ns = db + '.' + coll;
            if ( ! NamespaceString::normal(ns.c_str()) ) {
                errmsg = "bad namespace name";
                return false;
            }
            
            // parameter validation to avoid triggering assertions in compact()
            if ( str::contains(ns, ".system.") ) {
                errmsg = "can't compact a system namespace";
                return false;
            }
            
            {
                Lock::DBWrite lk(ns);
                Client::Context ctx(ns);
                NamespaceDetails *d = nsdetails(ns);
                if( ! d ) {
                    errmsg = "namespace does not exist";
                    return false;
                }

                if ( d->isCapped() ) {
                    errmsg = "cannot compact a capped collection";
                    return false;
                }
            }


            double pf = 1.0;
            int pb = 0;
            // preservePadding trumps all other compact methods
            bool preservePadding = false;
            // useDefaultPadding is used to track whether or not a padding requirement was passed in
            // if it wasn't than UsePowerOf2Sizes will be maintained when compacting
            bool useDefaultPadding = true;
            if (cmdObj.hasElement("preservePadding")) {
                preservePadding = cmdObj["preservePadding"].trueValue();
                useDefaultPadding = false;
            }

            if( cmdObj.hasElement("paddingFactor") ) {
                if (preservePadding == true) {
                    errmsg = "preservePadding is incompatible with paddingFactor";
                    return false;
                }
                useDefaultPadding = false;
                pf = cmdObj["paddingFactor"].Number();
                verify( pf >= 1.0 && pf <= 4.0 );
            }
            if( cmdObj.hasElement("paddingBytes") ) {
                if (preservePadding == true) {
                    errmsg = "preservePadding is incompatible with paddingBytes";
                    return false;
                }
                useDefaultPadding = false;
                pb = (int) cmdObj["paddingBytes"].Number();
                verify( pb >= 0 && pb <= 1024 * 1024 );
            }

            bool validate = !cmdObj.hasElement("validate") || cmdObj["validate"].trueValue(); // default is true at the moment

            massert( 14028, "bad ns", NamespaceString::normal(ns.c_str()) );
            massert( 14027, "can't compact a system namespace", !str::contains(ns, ".system.") ); // items in system.indexes cannot be moved there are pointers to those disklocs in NamespaceDetails

            bool ok;
            {
                Lock::DBWrite lk(ns);
                BackgroundOperation::assertNoBgOpInProgForNs(ns.c_str());
                Client::Context ctx(ns);
                NamespaceDetails *d = nsdetails(ns);
                massert( 13660, str::stream() << "namespace " << ns << " does not exist", d );
                massert( 13661, "cannot compact capped collection", !d->isCapped() );
                log() << "compact " << ns << " begin" << endl;

                std::vector<BSONObj> indexesInProg = stopIndexBuilds(db, cmdObj);

                if( pf != 0 || pb != 0 ) { 
                    log() << "paddingFactor:" << pf << " paddingBytes:" << pb << endl;
                } 
                try { 
                    ok = _compact(ns.c_str(), d, errmsg, validate,
                                  result, pf, pb, useDefaultPadding, preservePadding);
                }
                catch(...) { 
                    log() << "compact " << ns << " end (with error)" << endl;
                    throw;
                }
                log() << "compact " << ns << " end" << endl;

                IndexBuilder::restoreIndexes(indexesInProg);
            }

            return ok;
        }