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);
}
}
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);
}
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());
}
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);
}
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;
}
Aggregations