示例#1
0
    Database::Database(const char *nm, bool& newDb, const string& path )
        : _name(nm), _path(path),
          _namespaceIndex( _path, _name ),
          _extentManager(_name, _path, 0, storageGlobalParams.directoryperdb),
          _profileName(_name + ".system.profile"),
          _namespacesName(_name + ".system.namespaces"),
          _indexesName(_name + ".system.indexes"),
          _extentFreelistName( _name + ".$freelist" ),
          _collectionLock( "Database::_collectionLock" )
    {
        Status status = validateDBName( _name );
        if ( !status.isOK() ) {
            warning() << "tried to open invalid db: " << _name << endl;
            uasserted( 10028, status.toString() );
        }

        try {
            newDb = _namespaceIndex.exists();
            _profile = serverGlobalParams.defaultProfile;
            checkDuplicateUncasedNames(true);

            // If already exists, open.  Otherwise behave as if empty until
            // there's a write, then open.
            if (!newDb) {
                _namespaceIndex.init();
                _extentManager.init( _namespaceIndex.details( _extentFreelistName ) );
                openAllFiles();
            }
            _magic = 781231;
        }
        catch(std::exception& e) {
            log() << "warning database " << path << " " << nm << " could not be opened" << endl;
            DBException* dbe = dynamic_cast<DBException*>(&e);
            if ( dbe != 0 ) {
                log() << "DBException " << dbe->getCode() << ": " << e.what() << endl;
            }
            else {
                log() << e.what() << endl;
            }
            _extentManager.reset();
            throw;
        }
    }
示例#2
0
void Command::generateErrorResponse(OperationContext* txn,
                                    rpc::ReplyBuilderInterface* replyBuilder,
                                    const DBException& exception,
                                    const rpc::RequestInterface& request,
                                    Command* command,
                                    const BSONObj& metadata) {
    LOG(1) << "assertion while executing command '" << request.getCommandName() << "' "
           << "on database '" << request.getDatabase() << "' "
           << "with arguments '" << command->getRedactedCopyForLogging(request.getCommandArgs())
           << "' "
           << "and metadata '" << request.getMetadata() << "': " << exception.toString();

    _generateErrorResponse(txn, replyBuilder, exception, metadata);
}
示例#3
0
//-------------------------------------------------------------------------------------
bool DBInterfaceMysql::processException(std::exception & e)
{
	DBException* dbe = static_cast<DBException*>(&e);
	bool retry = false;

	if (dbe->isLostConnection())
	{
		INFO_MSG(boost::format("DBInterfaceMysql::processException: "
				"Thread %p lost connection to database. Exception: %s. "
				"Attempting to reconnect.\n") %
			this %
			dbe->what() );

		int attempts = 1;

		while (!this->reattach())
		{
			ERROR_MSG(boost::format("DBInterfaceMysql::processException: "
							"Thread %p reconnect(%s) attempt %d failed(%s).\n") %
						this %
						db_name_ %
						attempts %
						getLastError());

			KBEngine::sleep(30);
			++attempts;
		}

		INFO_MSG(boost::format("DBInterfaceMysql::processException: "
					"Thread %p reconnected(%s). Attempts = %d\n") %
				this %
				db_name_ %
				attempts);

		retry = true;
	}
	else if (dbe->shouldRetry())
	{
		WARNING_MSG(boost::format("DBInterfaceMysql::processException: Retrying %1%\nException:%2%\nnlastquery=%3%\n") %
				this % dbe->what() % lastquery_);

		retry = true;
	}
	else
	{
		WARNING_MSG(boost::format("DBInterfaceMysql::processException: "
				"Exception: %1%\nlastquery=%2%\n") %
			dbe->what() % lastquery_);
	}

	return retry;
}
示例#4
0
//-------------------------------------------------------------------------------------
bool DBInterfaceMysql::processException(std::exception & e)
{
	DBException* dbe = static_cast<DBException*>(&e);
	bool retry = false;

	if (dbe->isLostConnection())
	{
		INFO_MSG(fmt::format("DBInterfaceMysql::processException: "
				"Thread {:p} lost connection to database. Exception: {}. "
				"Attempting to reconnect.\n",
			(void*)this,
			dbe->what()));

		int attempts = 1;

		while (!this->reattach())
		{
			ERROR_MSG(fmt::format("DBInterfaceMysql::processException: "
							"Thread {:p} reconnect({}) attempt {} failed({}).\n",
						(void*)this,
						db_name_,
						attempts,
						getLastError()));

			KBEngine::sleep(30);
			++attempts;
		}

		INFO_MSG(fmt::format("DBInterfaceMysql::processException: "
					"Thread {:p} reconnected({}). Attempts = {}\n",
				(void*)this,
				db_name_,
				attempts));

		retry = true;
	}
	else if (dbe->shouldRetry())
	{
		WARNING_MSG(fmt::format("DBInterfaceMysql::processException: Retrying {:p}\nException:{}\nnlastquery={}\n",
				(void*)this, dbe->what(), lastquery_));

		retry = true;
	}
	else
	{
		WARNING_MSG(fmt::format("DBInterfaceMysql::processException: "
				"Exception: {}\nlastquery={}\n",
			dbe->what(), lastquery_));
	}

	return retry;
}
示例#5
0
/**
 * Returns true if the operation can continue.
 */
bool handleError(OperationContext* txn,
                 const DBException& ex,
                 const ParsedWriteOp& wholeOp,
                 WriteResult* out) {
    LastError::get(txn->getClient()).setLastError(ex.getCode(), ex.getInfo().msg);
    auto& curOp = *CurOp::get(txn);
    curOp.debug().exceptionInfo = ex.getInfo();

    if (ErrorCodes::isInterruption(ErrorCodes::Error(ex.getCode()))) {
        throw;  // These have always failed the whole batch.
    }

    if (ErrorCodes::isStaleShardingError(ErrorCodes::Error(ex.getCode()))) {
        auto staleConfigException = dynamic_cast<const SendStaleConfigException*>(&ex);
        if (!staleConfigException) {
            // We need to get extra info off of the SCE, but some common patterns can result in the
            // exception being converted to a Status then rethrown as a UserException, losing the
            // info we need. It would be a bug if this happens so we want to detect it in testing,
            // but it isn't severe enough that we should bring down the server if it happens in
            // production.
            dassert(staleConfigException);
            msgassertedNoTrace(35475,
                               str::stream()
                                   << "Got a StaleConfig error but exception was the wrong type: "
                                   << demangleName(typeid(ex)));
        }

        ShardingState::get(txn)
            ->onStaleShardVersion(txn, wholeOp.ns, staleConfigException->getVersionReceived());
        out->staleConfigException =
            stdx::make_unique<SendStaleConfigException>(*staleConfigException);
        return false;
    }

    out->results.emplace_back(ex.toStatus());
    return wholeOp.continueOnError;
}
示例#6
0
std::string causedBy(const DBException& e) {
    return causedBy(e.toString());
}
示例#7
0
void Command::generateErrorResponse(OperationContext* txn,
                                    rpc::ReplyBuilderInterface* replyBuilder,
                                    const DBException& exception) {
    LOG(1) << "assertion while executing command: " << exception.toString();
    _generateErrorResponse(txn, replyBuilder, exception, rpc::makeEmptyMetadata());
}
示例#8
0
 static bool isAuthenticationException( const DBException& ex ) {
     return ex.getCode() == ErrorCodes::AuthenticationFailed;
 }