use of herddb.model.StatementExecutionException in project herddb by diennea.
the class ScanDuringCheckPointTest method bigTableScan.
@Test
public // @Ignore
void bigTableScan() throws Exception {
int testSize = 10000;
String nodeId = "localhost";
try (DBManager manager = new DBManager("localhost", new MemoryMetadataStorageManager(), new MemoryDataStorageManager(), new MemoryCommitLogManager(), null, null)) {
// manager.setMaxLogicalPageSize(10);
// manager.setMaxPagesUsedMemory(Long.MAX_VALUE);
manager.start();
CreateTableSpaceStatement st1 = new CreateTableSpaceStatement("tblspace1", Collections.singleton(nodeId), nodeId, 1, 0, 0);
manager.executeStatement(st1, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
manager.waitForTablespace("tblspace1", 10000);
String tableSpaceUUID = manager.getTableSpaceManager("tblspace1").getTableSpaceUUID();
Table table = Table.builder().tablespace("tblspace1").name("t1").column("id", ColumnTypes.STRING).column("name", ColumnTypes.STRING).primaryKey("id").build();
CreateTableStatement st2 = new CreateTableStatement(table);
manager.executeStatement(st2, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
for (int i = 0; i < testSize / 2; i++) {
InsertStatement insert = new InsertStatement(table.tablespace, table.name, RecordSerializer.makeRecord(table, "id", "k" + i, "name", RandomString.getInstance().nextString(50, new StringBuilder().append("testname").append(i).append("_")).toString()));
assertEquals(1, manager.executeUpdate(insert, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION).getUpdateCount());
}
manager.checkpoint();
for (int i = testSize / 2; i < testSize; i++) {
InsertStatement insert = new InsertStatement(table.tablespace, table.name, RecordSerializer.makeRecord(table, "id", "k" + i, "name", RandomString.getInstance().nextString(50, new StringBuilder().append("testname").append(i).append("_")).toString()));
assertEquals(1, manager.executeUpdate(insert, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION).getUpdateCount());
}
manager.checkpoint();
assertTrue(manager.getDataStorageManager().getActualNumberOfPages(tableSpaceUUID, table.uuid) > 1);
TableManagerStats stats = manager.getTableSpaceManager(table.tablespace).getTableManager(table.name).getStats();
assertEquals(testSize, stats.getTablesize());
assertTrue(testSize > 100);
ExecutorService service = Executors.newFixedThreadPool(1);
Runnable checkPointPerformer = new Runnable() {
@Override
public void run() {
CountDownLatch checkpointDone = new CountDownLatch(1);
Thread fakeCheckpointThread = new Thread(new Runnable() {
@Override
public void run() {
try {
manager.checkpoint();
} catch (Throwable t) {
t.printStackTrace();
fail();
}
checkpointDone.countDown();
}
});
fakeCheckpointThread.setDaemon(true);
try {
fakeCheckpointThread.start();
checkpointDone.await();
fakeCheckpointThread.join();
} catch (InterruptedException err) {
throw new RuntimeException(err);
}
}
};
AtomicInteger done = new AtomicInteger();
Predicate slowPredicate = new Predicate() {
int count = 0;
@Override
public boolean evaluate(Record record, StatementEvaluationContext context) throws StatementExecutionException {
if (count++ % 10 == 0) {
// checkpoint will flush buffers, in the middle of the scan
try {
System.out.println("GO checkpoint !");
service.submit(checkPointPerformer).get();
done.incrementAndGet();
} catch (ExecutionException | InterruptedException err) {
throw new StatementExecutionException(err);
}
}
return true;
}
};
try (DataScanner scan = manager.scan(new ScanStatement(table.tablespace, table, slowPredicate), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION)) {
AtomicInteger count = new AtomicInteger();
scan.forEach(tuple -> {
count.incrementAndGet();
});
assertEquals(testSize, count.get());
}
assertEquals(testSize, stats.getTablesize());
assertEquals(testSize / 10, done.get());
}
}
use of herddb.model.StatementExecutionException in project herddb by diennea.
the class TableSpaceManager method dropTable.
private StatementExecutionResult dropTable(DropTableStatement statement, Transaction transaction) throws StatementExecutionException {
generalLock.writeLock().lock();
try {
if (!tables.containsKey(statement.getTable())) {
if (statement.isIfExists()) {
return new DDLStatementExecutionResult(transaction != null ? transaction.transactionId : 0);
}
throw new TableDoesNotExistException("table does not exist " + statement.getTable() + " on tableSpace " + statement.getTableSpace());
}
if (transaction != null && transaction.isTableDropped(statement.getTable())) {
if (statement.isIfExists()) {
return new DDLStatementExecutionResult(transaction.transactionId);
}
throw new TableDoesNotExistException("table does not exist " + statement.getTable() + " on tableSpace " + statement.getTableSpace());
}
Map<String, AbstractIndexManager> indexesOnTable = indexesByTable.get(statement.getTable());
if (indexesOnTable != null) {
for (String index : indexesOnTable.keySet()) {
LogEntry entry = LogEntryFactory.dropIndex(index, transaction);
CommitLogResult pos = log.log(entry, entry.transactionId <= 0);
apply(pos, entry, false);
}
}
LogEntry entry = LogEntryFactory.dropTable(statement.getTable(), 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 {
generalLock.writeLock().unlock();
}
}
use of herddb.model.StatementExecutionException in project herddb by diennea.
the class TableSpaceManager method createTable.
private StatementExecutionResult createTable(CreateTableStatement statement, Transaction transaction) throws StatementExecutionException {
generalLock.writeLock().lock();
try {
if (tables.containsKey(statement.getTableDefinition().name)) {
throw new TableAlreadyExistsException(statement.getTableDefinition().name);
}
for (Index additionalIndex : statement.getAdditionalIndexes()) {
if (indexes.containsKey(additionalIndex.name)) {
throw new IndexAlreadyExistsException(additionalIndex.name);
}
}
LogEntry entry = LogEntryFactory.createTable(statement.getTableDefinition(), transaction);
CommitLogResult pos = log.log(entry, entry.transactionId <= 0);
apply(pos, entry, false);
for (Index additionalIndex : statement.getAdditionalIndexes()) {
LogEntry index_entry = LogEntryFactory.createIndex(additionalIndex, transaction);
CommitLogResult index_pos = log.log(index_entry, index_entry.transactionId <= 0);
apply(index_pos, index_entry, false);
}
return new DDLStatementExecutionResult(entry.transactionId);
} catch (DataStorageManagerException | LogNotAvailableException err) {
throw new StatementExecutionException(err);
} finally {
generalLock.writeLock().unlock();
}
}
use of herddb.model.StatementExecutionException in project herddb by diennea.
the class TableSpaceManager method executeStatement.
public StatementExecutionResult executeStatement(Statement statement, StatementEvaluationContext context, TransactionContext transactionContext) throws StatementExecutionException {
boolean rollbackOnError = false;
/* Do not autostart transaction on alter table statements */
if (transactionContext.transactionId == TransactionContext.AUTOTRANSACTION_ID && statement.supportsTransactionAutoCreate()) {
StatementExecutionResult newTransaction = beginTransaction();
transactionContext = new TransactionContext(newTransaction.transactionId);
rollbackOnError = true;
}
Transaction transaction = transactions.get(transactionContext.transactionId);
if (transaction != null && !transaction.tableSpace.equals(tableSpaceName)) {
throw new StatementExecutionException("transaction " + transaction.transactionId + " is for tablespace " + transaction.tableSpace + ", not for " + tableSpaceName);
}
if (transactionContext.transactionId > 0 && transaction == null) {
throw new StatementExecutionException("transaction " + transactionContext.transactionId + " not found on tablespace " + tableSpaceName);
}
try {
if (statement instanceof TableAwareStatement) {
return executeTableAwareStatement(statement, transaction, context);
}
if (statement instanceof SQLPlannedOperationStatement) {
return executePlannedOperationStatement(statement, transactionContext, context);
}
if (statement instanceof BeginTransactionStatement) {
if (transaction != null) {
throw new IllegalArgumentException("transaction already started");
}
return beginTransaction();
}
if (statement instanceof RollbackTransactionStatement) {
return rollbackTransaction((RollbackTransactionStatement) statement);
}
if (statement instanceof CommitTransactionStatement) {
return commitTransaction((CommitTransactionStatement) statement);
}
if (statement instanceof CreateTableStatement) {
return createTable((CreateTableStatement) statement, transaction);
}
if (statement instanceof CreateIndexStatement) {
return createIndex((CreateIndexStatement) statement, transaction);
}
if (statement instanceof DropTableStatement) {
return dropTable((DropTableStatement) statement, transaction);
}
if (statement instanceof DropIndexStatement) {
return dropIndex((DropIndexStatement) statement, transaction);
}
if (statement instanceof AlterTableStatement) {
return alterTable((AlterTableStatement) statement, transactionContext);
}
throw new StatementExecutionException("unsupported statement " + statement);
} catch (StatementExecutionException error) {
if (rollbackOnError) {
rollbackTransaction(new RollbackTransactionStatement(tableSpaceName, transactionContext.transactionId));
}
throw error;
}
}
use of herddb.model.StatementExecutionException 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);
}
Aggregations