Search in sources :

Example 1 with BatchingVisitable

use of com.palantir.common.base.BatchingVisitable in project atlasdb by palantir.

the class Scrubber method runBackgroundScrubTask.

@VisibleForTesting
void runBackgroundScrubTask(final TransactionManager txManager) {
    log.debug("Starting scrub task");
    // Warning: Let T be the hard delete transaction that triggered a scrub, and let S be its
    // start timestamp.  If the locks for T happen to time out right after T checks that its
    // locks are held but right before T writes its commit timestamp (extremely rare case), AND
    // the unreadable timestamp is greater than S, then the scrub task could actually roll back
    // the hard delete transaction (forcing it to abort or retry).  Note that this doesn't affect
    // correctness, but could be an annoying edge cause that causes hard delete to take longer
    // than it otherwise would have.
    Long immutableTimestamp = immutableTimestampSupplier.get();
    Long unreadableTimestamp = unreadableTimestampSupplier.get();
    final long maxScrubTimestamp = aggressiveScrub ? immutableTimestamp : Math.min(unreadableTimestamp, immutableTimestamp);
    log.debug("Scrub task immutableTimestamp: {}, unreadableTimestamp: {}, maxScrubTimestamp: {}", immutableTimestamp, unreadableTimestamp, maxScrubTimestamp);
    final int batchSize = (int) Math.ceil(batchSizeSupplier.get() * ((double) threadCount / readThreadCount));
    List<byte[]> rangeBoundaries = Lists.newArrayList();
    rangeBoundaries.add(PtBytes.EMPTY_BYTE_ARRAY);
    if (readThreadCount > 1) {
        // This will actually partition into the closest higher power of 2 number of ranges.
        rangeBoundaries.addAll(Ordering.from(UnsignedBytes.lexicographicalComparator()).sortedCopy(new UniformRowNamePartitioner(ValueType.BLOB).getPartitions(readThreadCount - 1)));
    }
    rangeBoundaries.add(PtBytes.EMPTY_BYTE_ARRAY);
    List<Future<Void>> readerFutures = Lists.newArrayList();
    final AtomicInteger totalCellsRead = new AtomicInteger(0);
    for (int i = 0; i < rangeBoundaries.size() - 1; i++) {
        final byte[] startRow = rangeBoundaries.get(i);
        final byte[] endRow = rangeBoundaries.get(i + 1);
        readerFutures.add(readerExec.submit(() -> {
            BatchingVisitable<SortedMap<Long, Multimap<TableReference, Cell>>> scrubQueue = scrubberStore.getBatchingVisitableScrubQueue(maxScrubTimestamp, startRow, endRow);
            scrubQueue.batchAccept(batchSize, batch -> {
                for (SortedMap<Long, Multimap<TableReference, Cell>> cells : batch) {
                    // We may actually get more cells than the batch size. The batch size is used
                    // for pulling off the scrub queue, and a single entry in the scrub queue may
                    // match multiple tables. These will get broken down into smaller batches later
                    // on when we actually do deletes.
                    int numCellsRead = scrubSomeCells(cells, txManager, maxScrubTimestamp);
                    int totalRead = totalCellsRead.addAndGet(numCellsRead);
                    log.debug("Scrub task processed {} cells in a batch, total {} processed so far.", numCellsRead, totalRead);
                    if (!isScrubEnabled.get()) {
                        log.debug("Stopping scrub for banned hours.");
                        break;
                    }
                }
                return isScrubEnabled.get();
            });
            return null;
        }));
    }
    for (Future<Void> readerFuture : readerFutures) {
        Futures.getUnchecked(readerFuture);
    }
    log.debug("Scrub background task running at timestamp {} processed a total of {} cells", maxScrubTimestamp, totalCellsRead.get());
    log.debug("Finished scrub task");
}
Also used : ArrayListMultimap(com.google.common.collect.ArrayListMultimap) TransactionService(com.palantir.atlasdb.transaction.service.TransactionService) Throwables(com.palantir.common.base.Throwables) LoggerFactory(org.slf4j.LoggerFactory) BatchingVisitable(com.palantir.common.base.BatchingVisitable) Future(java.util.concurrent.Future) HashMultimap(com.google.common.collect.HashMultimap) PTExecutors(com.palantir.common.concurrent.PTExecutors) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) TableReference(com.palantir.atlasdb.keyvalue.api.TableReference) AtlasDbConstants(com.palantir.atlasdb.AtlasDbConstants) ImmutableSet(com.google.common.collect.ImmutableSet) NamedThreadFactory(com.palantir.common.concurrent.NamedThreadFactory) Cell(com.palantir.atlasdb.keyvalue.api.Cell) Collection(java.util.Collection) Set(java.util.Set) TransactionManager(com.palantir.atlasdb.transaction.api.TransactionManager) Maps2(com.palantir.common.collect.Maps2) GuardedBy(javax.annotation.concurrent.GuardedBy) Sets(com.google.common.collect.Sets) UniformRowNamePartitioner(com.palantir.atlasdb.table.description.UniformRowNamePartitioner) List(java.util.List) ValueType(com.palantir.atlasdb.table.description.ValueType) Transaction(com.palantir.atlasdb.transaction.api.Transaction) Entry(java.util.Map.Entry) Builder(com.google.common.collect.ImmutableMultimap.Builder) KeyAlreadyExistsException(com.palantir.atlasdb.keyvalue.api.KeyAlreadyExistsException) SortedMap(java.util.SortedMap) Iterables(com.google.common.collect.Iterables) Supplier(com.google.common.base.Supplier) TransactionFailedRetriableException(com.palantir.atlasdb.transaction.api.TransactionFailedRetriableException) Callable(java.util.concurrent.Callable) Multimap(com.google.common.collect.Multimap) PtBytes(com.palantir.atlasdb.encoding.PtBytes) Multimaps(com.google.common.collect.Multimaps) Lists(com.google.common.collect.Lists) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) ImmutableMultimap(com.google.common.collect.ImmutableMultimap) ExecutorService(java.util.concurrent.ExecutorService) UnsignedBytes(com.google.common.primitives.UnsignedBytes) Logger(org.slf4j.Logger) Value(com.palantir.atlasdb.keyvalue.api.Value) ExecutorInheritableThreadLocal(com.palantir.common.concurrent.ExecutorInheritableThreadLocal) Maps(com.google.common.collect.Maps) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) Futures(com.google.common.util.concurrent.Futures) TransactionConstants(com.palantir.atlasdb.transaction.impl.TransactionConstants) Ordering(com.google.common.collect.Ordering) KeyValueService(com.palantir.atlasdb.keyvalue.api.KeyValueService) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Collections(java.util.Collections) TransactionType(com.palantir.atlasdb.transaction.api.Transaction.TransactionType) UniformRowNamePartitioner(com.palantir.atlasdb.table.description.UniformRowNamePartitioner) BatchingVisitable(com.palantir.common.base.BatchingVisitable) ArrayListMultimap(com.google.common.collect.ArrayListMultimap) HashMultimap(com.google.common.collect.HashMultimap) Multimap(com.google.common.collect.Multimap) ImmutableMultimap(com.google.common.collect.ImmutableMultimap) TableReference(com.palantir.atlasdb.keyvalue.api.TableReference) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) SortedMap(java.util.SortedMap) Future(java.util.concurrent.Future) Cell(com.palantir.atlasdb.keyvalue.api.Cell) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 2 with BatchingVisitable

use of com.palantir.common.base.BatchingVisitable in project atlasdb by palantir.

the class AbstractTransactionTest method testColumnRangePagingTransaction.

@Test
public void testColumnRangePagingTransaction() {
    Transaction t = startTransaction();
    int totalPuts = 101;
    byte[] row = PtBytes.toBytes("row1");
    // Record expected results using byte ordering
    ImmutableSortedMap.Builder<Cell, byte[]> writes = ImmutableSortedMap.orderedBy(Ordering.from(UnsignedBytes.lexicographicalComparator()).onResultOf(key -> key.getColumnName()));
    for (int i = 0; i < totalPuts; i++) {
        put(t, "row1", "col" + i, "v" + i);
        writes.put(Cell.create(row, PtBytes.toBytes("col" + i)), PtBytes.toBytes("v" + i));
    }
    t.commit();
    t = startTransaction();
    Map<byte[], BatchingVisitable<Map.Entry<Cell, byte[]>>> columnRange = t.getRowsColumnRange(TEST_TABLE, ImmutableList.of(row), BatchColumnRangeSelection.create(PtBytes.EMPTY_BYTE_ARRAY, PtBytes.EMPTY_BYTE_ARRAY, 1));
    List<Map.Entry<Cell, byte[]>> expected = ImmutableList.copyOf(writes.build().entrySet());
    verifyMatchingResult(expected, row, columnRange);
    columnRange = t.getRowsColumnRange(TEST_TABLE, ImmutableList.of(row), BatchColumnRangeSelection.create(PtBytes.toBytes("col"), PtBytes.EMPTY_BYTE_ARRAY, 1));
    verifyMatchingResult(expected, row, columnRange);
    columnRange = t.getRowsColumnRange(TEST_TABLE, ImmutableList.of(row), BatchColumnRangeSelection.create(PtBytes.toBytes("col"), PtBytes.EMPTY_BYTE_ARRAY, 101));
    verifyMatchingResult(expected, row, columnRange);
    columnRange = t.getRowsColumnRange(TEST_TABLE, ImmutableList.of(row), BatchColumnRangeSelection.create(PtBytes.EMPTY_BYTE_ARRAY, RangeRequests.nextLexicographicName(expected.get(expected.size() - 1).getKey().getColumnName()), 1));
    verifyMatchingResult(expected, row, columnRange);
    columnRange = t.getRowsColumnRange(TEST_TABLE, ImmutableList.of(row), BatchColumnRangeSelection.create(PtBytes.EMPTY_BYTE_ARRAY, expected.get(expected.size() - 1).getKey().getColumnName(), 1));
    verifyMatchingResult(ImmutableList.copyOf(Iterables.limit(expected, 100)), row, columnRange);
}
Also used : RangeRequests(com.palantir.atlasdb.keyvalue.api.RangeRequests) Arrays(java.util.Arrays) AtlasDbDependencyException(com.palantir.common.exception.AtlasDbDependencyException) BatchColumnRangeSelection(com.palantir.atlasdb.keyvalue.api.BatchColumnRangeSelection) Throwables(com.palantir.common.base.Throwables) ClosableIterator(com.palantir.common.base.ClosableIterator) Random(java.util.Random) MapEntries(com.palantir.common.collect.MapEntries) BatchingVisitable(com.palantir.common.base.BatchingVisitable) Map(java.util.Map) TableReference(com.palantir.atlasdb.keyvalue.api.TableReference) Assert.fail(org.junit.Assert.fail) AtlasDbConstants(com.palantir.atlasdb.AtlasDbConstants) TableMetadata(com.palantir.atlasdb.table.description.TableMetadata) ImmutableSet(com.google.common.collect.ImmutableSet) ImmutableMap(com.google.common.collect.ImmutableMap) Cell(com.palantir.atlasdb.keyvalue.api.Cell) TransactionReadSentinelBehavior(com.palantir.atlasdb.transaction.api.TransactionReadSentinelBehavior) TableDefinition(com.palantir.atlasdb.table.description.TableDefinition) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) Executors(java.util.concurrent.Executors) ColumnSelection(com.palantir.atlasdb.keyvalue.api.ColumnSelection) RangeRequest(com.palantir.atlasdb.keyvalue.api.RangeRequest) TransactionConflictException(com.palantir.atlasdb.transaction.api.TransactionConflictException) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) IterableView(com.palantir.common.collect.IterableView) ValueType(com.palantir.atlasdb.table.description.ValueType) Transaction(com.palantir.atlasdb.transaction.api.Transaction) Assert.assertFalse(org.junit.Assert.assertFalse) NoOpCleaner(com.palantir.atlasdb.cleaner.NoOpCleaner) Iterables(com.google.common.collect.Iterables) ConflictHandler(com.palantir.atlasdb.transaction.api.ConflictHandler) FutureTask(java.util.concurrent.FutureTask) Multimap(com.google.common.collect.Multimap) Iterators(com.google.common.collect.Iterators) PtBytes(com.palantir.atlasdb.encoding.PtBytes) Multimaps(com.google.common.collect.Multimaps) AtlasDbConstraintCheckingMode(com.palantir.atlasdb.transaction.api.AtlasDbConstraintCheckingMode) Assertions.assertThatThrownBy(org.assertj.core.api.Assertions.assertThatThrownBy) ImmutableList(com.google.common.collect.ImmutableList) LegacyTimelockService(com.palantir.lock.impl.LegacyTimelockService) Assert.assertArrayEquals(org.junit.Assert.assertArrayEquals) AbortingVisitors(com.palantir.common.base.AbortingVisitors) ImmutableMultimap(com.google.common.collect.ImmutableMultimap) BatchingVisitables(com.palantir.common.base.BatchingVisitables) ExecutorService(java.util.concurrent.ExecutorService) ImmutableSortedMap(com.google.common.collect.ImmutableSortedMap) TableMetadataPersistence(com.palantir.atlasdb.protos.generated.TableMetadataPersistence) UnsignedBytes(com.google.common.primitives.UnsignedBytes) Value(com.palantir.atlasdb.keyvalue.api.Value) BaseEncoding(com.google.common.io.BaseEncoding) Assert.assertTrue(org.junit.Assert.assertTrue) TimestampCache(com.palantir.atlasdb.cache.TimestampCache) Test(org.junit.Test) TokenBackedBasicResultsPage(com.palantir.util.paging.TokenBackedBasicResultsPage) Maps(com.google.common.collect.Maps) Pair(com.palantir.util.Pair) ExecutionException(java.util.concurrent.ExecutionException) RowResult(com.palantir.atlasdb.keyvalue.api.RowResult) Assert.assertNull(org.junit.Assert.assertNull) Ordering(com.google.common.collect.Ordering) TransactionTask(com.palantir.atlasdb.transaction.api.TransactionTask) MultiTableSweepQueueWriter(com.palantir.atlasdb.sweep.queue.MultiTableSweepQueueWriter) Collections(java.util.Collections) Assert.assertEquals(org.junit.Assert.assertEquals) BatchingVisitable(com.palantir.common.base.BatchingVisitable) Transaction(com.palantir.atlasdb.transaction.api.Transaction) ImmutableSortedMap(com.google.common.collect.ImmutableSortedMap) Cell(com.palantir.atlasdb.keyvalue.api.Cell) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) ImmutableSortedMap(com.google.common.collect.ImmutableSortedMap) Test(org.junit.Test)

Example 3 with BatchingVisitable

use of com.palantir.common.base.BatchingVisitable in project atlasdb by palantir.

the class AbstractSerializableTransactionTest method testColumnRangeReadWriteConflictOnNewCell.

@Test
public void testColumnRangeReadWriteConflictOnNewCell() {
    byte[] row = PtBytes.toBytes("row1");
    writeColumns();
    Transaction t1 = startTransaction();
    Map<byte[], BatchingVisitable<Map.Entry<Cell, byte[]>>> columnRange = t1.getRowsColumnRange(TEST_TABLE, ImmutableList.of(row), BatchColumnRangeSelection.create(PtBytes.EMPTY_BYTE_ARRAY, PtBytes.EMPTY_BYTE_ARRAY, 1));
    // Serializable transaction records only the first column as read.
    Map.Entry<Cell, byte[]> read = BatchingVisitables.getFirst(Iterables.getOnlyElement(columnRange.values()));
    assertEquals(Cell.create(row, PtBytes.toBytes("col0")), read.getKey());
    // Write to avoid the read only path.
    put(t1, "row1_1", "col0", "v0");
    Transaction t2 = startTransaction();
    // Write on the start of the range.
    put(t2, "row1", "col", "v");
    t2.commit();
    try {
        t1.commit();
        fail();
    } catch (TransactionSerializableConflictException e) {
    // expected
    }
}
Also used : BatchingVisitable(com.palantir.common.base.BatchingVisitable) Transaction(com.palantir.atlasdb.transaction.api.Transaction) TransactionSerializableConflictException(com.palantir.atlasdb.transaction.api.TransactionSerializableConflictException) Map(java.util.Map) ImmutableSortedMap(com.google.common.collect.ImmutableSortedMap) ImmutableMap(com.google.common.collect.ImmutableMap) Cell(com.palantir.atlasdb.keyvalue.api.Cell) Test(org.junit.Test)

Example 4 with BatchingVisitable

use of com.palantir.common.base.BatchingVisitable in project atlasdb by palantir.

the class AbstractSerializableTransactionTest method testColumnRangeReadWriteConflict.

@Test
public void testColumnRangeReadWriteConflict() {
    byte[] row = PtBytes.toBytes("row1");
    writeColumns();
    Transaction t1 = startTransaction();
    Map<byte[], BatchingVisitable<Map.Entry<Cell, byte[]>>> columnRange = t1.getRowsColumnRange(TEST_TABLE, ImmutableList.of(row), BatchColumnRangeSelection.create(PtBytes.EMPTY_BYTE_ARRAY, PtBytes.EMPTY_BYTE_ARRAY, 1));
    // Serializable transaction records only the first column as read.
    Map.Entry<Cell, byte[]> read = BatchingVisitables.getFirst(Iterables.getOnlyElement(columnRange.values()));
    assertEquals(Cell.create(row, PtBytes.toBytes("col0")), read.getKey());
    // Write to avoid the read only path.
    put(t1, "row1_1", "col0", "v0");
    Transaction t2 = startTransaction();
    put(t2, "row1", "col0", "v0_0");
    t2.commit();
    try {
        t1.commit();
        fail();
    } catch (TransactionSerializableConflictException e) {
    // expected
    }
}
Also used : BatchingVisitable(com.palantir.common.base.BatchingVisitable) Transaction(com.palantir.atlasdb.transaction.api.Transaction) TransactionSerializableConflictException(com.palantir.atlasdb.transaction.api.TransactionSerializableConflictException) Map(java.util.Map) ImmutableSortedMap(com.google.common.collect.ImmutableSortedMap) ImmutableMap(com.google.common.collect.ImmutableMap) Cell(com.palantir.atlasdb.keyvalue.api.Cell) Test(org.junit.Test)

Example 5 with BatchingVisitable

use of com.palantir.common.base.BatchingVisitable in project atlasdb by palantir.

the class AbstractSerializableTransactionTest method testColumnRangeReadWriteEmptyRangeUnread.

@Test
public void testColumnRangeReadWriteEmptyRangeUnread() {
    byte[] row = PtBytes.toBytes("row1");
    Transaction t1 = startTransaction();
    Map<byte[], BatchingVisitable<Map.Entry<Cell, byte[]>>> columnRange = t1.getRowsColumnRange(TEST_TABLE, ImmutableList.of(row), BatchColumnRangeSelection.create(PtBytes.toBytes("col"), PtBytes.toBytes("col0"), 1));
    // Intentionally not reading anything from the result, so we shouldn't get a conflict.
    // Write to avoid the read only path.
    put(t1, "row1_1", "col0", "v0");
    Transaction t2 = startTransaction();
    put(t2, "row1", "col", "v0");
    t2.commit();
    t1.commit();
}
Also used : BatchingVisitable(com.palantir.common.base.BatchingVisitable) Transaction(com.palantir.atlasdb.transaction.api.Transaction) Map(java.util.Map) ImmutableSortedMap(com.google.common.collect.ImmutableSortedMap) ImmutableMap(com.google.common.collect.ImmutableMap) Cell(com.palantir.atlasdb.keyvalue.api.Cell) Test(org.junit.Test)

Aggregations

BatchingVisitable (com.palantir.common.base.BatchingVisitable)16 Cell (com.palantir.atlasdb.keyvalue.api.Cell)15 Map (java.util.Map)14 ImmutableMap (com.google.common.collect.ImmutableMap)13 Transaction (com.palantir.atlasdb.transaction.api.Transaction)13 Test (org.junit.Test)12 ImmutableSortedMap (com.google.common.collect.ImmutableSortedMap)11 RangeRequest (com.palantir.atlasdb.keyvalue.api.RangeRequest)8 RowResult (com.palantir.atlasdb.keyvalue.api.RowResult)8 Iterables (com.google.common.collect.Iterables)7 PtBytes (com.palantir.atlasdb.encoding.PtBytes)7 TableReference (com.palantir.atlasdb.keyvalue.api.TableReference)7 ImmutableSet (com.google.common.collect.ImmutableSet)6 Multimap (com.google.common.collect.Multimap)6 Multimaps (com.google.common.collect.Multimaps)6 List (java.util.List)6 ExecutorService (java.util.concurrent.ExecutorService)6 Maps (com.google.common.collect.Maps)5 UnsignedBytes (com.google.common.primitives.UnsignedBytes)5 AtlasDbConstants (com.palantir.atlasdb.AtlasDbConstants)5