Example #1
0
Status ChunkManagerTargeter::targetDelete( const BatchedDeleteDocument& deleteDoc,
        vector<ShardEndpoint*>* endpoints ) const {

    Status result = targetQuery( deleteDoc.getQuery(), endpoints );
    if ( !result.isOK() ) return result;

    if ( _manager ) {

        //
        // Sharded collections have the following further requirements for targeting:
        //
        // Limit-1 deletes must be targeted exactly by shard key *or* exact _id
        //

        bool exactShardKeyQuery = _manager->hasShardKey( deleteDoc.getQuery() );
        bool exactIdQuery = isExactIdQuery( deleteDoc.getQuery() );

        if ( deleteDoc.getLimit() == 1 && !exactShardKeyQuery && !exactIdQuery ) {
            return Status( ErrorCodes::ShardKeyNotFound,
                           stream() << "delete " << deleteDoc.toBSON()
                           << " does not contain _id or shard key for pattern "
                           << _manager->getShardKey().key() );
        }
    }

    return result;
}
Status ChunkManagerTargeter::targetDelete(OperationContext* txn,
                                          const BatchedDeleteDocument& deleteDoc,
                                          vector<ShardEndpoint*>* endpoints) const {
    BSONObj shardKey;

    if (_manager) {
        //
        // Sharded collections have the following further requirements for targeting:
        //
        // Limit-1 deletes must be targeted exactly by shard key *or* exact _id
        //

        // Get the shard key
        StatusWith<BSONObj> status =
            _manager->getShardKeyPattern().extractShardKeyFromQuery(deleteDoc.getQuery());

        // Bad query
        if (!status.isOK())
            return status.getStatus();

        shardKey = status.getValue();

        // Validate that single (limit-1) sharded deletes are targeted by shard key or _id
        if (deleteDoc.getLimit() == 1 && shardKey.isEmpty() &&
            !isExactIdQuery(deleteDoc.getQuery())) {
            return Status(ErrorCodes::ShardKeyNotFound,
                          stream() << "delete " << deleteDoc.toBSON()
                                   << " does not contain _id or shard key for pattern "
                                   << _manager->getShardKeyPattern().toString());
        }
    }

    // Target the shard key or delete query
    if (!shardKey.isEmpty()) {
        // We can't rely on our query targeting to be exact
        ShardEndpoint* endpoint = NULL;
        Status result = targetShardKey(txn, shardKey, 0, &endpoint);
        endpoints->push_back(endpoint);
        return result;
    } else {
        return targetQuery(deleteDoc.getQuery(), endpoints);
    }
}
    Status ChunkManagerTargeter::targetDelete( const BatchedDeleteDocument& deleteDoc,
                                               vector<ShardEndpoint*>* endpoints ) const {

        bool exactShardKeyQuery = false;

        if ( _manager ) {

            //
            // Sharded collections have the following further requirements for targeting:
            //
            // Limit-1 deletes must be targeted exactly by shard key *or* exact _id
            //

            exactShardKeyQuery = _manager->hasTargetableShardKey(deleteDoc.getQuery());
            bool exactIdQuery = isExactIdQuery( deleteDoc.getQuery() );

            if ( deleteDoc.getLimit() == 1 && !exactShardKeyQuery && !exactIdQuery ) {
                return Status( ErrorCodes::ShardKeyNotFound,
                               stream() << "delete " << deleteDoc.toBSON()
                                        << " does not contain _id or shard key for pattern "
                                        << _manager->getShardKey().key() );
            }
        }

        Status result = Status::OK();
        if (exactShardKeyQuery) {
            // We can't rely on our query targeting to be exact
            ShardEndpoint* endpoint = NULL;
            result = targetShardKey(deleteDoc.getQuery(), &endpoint);
            endpoints->push_back(endpoint);

            invariant(result.isOK());
            invariant(NULL != endpoint);
        }
        else {
            result = targetQuery(deleteDoc.getQuery(), endpoints);
        }

        return result;
    }
Example #4
0
    bool WriteBatchExecutor::doDelete( const string& ns,
                                       const BatchedDeleteDocument& deleteOp,
                                       CurOp* currentOp,
                                       WriteStats* stats,
                                       BatchedErrorDetail* error ) {
        OpDebug& opDebug = currentOp->debug();

        _opCounters->gotDelete();

        BSONObj queryObj = deleteOp.getQuery();

        currentOp->setQuery( queryObj );
        opDebug.op = dbDelete;
        opDebug.query = queryObj;

        long long n;

        try {
            n = deleteObjects( ns, queryObj, // ns, query
                               deleteOp.getLimit() == 1, // justOne
                               true, // logOp
                               false // god
                               );
            stats->numDeleted += n;
        }
        catch ( const UserException& ex ) {
            opDebug.exceptionInfo = ex.getInfo();
            toBatchedError( ex, error );
            return false;
        }

        _le->recordDelete( n );
        opDebug.ndeleted = n;

        return true;
    }