Search in sources :

Example 31 with LogNotAvailableException

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);
    }
}
Also used : Stat(org.apache.zookeeper.data.Stat) KeeperException(org.apache.zookeeper.KeeperException) MetadataStorageManagerException(herddb.metadata.MetadataStorageManagerException) TableSpaceDoesNotExistException(herddb.model.TableSpaceDoesNotExistException) LogNotAvailableException(herddb.log.LogNotAvailableException) KeeperException(org.apache.zookeeper.KeeperException) DDLException(herddb.model.DDLException) IOException(java.io.IOException) TableSpaceAlreadyExistsException(herddb.model.TableSpaceAlreadyExistsException) LogNotAvailableException(herddb.log.LogNotAvailableException)

Example 32 with LogNotAvailableException

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);
        }
    }
}
Also used : AtomicLong(java.util.concurrent.atomic.AtomicLong) BKException(org.apache.bookkeeper.client.BKException) LogNotAvailableException(herddb.log.LogNotAvailableException)

Example 33 with LogNotAvailableException

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;
    }
}
Also used : ReadHandle(org.apache.bookkeeper.client.api.ReadHandle) FullRecoveryNeededException(herddb.log.FullRecoveryNeededException) LogEntry(herddb.log.LogEntry) LogSequenceNumber(herddb.log.LogSequenceNumber) IOException(java.io.IOException) BKNotEnoughBookiesException(org.apache.bookkeeper.client.BKException.BKNotEnoughBookiesException) LogNotAvailableException(herddb.log.LogNotAvailableException) IOException(java.io.IOException) CompletionException(java.util.concurrent.CompletionException) BKException(org.apache.bookkeeper.client.BKException) FullRecoveryNeededException(herddb.log.FullRecoveryNeededException) BKClientClosedException(org.apache.bookkeeper.client.BKException.BKClientClosedException) LedgerMetadata(org.apache.bookkeeper.client.api.LedgerMetadata) LedgerEntries(org.apache.bookkeeper.client.api.LedgerEntries) BKException(org.apache.bookkeeper.client.BKException) LogNotAvailableException(herddb.log.LogNotAvailableException)

Example 34 with LogNotAvailableException

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();
    }
}
Also used : AtomicLong(java.util.concurrent.atomic.AtomicLong) BKException(org.apache.bookkeeper.client.BKException) LogNotAvailableException(herddb.log.LogNotAvailableException)

Example 35 with LogNotAvailableException

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);
    }
}
Also used : DataStorageManagerException(herddb.storage.DataStorageManagerException) DMLStatementExecutionResult(herddb.model.DMLStatementExecutionResult) CommitLogResult(herddb.log.CommitLogResult) StatementExecutionException(herddb.model.StatementExecutionException) LogEntry(herddb.log.LogEntry) LogNotAvailableException(herddb.log.LogNotAvailableException)

Aggregations

LogNotAvailableException (herddb.log.LogNotAvailableException)35 CommitLogResult (herddb.log.CommitLogResult)20 LogEntry (herddb.log.LogEntry)19 StatementExecutionException (herddb.model.StatementExecutionException)18 DataStorageManagerException (herddb.storage.DataStorageManagerException)18 IOException (java.io.IOException)15 LogSequenceNumber (herddb.log.LogSequenceNumber)12 DDLStatementExecutionResult (herddb.model.DDLStatementExecutionResult)11 DumpedLogEntry (herddb.backup.DumpedLogEntry)10 DDLException (herddb.model.DDLException)9 ArrayList (java.util.ArrayList)9 MetadataStorageManagerException (herddb.metadata.MetadataStorageManagerException)7 DMLStatementExecutionResult (herddb.model.DMLStatementExecutionResult)7 IndexAlreadyExistsException (herddb.model.IndexAlreadyExistsException)7 Table (herddb.model.Table)7 ScanStatement (herddb.model.commands.ScanStatement)7 Bytes (herddb.utils.Bytes)7 AtomicLong (java.util.concurrent.atomic.AtomicLong)7 CommitLog (herddb.log.CommitLog)6 FullRecoveryNeededException (herddb.log.FullRecoveryNeededException)6