use of herddb.cluster.BookkeeperCommitLog in project herddb by diennea.
the class EdgeCasesFollowerTest method testLeaderOnlineLogNoMoreAvailableDataAlreadyPresent.
@Test
public void testLeaderOnlineLogNoMoreAvailableDataAlreadyPresent() throws Exception {
final AtomicInteger countErase = new AtomicInteger();
SystemInstrumentation.addListener(new SystemInstrumentation.SingleInstrumentationPointListener("eraseTablespaceData") {
@Override
public void acceptSingle(Object... args) throws Exception {
countErase.incrementAndGet();
}
});
ServerConfiguration serverconfig_1 = newServerConfigurationWithAutoPort(folder.newFolder().toPath());
serverconfig_1.set(ServerConfiguration.PROPERTY_NODEID, "server1");
serverconfig_1.set(ServerConfiguration.PROPERTY_MODE, ServerConfiguration.PROPERTY_MODE_CLUSTER);
serverconfig_1.set(ServerConfiguration.PROPERTY_ZOOKEEPER_ADDRESS, testEnv.getAddress());
serverconfig_1.set(ServerConfiguration.PROPERTY_ZOOKEEPER_PATH, testEnv.getPath());
serverconfig_1.set(ServerConfiguration.PROPERTY_ZOOKEEPER_SESSIONTIMEOUT, testEnv.getTimeout());
serverconfig_1.set(ServerConfiguration.PROPERTY_ENFORCE_LEADERSHIP, false);
serverconfig_1.set(ServerConfiguration.PROPERTY_BOOKKEEPER_LEDGERS_RETENTION_PERIOD, 1);
serverconfig_1.set(ServerConfiguration.PROPERTY_CHECKPOINT_PERIOD, 0);
// disabled
serverconfig_1.set(ServerConfiguration.PROPERTY_BOOKKEEPER_MAX_IDLE_TIME, 0);
ServerConfiguration serverconfig_2 = serverconfig_1.copy().set(ServerConfiguration.PROPERTY_NODEID, "server2").set(ServerConfiguration.PROPERTY_BASEDIR, folder.newFolder().toPath().toAbsolutePath());
Table table = Table.builder().name("t1").column("c", ColumnTypes.INTEGER).column("s", ColumnTypes.INTEGER).primaryKey("c").build();
Index index = Index.builder().onTable(table).type(Index.TYPE_BRIN).column("s", ColumnTypes.STRING).build();
try (Server server_1 = new Server(serverconfig_1)) {
server_1.start();
server_1.waitForStandaloneBoot();
server_1.getManager().executeStatement(new CreateTableStatement(table), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
server_1.getManager().executeStatement(new CreateIndexStatement(index), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
server_1.getManager().executeUpdate(new InsertStatement(TableSpace.DEFAULT, "t1", RecordSerializer.makeRecord(table, "c", 1, "s", "1")), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
server_1.getManager().executeUpdate(new InsertStatement(TableSpace.DEFAULT, "t1", RecordSerializer.makeRecord(table, "c", 2, "s", "2")), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
server_1.getManager().executeUpdate(new InsertStatement(TableSpace.DEFAULT, "t1", RecordSerializer.makeRecord(table, "c", 3, "s", "3")), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
server_1.getManager().executeUpdate(new InsertStatement(TableSpace.DEFAULT, "t1", RecordSerializer.makeRecord(table, "c", 4, "s", "4")), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
server_1.getManager().executeStatement(new AlterTableSpaceStatement(TableSpace.DEFAULT, new HashSet<>(Arrays.asList("server1", "server2")), "server1", 1, 0), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
TranslatedQuery translated = server_1.getManager().getPlanner().translate(TableSpace.DEFAULT, "SELECT * FROM " + TableSpace.DEFAULT + ".t1 WHERE s=1", Collections.emptyList(), true, true, false, -1);
ScanStatement statement = translated.plan.mainStatement.unwrap(ScanStatement.class);
assertTrue(statement.getPredicate().getIndexOperation() instanceof SecondaryIndexSeek);
try (DataScanner scan = server_1.getManager().scan(statement, translated.context, TransactionContext.NO_TRANSACTION)) {
assertEquals(1, scan.consume().size());
}
}
String tableSpaceUUID;
try (Server server_1 = new Server(serverconfig_1)) {
server_1.start();
server_1.waitForStandaloneBoot();
{
ZookeeperMetadataStorageManager man = (ZookeeperMetadataStorageManager) server_1.getMetadataStorageManager();
tableSpaceUUID = man.describeTableSpace(TableSpace.DEFAULT).uuid;
LedgersInfo ledgersList = ZookeeperMetadataStorageManager.readActualLedgersListFromZookeeper(man.getZooKeeper(), testEnv.getPath() + "/ledgers", tableSpaceUUID);
assertEquals(2, ledgersList.getActiveLedgers().size());
}
server_1.getManager().executeUpdate(new InsertStatement(TableSpace.DEFAULT, "t1", RecordSerializer.makeRecord(table, "c", 5, "s", "5")), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
server_1.getManager().checkpoint();
}
try (Server server_1 = new Server(serverconfig_1)) {
server_1.start();
server_1.waitForStandaloneBoot();
{
ZookeeperMetadataStorageManager man = (ZookeeperMetadataStorageManager) server_1.getMetadataStorageManager();
LedgersInfo ledgersList = ZookeeperMetadataStorageManager.readActualLedgersListFromZookeeper(man.getZooKeeper(), testEnv.getPath() + "/ledgers", tableSpaceUUID);
assertEquals(2, ledgersList.getActiveLedgers().size());
}
server_1.getManager().executeUpdate(new InsertStatement(TableSpace.DEFAULT, "t1", RecordSerializer.makeRecord(table, "c", 6, "s", "6")), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
{
ZookeeperMetadataStorageManager man = (ZookeeperMetadataStorageManager) server_1.getMetadataStorageManager();
LedgersInfo ledgersList = ZookeeperMetadataStorageManager.readActualLedgersListFromZookeeper(man.getZooKeeper(), testEnv.getPath() + "/ledgers", tableSpaceUUID);
assertEquals(2, ledgersList.getActiveLedgers().size());
}
server_1.getManager().checkpoint();
}
assertEquals(0, countErase.get());
LogSequenceNumber server2checkpointPosition;
try (Server server_1 = new Server(serverconfig_1)) {
server_1.start();
server_1.waitForStandaloneBoot();
// start server_2, and flush data locally
try (Server server_2 = new Server(serverconfig_2)) {
server_2.start();
assertTrue(server_2.getManager().waitForTablespace(TableSpace.DEFAULT, 60000, false));
// wait for data to arrive on server_2
for (int i = 0; i < 100; i++) {
GetResult found = server_2.getManager().get(new GetStatement(TableSpace.DEFAULT, "t1", Bytes.from_int(1), null, false), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
if (found.found()) {
break;
}
Thread.sleep(100);
}
// force a checkpoint, data is flushed to disk
server_2.getManager().checkpoint();
server2checkpointPosition = server_2.getManager().getTableSpaceManager(TableSpace.DEFAULT).getLog().getLastSequenceNumber();
System.out.println("server2 checkpoint time: " + server2checkpointPosition);
}
}
// start again server_1, in order to create a new ledger
try (Server server_1 = new Server(serverconfig_1)) {
server_1.start();
server_1.waitForStandaloneBoot();
BookkeeperCommitLog ll = (BookkeeperCommitLog) server_1.getManager().getTableSpaceManager(TableSpace.DEFAULT).getLog();
// server_1 make much progress
ll.rollNewLedger();
ll.rollNewLedger();
ll.rollNewLedger();
ll.rollNewLedger();
ll.rollNewLedger();
ll.rollNewLedger();
ll.rollNewLedger();
ll.rollNewLedger();
// a checkpoint will delete old ledgers
server_1.getManager().checkpoint();
{
ZookeeperMetadataStorageManager man = (ZookeeperMetadataStorageManager) server_1.getMetadataStorageManager();
LedgersInfo ledgersList = ZookeeperMetadataStorageManager.readActualLedgersListFromZookeeper(man.getZooKeeper(), testEnv.getPath() + "/ledgers", tableSpaceUUID);
System.out.println("ledgerList: " + ledgersList);
assertEquals(1, ledgersList.getActiveLedgers().size());
assertTrue(!ledgersList.getActiveLedgers().contains(ledgersList.getFirstLedger()));
// we want to be sure that server_2 cannot recover from log
assertTrue(!ledgersList.getActiveLedgers().contains(server2checkpointPosition.ledgerId));
}
assertEquals(1, countErase.get());
// but the server already has local data, tablespace directory must be erased
try (Server server_2 = new Server(serverconfig_2)) {
server_2.start();
assertTrue(server_2.getManager().waitForTablespace(TableSpace.DEFAULT, 60000, false));
assertTrue(server_2.getManager().get(new GetStatement(TableSpace.DEFAULT, "t1", Bytes.from_int(1), null, false), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION).found());
assertEquals(2, countErase.get());
TranslatedQuery translated = server_2.getManager().getPlanner().translate(TableSpace.DEFAULT, "SELECT * FROM " + TableSpace.DEFAULT + ".t1 WHERE s=1", Collections.emptyList(), true, true, false, -1);
ScanStatement statement = translated.plan.mainStatement.unwrap(ScanStatement.class);
assertTrue(statement.getPredicate().getIndexOperation() instanceof SecondaryIndexSeek);
try (DataScanner scan = server_2.getManager().scan(statement, translated.context, TransactionContext.NO_TRANSACTION)) {
assertEquals(1, scan.consume().size());
}
}
}
}
use of herddb.cluster.BookkeeperCommitLog in project herddb by diennea.
the class BookKeeperCommitLogTest method testMaxLedgerSizeWithTemporaryError.
@Test
public void testMaxLedgerSizeWithTemporaryError() throws Exception {
final String tableSpaceUUID = UUID.randomUUID().toString();
final String name = TableSpace.DEFAULT;
final String nodeid = "nodeid";
final int maxLedgerSize = 1024;
final LogEntry entry = LogEntryFactory.beginTransaction(1);
final int estimateSize = entry.serialize().length;
final int numberOfLedgers = 10;
final int numberOfEntries = 1 + numberOfLedgers * maxLedgerSize / estimateSize;
System.out.println("writing " + numberOfEntries + " entries");
ServerConfiguration serverConfiguration = newServerConfigurationWithAutoPort();
try (ZookeeperMetadataStorageManager man = new ZookeeperMetadataStorageManager(testEnv.getAddress(), testEnv.getTimeout(), testEnv.getPath());
BookkeeperCommitLogManager logManager = new BookkeeperCommitLogManager(man, serverConfiguration, NullStatsLogger.INSTANCE)) {
logManager.setMaxLedgerSizeBytes(maxLedgerSize);
man.start();
logManager.start();
assertTrue(numberOfEntries > 70);
try (BookkeeperCommitLog writer = logManager.createCommitLog(tableSpaceUUID, name, nodeid)) {
// do not pollute the count with NOOP entries
writer.setWriteLedgerHeader(false);
writer.startWriting(1);
for (int i = 0; i < numberOfEntries; i++) {
writer.log(entry, false);
if (i == 70) {
// stop bookie, but writes will continue to be acklowledged
testEnv.pauseBookie();
}
}
// even if we restart the bookie we must not be able to acknowledge the write
testEnv.resumeBookie();
TestUtils.assertThrows(LogNotAvailableException.class, () -> writer.log(entry, true).getLogSequenceNumber());
}
try (BookkeeperCommitLog reader = logManager.createCommitLog(tableSpaceUUID, name, nodeid)) {
List<Map.Entry<LogSequenceNumber, LogEntry>> list = new ArrayList<>();
reader.recovery(LogSequenceNumber.START_OF_TIME, (a, b) -> {
if (b.type != LogEntryType.NOOP) {
list.add(new AbstractMap.SimpleImmutableEntry<>(a, b));
}
}, false);
assertTrue("unexpected number of entries on reader: " + list.size(), list.size() <= 80);
}
}
}
use of herddb.cluster.BookkeeperCommitLog in project herddb by diennea.
the class BookKeeperCommitLogTest method testSimpleReadWrite.
@Test
public void testSimpleReadWrite() throws Exception {
final String tableSpaceUUID = UUID.randomUUID().toString();
final String name = TableSpace.DEFAULT;
final String nodeid = "nodeid";
ServerConfiguration serverConfiguration = newServerConfigurationWithAutoPort();
try (ZookeeperMetadataStorageManager man = new ZookeeperMetadataStorageManager(testEnv.getAddress(), testEnv.getTimeout(), testEnv.getPath());
BookkeeperCommitLogManager logManager = new BookkeeperCommitLogManager(man, serverConfiguration, NullStatsLogger.INSTANCE)) {
man.start();
logManager.start();
LogSequenceNumber lsn1;
LogSequenceNumber lsn2;
LogSequenceNumber lsn3;
try (BookkeeperCommitLog writer = logManager.createCommitLog(tableSpaceUUID, name, nodeid)) {
writer.startWriting(1);
lsn1 = writer.log(LogEntryFactory.beginTransaction(1), true).getLogSequenceNumber();
lsn2 = writer.log(LogEntryFactory.beginTransaction(2), true).getLogSequenceNumber();
lsn3 = writer.log(LogEntryFactory.beginTransaction(3), true).getLogSequenceNumber();
assertTrue(lsn1.after(LogSequenceNumber.START_OF_TIME));
assertTrue(lsn2.after(lsn1));
assertTrue(lsn3.after(lsn2));
}
try (BookkeeperCommitLog reader = logManager.createCommitLog(tableSpaceUUID, name, nodeid)) {
List<Map.Entry<LogSequenceNumber, LogEntry>> list = new ArrayList<>();
reader.recovery(LogSequenceNumber.START_OF_TIME, (a, b) -> {
if (b.type != LogEntryType.NOOP) {
list.add(new AbstractMap.SimpleImmutableEntry<>(a, b));
}
}, false);
assertEquals(3, list.size());
assertEquals(lsn1, list.get(0).getKey());
assertEquals(lsn2, list.get(1).getKey());
assertEquals(lsn3, list.get(2).getKey());
}
}
}
use of herddb.cluster.BookkeeperCommitLog in project herddb by diennea.
the class LedgerClosedTest method uselessLedgerDroppedError.
@Test
public void uselessLedgerDroppedError() throws Exception {
ServerConfiguration serverconfig_1 = newServerConfigurationWithAutoPort(folder.newFolder().toPath());
serverconfig_1.set(ServerConfiguration.PROPERTY_NODEID, "server1");
serverconfig_1.set(ServerConfiguration.PROPERTY_MODE, ServerConfiguration.PROPERTY_MODE_CLUSTER);
serverconfig_1.set(ServerConfiguration.PROPERTY_ZOOKEEPER_ADDRESS, testEnv.getAddress());
serverconfig_1.set(ServerConfiguration.PROPERTY_ZOOKEEPER_PATH, testEnv.getPath());
serverconfig_1.set(ServerConfiguration.PROPERTY_ZOOKEEPER_SESSIONTIMEOUT, testEnv.getTimeout());
try (Server server = new Server(serverconfig_1)) {
server.start();
server.waitForStandaloneBoot();
Table table = Table.builder().name("t1").column("c", ColumnTypes.INTEGER).primaryKey("c").build();
server.getManager().executeStatement(new CreateTableStatement(table), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
server.getManager().executeUpdate(new InsertStatement(TableSpace.DEFAULT, "t1", RecordSerializer.makeRecord(table, "c", 1)), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
server.getManager().executeUpdate(new InsertStatement(TableSpace.DEFAULT, "t1", RecordSerializer.makeRecord(table, "c", 2)), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
server.getManager().executeUpdate(new InsertStatement(TableSpace.DEFAULT, "t1", RecordSerializer.makeRecord(table, "c", 3)), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
TableSpaceManager tableSpaceManager = server.getManager().getTableSpaceManager(TableSpace.DEFAULT);
BookkeeperCommitLog log = (BookkeeperCommitLog) tableSpaceManager.getLog();
long ledgerId = log.getLastSequenceNumber().ledgerId;
assertTrue(ledgerId >= 0);
}
// restart
try (Server server = new Server(serverconfig_1)) {
server.start();
server.waitForStandaloneBoot();
}
// restart
LedgersInfo actualLedgersList;
try (Server server = new Server(serverconfig_1)) {
server.start();
server.waitForStandaloneBoot();
TableSpaceManager tableSpaceManager = server.getManager().getTableSpaceManager(TableSpace.DEFAULT);
BookkeeperCommitLog log = (BookkeeperCommitLog) tableSpaceManager.getLog();
actualLedgersList = log.getActualLedgersList();
assertEquals(3, actualLedgersList.getActiveLedgers().size());
System.out.println("actualLedgersList: " + actualLedgersList);
long lastLedgerId = log.getLastLedgerId();
assertEquals(lastLedgerId, actualLedgersList.getActiveLedgers().get(actualLedgersList.getActiveLedgers().size() - 1).longValue());
try (BookKeeper bk = createBookKeeper()) {
long ledgerIdToDrop = actualLedgersList.getActiveLedgers().get(0);
System.out.println("dropping " + ledgerIdToDrop);
bk.newDeleteLedgerOp().withLedgerId(ledgerIdToDrop).execute().get();
}
}
// the server should boot even if the ledger does not exist anymore
try (Server server = new Server(serverconfig_1)) {
server.start();
server.waitForStandaloneBoot();
}
}
use of herddb.cluster.BookkeeperCommitLog in project herddb by diennea.
the class BookKeeperCommitLogTest method testSimpleFence.
@Test
public void testSimpleFence() throws Exception {
final String tableSpaceUUID = UUID.randomUUID().toString();
final String name = TableSpace.DEFAULT;
final String nodeid = "nodeid";
ServerConfiguration serverConfiguration = newServerConfigurationWithAutoPort();
try (ZookeeperMetadataStorageManager man = new ZookeeperMetadataStorageManager(testEnv.getAddress(), testEnv.getTimeout(), testEnv.getPath());
BookkeeperCommitLogManager logManager = new BookkeeperCommitLogManager(man, serverConfiguration, NullStatsLogger.INSTANCE)) {
man.start();
logManager.start();
LogSequenceNumber lsn1;
LogSequenceNumber lsn2;
LogSequenceNumber lsn3;
try (BookkeeperCommitLog writer = logManager.createCommitLog(tableSpaceUUID, name, nodeid)) {
writer.startWriting(1);
lsn1 = writer.log(LogEntryFactory.beginTransaction(1), true).getLogSequenceNumber();
lsn2 = writer.log(LogEntryFactory.beginTransaction(2), true).getLogSequenceNumber();
// a new leader starts, from START_OF_TIME
try (BookkeeperCommitLog writer2 = logManager.createCommitLog(tableSpaceUUID, name, nodeid)) {
writer2.recovery(LogSequenceNumber.START_OF_TIME, (a, b) -> {
}, true);
writer2.startWriting(1);
lsn3 = writer2.log(LogEntryFactory.beginTransaction(3), true).getLogSequenceNumber();
}
TestUtils.assertThrows(LogNotAvailableException.class, () -> FutureUtils.result(writer.log(LogEntryFactory.beginTransaction(3), true).logSequenceNumber));
assertTrue(writer.isFailed());
assertTrue(lsn1.after(LogSequenceNumber.START_OF_TIME));
assertTrue(lsn2.after(lsn1));
// written by second writer
assertTrue(lsn3.after(lsn2));
}
try (BookkeeperCommitLog reader = logManager.createCommitLog(tableSpaceUUID, name, nodeid)) {
List<Map.Entry<LogSequenceNumber, LogEntry>> list = new ArrayList<>();
reader.recovery(LogSequenceNumber.START_OF_TIME, (lsn, entry) -> {
if (entry.type != LogEntryType.NOOP) {
list.add(new AbstractMap.SimpleImmutableEntry<>(lsn, entry));
}
}, false);
assertEquals(3, list.size());
assertEquals(lsn1, list.get(0).getKey());
assertEquals(lsn2, list.get(1).getKey());
assertEquals(lsn3, list.get(2).getKey());
}
}
}
Aggregations