use of herddb.model.TableSpace in project herddb by diennea.
the class DBManager method manageTableSpaces.
private boolean manageTableSpaces() {
Collection<String> actualTablesSpaces;
try {
// all lowercase names
actualTablesSpaces = metadataStorageManager.listTableSpaces();
} catch (MetadataStorageManagerException error) {
LOGGER.log(Level.SEVERE, "cannot access tablespaces metadata", error);
return true;
}
Map<String, TableSpace> currentTableSpaceMetadata = new HashMap<>();
generalLock.writeLock().lock();
try {
for (String tableSpace : actualTablesSpaces) {
TableSpace tableSpaceMetadata = metadataStorageManager.describeTableSpace(tableSpace);
if (tableSpaceMetadata == null) {
LOGGER.log(Level.INFO, "tablespace {0} does not exist", tableSpace);
continue;
}
currentTableSpaceMetadata.put(tableSpaceMetadata.uuid, tableSpaceMetadata);
try {
handleTableSpace(tableSpaceMetadata);
} catch (Exception err) {
LOGGER.log(Level.SEVERE, "cannot handle tablespace " + tableSpace, err);
if (haltOnTableSpaceBootError && haltProcedure != null) {
err.printStackTrace();
haltProcedure.run();
}
}
}
} catch (MetadataStorageManagerException error) {
LOGGER.log(Level.SEVERE, "cannot access tablespaces metadata", error);
return true;
} finally {
generalLock.writeLock().unlock();
}
List<TableSpaceManager> followingActiveTableSpaces = new ArrayList<>();
Set<String> failedTableSpaces = new HashSet<>();
for (Map.Entry<String, TableSpaceManager> entry : tablesSpaces.entrySet()) {
try {
String tableSpaceUuid = entry.getValue().getTableSpaceUUID();
if (entry.getValue().isFailed()) {
LOGGER.log(Level.SEVERE, "tablespace " + tableSpaceUuid + " failed");
failedTableSpaces.add(entry.getKey());
} else if (!entry.getKey().equals(virtualTableSpaceId) && !actualTablesSpaces.contains(entry.getKey().toLowerCase())) {
LOGGER.log(Level.SEVERE, "tablespace " + tableSpaceUuid + " should not run here");
failedTableSpaces.add(entry.getKey());
} else if (entry.getValue().isLeader()) {
metadataStorageManager.updateTableSpaceReplicaState(TableSpaceReplicaState.builder().mode(TableSpaceReplicaState.MODE_LEADER).nodeId(nodeId).uuid(tableSpaceUuid).timestamp(System.currentTimeMillis()).build());
} else {
metadataStorageManager.updateTableSpaceReplicaState(TableSpaceReplicaState.builder().mode(TableSpaceReplicaState.MODE_FOLLOWER).nodeId(nodeId).uuid(tableSpaceUuid).timestamp(System.currentTimeMillis()).build());
followingActiveTableSpaces.add(entry.getValue());
}
} catch (MetadataStorageManagerException error) {
LOGGER.log(Level.SEVERE, "cannot access tablespace " + entry.getKey() + " metadata", error);
return true;
}
}
if (!failedTableSpaces.isEmpty()) {
generalLock.writeLock().lock();
try {
for (String tableSpace : failedTableSpaces) {
stopTableSpace(tableSpace, null);
}
} catch (MetadataStorageManagerException error) {
LOGGER.log(Level.SEVERE, "cannot access tablespace metadata", error);
return true;
} finally {
generalLock.writeLock().unlock();
}
}
if (!followingActiveTableSpaces.isEmpty()) {
long now = System.currentTimeMillis();
try {
for (TableSpaceManager tableSpaceManager : followingActiveTableSpaces) {
String tableSpaceUuid = tableSpaceManager.getTableSpaceUUID();
TableSpace tableSpaceInfo = currentTableSpaceMetadata.get(tableSpaceUuid);
if (tableSpaceInfo != null && !tableSpaceInfo.leaderId.equals(nodeId) && tableSpaceInfo.maxLeaderInactivityTime > 0 && !tableSpaceManager.isFailed()) {
List<TableSpaceReplicaState> allReplicas = metadataStorageManager.getTableSpaceReplicaState(tableSpaceUuid);
TableSpaceReplicaState leaderState = allReplicas.stream().filter(t -> t.nodeId.equals(tableSpaceInfo.leaderId)).findAny().orElse(null);
if (leaderState == null) {
leaderState = new TableSpaceReplicaState(tableSpaceUuid, tableSpaceInfo.leaderId, tableSpaceInfo.metadataStorageCreationTime, TableSpaceReplicaState.MODE_STOPPED);
LOGGER.log(Level.INFO, "Leader for " + tableSpaceUuid + " should be " + tableSpaceInfo.leaderId + ", but it never sent pings or it disappeared," + " considering last activity as tablespace creation time: " + new java.sql.Timestamp(tableSpaceInfo.metadataStorageCreationTime) + " to leave a minimal grace period");
}
long delta = now - leaderState.timestamp;
if (tableSpaceInfo.maxLeaderInactivityTime > delta) {
LOGGER.log(Level.FINE, "Leader for " + tableSpaceUuid + " is " + tableSpaceInfo.leaderId + ", last ping " + new java.sql.Timestamp(leaderState.timestamp) + ". leader is healty");
} else {
LOGGER.log(Level.SEVERE, "Leader for " + tableSpaceUuid + " is " + tableSpaceInfo.leaderId + ", last ping " + new java.sql.Timestamp(leaderState.timestamp) + ". leader is failed.");
if (tryBecomeLeaderFor(tableSpaceInfo)) {
// only one change at a time
break;
}
}
}
}
} catch (MetadataStorageManagerException | DDLException error) {
LOGGER.log(Level.SEVERE, "cannot access tablespace metadata", error);
return true;
}
}
return false;
}
use of herddb.model.TableSpace in project herddb by diennea.
the class DBManager method dropTableSpace.
private StatementExecutionResult dropTableSpace(DropTableSpaceStatement dropTableSpaceStatement) throws StatementExecutionException {
try {
TableSpace previous = metadataStorageManager.describeTableSpace(dropTableSpaceStatement.getTableSpace());
if (previous == null) {
throw new TableSpaceDoesNotExistException(dropTableSpaceStatement.getTableSpace());
}
metadataStorageManager.dropTableSpace(dropTableSpaceStatement.getTableSpace(), previous);
triggerActivator(ActivatorRunRequest.TABLESPACEMANAGEMENT);
return new DDLStatementExecutionResult(TransactionContext.NOTRANSACTION_ID);
} catch (Exception err) {
throw new StatementExecutionException(err);
}
}
use of herddb.model.TableSpace in project herddb by diennea.
the class DBManager method handleTableSpace.
private void handleTableSpace(TableSpace tableSpace) throws DataStorageManagerException, LogNotAvailableException, MetadataStorageManagerException, DDLException {
String tableSpaceName = tableSpace.name;
TableSpaceManager actual_manager = tablesSpaces.get(tableSpaceName);
if (actual_manager != null && actual_manager.isFailed()) {
LOGGER.log(Level.INFO, "Tablespace {0} is in 'Failed' status", new Object[] { tableSpaceName, nodeId });
return;
}
if (actual_manager != null && actual_manager.isLeader() && !tableSpace.leaderId.equals(nodeId)) {
LOGGER.log(Level.INFO, "Tablespace {0} leader is no more {1}, it changed to {2}", new Object[] { tableSpaceName, nodeId, tableSpace.leaderId });
stopTableSpace(tableSpaceName, tableSpace.uuid);
return;
}
if (actual_manager != null && !actual_manager.isLeader() && tableSpace.leaderId.equals(nodeId)) {
LOGGER.log(Level.INFO, "Tablespace {0} need to switch to leadership on node {1}", new Object[] { tableSpaceName, nodeId });
stopTableSpace(tableSpaceName, tableSpace.uuid);
return;
}
if (tableSpace.isNodeAssignedToTableSpace(nodeId) && !tablesSpaces.containsKey(tableSpaceName)) {
LOGGER.log(Level.INFO, "Booting tablespace {0} on {1}, uuid {2}", new Object[] { tableSpaceName, nodeId, tableSpace.uuid });
long _start = System.currentTimeMillis();
CommitLog commitLog = commitLogManager.createCommitLog(tableSpace.uuid, tableSpace.name, nodeId);
TableSpaceManager manager = new TableSpaceManager(nodeId, tableSpaceName, tableSpace.uuid, tableSpace.expectedReplicaCount, metadataStorageManager, dataStorageManager, commitLog, this, false);
try {
manager.start();
LOGGER.log(Level.INFO, "Boot success tablespace {0} on {1}, uuid {2}, time {3} ms leader:{4}", new Object[] { tableSpaceName, nodeId, tableSpace.uuid, (System.currentTimeMillis() - _start) + "", manager.isLeader() });
tablesSpaces.put(tableSpaceName, manager);
if (serverConfiguration.getBoolean(ServerConfiguration.PROPERTY_JMX_ENABLE, ServerConfiguration.PROPERTY_JMX_ENABLE_DEFAULT)) {
JMXUtils.registerTableSpaceManagerStatsMXBean(tableSpaceName, manager.getStats());
}
} catch (DataStorageManagerException | LogNotAvailableException | MetadataStorageManagerException | DDLException t) {
LOGGER.log(Level.SEVERE, "Error Booting tablespace {0} on {1}", new Object[] { tableSpaceName, nodeId });
LOGGER.log(Level.SEVERE, "Error", t);
tablesSpaces.remove(tableSpaceName);
try {
manager.close();
} catch (Throwable t2) {
LOGGER.log(Level.SEVERE, "Other Error", t2);
t.addSuppressed(t2);
}
throw t;
}
return;
}
if (tablesSpaces.containsKey(tableSpaceName) && !tableSpace.isNodeAssignedToTableSpace(nodeId)) {
LOGGER.log(Level.INFO, "Tablespace {0} on {1} is not more in replica list {3}, uuid {2}", new Object[] { tableSpaceName, nodeId, tableSpace.uuid, tableSpace.replicas + "" });
stopTableSpace(tableSpaceName, tableSpace.uuid);
return;
}
if (!tableSpace.isNodeAssignedToTableSpace("*") && tableSpace.replicas.size() < tableSpace.expectedReplicaCount) {
List<NodeMetadata> nodes = metadataStorageManager.listNodes();
LOGGER.log(Level.WARNING, "Tablespace {0} is underreplicated expectedReplicaCount={1}, replicas={2}, nodes={3}", new Object[] { tableSpaceName, tableSpace.expectedReplicaCount, tableSpace.replicas, nodes });
List<String> availableOtherNodes = nodes.stream().map(n -> {
return n.nodeId;
}).filter(n -> {
return !tableSpace.replicas.contains(n);
}).collect(Collectors.toList());
Collections.shuffle(availableOtherNodes);
int countMissing = tableSpace.expectedReplicaCount - tableSpace.replicas.size();
LOGGER.log(Level.WARNING, "Tablespace {0} is underreplicated expectedReplicaCount={1}, replicas={2}, missing {3}, availableOtherNodes={4}", new Object[] { tableSpaceName, tableSpace.expectedReplicaCount, tableSpace.replicas, countMissing, availableOtherNodes });
if (!availableOtherNodes.isEmpty()) {
TableSpace.Builder newTableSpaceBuilder = TableSpace.builder().cloning(tableSpace);
while (!availableOtherNodes.isEmpty() && countMissing-- > 0) {
String node = availableOtherNodes.remove(0);
LOGGER.log(Level.WARNING, "Tablespace {0} adding {1} node as replica", new Object[] { tableSpaceName, node });
newTableSpaceBuilder.replica(node);
}
TableSpace newTableSpace = newTableSpaceBuilder.build();
boolean ok = metadataStorageManager.updateTableSpace(newTableSpace, tableSpace);
if (!ok) {
LOGGER.log(Level.SEVERE, "updating tableSpace {0} metadata failed, someone else altered metadata", tableSpaceName);
}
}
}
if (actual_manager != null && !actual_manager.isFailed() && actual_manager.isLeader()) {
actual_manager.metadataUpdated(tableSpace);
}
}
use of herddb.model.TableSpace in project herddb by diennea.
the class DBManager method waitForBootOfLocalTablespaces.
public boolean waitForBootOfLocalTablespaces(int millis) throws InterruptedException, MetadataStorageManagerException {
List<String> tableSpacesToWaitFor = new ArrayList<>();
Collection<String> allTableSpaces = metadataStorageManager.listTableSpaces();
for (String tableSpaceName : allTableSpaces) {
TableSpace tableSpace = metadataStorageManager.describeTableSpace(tableSpaceName);
if (tableSpace.leaderId.equals(nodeId)) {
tableSpacesToWaitFor.add(tableSpaceName);
}
}
LOGGER.log(Level.INFO, "Waiting (max " + millis + " ms) for boot of local tablespaces: " + tableSpacesToWaitFor);
for (String tableSpace : tableSpacesToWaitFor) {
boolean ok = waitForTablespace(tableSpace, millis, true);
if (!ok) {
return false;
}
}
return true;
}
use of herddb.model.TableSpace in project herddb by diennea.
the class SystablespacesTableManager method buildVirtualRecordList.
@Override
protected Iterable<Record> buildVirtualRecordList(Transaction transaction) throws StatementExecutionException {
try {
Collection<String> names = tableSpaceManager.getMetadataStorageManager().listTableSpaces();
List<Record> result = new ArrayList<>();
for (String name : names) {
TableSpace t = tableSpaceManager.getMetadataStorageManager().describeTableSpace(name);
if (t != null) {
result.add(RecordSerializer.makeRecord(table, "tablespace_name", t.name, "uuid", t.uuid, "leader", t.leaderId, "expectedreplicacount", t.expectedReplicaCount, "maxleaderinactivitytime", t.maxLeaderInactivityTime, "replica", t.replicas.stream().collect(Collectors.joining(","))));
}
}
return result;
} catch (MetadataStorageManagerException error) {
throw new StatementExecutionException(error);
}
}
Aggregations