Search in sources :

Example 6 with MongoException

use of com.eightkdata.mongowp.exceptions.MongoException in project torodb by torodb.

the class OplogManager method loadState.

@Locked(exclusive = true)
private void loadState() throws OplogManagerPersistException {
    try {
        retrier.retry(() -> {
            try (ReadOnlyMongodTransaction transaction = connection.openReadOnlyTransaction()) {
                Status<FindResult> status = transaction.execute(new Request(OPLOG_DB, null, true, null), FindCommand.INSTANCE, new FindArgument.Builder().setCollection(OPLOG_COL).setSlaveOk(true).build());
                if (!status.isOk()) {
                    throw new RetrierAbortException(new MongoException(status));
                }
                Iterator<BsonDocument> batch = status.getResult().getCursor().getFirstBatch();
                if (!batch.hasNext()) {
                    lastAppliedHash = 0;
                    lastAppliedOpTime = OpTime.EPOCH;
                } else {
                    BsonDocument doc = batch.next();
                    BsonDocument subDoc = BsonReaderTool.getDocument(doc, KEY);
                    lastAppliedHash = BsonReaderTool.getLong(subDoc, "hash");
                    long optimeAsLong = BsonReaderTool.getLong(subDoc, "optime_i");
                    BsonDateTime optimeAsDateTime = DefaultBsonValues.newDateTime(optimeAsLong);
                    lastAppliedOpTime = new OpTime(TimestampToDateTime.toTimestamp(optimeAsDateTime, DefaultBsonValues::newTimestamp), BsonReaderTool.getLong(subDoc, "optime_t"));
                }
                notifyLastAppliedOpTimeChange();
                return Empty.getInstance();
            }
        }, Hint.INFREQUENT_ROLLBACK);
    } catch (RetrierGiveUpException ex) {
        throw new OplogManagerPersistException(ex);
    }
}
Also used : MongoException(com.eightkdata.mongowp.exceptions.MongoException) ReadOnlyMongodTransaction(com.torodb.mongodb.core.ReadOnlyMongodTransaction) BsonDocumentBuilder(com.eightkdata.mongowp.utils.BsonDocumentBuilder) Request(com.eightkdata.mongowp.server.api.Request) RetrierGiveUpException(com.torodb.core.retrier.RetrierGiveUpException) OpTime(com.eightkdata.mongowp.OpTime) DefaultBsonValues(com.eightkdata.mongowp.bson.utils.DefaultBsonValues) BsonDocument(com.eightkdata.mongowp.bson.BsonDocument) RetrierAbortException(com.torodb.core.retrier.RetrierAbortException) BsonDateTime(com.eightkdata.mongowp.bson.BsonDateTime) FindResult(com.torodb.mongodb.commands.signatures.general.FindCommand.FindResult) Locked(com.torodb.mongodb.annotations.Locked)

Example 7 with MongoException

use of com.eightkdata.mongowp.exceptions.MongoException in project torodb by torodb.

the class TopologyHeartbeatHandler method handleHeartbeatError.

@Nonnull
private RemoteCommandResponse<ReplSetHeartbeatReply> handleHeartbeatError(Throwable t, Instant start) {
    Duration d = Duration.between(clock.instant(), start);
    ErrorCode errorCode;
    if (t instanceof MongoException) {
        return new FromExceptionRemoteCommandRequest((MongoException) t, d);
    } else if (t instanceof UnreachableMongoServerException) {
        errorCode = ErrorCode.HOST_UNREACHABLE;
    } else {
        if (!(t instanceof MongoRuntimeException) && !(t instanceof UnreachableMongoServerException)) {
            LOGGER.warn("Unexpected exception {} catched by the topology " + "heartbeat handler", t.getClass().getSimpleName());
        }
        errorCode = ErrorCode.UNKNOWN_ERROR;
    }
    return new ErroneousRemoteCommandResponse<>(errorCode, t.getLocalizedMessage(), d);
}
Also used : MongoException(com.eightkdata.mongowp.exceptions.MongoException) UnreachableMongoServerException(com.eightkdata.mongowp.client.core.UnreachableMongoServerException) Duration(java.time.Duration) MongoRuntimeException(com.eightkdata.mongowp.server.api.MongoRuntimeException) ErrorCode(com.eightkdata.mongowp.ErrorCode) ErroneousRemoteCommandResponse(com.eightkdata.mongowp.client.core.MongoConnection.ErroneousRemoteCommandResponse) FromExceptionRemoteCommandRequest(com.eightkdata.mongowp.client.core.MongoConnection.FromExceptionRemoteCommandRequest) Nonnull(javax.annotation.Nonnull)

Example 8 with MongoException

use of com.eightkdata.mongowp.exceptions.MongoException in project torodb by torodb.

the class OplogTestParser method getOps.

private static List<OplogOperation> getOps(BsonDocument doc) {
    BsonValue<?> oplogValue = doc.get("oplog");
    if (oplogValue == null) {
        throw new AssertionError("Does not contain oplog");
    }
    AtomicInteger tsFactory = new AtomicInteger();
    AtomicInteger tFactory = new AtomicInteger();
    BsonInt32 twoInt32 = DefaultBsonValues.newInt(2);
    return oplogValue.asArray().asList().stream().map(BsonValue::asDocument).map(child -> {
        BsonDocumentBuilder builder = new BsonDocumentBuilder(child);
        if (child.get("ts") == null) {
            builder.appendUnsafe("ts", DefaultBsonValues.newTimestamp(tsFactory.incrementAndGet(), tFactory.incrementAndGet()));
        }
        if (child.get("h") == null) {
            builder.appendUnsafe("h", DefaultBsonValues.INT32_ONE);
        }
        if (child.get("v") == null) {
            builder.appendUnsafe("v", twoInt32);
        }
        return builder.build();
    }).map(child -> {
        try {
            return OplogOperationParser.fromBson(child);
        } catch (MongoException ex) {
            throw new AssertionError("Invalid oplog operation", ex);
        }
    }).collect(Collectors.toList());
}
Also used : java.util(java.util) BsonDocument(com.eightkdata.mongowp.bson.BsonDocument) Truth(com.google.common.truth.Truth) KvValue(com.torodb.kvdocument.values.KvValue) BsonValue(com.eightkdata.mongowp.bson.BsonValue) OplogOperation(com.eightkdata.mongowp.server.api.oplog.OplogOperation) MongoWpConverter(com.torodb.kvdocument.conversion.mongowp.MongoWpConverter) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TorodTransaction(com.torodb.torod.TorodTransaction) BsonDocumentBuilder(com.eightkdata.mongowp.utils.BsonDocumentBuilder) MongoException(com.eightkdata.mongowp.exceptions.MongoException) DefaultBsonValues(com.eightkdata.mongowp.bson.utils.DefaultBsonValues) MongoBsonTranslator(com.eightkdata.mongowp.bson.org.bson.utils.MongoBsonTranslator) OplogOperationParser(com.torodb.mongodb.commands.pojos.OplogOperationParser) Charsets(com.google.common.base.Charsets) Files(java.nio.file.Files) BsonInt32(com.eightkdata.mongowp.bson.BsonInt32) KvDocument(com.torodb.kvdocument.values.KvDocument) Collectors(java.util.stream.Collectors) WriteMongodTransaction(com.torodb.mongodb.core.WriteMongodTransaction) Stream(java.util.stream.Stream) java.io(java.io) Paths(java.nio.file.Paths) ReadOnlyMongodTransaction(com.torodb.mongodb.core.ReadOnlyMongodTransaction) Assert(org.junit.Assert) BsonInt32(com.eightkdata.mongowp.bson.BsonInt32) MongoException(com.eightkdata.mongowp.exceptions.MongoException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) BsonDocumentBuilder(com.eightkdata.mongowp.utils.BsonDocumentBuilder)

Example 9 with MongoException

use of com.eightkdata.mongowp.exceptions.MongoException in project torodb by torodb.

the class SimpleAnalyzedOplogBatchExecutorTest method testVisit_SingleOp_OplogApplyingEx.

@Test
public void testVisit_SingleOp_OplogApplyingEx() throws Exception {
    //GIVEN
    OplogOperation operation = mock(OplogOperation.class);
    SingleOpAnalyzedOplogBatch batch = new SingleOpAnalyzedOplogBatch(operation);
    ApplierContext applierContext = new ApplierContext.Builder().setReapplying(true).setUpdatesAsUpserts(true).build();
    Timer timer = mock(Timer.class);
    Context context = mock(Context.class);
    given(metrics.getSingleOpTimer(operation)).willReturn(timer);
    given(timer.time()).willReturn(context);
    doThrow(new OplogApplyingException(new MongoException(ErrorCode.BAD_VALUE))).when(executor).execute(operation, applierContext);
    //WHEN
    try {
        executor.visit(batch, applierContext);
        fail("An exception was expected");
    } catch (RetrierGiveUpException | RetrierAbortException ignore) {
    }
    //THEN
    then(metrics).should().getSingleOpTimer(operation);
    then(timer).should().time();
    then(executor).should(times(1)).execute(operation, applierContext);
}
Also used : ApplierContext(com.torodb.mongodb.repl.oplogreplier.ApplierContext) Context(com.codahale.metrics.Timer.Context) OplogApplyingException(com.torodb.mongodb.repl.oplogreplier.OplogOperationApplier.OplogApplyingException) MongoException(com.eightkdata.mongowp.exceptions.MongoException) Timer(com.codahale.metrics.Timer) RetrierAbortException(com.torodb.core.retrier.RetrierAbortException) OplogOperation(com.eightkdata.mongowp.server.api.oplog.OplogOperation) RetrierGiveUpException(com.torodb.core.retrier.RetrierGiveUpException) ApplierContext(com.torodb.mongodb.repl.oplogreplier.ApplierContext) Test(org.junit.Test)

Example 10 with MongoException

use of com.eightkdata.mongowp.exceptions.MongoException in project torodb by torodb.

the class RecoveryService method initialSync.

private boolean initialSync() throws TryAgainException, FatalErrorException {
    /*
     * 1. store that data is inconsistent 2. decide a sync source 3. lastRemoteOptime1 = get the
     * last optime of the sync source 4. clone all databases except local 5. lastRemoteOptime2 = get
     * the last optime of the sync source 6. apply remote oplog from lastRemoteOptime1 to
     * lastRemoteOptime2 7. lastRemoteOptime3 = get the last optime of the sync source 8. apply
     * remote oplog from lastRemoteOptime2 to lastRemoteOptime3 9. rebuild indexes 10. store
     * lastRemoteOptime3 as the last applied operation optime 11. store that data is consistent 12.
     * change replication state to SECONDARY
     */
    //TODO: Support fastsync (used to restore a node by copying the data from other up-to-date node)
    LOGGER.info("Starting initial sync");
    callback.setConsistentState(false);
    HostAndPort syncSource;
    try {
        syncSource = syncSourceProvider.newSyncSource();
        LOGGER.info("Using node " + syncSource + " to replicate from");
    } catch (NoSyncSourceFoundException ex) {
        throw new TryAgainException("No sync source");
    }
    MongoClient remoteClient;
    try {
        remoteClient = remoteClientFactory.createClient(syncSource);
    } catch (UnreachableMongoServerException ex) {
        throw new TryAgainException(ex);
    }
    try {
        LOGGER.debug("Remote client obtained");
        MongoConnection remoteConnection = remoteClient.openConnection();
        try (OplogReader reader = oplogReaderProvider.newReader(remoteConnection)) {
            OplogOperation lastClonedOp = reader.getLastOp();
            OpTime lastRemoteOptime1 = lastClonedOp.getOpTime();
            try (WriteOplogTransaction oplogTransaction = oplogManager.createWriteTransaction()) {
                LOGGER.info("Remote database cloning started");
                oplogTransaction.truncate();
                LOGGER.info("Local databases dropping started");
                Status<?> status = dropDatabases();
                if (!status.isOk()) {
                    throw new TryAgainException("Error while trying to drop collections: " + status);
                }
                LOGGER.info("Local databases dropping finished");
                if (!isRunning()) {
                    LOGGER.warn("Recovery stopped before it can finish");
                    return false;
                }
                LOGGER.info("Remote database cloning started");
                cloneDatabases(remoteClient);
                LOGGER.info("Remote database cloning finished");
                oplogTransaction.forceNewValue(lastClonedOp.getHash(), lastClonedOp.getOpTime());
            }
            if (!isRunning()) {
                LOGGER.warn("Recovery stopped before it can finish");
                return false;
            }
            TorodServer torodServer = server.getTorodServer();
            try (TorodConnection connection = torodServer.openConnection();
                SharedWriteTorodTransaction trans = connection.openWriteTransaction(false)) {
                OpTime lastRemoteOptime2 = reader.getLastOp().getOpTime();
                LOGGER.info("First oplog application started");
                applyOplog(reader, lastRemoteOptime1, lastRemoteOptime2);
                trans.commit();
                LOGGER.info("First oplog application finished");
                if (!isRunning()) {
                    LOGGER.warn("Recovery stopped before it can finish");
                    return false;
                }
                OplogOperation lastOperation = reader.getLastOp();
                OpTime lastRemoteOptime3 = lastOperation.getOpTime();
                LOGGER.info("Second oplog application started");
                applyOplog(reader, lastRemoteOptime2, lastRemoteOptime3);
                trans.commit();
                LOGGER.info("Second oplog application finished");
                if (!isRunning()) {
                    LOGGER.warn("Recovery stopped before it can finish");
                    return false;
                }
                LOGGER.info("Index rebuild started");
                rebuildIndexes();
                trans.commit();
                LOGGER.info("Index rebuild finished");
                if (!isRunning()) {
                    LOGGER.warn("Recovery stopped before it can finish");
                    return false;
                }
                trans.commit();
            }
        } catch (OplogStartMissingException ex) {
            throw new TryAgainException(ex);
        } catch (OplogOperationUnsupported ex) {
            throw new TryAgainException(ex);
        } catch (MongoException | RollbackException ex) {
            throw new TryAgainException(ex);
        } catch (OplogManagerPersistException ex) {
            throw new FatalErrorException();
        } catch (UserException ex) {
            throw new FatalErrorException(ex);
        }
        callback.setConsistentState(true);
        LOGGER.info("Initial sync finished");
    } finally {
        remoteClient.close();
    }
    return true;
}
Also used : OplogManagerPersistException(com.torodb.mongodb.repl.OplogManager.OplogManagerPersistException) SharedWriteTorodTransaction(com.torodb.torod.SharedWriteTorodTransaction) MongoException(com.eightkdata.mongowp.exceptions.MongoException) OplogOperationUnsupported(com.eightkdata.mongowp.exceptions.OplogOperationUnsupported) UnreachableMongoServerException(com.eightkdata.mongowp.client.core.UnreachableMongoServerException) OplogStartMissingException(com.eightkdata.mongowp.exceptions.OplogStartMissingException) RollbackException(com.torodb.core.transaction.RollbackException) OpTime(com.eightkdata.mongowp.OpTime) WriteOplogTransaction(com.torodb.mongodb.repl.OplogManager.WriteOplogTransaction) HostAndPort(com.google.common.net.HostAndPort) MongoClient(com.eightkdata.mongowp.client.core.MongoClient) TorodServer(com.torodb.torod.TorodServer) UserException(com.torodb.core.exceptions.user.UserException) NoSyncSourceFoundException(com.torodb.mongodb.repl.exceptions.NoSyncSourceFoundException) OplogOperation(com.eightkdata.mongowp.server.api.oplog.OplogOperation) MongoConnection(com.eightkdata.mongowp.client.core.MongoConnection) TorodConnection(com.torodb.torod.TorodConnection)

Aggregations

MongoException (com.eightkdata.mongowp.exceptions.MongoException)18 OplogOperation (com.eightkdata.mongowp.server.api.oplog.OplogOperation)6 Request (com.eightkdata.mongowp.server.api.Request)4 UserException (com.torodb.core.exceptions.user.UserException)4 RetrierAbortException (com.torodb.core.retrier.RetrierAbortException)4 RetrierGiveUpException (com.torodb.core.retrier.RetrierGiveUpException)4 RollbackException (com.torodb.core.transaction.RollbackException)4 OpTime (com.eightkdata.mongowp.OpTime)3 Status (com.eightkdata.mongowp.Status)3 BsonDocument (com.eightkdata.mongowp.bson.BsonDocument)3 MongoConnection (com.eightkdata.mongowp.client.core.MongoConnection)3 UnreachableMongoServerException (com.eightkdata.mongowp.client.core.UnreachableMongoServerException)3 BsonDocumentBuilder (com.eightkdata.mongowp.utils.BsonDocumentBuilder)3 HostAndPort (com.google.common.net.HostAndPort)3 WriteMongodTransaction (com.torodb.mongodb.core.WriteMongodTransaction)3 ErrorCode (com.eightkdata.mongowp.ErrorCode)2 DefaultBsonValues (com.eightkdata.mongowp.bson.utils.DefaultBsonValues)2 MongoClient (com.eightkdata.mongowp.client.core.MongoClient)2 NotMasterException (com.eightkdata.mongowp.exceptions.NotMasterException)2 OplogOperationUnsupported (com.eightkdata.mongowp.exceptions.OplogOperationUnsupported)2