Search in sources :

Example 1 with LoggerOperation

use of org.apache.accumulo.tserver.log.DfsLogger.LoggerOperation in project accumulo by apache.

the class TabletServerLogger method write.

private void write(final Collection<CommitSession> sessions, boolean mincFinish, Writer writer, Retry writeRetry) throws IOException {
    // Work very hard not to lock this during calls to the outside world
    int currentLogId = logId.get();
    boolean success = false;
    while (!success) {
        try {
            // get a reference to the loggers that no other thread can touch
            DfsLogger copy = null;
            AtomicInteger currentId = new AtomicInteger(-1);
            copy = initializeLoggers(currentId);
            currentLogId = currentId.get();
            if (currentLogId == logId.get()) {
                for (CommitSession commitSession : sessions) {
                    if (commitSession.beginUpdatingLogsUsed(copy, mincFinish)) {
                        try {
                            // Scribble out a tablet definition and then write to the metadata table
                            defineTablet(commitSession, writeRetry);
                        } finally {
                            commitSession.finishUpdatingLogsUsed();
                        }
                        // Need to release
                        KeyExtent extent = commitSession.getExtent();
                        if (ReplicationConfigurationUtil.isEnabled(extent, tserver.getTableConfiguration(extent))) {
                            Status status = StatusUtil.openWithUnknownLength(System.currentTimeMillis());
                            log.debug("Writing " + ProtobufUtil.toString(status) + " to metadata table for " + copy.getFileName());
                            // Got some new WALs, note this in the metadata table
                            ReplicationTableUtil.updateFiles(tserver, commitSession.getExtent(), copy.getFileName(), status);
                        }
                    }
                }
            }
            // Make sure that the logs haven't changed out from underneath our copy
            if (currentLogId == logId.get()) {
                // write the mutation to the logs
                LoggerOperation lop = writer.write(copy);
                lop.await();
                // double-check: did the log set change?
                success = (currentLogId == logId.get());
            }
        } catch (DfsLogger.LogClosedException ex) {
            writeRetry.logRetry(log, "Logs closed while writing", ex);
        } catch (Exception t) {
            writeRetry.logRetry(log, "Failed to write to WAL", t);
            try {
                // Backoff
                writeRetry.waitForNextAttempt();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new RuntimeException(e);
            }
        } finally {
            writeRetry.useRetry();
        }
        // Some sort of write failure occurred. Grab the write lock and reset the logs.
        // But since multiple threads will attempt it, only attempt the reset when
        // the logs haven't changed.
        final int finalCurrent = currentLogId;
        if (!success) {
            testLockAndRun(logIdLock, new TestCallWithWriteLock() {

                @Override
                boolean test() {
                    return finalCurrent == logId.get();
                }

                @Override
                void withWriteLock() throws IOException {
                    close();
                    closeForReplication(sessions);
                }
            });
        }
    }
    // if the log gets too big or too old, reset it .. grab the write lock first
    // event, tid, seq overhead
    logSizeEstimate.addAndGet(4 * 3);
    testLockAndRun(logIdLock, new TestCallWithWriteLock() {

        @Override
        boolean test() {
            return (logSizeEstimate.get() > maxSize) || ((System.currentTimeMillis() - createTime) > maxAge);
        }

        @Override
        void withWriteLock() throws IOException {
            close();
            closeForReplication(sessions);
        }
    });
}
Also used : Status(org.apache.accumulo.server.replication.proto.Replication.Status) CommitSession(org.apache.accumulo.tserver.tablet.CommitSession) IOException(java.io.IOException) KeyExtent(org.apache.accumulo.core.data.impl.KeyExtent) LoggerOperation(org.apache.accumulo.tserver.log.DfsLogger.LoggerOperation) IOException(java.io.IOException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger)

Example 2 with LoggerOperation

use of org.apache.accumulo.tserver.log.DfsLogger.LoggerOperation in project accumulo by apache.

the class TabletServerLogger method logManyTablets.

public void logManyTablets(Map<CommitSession, Mutations> mutations) throws IOException {
    final Map<CommitSession, Mutations> loggables = new HashMap<>(mutations);
    for (Entry<CommitSession, Mutations> entry : mutations.entrySet()) {
        if (entry.getValue().getDurability() == Durability.NONE) {
            loggables.remove(entry.getKey());
        }
    }
    if (loggables.size() == 0)
        return;
    write(loggables.keySet(), false, new Writer() {

        @Override
        public LoggerOperation write(DfsLogger logger) throws Exception {
            List<TabletMutations> copy = new ArrayList<>(loggables.size());
            for (Entry<CommitSession, Mutations> entry : loggables.entrySet()) {
                CommitSession cs = entry.getKey();
                Durability durability = entry.getValue().getDurability();
                copy.add(new TabletMutations(cs.getLogId(), cs.getWALogSeq(), entry.getValue().getMutations(), durability));
            }
            return logger.logManyTablets(copy);
        }
    });
    for (Mutations entry : loggables.values()) {
        if (entry.getMutations().size() < 1) {
            throw new IllegalArgumentException("logManyTablets: logging empty mutation list");
        }
        for (Mutation m : entry.getMutations()) {
            logSizeEstimate.addAndGet(m.numBytes());
        }
    }
}
Also used : Mutations(org.apache.accumulo.tserver.Mutations) TabletMutations(org.apache.accumulo.tserver.TabletMutations) HashMap(java.util.HashMap) CommitSession(org.apache.accumulo.tserver.tablet.CommitSession) Durability(org.apache.accumulo.core.client.Durability) LoggerOperation(org.apache.accumulo.tserver.log.DfsLogger.LoggerOperation) IOException(java.io.IOException) Entry(java.util.Map.Entry) TabletMutations(org.apache.accumulo.tserver.TabletMutations) ArrayList(java.util.ArrayList) List(java.util.List) Mutation(org.apache.accumulo.core.data.Mutation)

Aggregations

IOException (java.io.IOException)2 LoggerOperation (org.apache.accumulo.tserver.log.DfsLogger.LoggerOperation)2 CommitSession (org.apache.accumulo.tserver.tablet.CommitSession)2 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Entry (java.util.Map.Entry)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 Durability (org.apache.accumulo.core.client.Durability)1 Mutation (org.apache.accumulo.core.data.Mutation)1 KeyExtent (org.apache.accumulo.core.data.impl.KeyExtent)1 Status (org.apache.accumulo.server.replication.proto.Replication.Status)1 Mutations (org.apache.accumulo.tserver.Mutations)1 TabletMutations (org.apache.accumulo.tserver.TabletMutations)1