use of herddb.metadata.MetadataStorageManagerException in project herddb by diennea.
the class ZookeeperMetadataStorageManagerTest method testSessionExpired.
@Test
public void testSessionExpired() throws Exception {
try (ZookeeperMetadataStorageManager man = new ZookeeperMetadataStorageManager(testEnv.getAddress(), testEnv.getTimeout(), testEnv.getPath())) {
man.start();
TableSpace tableSpace = TableSpace.builder().leader("test").replica("test").name(TableSpace.DEFAULT).build();
man.registerTableSpace(tableSpace);
assertEquals(1, man.listTableSpaces().size());
ZooKeeper actual = man.getZooKeeper();
long sessionId = actual.getSessionId();
byte[] passwd = actual.getSessionPasswd();
expireZkSession(sessionId, passwd);
for (int i = 0; i < 10; i++) {
try {
man.listTableSpaces();
fail("session should be expired or not connected");
} catch (MetadataStorageManagerException ok) {
System.out.println("ok: " + ok);
assertTrue(ok.getCause() instanceof KeeperException.ConnectionLossException || ok.getCause() instanceof KeeperException.SessionExpiredException);
if (ok.getCause() instanceof KeeperException.SessionExpiredException) {
break;
}
}
Thread.sleep(500);
}
assertNotSame(actual, man.getZooKeeper());
assertEquals(1, man.listTableSpaces().size());
assertNotNull(tableSpace = man.describeTableSpace(TableSpace.DEFAULT));
man.dropTableSpace(TableSpace.DEFAULT, tableSpace);
}
}
use of herddb.metadata.MetadataStorageManagerException in project herddb by diennea.
the class CalcitePlanner method translate.
@Override
public TranslatedQuery translate(String defaultTableSpace, String query, List<Object> parameters, boolean scan, boolean allowCache, boolean returnValues, int maxRows) throws StatementExecutionException {
ensureDefaultTableSpaceBootedLocally(defaultTableSpace);
/* Strips out leading comments */
int idx = SQLUtils.findQueryStart(query);
if (idx != -1) {
query = query.substring(idx);
}
if (parameters == null) {
parameters = Collections.emptyList();
}
String cacheKey = "scan:" + scan + ",defaultTableSpace:" + defaultTableSpace + ",query:" + query + ",returnValues:" + returnValues + ",maxRows:" + maxRows;
boolean forceAcquireWriteLock;
if (// this looks very hacky
query.endsWith(" FOR UPDATE") && query.substring(0, 6).toLowerCase().equals("select")) {
forceAcquireWriteLock = true;
query = query.substring(0, query.length() - " FOR UPDATE".length());
} else {
forceAcquireWriteLock = false;
}
if (allowCache) {
ExecutionPlan cached = cache.get(cacheKey);
if (cached != null) {
return new TranslatedQuery(cached, new SQLStatementEvaluationContext(query, parameters, forceAcquireWriteLock, false));
}
}
if (isDDL(query)) {
query = JSQLParserPlanner.rewriteExecuteSyntax(query);
return fallback.translate(defaultTableSpace, query, parameters, scan, allowCache, returnValues, maxRows);
}
if (query.startsWith(TABLE_CONSISTENCY_COMMAND)) {
query = JSQLParserPlanner.rewriteExecuteSyntax(query);
return fallback.translate(defaultTableSpace, query, parameters, scan, allowCache, returnValues, maxRows);
}
if (query.startsWith(TABLESPACE_CONSISTENCY_COMMAND)) {
query = JSQLParserPlanner.rewriteExecuteSyntax(query);
return fallback.translate(defaultTableSpace, query, parameters, scan, allowCache, returnValues, maxRows);
}
if (!isCachable(query)) {
allowCache = false;
}
try {
if (query.startsWith("EXPLAIN ")) {
query = query.substring("EXPLAIN ".length());
PlannerResult plan = runPlanner(defaultTableSpace, query);
boolean upsert = detectUpsert(plan);
PlannerOp finalPlan = convertRelNode(plan.topNode, plan.originalRowType, returnValues, upsert).optimize();
ValuesOp values = new ValuesOp(manager.getNodeId(), new String[] { "name", "value" }, new Column[] { column("name", ColumnTypes.STRING), column("value", ColumnTypes.STRING) }, java.util.Arrays.asList(java.util.Arrays.asList(new ConstantExpression("query", ColumnTypes.NOTNULL_STRING), new ConstantExpression(query, ColumnTypes.NOTNULL_STRING)), java.util.Arrays.asList(new ConstantExpression("logicalplan", ColumnTypes.NOTNULL_STRING), new ConstantExpression(RelOptUtil.dumpPlan("", plan.logicalPlan, SqlExplainFormat.TEXT, SqlExplainLevel.ALL_ATTRIBUTES), ColumnTypes.NOTNULL_STRING)), java.util.Arrays.asList(new ConstantExpression("plan", ColumnTypes.NOTNULL_STRING), new ConstantExpression(RelOptUtil.dumpPlan("", plan.topNode, SqlExplainFormat.TEXT, SqlExplainLevel.ALL_ATTRIBUTES), ColumnTypes.NOTNULL_STRING)), java.util.Arrays.asList(new ConstantExpression("finalplan", ColumnTypes.NOTNULL_STRING), new ConstantExpression(finalPlan + "", ColumnTypes.NOTNULL_STRING))));
ExecutionPlan executionPlan = ExecutionPlan.simple(new SQLPlannedOperationStatement(values), values);
return new TranslatedQuery(executionPlan, new SQLStatementEvaluationContext(query, parameters, false, false));
}
if (query.startsWith("SHOW")) {
return calculateShowCreateTable(query, defaultTableSpace, parameters, manager);
}
PlannerResult plan = runPlanner(defaultTableSpace, query);
boolean upsert = detectUpsert(plan);
SQLPlannedOperationStatement sqlPlannedOperationStatement = new SQLPlannedOperationStatement(convertRelNode(plan.topNode, plan.originalRowType, returnValues, upsert).optimize());
if (LOG.isLoggable(DUMP_QUERY_LEVEL)) {
LOG.log(DUMP_QUERY_LEVEL, "Query: {0} --HerdDB Plan\n{1}", new Object[] { query, sqlPlannedOperationStatement.getRootOp() });
}
if (!scan) {
ScanStatement scanStatement = sqlPlannedOperationStatement.unwrap(ScanStatement.class);
if (scanStatement != null) {
Table tableDef = scanStatement.getTableDef();
CompiledSQLExpression where = scanStatement.getPredicate().unwrap(CompiledSQLExpression.class);
SQLRecordKeyFunction keyFunction = IndexUtils.findIndexAccess(where, tableDef.getPrimaryKey(), tableDef, "=", tableDef);
if (keyFunction == null || !keyFunction.isFullPrimaryKey()) {
throw new StatementExecutionException("unsupported GET not on PK, bad where clause: " + query);
}
GetStatement get = new GetStatement(scanStatement.getTableSpace(), scanStatement.getTable(), keyFunction, scanStatement.getPredicate(), true);
ExecutionPlan executionPlan = ExecutionPlan.simple(get);
if (allowCache) {
cache.put(cacheKey, executionPlan);
}
return new TranslatedQuery(executionPlan, new SQLStatementEvaluationContext(query, parameters, forceAcquireWriteLock, false));
}
}
if (maxRows > 0) {
PlannerOp op = new LimitOp(sqlPlannedOperationStatement.getRootOp(), new ConstantExpression(maxRows, ColumnTypes.NOTNULL_LONG), new ConstantExpression(0, ColumnTypes.NOTNULL_LONG)).optimize();
sqlPlannedOperationStatement = new SQLPlannedOperationStatement(op);
}
PlannerOp rootOp = sqlPlannedOperationStatement.getRootOp();
ExecutionPlan executionPlan;
if (rootOp.isSimpleStatementWrapper()) {
executionPlan = ExecutionPlan.simple(rootOp.unwrap(herddb.model.Statement.class), rootOp);
} else {
executionPlan = ExecutionPlan.simple(sqlPlannedOperationStatement, rootOp);
}
if (allowCache) {
cache.put(cacheKey, executionPlan);
}
return new TranslatedQuery(executionPlan, new SQLStatementEvaluationContext(query, parameters, forceAcquireWriteLock, false));
} catch (CalciteContextException ex) {
LOG.log(Level.INFO, "Error while parsing '" + ex.getOriginalStatement() + "'", ex);
// TODO can this be done better ?
throw new StatementExecutionException(ex.getMessage());
} catch (RelConversionException | ValidationException | SqlParseException ex) {
LOG.log(Level.INFO, "Error while parsing '" + query + "'", ex);
// TODO can this be done better ?
throw new StatementExecutionException(ex.getMessage().replace("org.apache.calcite.runtime.CalciteContextException: ", ""), ex);
} catch (MetadataStorageManagerException ex) {
LOG.log(Level.INFO, "Error while parsing '" + query + "'", ex);
throw new StatementExecutionException(ex);
}
}
use of herddb.metadata.MetadataStorageManagerException in project herddb by diennea.
the class TableSpaceManager method recover.
void recover(TableSpace tableSpaceInfo) throws DataStorageManagerException, LogNotAvailableException, MetadataStorageManagerException {
if (recoveryInProgress) {
throw new HerdDBInternalException("Cannot run recovery twice");
}
recoveryInProgress = true;
LogSequenceNumber logSequenceNumber = dataStorageManager.getLastcheckpointSequenceNumber(tableSpaceUUID);
actualLogSequenceNumber = logSequenceNumber;
LOGGER.log(Level.INFO, "{0} recover {1}, logSequenceNumber from DataStorage: {2}", new Object[] { nodeId, tableSpaceName, logSequenceNumber });
List<Table> tablesAtBoot = dataStorageManager.loadTables(logSequenceNumber, tableSpaceUUID);
List<Index> indexesAtBoot = dataStorageManager.loadIndexes(logSequenceNumber, tableSpaceUUID);
String tableNames = tablesAtBoot.stream().map(t -> {
return t.name;
}).collect(Collectors.joining(","));
String indexNames = indexesAtBoot.stream().map(t -> {
return t.name + " on table " + t.table;
}).collect(Collectors.joining(","));
if (!tableNames.isEmpty()) {
LOGGER.log(Level.INFO, "{0} {1} tablesAtBoot: {2}, indexesAtBoot: {3}", new Object[] { nodeId, tableSpaceName, tableNames, indexNames });
}
for (Table table : tablesAtBoot) {
TableManager tableManager = bootTable(table, 0, null, false);
for (Index index : indexesAtBoot) {
if (index.table.equals(table.name)) {
bootIndex(index, tableManager, false, 0, false, false);
}
}
}
dataStorageManager.loadTransactions(logSequenceNumber, tableSpaceUUID, t -> {
transactions.put(t.transactionId, t);
LOGGER.log(Level.FINER, "{0} {1} tx {2} at boot lsn {3}", new Object[] { nodeId, tableSpaceName, t.transactionId, t.lastSequenceNumber });
try {
if (t.newTables != null) {
for (Table table : t.newTables.values()) {
if (!tables.containsKey(table.name)) {
bootTable(table, t.transactionId, null, false);
}
}
}
if (t.newIndexes != null) {
for (Index index : t.newIndexes.values()) {
if (!indexes.containsKey(index.name)) {
AbstractTableManager tableManager = tables.get(index.table);
bootIndex(index, tableManager, false, t.transactionId, false, false);
}
}
}
} catch (Exception err) {
LOGGER.log(Level.SEVERE, "error while booting tmp tables " + err, err);
throw new RuntimeException(err);
}
});
if (LogSequenceNumber.START_OF_TIME.equals(logSequenceNumber) && dbmanager.getServerConfiguration().getBoolean(ServerConfiguration.PROPERTY_BOOT_FORCE_DOWNLOAD_SNAPSHOT, ServerConfiguration.PROPERTY_BOOT_FORCE_DOWNLOAD_SNAPSHOT_DEFAULT)) {
LOGGER.log(Level.SEVERE, nodeId + " full recovery of data is forced (" + ServerConfiguration.PROPERTY_BOOT_FORCE_DOWNLOAD_SNAPSHOT + "=true) for tableSpace " + tableSpaceName);
downloadTableSpaceData();
log.recovery(actualLogSequenceNumber, new ApplyEntryOnRecovery(), false);
} else {
try {
log.recovery(logSequenceNumber, new ApplyEntryOnRecovery(), false);
} catch (FullRecoveryNeededException fullRecoveryNeeded) {
LOGGER.log(Level.SEVERE, nodeId + " full recovery of data is needed for tableSpace " + tableSpaceName, fullRecoveryNeeded);
downloadTableSpaceData();
log.recovery(actualLogSequenceNumber, new ApplyEntryOnRecovery(), false);
}
}
recoveryInProgress = false;
if (!LogSequenceNumber.START_OF_TIME.equals(actualLogSequenceNumber)) {
LOGGER.log(Level.INFO, "Recovery finished for {0} seqNum {1}", new Object[] { tableSpaceName, actualLogSequenceNumber });
checkpoint(false, false, false);
}
}
use of herddb.metadata.MetadataStorageManagerException in project herddb by diennea.
the class TableSpaceManager method downloadTableSpaceData.
private void downloadTableSpaceData() throws MetadataStorageManagerException, DataStorageManagerException, LogNotAvailableException {
TableSpace tableSpaceData = metadataStorageManager.describeTableSpace(tableSpaceName);
String leaderId = tableSpaceData.leaderId;
if (this.nodeId.equals(leaderId)) {
throw new DataStorageManagerException("cannot download data of tableSpace " + tableSpaceName + " from myself");
}
Optional<NodeMetadata> leaderAddress = metadataStorageManager.listNodes().stream().filter(n -> n.nodeId.equals(leaderId)).findAny();
if (!leaderAddress.isPresent()) {
throw new DataStorageManagerException("cannot download data of tableSpace " + tableSpaceName + " from leader " + leaderId + ", no metadata found");
}
// ensure we do not have any data on disk and in memory
actualLogSequenceNumber = LogSequenceNumber.START_OF_TIME;
newTransactionId.set(0);
LOGGER.log(Level.INFO, "tablespace " + tableSpaceName + " at downloadTableSpaceData " + tables + ", " + indexes + ", " + transactions);
for (AbstractTableManager manager : tables.values()) {
// and all indexes
if (!manager.isSystemTable()) {
manager.dropTableData();
}
manager.close();
}
tables.clear();
// this map should be empty
for (AbstractIndexManager manager : indexes.values()) {
manager.dropIndexData();
manager.close();
}
indexes.clear();
transactions.clear();
dataStorageManager.eraseTablespaceData(tableSpaceUUID);
NodeMetadata nodeData = leaderAddress.get();
ClientConfiguration clientConfiguration = new ClientConfiguration(dbmanager.getTmpDirectory());
clientConfiguration.set(ClientConfiguration.PROPERTY_CLIENT_USERNAME, dbmanager.getServerToServerUsername());
clientConfiguration.set(ClientConfiguration.PROPERTY_CLIENT_PASSWORD, dbmanager.getServerToServerPassword());
// always use network, we want to run tests with this case
clientConfiguration.set(ClientConfiguration.PROPERTY_CLIENT_CONNECT_LOCALVM_SERVER, false);
try (HDBClient client = new HDBClient(clientConfiguration)) {
client.setClientSideMetadataProvider(new ClientSideMetadataProvider() {
@Override
public String getTableSpaceLeader(String tableSpace) throws ClientSideMetadataProviderException {
return leaderId;
}
@Override
public ServerHostData getServerHostData(String nodeId) throws ClientSideMetadataProviderException {
return new ServerHostData(nodeData.host, nodeData.port, "?", nodeData.ssl, Collections.emptyMap());
}
});
try (HDBConnection con = client.openConnection()) {
ReplicaFullTableDataDumpReceiver receiver = new ReplicaFullTableDataDumpReceiver(this);
int fetchSize = 10000;
con.dumpTableSpace(tableSpaceName, receiver, fetchSize, false);
receiver.getLatch().get(1, TimeUnit.HOURS);
this.actualLogSequenceNumber = receiver.logSequenceNumber;
LOGGER.log(Level.INFO, tableSpaceName + " After download local actualLogSequenceNumber is " + actualLogSequenceNumber);
} catch (ClientSideMetadataProviderException | HDBException | InterruptedException | ExecutionException | TimeoutException internalError) {
LOGGER.log(Level.SEVERE, tableSpaceName + " error downloading snapshot", internalError);
throw new DataStorageManagerException(internalError);
}
}
}
use of herddb.metadata.MetadataStorageManagerException in project herddb by diennea.
the class ZookeeperMetadataStorageManager method registerNode.
@Override
public void registerNode(NodeMetadata nodeMetadata) throws MetadataStorageManagerException {
try {
String path = nodesPath + "/" + nodeMetadata.nodeId;
LOGGER.severe("registerNode at " + path + " -> " + nodeMetadata);
byte[] data = nodeMetadata.serialize();
try {
ensureZooKeeper().create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
} catch (KeeperException.NodeExistsException ok) {
LOGGER.severe("registerNode at " + path + " " + ok);
ensureZooKeeper().setData(path, data, -1);
}
notifyMetadataChanged("registerNode " + nodeMetadata);
} catch (IOException | InterruptedException | KeeperException err) {
handleSessionExpiredError(err);
throw new MetadataStorageManagerException(err);
}
}
Aggregations