Search in sources :

Example 21 with CommitLogResult

use of herddb.log.CommitLogResult in project herddb by diennea.

the class TableManager method executeUpdate.

private StatementExecutionResult executeUpdate(UpdateStatement update, Transaction transaction, StatementEvaluationContext context) throws StatementExecutionException, DataStorageManagerException {
    AtomicInteger updateCount = new AtomicInteger();
    Holder<Bytes> lastKey = new Holder<>();
    Holder<byte[]> lastValue = new Holder<>();
    /*
         an update can succeed only if the row is valid, the key is contains in the "keys" structure
         the update will simply override the value of the row, assigning a null page to the row
         the update can have a 'where' predicate which is to be evaluated against the decoded row, the update will be executed only if the predicate returns boolean 'true' value  (CAS operation)
         locks: the update  uses a lock on the the key
         */
    RecordFunction function = update.getFunction();
    long transactionId = transaction != null ? transaction.transactionId : 0;
    Predicate predicate = update.getPredicate();
    ScanStatement scan = new ScanStatement(table.tablespace, table, predicate);
    accessTableData(scan, context, new ScanResultOperation() {

        @Override
        public void accept(Record actual) throws StatementExecutionException, LogNotAvailableException, DataStorageManagerException {
            byte[] newValue = function.computeNewValue(actual, context, tableContext);
            final long size = DataPage.estimateEntrySize(actual.key, newValue);
            if (size > maxLogicalPageSize) {
                throw new RecordTooBigException("New version of record " + actual.key + " is to big to be update: new size " + size + ", actual size " + DataPage.estimateEntrySize(actual) + ", max size " + maxLogicalPageSize);
            }
            LogEntry entry = LogEntryFactory.update(table, actual.key.data, newValue, transaction);
            CommitLogResult pos = log.log(entry, entry.transactionId <= 0);
            apply(pos, entry, false);
            lastKey.value = actual.key;
            lastValue.value = newValue;
            updateCount.incrementAndGet();
        }
    }, transaction, true, true);
    return new DMLStatementExecutionResult(transactionId, updateCount.get(), lastKey.value, update.isReturnValues() ? (lastValue.value != null ? Bytes.from_array(lastValue.value) : null) : null);
}
Also used : DataStorageManagerException(herddb.storage.DataStorageManagerException) Holder(herddb.utils.Holder) CommitLogResult(herddb.log.CommitLogResult) RecordTooBigException(herddb.model.RecordTooBigException) StatementExecutionException(herddb.model.StatementExecutionException) Predicate(herddb.model.Predicate) Bytes(herddb.utils.Bytes) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) DMLStatementExecutionResult(herddb.model.DMLStatementExecutionResult) Record(herddb.model.Record) RecordFunction(herddb.model.RecordFunction) LogEntry(herddb.log.LogEntry) ScanStatement(herddb.model.commands.ScanStatement) LogNotAvailableException(herddb.log.LogNotAvailableException)

Example 22 with CommitLogResult

use of herddb.log.CommitLogResult in project herddb by diennea.

the class TableManager method executeDelete.

private StatementExecutionResult executeDelete(DeleteStatement delete, Transaction transaction, StatementEvaluationContext context) throws StatementExecutionException, DataStorageManagerException {
    AtomicInteger updateCount = new AtomicInteger();
    Holder<Bytes> lastKey = new Holder<>();
    Holder<byte[]> lastValue = new Holder<>();
    long transactionId = transaction != null ? transaction.transactionId : 0;
    Predicate predicate = delete.getPredicate();
    ScanStatement scan = new ScanStatement(table.tablespace, table, predicate);
    accessTableData(scan, context, new ScanResultOperation() {

        @Override
        public void accept(Record actual) throws StatementExecutionException, LogNotAvailableException, DataStorageManagerException {
            LogEntry entry = LogEntryFactory.delete(table, actual.key.data, transaction);
            CommitLogResult pos = log.log(entry, entry.transactionId <= 0);
            apply(pos, entry, false);
            lastKey.value = actual.key;
            lastValue.value = actual.value.data;
            updateCount.incrementAndGet();
        }
    }, transaction, true, true);
    return new DMLStatementExecutionResult(transactionId, updateCount.get(), lastKey.value, delete.isReturnValues() ? (lastValue.value != null ? Bytes.from_array(lastValue.value) : null) : null);
}
Also used : DataStorageManagerException(herddb.storage.DataStorageManagerException) Holder(herddb.utils.Holder) CommitLogResult(herddb.log.CommitLogResult) StatementExecutionException(herddb.model.StatementExecutionException) Predicate(herddb.model.Predicate) Bytes(herddb.utils.Bytes) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) DMLStatementExecutionResult(herddb.model.DMLStatementExecutionResult) Record(herddb.model.Record) LogEntry(herddb.log.LogEntry) ScanStatement(herddb.model.commands.ScanStatement) LogNotAvailableException(herddb.log.LogNotAvailableException)

Example 23 with CommitLogResult

use of herddb.log.CommitLogResult in project herddb by diennea.

the class TableSpaceManager method commitTransaction.

private CompletableFuture<StatementExecutionResult> commitTransaction(CommitTransactionStatement statement, StatementEvaluationContext context) throws StatementExecutionException {
    long txId = statement.getTransactionId();
    validateTransactionBeforeTxCommand(txId);
    LogEntry entry = LogEntryFactory.commitTransaction(txId);
    long lockStamp = context.getTableSpaceLock();
    boolean lockAcquired = false;
    if (lockStamp == 0) {
        lockStamp = acquireReadLock(statement);
        context.setTableSpaceLock(lockStamp);
        lockAcquired = true;
    }
    CommitLogResult pos = log.log(entry, true);
    CompletableFuture<StatementExecutionResult> res = pos.logSequenceNumber.handleAsync((lsn, error) -> {
        if (error == null) {
            apply(pos, entry, false);
            return new TransactionResult(txId, TransactionResult.OutcomeType.COMMIT);
        } else {
            // if the log is not able to write the commit
            // apply a dummy "rollback", we are no more going to accept commands
            // in the scope of this transaction
            LogEntry rollback = LogEntryFactory.rollbackTransaction(txId);
            apply(new CommitLogResult(LogSequenceNumber.START_OF_TIME, false, false), rollback, false);
            throw new CompletionException(error);
        }
    }, callbacksExecutor);
    if (lockAcquired) {
        res = releaseReadLock(res, lockStamp, statement).thenApply(s -> {
            context.setTableSpaceLock(0);
            return s;
        });
    }
    return res;
}
Also used : HDBException(herddb.client.HDBException) SystablesTableManager(herddb.core.system.SystablesTableManager) CommitTransactionStatement(herddb.model.commands.CommitTransactionStatement) TableCheckpoint(herddb.core.AbstractTableManager.TableCheckpoint) Table(herddb.model.Table) ClientConfiguration(herddb.client.ClientConfiguration) SyslogstatusManager(herddb.core.system.SyslogstatusManager) OpStatsLogger(org.apache.bookkeeper.stats.OpStatsLogger) IndexAlreadyExistsException(herddb.model.IndexAlreadyExistsException) Map(java.util.Map) DDLStatementExecutionResult(herddb.model.DDLStatementExecutionResult) LogNotAvailableException(herddb.log.LogNotAvailableException) PduCodec(herddb.proto.PduCodec) CommitLogResult(herddb.log.CommitLogResult) ClientSideMetadataProviderException(herddb.client.ClientSideMetadataProviderException) LogSequenceNumber(herddb.log.LogSequenceNumber) Set(java.util.Set) ScanStatement(herddb.model.commands.ScanStatement) CountDownLatch(java.util.concurrent.CountDownLatch) Stream(java.util.stream.Stream) HDBClient(herddb.client.HDBClient) TranslatedQuery(herddb.sql.TranslatedQuery) StatsLogger(org.apache.bookkeeper.stats.StatsLogger) TableDataChecksum(herddb.data.consistency.TableDataChecksum) DropTableStatement(herddb.model.commands.DropTableStatement) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) Bytes(herddb.utils.Bytes) SysdualTableManager(herddb.core.system.SysdualTableManager) LogEntry(herddb.log.LogEntry) SysnodesTableManager(herddb.core.system.SysnodesTableManager) ArrayList(java.util.ArrayList) CreateIndexStatement(herddb.model.commands.CreateIndexStatement) TableSpaceDoesNotExistException(herddb.model.TableSpaceDoesNotExistException) TransactionContext(herddb.model.TransactionContext) Transaction(herddb.model.Transaction) BRINIndexManager(herddb.index.brin.BRINIndexManager) SystablestatsTableManager(herddb.core.system.SystablestatsTableManager) BiConsumer(java.util.function.BiConsumer) CommitLogListener(herddb.log.CommitLogListener) ForeignKeyDef(herddb.model.ForeignKeyDef) IndexDoesNotExistException(herddb.model.IndexDoesNotExistException) TableSpaceManagerStats(herddb.core.stats.TableSpaceManagerStats) LogEntryType(herddb.log.LogEntryType) LogEntryFactory(herddb.log.LogEntryFactory) IOException(java.io.IOException) DataStorageManager(herddb.storage.DataStorageManager) DropIndexStatement(herddb.model.commands.DropIndexStatement) ColumnTypes(herddb.model.ColumnTypes) ExecutionException(java.util.concurrent.ExecutionException) AtomicLong(java.util.concurrent.atomic.AtomicLong) Column(herddb.model.Column) KeyValue(herddb.utils.KeyValue) FullRecoveryNeededException(herddb.log.FullRecoveryNeededException) StampedLock(java.util.concurrent.locks.StampedLock) ServerHostData(herddb.network.ServerHostData) TableAlreadyExistsException(herddb.model.TableAlreadyExistsException) RollbackTransactionStatement(herddb.model.commands.RollbackTransactionStatement) CreateTableStatement(herddb.model.commands.CreateTableStatement) TimeoutException(java.util.concurrent.TimeoutException) JMXUtils(herddb.jmx.JMXUtils) TransactionResult(herddb.model.TransactionResult) MetadataStorageManager(herddb.metadata.MetadataStorageManager) Channel(herddb.network.Channel) ServerConfiguration(herddb.server.ServerConfiguration) Futures(herddb.utils.Futures) DataStorageManagerException(herddb.storage.DataStorageManagerException) Index(herddb.model.Index) TableDoesNotExistException(herddb.model.TableDoesNotExistException) AlterTableStatement(herddb.model.commands.AlterTableStatement) SysindexcolumnsTableManager(herddb.core.system.SysindexcolumnsTableManager) DataScanner(herddb.model.DataScanner) DDLException(herddb.model.DDLException) StatementExecutionException(herddb.model.StatementExecutionException) Collection(java.util.Collection) SysstatementsTableManager(herddb.core.system.SysstatementsTableManager) BeginTransactionStatement(herddb.model.commands.BeginTransactionStatement) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) CompletionException(java.util.concurrent.CompletionException) TableAwareStatement(herddb.model.TableAwareStatement) Logger(java.util.logging.Logger) EOFException(java.io.EOFException) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) HDBConnection(herddb.client.HDBConnection) List(java.util.List) FullTableScanConsumer(herddb.storage.FullTableScanConsumer) SystransactionsTableManager(herddb.core.system.SystransactionsTableManager) NodeMetadata(herddb.model.NodeMetadata) Entry(java.util.Map.Entry) Optional(java.util.Optional) TableSpace(herddb.model.TableSpace) SysconfigTableManager(herddb.core.system.SysconfigTableManager) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings) SysindexesTableManager(herddb.core.system.SysindexesTableManager) Statement(herddb.model.Statement) MetadataStorageManagerException(herddb.metadata.MetadataStorageManagerException) DataScannerException(herddb.model.DataScannerException) SystablespacesTableManager(herddb.core.system.SystablespacesTableManager) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Pdu(herddb.proto.Pdu) Level(java.util.logging.Level) HashSet(java.util.HashSet) SysclientsTableManager(herddb.core.system.SysclientsTableManager) TableChecksum(herddb.data.consistency.TableChecksum) ExecutorService(java.util.concurrent.ExecutorService) DumpedLogEntry(herddb.backup.DumpedLogEntry) SysforeignkeysTableManager(herddb.core.system.SysforeignkeysTableManager) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) StatementExecutionResult(herddb.model.StatementExecutionResult) TimeUnit(java.util.concurrent.TimeUnit) CommitLog(herddb.log.CommitLog) ClientSideMetadataProvider(herddb.client.ClientSideMetadataProvider) ConcurrentSkipListSet(java.util.concurrent.ConcurrentSkipListSet) SystablespacereplicastateTableManager(herddb.core.system.SystablespacereplicastateTableManager) SQLPlannedOperationStatement(herddb.model.commands.SQLPlannedOperationStatement) StatementEvaluationContext(herddb.model.StatementEvaluationContext) SyscolumnsTableManager(herddb.core.system.SyscolumnsTableManager) Comparator(java.util.Comparator) Collections(java.util.Collections) TableManagerStats(herddb.core.stats.TableManagerStats) MemoryHashIndexManager(herddb.index.MemoryHashIndexManager) SystemProperties(herddb.utils.SystemProperties) TransactionResult(herddb.model.TransactionResult) CompletionException(java.util.concurrent.CompletionException) DDLStatementExecutionResult(herddb.model.DDLStatementExecutionResult) StatementExecutionResult(herddb.model.StatementExecutionResult) CommitLogResult(herddb.log.CommitLogResult) LogEntry(herddb.log.LogEntry) DumpedLogEntry(herddb.backup.DumpedLogEntry)

Example 24 with CommitLogResult

use of herddb.log.CommitLogResult in project herddb by diennea.

the class TableSpaceManager method checkpoint.

// visible for testing
public TableSpaceCheckpoint checkpoint(boolean full, boolean pin, boolean alreadLocked) throws DataStorageManagerException, LogNotAvailableException {
    if (virtual) {
        return null;
    }
    if (recoveryInProgress) {
        LOGGER.log(Level.INFO, "Checkpoint for tablespace {0} skipped. Recovery is still in progress", tableSpaceName);
        return null;
    }
    long _start = System.currentTimeMillis();
    LogSequenceNumber logSequenceNumber = null;
    LogSequenceNumber _logSequenceNumber = null;
    Map<String, LogSequenceNumber> checkpointsTableNameSequenceNumber = new HashMap<>();
    try {
        List<PostCheckpointAction> actions = new ArrayList<>();
        long lockStamp = 0;
        if (!alreadLocked) {
            lockStamp = acquireWriteLock("checkpoint");
        }
        try {
            logSequenceNumber = log.getLastSequenceNumber();
            if (logSequenceNumber.isStartOfTime()) {
                LOGGER.log(Level.INFO, "{0} checkpoint {1} at {2}. skipped (no write ever issued to log)", new Object[] { nodeId, tableSpaceName, logSequenceNumber });
                return new TableSpaceCheckpoint(logSequenceNumber, checkpointsTableNameSequenceNumber);
            }
            LOGGER.log(Level.INFO, "{0} checkpoint start {1} at {2}", new Object[] { nodeId, tableSpaceName, logSequenceNumber });
            if (actualLogSequenceNumber == null) {
                throw new DataStorageManagerException("actualLogSequenceNumber cannot be null");
            }
            // TODO: transactions checkpoint is not atomic
            Collection<Transaction> currentTransactions = new ArrayList<>(transactions.values());
            for (Transaction t : currentTransactions) {
                LogSequenceNumber txLsn = t.lastSequenceNumber;
                if (txLsn != null && txLsn.after(logSequenceNumber)) {
                    LOGGER.log(Level.SEVERE, "Found transaction {0} with LSN {1} in the future", new Object[] { t.transactionId, txLsn });
                }
            }
            actions.addAll(dataStorageManager.writeTransactionsAtCheckpoint(tableSpaceUUID, logSequenceNumber, currentTransactions));
            actions.addAll(writeTablesOnDataStorageManager(new CommitLogResult(logSequenceNumber, false, true), true));
            // we checkpoint all data to disk and save the actual log sequence number
            for (AbstractTableManager tableManager : tables.values()) {
                if (!tableManager.isSystemTable()) {
                    TableCheckpoint checkpoint = full ? tableManager.fullCheckpoint(pin) : tableManager.checkpoint(pin);
                    if (checkpoint != null) {
                        LOGGER.log(Level.INFO, "checkpoint done for table {0}.{1} (pin: {2})", new Object[] { tableSpaceName, tableManager.getTable().name, pin });
                        actions.addAll(checkpoint.actions);
                        checkpointsTableNameSequenceNumber.put(checkpoint.tableName, checkpoint.sequenceNumber);
                        if (afterTableCheckPointAction != null) {
                            afterTableCheckPointAction.run();
                        }
                    }
                }
            }
            // we are sure that all data as been flushed. upon recovery we will replay the log starting from this position
            actions.addAll(dataStorageManager.writeCheckpointSequenceNumber(tableSpaceUUID, logSequenceNumber));
            /* Indexes checkpoint is handled by TableManagers */
            if (leader) {
                log.dropOldLedgers(logSequenceNumber);
            }
            _logSequenceNumber = log.getLastSequenceNumber();
        } finally {
            if (!alreadLocked) {
                releaseWriteLock(lockStamp, "checkpoint");
            }
        }
        for (PostCheckpointAction action : actions) {
            try {
                action.run();
            } catch (Exception error) {
                LOGGER.log(Level.SEVERE, "postcheckpoint error:" + error, error);
            }
        }
        return new TableSpaceCheckpoint(logSequenceNumber, checkpointsTableNameSequenceNumber);
    } finally {
        long _stop = System.currentTimeMillis();
        LOGGER.log(Level.INFO, "{0} checkpoint finish {1} started ad {2}, finished at {3}, total time {4} ms", new Object[] { nodeId, tableSpaceName, logSequenceNumber, _logSequenceNumber, Long.toString(_stop - _start) });
        checkpointTimeStats.registerSuccessfulEvent(_stop, TimeUnit.MILLISECONDS);
    }
}
Also used : TableCheckpoint(herddb.core.AbstractTableManager.TableCheckpoint) DataStorageManagerException(herddb.storage.DataStorageManagerException) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) LogSequenceNumber(herddb.log.LogSequenceNumber) CommitLogResult(herddb.log.CommitLogResult) HDBException(herddb.client.HDBException) IndexAlreadyExistsException(herddb.model.IndexAlreadyExistsException) LogNotAvailableException(herddb.log.LogNotAvailableException) ClientSideMetadataProviderException(herddb.client.ClientSideMetadataProviderException) TableSpaceDoesNotExistException(herddb.model.TableSpaceDoesNotExistException) IndexDoesNotExistException(herddb.model.IndexDoesNotExistException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) FullRecoveryNeededException(herddb.log.FullRecoveryNeededException) TableAlreadyExistsException(herddb.model.TableAlreadyExistsException) TimeoutException(java.util.concurrent.TimeoutException) DataStorageManagerException(herddb.storage.DataStorageManagerException) TableDoesNotExistException(herddb.model.TableDoesNotExistException) DDLException(herddb.model.DDLException) StatementExecutionException(herddb.model.StatementExecutionException) CompletionException(java.util.concurrent.CompletionException) EOFException(java.io.EOFException) MetadataStorageManagerException(herddb.metadata.MetadataStorageManagerException) DataScannerException(herddb.model.DataScannerException) Transaction(herddb.model.Transaction)

Example 25 with CommitLogResult

use of herddb.log.CommitLogResult in project herddb by diennea.

the class TableSpaceManager method dropTable.

private StatementExecutionResult dropTable(DropTableStatement statement, Transaction transaction, StatementEvaluationContext context) throws StatementExecutionException {
    boolean lockAcquired = false;
    if (context.getTableSpaceLock() == 0) {
        long lockStamp = acquireWriteLock(statement);
        context.setTableSpaceLock(lockStamp);
        lockAcquired = true;
    }
    try {
        String tableNameUpperCase = statement.getTable().toUpperCase();
        String tableNameNormalized = tables.keySet().stream().filter(t -> t.toUpperCase().equals(tableNameUpperCase)).findFirst().orElse(statement.getTable());
        AbstractTableManager tableManager = tables.get(tableNameNormalized);
        if (tableManager == null) {
            if (statement.isIfExists()) {
                return new DDLStatementExecutionResult(transaction != null ? transaction.transactionId : 0);
            }
            throw new TableDoesNotExistException("table does not exist " + tableNameNormalized + " on tableSpace " + statement.getTableSpace());
        }
        if (transaction != null && transaction.isTableDropped(tableNameNormalized)) {
            if (statement.isIfExists()) {
                return new DDLStatementExecutionResult(transaction.transactionId);
            }
            throw new TableDoesNotExistException("table does not exist " + tableNameNormalized + " on tableSpace " + statement.getTableSpace());
        }
        Table table = tableManager.getTable();
        Table[] childrenTables = collectChildrenTables(table);
        if (childrenTables != null) {
            String errorMsg = "Cannot drop table " + table.tablespace + "." + table.name + " because it has children tables: " + Stream.of(childrenTables).map(t -> t.name).collect(Collectors.joining(","));
            throw new StatementExecutionException(errorMsg);
        }
        Map<String, AbstractIndexManager> indexesOnTable = indexesByTable.get(tableNameNormalized);
        if (indexesOnTable != null) {
            for (String index : new ArrayList<>(indexesOnTable.keySet())) {
                LogEntry entry = LogEntryFactory.dropIndex(index, transaction);
                CommitLogResult pos = log.log(entry, entry.transactionId <= 0);
                apply(pos, entry, false);
            }
        }
        LogEntry entry = LogEntryFactory.dropTable(tableNameNormalized, transaction);
        CommitLogResult pos = log.log(entry, entry.transactionId <= 0);
        apply(pos, entry, false);
        return new DDLStatementExecutionResult(entry.transactionId);
    } catch (DataStorageManagerException | LogNotAvailableException err) {
        throw new StatementExecutionException(err);
    } finally {
        if (lockAcquired) {
            releaseWriteLock(context.getTableSpaceLock(), statement);
            context.setTableSpaceLock(0);
        }
    }
}
Also used : DataStorageManagerException(herddb.storage.DataStorageManagerException) Table(herddb.model.Table) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) DDLStatementExecutionResult(herddb.model.DDLStatementExecutionResult) CommitLogResult(herddb.log.CommitLogResult) StatementExecutionException(herddb.model.StatementExecutionException) TableDoesNotExistException(herddb.model.TableDoesNotExistException) LogEntry(herddb.log.LogEntry) DumpedLogEntry(herddb.backup.DumpedLogEntry) LogNotAvailableException(herddb.log.LogNotAvailableException)

Aggregations

CommitLogResult (herddb.log.CommitLogResult)34 LogEntry (herddb.log.LogEntry)30 LogNotAvailableException (herddb.log.LogNotAvailableException)26 StatementExecutionException (herddb.model.StatementExecutionException)23 DataStorageManagerException (herddb.storage.DataStorageManagerException)22 DumpedLogEntry (herddb.backup.DumpedLogEntry)19 DDLStatementExecutionResult (herddb.model.DDLStatementExecutionResult)13 IndexAlreadyExistsException (herddb.model.IndexAlreadyExistsException)12 LogSequenceNumber (herddb.log.LogSequenceNumber)11 DDLException (herddb.model.DDLException)11 TableDoesNotExistException (herddb.model.TableDoesNotExistException)11 IndexDoesNotExistException (herddb.model.IndexDoesNotExistException)10 TableAlreadyExistsException (herddb.model.TableAlreadyExistsException)10 Bytes (herddb.utils.Bytes)10 FullRecoveryNeededException (herddb.log.FullRecoveryNeededException)9 Table (herddb.model.Table)9 Transaction (herddb.model.Transaction)9 ArrayList (java.util.ArrayList)9 ClientSideMetadataProviderException (herddb.client.ClientSideMetadataProviderException)8 HDBException (herddb.client.HDBException)8