use of com.orientechnologies.orient.server.distributed.task.ODistributedOperationException in project orientdb by orientechnologies.
the class TestDistributedDatabaseRepair method testRepairClusters.
/**
* Breaks a cluster by creating new records only on certain servers
*/
private void testRepairClusters(OrientGraphFactory localFactory0, OrientGraphFactory localFactory1, OrientGraphFactory localFactory2) throws Exception {
Thread.sleep(2000);
OrientBaseGraph graph = localFactory0.getNoTx();
graph.createVertexType("Employee");
graph.shutdown();
final ODistributedConfiguration cfg = serverInstance.get(1).getServerInstance().getDistributedManager().getDatabaseConfiguration(getDatabaseName());
// FIND THE LOCAL CLUSTER
String localCluster = null;
final Set<String> owner = cfg.getClustersOwnedByServer(serverInstance.get(1).getServerInstance().getDistributedManager().getLocalNodeName());
for (String s : owner) {
if (s.toLowerCase().startsWith("employee")) {
localCluster = s;
break;
}
}
graph = localFactory1.getTx();
OrientVertex employee;
try {
employee = graph.addVertex("Employee", localCluster);
employee.setProperty("status", "ok");
} finally {
graph.shutdown();
}
banner("CREATE 10 RECORDS ONLY ON local (1) SERVER and 0");
graph = localFactory1.getTx();
try {
for (int i = 0; i < 10; ++i) {
OrientVertex v = graph.addVertex("Employee", localCluster);
v.setProperty("status", "onlyServer0and1");
graph.getRawGraph().getStorage().getUnderlying().createRecord((ORecordId) v.getRecord().getIdentity(), v.getRecord().toStream(), v.getRecord().getVersion(), ODocument.RECORD_TYPE, 0, null);
final ODistributedResponse result = createRemoteRecord(0, v.getRecord(), new String[] { serverInstance.get(0).getServerInstance().getDistributedManager().getLocalNodeName() });
Assert.assertFalse(result.getPayload() instanceof Throwable);
}
} finally {
graph.rollback();
}
banner("CREATE 10 RECORDS ONLY ON SERVER 0");
graph = localFactory1.getTx();
try {
for (int i = 0; i < 10; ++i) {
OrientVertex v = graph.addVertex("Employee", localCluster);
v.setProperty("status", "onlyServer0and1");
graph.getRawGraph().getStorage().getUnderlying().createRecord((ORecordId) v.getRecord().getIdentity(), v.getRecord().toStream(), v.getRecord().getVersion(), ODocument.RECORD_TYPE, 0, null);
}
} finally {
graph.rollback();
}
// TRY TO CREATE A RECORD TO START THE REPAIR
graph = localFactory1.getTx();
try {
OrientVertex v = graph.addVertex("Employee", localCluster);
v.setProperty("status", "check");
graph.commit();
} catch (ODistributedOperationException e) {
Assert.assertTrue(true);
} finally {
graph.shutdown();
}
Thread.sleep(5000);
banner("CHECK RECORDS...");
graph = localFactory0.getNoTx();
try {
Assert.assertEquals(21, graph.countVertices("Employee"));
} finally {
graph.shutdown();
}
graph = localFactory1.getNoTx();
try {
Assert.assertEquals(21, graph.countVertices("Employee"));
} finally {
graph.shutdown();
}
graph = localFactory2.getNoTx();
try {
Assert.assertEquals(21, graph.countVertices("Employee"));
} finally {
graph.shutdown();
}
}
use of com.orientechnologies.orient.server.distributed.task.ODistributedOperationException in project orientdb by orientechnologies.
the class ODistributedResponseManager method manageConflicts.
protected RuntimeException manageConflicts() {
if (!groupResponsesByResult || request.getTask().getQuorumType() == OCommandDistributedReplicateRequest.QUORUM_TYPE.NONE)
// NO QUORUM
return null;
if (dManager.getNodeStatus() != ODistributedServerManager.NODE_STATUS.ONLINE)
// CURRENT NODE OFFLINE: JUST RETURN
return null;
final int bestResponsesGroupIndex = getBestResponsesGroup();
final List<ODistributedResponse> bestResponsesGroup = responseGroups.get(bestResponsesGroupIndex);
final int maxCoherentResponses = bestResponsesGroup.size();
final int conflicts = getExpectedResponses() - (maxCoherentResponses);
if (isMinimumQuorumReached(true)) {
// QUORUM SATISFIED
if (responseGroups.size() == 1)
// NO CONFLICT
return null;
if (checkNoWinnerCase(bestResponsesGroup))
// TODO: CALL THE RECORD CONFLICT PIPELINE
return null;
if (fixNodesInConflict(bestResponsesGroup, conflicts))
// FIX SUCCEED
return null;
}
// QUORUM HASN'T BEEN REACHED
if (ODistributedServerLog.isDebugEnabled()) {
ODistributedServerLog.debug(this, dManager.getLocalNodeName(), null, DIRECTION.NONE, "Detected %d node(s) in timeout or in conflict and quorum (%d) has not been reached, rolling back changes for request (%s)", conflicts, quorum, request);
ODistributedServerLog.debug(this, dManager.getLocalNodeName(), null, DIRECTION.NONE, composeConflictMessage());
}
if (!undoRequest()) {
// SKIP UNDO
return null;
}
// CHECK IF THERE IS AT LEAST ONE ODistributedRecordLockedException or OConcurrentCreateException
for (Object r : responses.values()) {
if (r instanceof ODistributedRecordLockedException)
throw (ODistributedRecordLockedException) r;
else if (r instanceof OConcurrentCreateException)
throw (OConcurrentCreateException) r;
}
final Object goodResponsePayload = bestResponsesGroup.isEmpty() ? null : bestResponsesGroup.get(0).getPayload();
if (goodResponsePayload instanceof RuntimeException)
// RESPONSE IS ALREADY AN EXCEPTION: THROW THIS
return (RuntimeException) goodResponsePayload;
else if (goodResponsePayload instanceof Throwable)
return OException.wrapException(new ODistributedException(composeConflictMessage()), (Throwable) goodResponsePayload);
else {
if (responseGroups.size() <= 2) {
// CHECK IF THE BAD RESPONSE IS AN EXCEPTION, THEN PROPAGATE IT
for (int i = 0; i < responseGroups.size(); ++i) {
if (i == bestResponsesGroupIndex)
continue;
final List<ODistributedResponse> badResponses = responseGroups.get(i);
if (badResponses.get(0).getPayload() instanceof RuntimeException)
return (RuntimeException) badResponses.get(0).getPayload();
}
}
return new ODistributedOperationException(composeConflictMessage());
}
}
use of com.orientechnologies.orient.server.distributed.task.ODistributedOperationException in project orientdb by orientechnologies.
the class OCreateRecordTask method forceUpdate.
protected ORecord forceUpdate(final ODistributedServerManager manager, final ODatabaseDocumentInternal database, final ODistributedRequestId requestId, final ORawBuffer loadedRecord) {
// LOAD IT AS RECORD
final ORecord loadedRecordInstance = Orient.instance().getRecordFactoryManager().newInstance(loadedRecord.recordType);
ORecordInternal.fill(loadedRecordInstance, rid, loadedRecord.version, loadedRecord.getBuffer(), false);
// RECORD HAS BEEN ALREADY CREATED (PROBABLY DURING DATABASE SYNC) CHECKING COHERENCY
if (Arrays.equals(loadedRecord.getBuffer(), content))
// SAME CONTENT
return loadedRecordInstance;
ODistributedServerLog.info(this, manager.getLocalNodeName(), getNodeSource(), DIRECTION.IN, "Error on creating record in an existent position. toStore=%s stored=%s reqId=%s", getRecord(), loadedRecordInstance, requestId);
throw new ODistributedOperationException("Cannot create the record " + rid + " in an already existent position");
}
use of com.orientechnologies.orient.server.distributed.task.ODistributedOperationException in project orientdb by orientechnologies.
the class AbstractServerClusterInsertTest method recreateIndexNode2.
protected void recreateIndexNode2() {
// RE-CREATE INDEX ON NODE 1
ServerRun server = serverInstance.get(1);
ODatabaseDocumentTx database = poolFactory.get(getDatabaseURL(server), "admin", "admin").acquire();
try {
Object result = database.command(new OCommandSQL("create index Person.name on Person (name) unique")).execute();
System.out.println("recreateIndexNode2: Node2 created index: " + result);
Assert.assertEquals(expected, ((Number) result).intValue());
} catch (ODistributedOperationException t) {
for (ServerRun s : serverInstance) {
final ODatabaseDocumentTx db = new ODatabaseDocumentTx(getDatabaseURL(s)).open("admin", "admin");
try {
List<ODocument> result = db.command(new OCommandSQL("select count(*) as count from Person where name is not null")).execute();
Assert.assertEquals(expected, ((Number) result.get(0).field("count")).longValue());
final OClass person = db.getMetadata().getSchema().getClass("Person");
final int[] clIds = person.getPolymorphicClusterIds();
long tot = 0;
for (int clId : clIds) {
long count = db.countClusterElements(clId);
System.out.println("Cluster " + clId + " record: " + count);
tot += count;
}
Assert.assertEquals(expected, tot);
} finally {
db.close();
}
}
database.activateOnCurrentThread();
throw t;
} finally {
database.close();
}
// CHECK ON NODE 1
server = serverInstance.get(0);
database = poolFactory.get(getDatabaseURL(server), "admin", "admin").acquire();
try {
final long indexSize = database.getMetadata().getIndexManager().getIndex("Person.name").getSize();
Assert.assertEquals(expected, indexSize);
System.out.println("recreateIndexNode2: Node1 has the index too, ok");
} finally {
database.close();
}
}
use of com.orientechnologies.orient.server.distributed.task.ODistributedOperationException in project orientdb by orientechnologies.
the class ODistributedLockManagerRequester method acquireExclusiveLock.
@Override
public void acquireExclusiveLock(final String resource, final String nodeSource, final long timeout) {
while (true) {
if (coordinatorServer == null || coordinatorServer.equals(manager.getLocalNodeName())) {
// NO MASTERS, USE LOCAL SERVER
manager.getLockManagerExecutor().acquireExclusiveLock(resource, manager.getLocalNodeName(), timeout);
break;
} else {
// SEND A DISTRIBUTED MSG TO THE COORDINATOR SERVER
final Set<String> servers = new HashSet<String>();
servers.add(coordinatorServer);
ODistributedServerLog.debug(this, manager.getLocalNodeName(), coordinatorServer, ODistributedServerLog.DIRECTION.OUT, "Server '%s' is acquiring distributed lock on resource '%s'...", nodeSource, resource);
final ODistributedResponse dResponse = manager.sendRequest(OSystemDatabase.SYSTEM_DB_NAME, null, servers, new ODistributedLockTask(resource, timeout, true), manager.getNextMessageIdCounter(), ODistributedRequest.EXECUTION_MODE.RESPONSE, null, null);
if (dResponse == null) {
ODistributedServerLog.warn(this, manager.getLocalNodeName(), coordinatorServer, ODistributedServerLog.DIRECTION.OUT, "Server '%s' cannot acquire distributed lock on resource '%s' (timeout=%d)...", nodeSource, resource, timeout);
throw new OLockException("Server '" + nodeSource + "' cannot acquire exclusive lock on resource '" + resource + "' (timeout=" + timeout + ")");
}
final Object result = dResponse.getPayload();
if (result instanceof ODistributedOperationException) {
if (manager.getActiveServers().contains(coordinatorServer))
// WAIT ONLY IN THE CASE THE COORDINATOR IS STILL ONLINE
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// IGNORE IT
}
if (!manager.getActiveServers().contains(coordinatorServer)) {
// THE COORDINATOR WAS DOWN DURING THE REQUEST, RETRY WITH ANOTHER COORDINATOR
coordinatorServer = manager.getCoordinatorServer();
continue;
}
} else if (result instanceof RuntimeException)
throw (RuntimeException) result;
break;
}
}
ODistributedServerLog.debug(this, manager.getLocalNodeName(), coordinatorServer, ODistributedServerLog.DIRECTION.OUT, "Server '%s' has acquired distributed lock on resource '%s'", nodeSource, resource);
acquiredResources.put(resource, System.currentTimeMillis());
}
Aggregations