Search in sources :

Example 41 with StoredTabletFile

use of org.apache.accumulo.core.metadata.StoredTabletFile in project accumulo by apache.

the class DatafileManager method importMapFiles.

public Collection<StoredTabletFile> importMapFiles(long tid, Map<TabletFile, DataFileValue> paths, boolean setTime) throws IOException {
    String bulkDir = null;
    // once tablet files are inserted into the metadata they will become StoredTabletFiles
    Map<StoredTabletFile, DataFileValue> newFiles = new HashMap<>(paths.size());
    for (TabletFile tpath : paths.keySet()) {
        boolean inTheRightDirectory = false;
        Path parent = tpath.getPath().getParent().getParent();
        for (String tablesDir : tablet.getContext().getTablesDirs()) {
            if (parent.equals(new Path(tablesDir, tablet.getExtent().tableId().canonical()))) {
                inTheRightDirectory = true;
                break;
            }
        }
        if (!inTheRightDirectory) {
            throw new IOException("Data file " + tpath + " not in table dirs");
        }
        if (bulkDir == null)
            bulkDir = tpath.getTabletDir();
        else if (!bulkDir.equals(tpath.getTabletDir()))
            throw new IllegalArgumentException("bulk files in different dirs " + bulkDir + " " + tpath);
    }
    if (tablet.getExtent().isMeta()) {
        throw new IllegalArgumentException("Can not import files to a metadata tablet");
    }
    synchronized (bulkFileImportLock) {
        if (!paths.isEmpty()) {
            long bulkTime = Long.MIN_VALUE;
            if (setTime) {
                for (DataFileValue dfv : paths.values()) {
                    long nextTime = tablet.getAndUpdateTime();
                    if (nextTime < bulkTime)
                        throw new IllegalStateException("Time went backwards unexpectedly " + nextTime + " " + bulkTime);
                    bulkTime = nextTime;
                    dfv.setTime(bulkTime);
                }
            }
            newFiles = tablet.updatePersistedTime(bulkTime, paths, tid);
        }
    }
    synchronized (tablet) {
        for (Entry<StoredTabletFile, DataFileValue> tpath : newFiles.entrySet()) {
            if (datafileSizes.containsKey(tpath.getKey())) {
                log.error("Adding file that is already in set {}", tpath.getKey());
            }
            datafileSizes.put(tpath.getKey(), tpath.getValue());
        }
        updateCount++;
        tablet.getTabletResources().importedMapFiles();
        tablet.computeNumEntries();
    }
    for (Entry<StoredTabletFile, DataFileValue> entry : newFiles.entrySet()) {
        TabletLogger.bulkImported(tablet.getExtent(), entry.getKey());
    }
    return newFiles.keySet();
}
Also used : Path(org.apache.hadoop.fs.Path) DataFileValue(org.apache.accumulo.core.metadata.schema.DataFileValue) HashMap(java.util.HashMap) IOException(java.io.IOException) StoredTabletFile(org.apache.accumulo.core.metadata.StoredTabletFile) StoredTabletFile(org.apache.accumulo.core.metadata.StoredTabletFile) TabletFile(org.apache.accumulo.core.metadata.TabletFile)

Example 42 with StoredTabletFile

use of org.apache.accumulo.core.metadata.StoredTabletFile in project accumulo by apache.

the class DatafileManager method waitForScansToFinish.

private TreeSet<StoredTabletFile> waitForScansToFinish(Set<StoredTabletFile> pathsToWaitFor) {
    long maxWait = 10000L;
    long startTime = System.currentTimeMillis();
    TreeSet<StoredTabletFile> inUse = new TreeSet<>();
    Span span = TraceUtil.startSpan(this.getClass(), "waitForScans");
    try (Scope scope = span.makeCurrent()) {
        synchronized (tablet) {
            for (StoredTabletFile path : pathsToWaitFor) {
                while (fileScanReferenceCounts.get(path) > 0 && System.currentTimeMillis() - startTime < maxWait) {
                    try {
                        tablet.wait(100);
                    } catch (InterruptedException e) {
                        log.warn("{}", e.getMessage(), e);
                    }
                }
            }
            for (StoredTabletFile path : pathsToWaitFor) {
                if (fileScanReferenceCounts.get(path) > 0)
                    inUse.add(path);
            }
        }
    } catch (Exception e) {
        TraceUtil.setException(span, e, true);
        throw e;
    } finally {
        span.end();
    }
    return inUse;
}
Also used : Scope(io.opentelemetry.context.Scope) TreeSet(java.util.TreeSet) StoredTabletFile(org.apache.accumulo.core.metadata.StoredTabletFile) Span(io.opentelemetry.api.trace.Span) IOException(java.io.IOException)

Example 43 with StoredTabletFile

use of org.apache.accumulo.core.metadata.StoredTabletFile in project accumulo by apache.

the class CompactionPlanTest method testOverlappingInputAndDelete.

@Test
public void testOverlappingInputAndDelete() {
    CompactionPlan cp1 = new CompactionPlan();
    StoredTabletFile fr1 = new StoredTabletFile("hdfs://nn1/accumulo/tables/1/t-1/1.rf");
    StoredTabletFile fr2 = new StoredTabletFile("hdfs://nn1/accumulo/tables/1/t-1/2.rf");
    cp1.inputFiles.add(fr1);
    cp1.deleteFiles.add(fr1);
    cp1.deleteFiles.add(fr2);
    Set<StoredTabletFile> allFiles = Set.of(fr1, fr2);
    assertThrows(IllegalStateException.class, () -> cp1.validate(allFiles));
}
Also used : StoredTabletFile(org.apache.accumulo.core.metadata.StoredTabletFile) Test(org.junit.Test)

Example 44 with StoredTabletFile

use of org.apache.accumulo.core.metadata.StoredTabletFile in project accumulo by apache.

the class CompactableImpl method processExternalMetadata.

/**
 * This method validates metadata about external compactions. It also extracts specific
 * information needed for user and selector compactions.
 */
static Optional<SelectedInfo> processExternalMetadata(Map<ExternalCompactionId, ExternalCompactionMetadata> extCompactions, Supplier<Optional<Long>> tabletCompactionId, Set<StoredTabletFile> tabletFiles, Map<ExternalCompactionId, String> externalCompactionsToRemove) {
    // Check that external compactions have disjoint sets of files. Also check that each external
    // compaction only has files inside a tablet.
    Set<StoredTabletFile> seen = new HashSet<>();
    boolean overlap = false;
    for (var entry : extCompactions.entrySet()) {
        ExternalCompactionMetadata ecMeta = entry.getValue();
        if (!tabletFiles.containsAll(ecMeta.getJobFiles())) {
            externalCompactionsToRemove.putIfAbsent(entry.getKey(), "Has files outside of tablet files");
        } else if (!Collections.disjoint(seen, ecMeta.getJobFiles())) {
            overlap = true;
        }
        seen.addAll(ecMeta.getJobFiles());
    }
    if (overlap) {
        extCompactions.keySet().forEach(ecid -> {
            externalCompactionsToRemove.putIfAbsent(ecid, "Some external compaction files overlap");
        });
        return Optional.empty();
    }
    /*
     * The rest of the code validates user compaction metadata and extracts needed information.
     *
     * For user compactions a set of files is selected. Those files then get compacted by one or
     * more compactions until the set is empty. This method attempts to reconstruct the selected set
     * of files when a tablet is loaded with an external user compaction. It avoids repeating work
     * and when a user compaction completes, files are verified against the selected set. Since the
     * data is coming from persisted storage, lots of checks are done in this method rather than
     * assuming the persisted data is correct.
     */
    CompactionKind extKind = null;
    boolean unexpectedExternal = false;
    Set<StoredTabletFile> tmpSelectedFiles = null;
    Boolean initiallySelAll = null;
    Long cid = null;
    Boolean propDel = null;
    int count = 0;
    ArrayList<String> reasons = new ArrayList<>();
    for (Entry<ExternalCompactionId, ExternalCompactionMetadata> entry : extCompactions.entrySet()) {
        var ecMeta = entry.getValue();
        if (ecMeta.getKind() != CompactionKind.USER && ecMeta.getKind() != CompactionKind.SELECTOR) {
            continue;
        }
        count++;
        if (extKind == null || extKind == ecMeta.getKind()) {
            extKind = ecMeta.getKind();
        } else {
            reasons.add("Saw USER and SELECTOR");
            unexpectedExternal = true;
            break;
        }
        if (tmpSelectedFiles == null) {
            tmpSelectedFiles = Sets.union(ecMeta.getJobFiles(), ecMeta.getNextFiles());
        } else if (!Sets.union(ecMeta.getJobFiles(), ecMeta.getNextFiles()).equals(tmpSelectedFiles)) {
            reasons.add("Selected set of files differs");
            unexpectedExternal = true;
            break;
        }
        if (initiallySelAll == null) {
            initiallySelAll = ecMeta.getInitiallySelecteAll();
        } else if (initiallySelAll != ecMeta.getInitiallySelecteAll()) {
            unexpectedExternal = true;
            reasons.add("Disagreement on selectedAll");
            break;
        }
        if (ecMeta.getKind() == CompactionKind.USER) {
            if (ecMeta.getCompactionId() == null) {
                unexpectedExternal = true;
                reasons.add("Missing compactionId");
                break;
            } else if (cid == null) {
                cid = ecMeta.getCompactionId();
            } else if (!cid.equals(ecMeta.getCompactionId())) {
                unexpectedExternal = true;
                reasons.add("Disagreement on compactionId");
                break;
            }
        } else if (ecMeta.getCompactionId() != null) {
            unexpectedExternal = true;
            reasons.add("Unexpected compactionId");
            break;
        }
        if (propDel == null) {
            propDel = ecMeta.getPropagateDeletes();
        } else if (propDel != ecMeta.getPropagateDeletes()) {
            unexpectedExternal = true;
            reasons.add("Disagreement on propagateDeletes");
            break;
        }
    }
    if (propDel != null && !propDel && count > 1) {
        unexpectedExternal = true;
        reasons.add("Concurrent compactions not propagatingDeletes");
    }
    if (extKind == CompactionKind.USER) {
        Optional<Long> compactionId = tabletCompactionId.get();
        if (compactionId.isEmpty()) {
            unexpectedExternal = true;
            reasons.add("No compaction id in zookeeper");
        } else if (!compactionId.get().equals(cid)) {
            unexpectedExternal = true;
            reasons.add("Compaction id mismatch with zookeeper");
        }
    }
    if (unexpectedExternal) {
        String reason = reasons.toString();
        extCompactions.entrySet().stream().filter(e -> {
            var kind = e.getValue().getKind();
            return kind == CompactionKind.SELECTOR || kind == CompactionKind.USER;
        }).map(Entry::getKey).forEach(ecid -> externalCompactionsToRemove.putIfAbsent(ecid, reason));
        return Optional.empty();
    }
    if (extKind != null)
        return Optional.of(new SelectedInfo(initiallySelAll, tmpSelectedFiles, extKind));
    return Optional.empty();
}
Also used : ExternalCompactionId(org.apache.accumulo.core.metadata.schema.ExternalCompactionId) ArrayList(java.util.ArrayList) ExternalCompactionMetadata(org.apache.accumulo.core.metadata.schema.ExternalCompactionMetadata) CompactionKind(org.apache.accumulo.core.spi.compaction.CompactionKind) AtomicLong(java.util.concurrent.atomic.AtomicLong) StoredTabletFile(org.apache.accumulo.core.metadata.StoredTabletFile) HashSet(java.util.HashSet)

Example 45 with StoredTabletFile

use of org.apache.accumulo.core.metadata.StoredTabletFile in project accumulo by apache.

the class CompactableImpl method compact.

@Override
public void compact(CompactionServiceId service, CompactionJob job, RateLimiter readLimiter, RateLimiter writeLimiter, long queuedTime) {
    Optional<CompactionInfo> ocInfo = reserveFilesForCompaction(service, job);
    if (ocInfo.isEmpty())
        return;
    var cInfo = ocInfo.get();
    StoredTabletFile newFile = null;
    long startTime = System.currentTimeMillis();
    CompactionKind kind = job.getKind();
    CompactionStats stats = new CompactionStats();
    try {
        TabletLogger.compacting(getExtent(), job, cInfo.localCompactionCfg);
        tablet.incrementStatusMajor();
        var check = new CompactionCheck(service, kind, cInfo.checkCompactionId);
        TabletFile tmpFileName = tablet.getNextMapFilenameForMajc(cInfo.propagateDeletes);
        var compactEnv = new MajCEnv(kind, check, readLimiter, writeLimiter, cInfo.propagateDeletes);
        SortedMap<StoredTabletFile, DataFileValue> allFiles = tablet.getDatafiles();
        HashMap<StoredTabletFile, DataFileValue> compactFiles = new HashMap<>();
        cInfo.jobFiles.forEach(file -> compactFiles.put(file, allFiles.get(file)));
        stats = CompactableUtils.compact(tablet, job, cInfo, compactEnv, compactFiles, tmpFileName);
        newFile = CompactableUtils.bringOnline(tablet.getDatafileManager(), cInfo, stats, compactFiles, allFiles, kind, tmpFileName);
        TabletLogger.compacted(getExtent(), job, newFile);
    } catch (CompactionCanceledException cce) {
        log.debug("Compaction canceled {} ", getExtent());
    } catch (Exception e) {
        newFile = null;
        throw new RuntimeException(e);
    } finally {
        completeCompaction(job, cInfo.jobFiles, newFile);
        tablet.updateTimer(MAJOR, queuedTime, startTime, stats.getEntriesRead(), newFile == null);
    }
}
Also used : DataFileValue(org.apache.accumulo.core.metadata.schema.DataFileValue) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) CompactionStats(org.apache.accumulo.server.compaction.CompactionStats) UncheckedIOException(java.io.UncheckedIOException) CompactionCanceledException(org.apache.accumulo.server.compaction.FileCompactor.CompactionCanceledException) IOException(java.io.IOException) NoNodeException(org.apache.zookeeper.KeeperException.NoNodeException) CompactionKind(org.apache.accumulo.core.spi.compaction.CompactionKind) StoredTabletFile(org.apache.accumulo.core.metadata.StoredTabletFile) StoredTabletFile(org.apache.accumulo.core.metadata.StoredTabletFile) TabletFile(org.apache.accumulo.core.metadata.TabletFile) CompactionCanceledException(org.apache.accumulo.server.compaction.FileCompactor.CompactionCanceledException)

Aggregations

StoredTabletFile (org.apache.accumulo.core.metadata.StoredTabletFile)47 DataFileValue (org.apache.accumulo.core.metadata.schema.DataFileValue)25 TabletFile (org.apache.accumulo.core.metadata.TabletFile)18 IOException (java.io.IOException)12 KeyExtent (org.apache.accumulo.core.dataImpl.KeyExtent)11 HashMap (java.util.HashMap)9 HashSet (java.util.HashSet)9 Key (org.apache.accumulo.core.data.Key)9 ArrayList (java.util.ArrayList)8 TreeMap (java.util.TreeMap)8 Value (org.apache.accumulo.core.data.Value)8 Path (org.apache.hadoop.fs.Path)7 Text (org.apache.hadoop.io.Text)7 Pair (org.apache.accumulo.core.util.Pair)6 MajorCompactionRequest (org.apache.accumulo.tserver.compaction.MajorCompactionRequest)6 Test (org.junit.Test)6 LogEntry (org.apache.accumulo.core.tabletserver.log.LogEntry)5 UncheckedIOException (java.io.UncheckedIOException)4 CompactionConfig (org.apache.accumulo.core.client.admin.CompactionConfig)4 TServerInstance (org.apache.accumulo.core.metadata.TServerInstance)4