use of herddb.log.LogNotAvailableException in project herddb by diennea.
the class ZookeeperMetadataStorageManager method saveActualLedgersList.
public void saveActualLedgersList(String tableSpaceUUID, LedgersInfo info) throws LogNotAvailableException {
byte[] actualLedgers = info.serialize();
try {
while (true) {
try {
try {
Stat newStat = ensureZooKeeper().setData(ledgersPath + "/" + tableSpaceUUID, actualLedgers, info.getZkVersion());
info.setZkVersion(newStat.getVersion());
LOGGER.log(Level.SEVERE, "save new ledgers list " + info + " to " + ledgersPath + "/" + tableSpaceUUID);
return;
} catch (KeeperException.NoNodeException firstboot) {
ensureZooKeeper().create(ledgersPath + "/" + tableSpaceUUID, actualLedgers, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
} catch (KeeperException.BadVersionException fenced) {
throw new LogNotAvailableException(new Exception("ledgers actual list was fenced, expecting version " + info.getZkVersion() + " " + fenced, fenced).fillInStackTrace());
}
} catch (KeeperException.ConnectionLossException anyError) {
LOGGER.log(Level.SEVERE, "temporary error", anyError);
Thread.sleep(10000);
} catch (Exception anyError) {
handleSessionExpiredError(anyError);
throw new LogNotAvailableException(anyError);
}
}
} catch (InterruptedException stop) {
LOGGER.log(Level.SEVERE, "fatal error", stop);
throw new LogNotAvailableException(stop);
}
}
use of herddb.log.LogNotAvailableException in project herddb by diennea.
the class BookkeeperCommitLog method dropOldLedgers.
@Override
public void dropOldLedgers(LogSequenceNumber lastCheckPointSequenceNumber) throws LogNotAvailableException {
if (ledgersRetentionPeriod <= 0) {
return;
}
LOGGER.log(Level.INFO, "dropOldLedgers lastCheckPointSequenceNumber: {0}, ledgersRetentionPeriod: {1} ,lastLedgerId: {2}, currentLedgerId: {3}, tablespace {4}, actualLedgersList {5}", new Object[] { lastCheckPointSequenceNumber, ledgersRetentionPeriod, lastLedgerId, currentLedgerId, tableSpaceDescription(), actualLedgersList });
long min_timestamp = System.currentTimeMillis() - ledgersRetentionPeriod;
List<Long> oldLedgers = actualLedgersList.getOldLedgers(min_timestamp);
LOGGER.log(Level.INFO, "dropOldLedgers currentLedgerId: {0}, lastLedgerId: {1}, dropping ledgers before {2}: {3} tablespace {4}", new Object[] { currentLedgerId, lastLedgerId, new java.sql.Timestamp(min_timestamp), oldLedgers, tableSpaceDescription() });
oldLedgers.remove(this.currentLedgerId);
oldLedgers.remove(this.lastLedgerId);
if (oldLedgers.isEmpty()) {
LOGGER.log(Level.INFO, "dropOldLedgers no ledger to drop now, tablespace {0}", new Object[] { tableSpaceDescription() });
return;
}
for (long ledgerId : oldLedgers) {
try {
LOGGER.log(Level.INFO, "dropping ledger {0}, tablespace {1}", new Object[] { ledgerId, tableSpaceDescription() });
actualLedgersList.removeLedger(ledgerId);
metadataManager.saveActualLedgersList(tableSpaceUUID, actualLedgersList);
try {
bookKeeper.deleteLedger(ledgerId);
} catch (BKException.BKNoSuchLedgerExistsException | BKException.BKNoSuchLedgerExistsOnMetadataServerException error) {
LOGGER.log(Level.SEVERE, "error while dropping ledger " + ledgerId + " for tablespace " + tableSpaceDescription(), error);
}
LOGGER.log(Level.INFO, "dropping ledger {0}, finished, tablespace {1}", new Object[] { ledgerId, tableSpaceDescription() });
} catch (BKException | InterruptedException error) {
LOGGER.log(Level.SEVERE, "error while dropping ledger " + ledgerId + " for tablespace " + tableSpaceDescription(), error);
throw new LogNotAvailableException(error);
}
}
}
use of herddb.log.LogNotAvailableException in project herddb by diennea.
the class BookkeeperCommitLog method recovery.
@Override
public void recovery(LogSequenceNumber snapshotSequenceNumber, BiConsumer<LogSequenceNumber, LogEntry> consumer, boolean fencing) throws LogNotAvailableException {
String tableSpaceDescription = tableSpaceDescription();
this.actualLedgersList = metadataManager.getActualLedgersList(tableSpaceUUID);
LOGGER.log(Level.INFO, "Actual ledgers list:{0} tableSpace {1}", new Object[] { actualLedgersList, tableSpaceDescription });
this.lastLedgerId = snapshotSequenceNumber.ledgerId;
this.currentLedgerId = snapshotSequenceNumber.ledgerId;
this.lastSequenceNumber.set(snapshotSequenceNumber.offset);
LOGGER.log(Level.INFO, "recovery from latest snapshotSequenceNumber:{0} tableSpace {1}, node {2}, fencing {3}", new Object[] { snapshotSequenceNumber, tableSpaceDescription, localNodeId, fencing });
if (!isRecoveryAvailable(snapshotSequenceNumber, actualLedgersList, tableSpaceDescription)) {
throw new FullRecoveryNeededException("Cannot recover from BookKeeper, not enough data, plese check the logs");
}
for (long ledgerId : actualLedgersList.getActiveLedgers()) {
try {
Versioned<LedgerMetadata> result = FutureUtils.result(bookKeeper.getLedgerManager().readLedgerMetadata(ledgerId));
LedgerMetadata metadata = result.getValue();
String ledgerLeader = extractLeaderFromMetadata(metadata.getCustomMetadata());
LOGGER.log(Level.INFO, "Ledger {0}: {1} {2} created by {3}, LastEntryId {4} Length {5}", new Object[] { String.valueOf(ledgerId), metadata.getState(), metadata.getAllEnsembles(), ledgerLeader, metadata.getLastEntryId(), metadata.getLength() });
} catch (BKException.BKNoSuchLedgerExistsException | BKException.BKNoSuchLedgerExistsOnMetadataServerException e) {
if (ledgerId < snapshotSequenceNumber.ledgerId) {
LOGGER.log(Level.INFO, "Actual ledgers list includes a not existing ledgerid:" + ledgerId + " tablespace " + tableSpaceDescription + ", but this ledger is not useful for recovery (snapshotSequenceNumber.ledgerId is " + snapshotSequenceNumber.ledgerId);
} else {
throw new FullRecoveryNeededException(new Exception("Actual ledgers list includes a not existing ledgerid:" + ledgerId + " tablespace " + tableSpaceDescription));
}
} catch (LogNotAvailableException e) {
throw e;
} catch (Exception e) {
throw new LogNotAvailableException(e);
}
}
try {
for (long ledgerId : actualLedgersList.getActiveLedgers()) {
if (ledgerId < snapshotSequenceNumber.ledgerId) {
LOGGER.log(Level.FINER, "Skipping ledger {0}", ledgerId);
continue;
}
ReadHandle handle;
try {
if (fencing) {
handle = bookKeeper.openLedger(ledgerId, BookKeeper.DigestType.CRC32C, SHARED_SECRET.getBytes(StandardCharsets.UTF_8));
} else {
handle = bookKeeper.openLedgerNoRecovery(ledgerId, BookKeeper.DigestType.CRC32C, SHARED_SECRET.getBytes(StandardCharsets.UTF_8));
}
} catch (org.apache.bookkeeper.client.api.BKException errorDuringOpen) {
throw new LogNotAvailableException("Cannot open ledger " + ledgerId + " (fencing " + fencing + "): " + errorDuringOpen, errorDuringOpen);
}
try {
long first;
if (ledgerId == snapshotSequenceNumber.ledgerId) {
first = snapshotSequenceNumber.offset;
if (first == -1) {
// this can happen if checkpoint happened while starting to follow a new ledger but actually no entry was ever read
LOGGER.log(Level.INFO, "Tablespace " + tableSpaceDescription + ", recovering from latest snapshot ledger " + ledgerId + ", first entry " + first + " is not valid. Adjusting to 0");
first = 0;
}
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, "Tablespace " + tableSpaceDescription + ", recovering from latest snapshot ledger " + ledgerId + ", starting from entry " + first);
}
} else {
first = 0;
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, "Tablespace " + tableSpaceDescription + ", recovering from ledger " + ledgerId + ", starting from entry " + first);
}
}
long lastAddConfirmed = handle.getLastAddConfirmed();
String ledgerLeader = extractLeaderFromMetadata(handle.getLedgerMetadata().getCustomMetadata());
LOGGER.log(Level.INFO, "Tablespace " + tableSpaceDescription + ", Recovering from ledger " + ledgerId + ", first=" + first + " lastAddConfirmed=" + lastAddConfirmed + " written by " + ledgerLeader);
if (lastAddConfirmed >= 0) {
for (long b = first; b <= lastAddConfirmed; ) {
long start = b;
long end = b + RECOVERY_BATCH_SIZE;
if (end > lastAddConfirmed) {
end = lastAddConfirmed;
}
b = end + 1;
double percent = ((start - first) * 100.0 / (lastAddConfirmed + 1));
int entriesToRead = (int) (1 + end - start);
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, "{3} From entry {0}, to entry {1} ({2} %)", new Object[] { start, end, percent, tableSpaceDescription });
}
long _start = System.currentTimeMillis();
int localEntryCount = 0;
try (LedgerEntries entries = handle.read(start, end)) {
for (org.apache.bookkeeper.client.api.LedgerEntry entry : entries) {
long entryId = entry.getEntryId();
LogSequenceNumber number = new LogSequenceNumber(ledgerId, entryId);
LogEntry statusEdit = readLogEntry(entry);
lastLedgerId = ledgerId;
currentLedgerId = ledgerId;
lastSequenceNumber.set(entryId);
if (number.after(snapshotSequenceNumber)) {
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.log(Level.FINEST, "rec " + tableSpaceName + " #" + localEntryCount + " {0}, {1}", new Object[] { number, statusEdit });
}
consumer.accept(number, statusEdit);
} else {
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.log(Level.FINEST, "skip " + tableSpaceName + " #" + localEntryCount + " {0}<{1}, {2}", new Object[] { number, snapshotSequenceNumber, statusEdit });
}
}
localEntryCount++;
}
}
LOGGER.log(Level.FINER, tableSpaceDescription() + " read " + localEntryCount + " entries from ledger " + ledgerId + ", expected " + entriesToRead);
if (localEntryCount != entriesToRead) {
throw new LogNotAvailableException(tableSpaceDescription() + " Read " + localEntryCount + " entries, expected " + entriesToRead);
}
lastLedgerId = ledgerId;
lastSequenceNumber.set(end);
long _stop = System.currentTimeMillis();
LOGGER.log(Level.INFO, "{4} From entry {0}, to entry {1} ({2} %) read time {3}", new Object[] { start, end, percent, (_stop - _start) + " ms", tableSpaceDescription });
}
}
} catch (RuntimeException err) {
LOGGER.log(Level.SEVERE, "Internal error while recovering tablespace " + tableSpaceDescription() + ": " + err, err);
throw err;
} finally {
handle.close();
}
}
LOGGER.log(Level.INFO, "After recovery of {0} lastSequenceNumber {1}", new Object[] { tableSpaceDescription, getLastSequenceNumber() });
} catch (IOException | InterruptedException | org.apache.bookkeeper.client.api.BKException err) {
LOGGER.log(Level.SEVERE, "Fatal error during recovery of " + tableSpaceDescription(), err);
signalLogFailed();
throw new LogNotAvailableException(err);
} catch (LogNotAvailableException err) {
LOGGER.log(Level.SEVERE, "Fatal error during recovery of " + tableSpaceDescription(), err);
signalLogFailed();
throw err;
}
}
use of herddb.log.LogNotAvailableException in project herddb by diennea.
the class BookkeeperCommitLog method openNewLedger.
private CommitFileWriter openNewLedger() throws LogNotAvailableException {
Long pendingLedgerId = null;
lock.writeLock().lock();
try {
if (!startWritingCalled) {
throw new LogNotAvailableException("this log has is not allowed to write");
}
// wait for all previous writes to succeed and then close the ledger
// closing a ledger invalidates all pending writes and seals metadata
// if a pending write fails we are failing the creation of the new ledger
closeCurrentWriter(true);
writer = new CommitFileWriter();
pendingLedgerId = writer.getLedgerId();
writer.writeLedgerHeader();
pendingLedgerId = null;
currentLedgerId = writer.getLedgerId();
LOGGER.log(Level.INFO, "Tablespace {1}, opened new ledger:{0}, expectedReplicaCount {2}", new Object[] { currentLedgerId, tableSpaceDescription(), expectedReplicaCount });
if (actualLedgersList.getFirstLedger() < 0) {
actualLedgersList.setFirstLedger(currentLedgerId);
}
actualLedgersList.addLedger(currentLedgerId);
metadataManager.saveActualLedgersList(tableSpaceUUID, actualLedgersList);
return writer;
} catch (LogNotAvailableException err) {
signalLogFailed();
throw err;
} finally {
if (pendingLedgerId != null) {
LOGGER.log(Level.SEVERE, tableSpaceDescription() + " Trying to delete bad ledge from metadata {0}", pendingLedgerId);
try {
bookKeeper.deleteLedger(pendingLedgerId);
} catch (InterruptedException ex) {
LOGGER.log(Level.SEVERE, tableSpaceDescription() + " Cannot delete bad ledge from metadata " + pendingLedgerId, ex);
Thread.currentThread().interrupt();
} catch (BKException ex) {
LOGGER.log(Level.SEVERE, tableSpaceDescription() + " Cannot delete bad ledge from metadata " + pendingLedgerId, ex);
}
}
lock.writeLock().unlock();
}
}
use of herddb.log.LogNotAvailableException in project herddb by diennea.
the class TableManager method executeTruncate.
private StatementExecutionResult executeTruncate(TruncateTableStatement truncate, Transaction transaction, StatementEvaluationContext context) throws StatementExecutionException, DataStorageManagerException {
if (transaction != null) {
throw new StatementExecutionException("TRUNCATE TABLE cannot be executed within the context of a Transaction");
}
try {
long estimatedSize = keyToPage.size();
LOGGER.log(Level.INFO, "TRUNCATING TABLE {0} with approx {1} records", new Object[] { table.name, estimatedSize });
LogEntry entry = LogEntryFactory.truncate(table, null);
CommitLogResult pos = log.log(entry, entry.transactionId <= 0);
apply(pos, entry, false);
return new DMLStatementExecutionResult(0, estimatedSize > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) estimatedSize, null, null);
} catch (LogNotAvailableException | DataStorageManagerException error) {
LOGGER.log(Level.SEVERE, "Error during TRUNCATE table " + table.tablespace + "." + table.name, error);
throw new StatementExecutionException(error);
}
}
Aggregations