use of herddb.log.LogNotAvailableException in project herddb by diennea.
the class FileCommitLog method ensureDirectories.
private void ensureDirectories() throws LogNotAvailableException {
try {
if (!Files.isDirectory(logDirectory)) {
LOGGER.log(Level.INFO, "directory {0} does not exist. creating", logDirectory);
Files.createDirectories(logDirectory);
}
} catch (IOException err) {
failed = true;
throw new LogNotAvailableException(err);
}
}
use of herddb.log.LogNotAvailableException in project herddb by diennea.
the class MemoryCommitLogManager method createCommitLog.
@Override
public CommitLog createCommitLog(String tableSpace, String tablespaceName, String localNodeId) {
return new CommitLog() {
AtomicLong offset = new AtomicLong(-1);
@Override
public CommitLogResult log(LogEntry entry, boolean synch) throws LogNotAvailableException {
if (isHasListeners()) {
synch = true;
}
if (testSerialize) {
// NOOP, but trigger serialization subsystem
try {
entry.serialize(ExtendedDataOutputStream.NULL);
} catch (IOException err) {
throw new LogNotAvailableException(err);
}
}
LogSequenceNumber logPos = new LogSequenceNumber(1, offset.incrementAndGet());
notifyListeners(logPos, entry);
return new CommitLogResult(logPos, !synch, synch);
}
@Override
public LogSequenceNumber getLastSequenceNumber() {
return new LogSequenceNumber(1, offset.get());
}
private volatile boolean closed;
@Override
public void close() throws LogNotAvailableException {
closed = true;
}
@Override
public boolean isFailed() {
return false;
}
@Override
public boolean isClosed() {
return closed;
}
@Override
public void recovery(LogSequenceNumber snapshotSequenceNumber, BiConsumer<LogSequenceNumber, LogEntry> consumer, boolean fencing) throws LogNotAvailableException {
}
@Override
public void dropOldLedgers(LogSequenceNumber lastCheckPointSequenceNumber) throws LogNotAvailableException {
}
@Override
public void startWriting(int expectedReplicaCount) throws LogNotAvailableException {
}
@Override
public void clear() throws LogNotAvailableException {
}
};
}
use of herddb.log.LogNotAvailableException in project herddb by diennea.
the class TableManager method executeDeleteAsync.
private CompletableFuture<StatementExecutionResult> executeDeleteAsync(DeleteStatement delete, Transaction transaction, StatementEvaluationContext context) {
AtomicInteger updateCount = new AtomicInteger();
Holder<Bytes> lastKey = new Holder<>();
Holder<Bytes> lastValue = new Holder<>();
long transactionId = transaction != null ? transaction.transactionId : 0;
Predicate predicate = delete.getPredicate();
List<CompletableFuture<PendingLogEntryWork>> writes = new ArrayList<>();
Map<String, AbstractIndexManager> indexes = tableSpaceManager.getIndexesOnTable(table.name);
ScanStatement scan = new ScanStatement(table.tablespace, table, predicate);
try {
accessTableData(scan, context, new ScanResultOperation() {
@Override
public void accept(Record current, LockHandle lockHandle) throws StatementExecutionException, LogNotAvailableException, DataStorageManagerException {
// ensure we are holding the write locks on every unique index
List<UniqueIndexLockReference> uniqueIndexes = null;
try {
if (indexes != null || childrenTables != null) {
DataAccessor dataAccessor = current.getDataAccessor(table);
if (childrenTables != null) {
for (Table childTable : childrenTables) {
executeForeignKeyConstraintsAsParentTable(childTable, dataAccessor, context, transaction, true);
}
}
if (indexes != null) {
for (AbstractIndexManager index : indexes.values()) {
if (index.isUnique()) {
Bytes indexKey = RecordSerializer.serializeIndexKey(dataAccessor, index.getIndex(), index.getColumnNames());
if (uniqueIndexes == null) {
uniqueIndexes = new ArrayList<>(1);
}
UniqueIndexLockReference uniqueIndexLock = new UniqueIndexLockReference(index, indexKey);
uniqueIndexes.add(uniqueIndexLock);
LockHandle lockForIndex = lockForWrite(uniqueIndexLock.key, transaction, index.getIndexName(), index.getLockManager());
if (transaction == null) {
uniqueIndexLock.lockHandle = lockForIndex;
}
}
}
}
}
} catch (IllegalArgumentException | herddb.utils.IllegalDataAccessException | StatementExecutionException err) {
locksManager.releaseLock(lockHandle);
StatementExecutionException finalError;
if (!(err instanceof StatementExecutionException)) {
finalError = new StatementExecutionException(err.getMessage(), err);
} else {
finalError = (StatementExecutionException) err;
}
CompletableFuture<PendingLogEntryWork> res = Futures.exception(finalError);
if (uniqueIndexes != null) {
for (UniqueIndexLockReference lock : uniqueIndexes) {
res = releaseWriteLock(res, lockHandle, lock.indexManager.getLockManager());
}
}
writes.add(res);
return;
}
LogEntry entry = LogEntryFactory.delete(table, current.key, transaction);
CommitLogResult pos = log.log(entry, entry.transactionId <= 0);
final List<UniqueIndexLockReference> _uniqueIndexes = uniqueIndexes;
writes.add(pos.logSequenceNumber.thenApply(lsn -> new PendingLogEntryWork(entry, pos, lockHandle, _uniqueIndexes)));
lastKey.value = current.key;
lastValue.value = current.value;
updateCount.incrementAndGet();
}
}, transaction, true, true);
} catch (HerdDBInternalException err) {
LOGGER.log(Level.SEVERE, "bad error during a delete", err);
return Futures.exception(err);
}
if (writes.isEmpty()) {
return CompletableFuture.completedFuture(new DMLStatementExecutionResult(transactionId, 0, null, null));
}
if (writes.size() == 1) {
return writes.get(0).whenCompleteAsync((pending, error) -> {
try {
// apply any of the DML operations
if (error == null) {
apply(pending.pos, pending.entry, false);
}
} finally {
releaseMultiplePendingLogEntryWorks(writes);
}
}, tableSpaceManager.getCallbacksExecutor()).thenApply((pending) -> {
return new DMLStatementExecutionResult(transactionId, updateCount.get(), lastKey.value, delete.isReturnValues() ? lastValue.value : null);
});
} else {
return Futures.collect(writes).whenCompleteAsync((pendings, error) -> {
try {
// apply any of the DML operations
if (error == null) {
for (PendingLogEntryWork pending : pendings) {
apply(pending.pos, pending.entry, false);
}
}
} finally {
releaseMultiplePendingLogEntryWorks(writes);
}
}, tableSpaceManager.getCallbacksExecutor()).thenApply((pendings) -> {
return new DMLStatementExecutionResult(transactionId, updateCount.get(), lastKey.value, delete.isReturnValues() ? lastValue.value : null);
});
}
}
use of herddb.log.LogNotAvailableException 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.log.LogNotAvailableException 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);
}
}
}
Aggregations