long firstEntryId = ledgerFragment.getFirstStoredEntryId(); long lastEntryId = ledgerFragment.getLastStoredEntryId(); long numberOfEntriesToReplicate = (lastEntryId - firstEntryId) + 1; long splitsWithFullEntries = numberOfEntriesToReplicate for (int i = 0; i < splitsWithFullEntries; i++) { fragmentSplitLastEntry = (firstEntryId + rereplicationEntryBatchSize) - 1; fragments.add(new LedgerFragment(lh, firstEntryId, fragmentSplitLastEntry, ledgerFragment.getBookiesIndexes())); firstEntryId = fragmentSplitLastEntry + 1; % rereplicationEntryBatchSize; if (lastSplitWithPartialEntries > 0) { fragments.add(new LedgerFragment(lh, firstEntryId, firstEntryId + lastSplitWithPartialEntries - 1, ledgerFragment .getBookiesIndexes()));
private static Map<BookieSocketAddress, BookieSocketAddress> getReplacementBookiesMap( LedgerFragment ledgerFragment, Map<Integer, BookieSocketAddress> targetBookieAddresses) { Map<BookieSocketAddress, BookieSocketAddress> bookiesMap = new HashMap<BookieSocketAddress, BookieSocketAddress>(); for (Integer bookieIndex : ledgerFragment.getBookiesIndexes()) { BookieSocketAddress oldBookie = ledgerFragment.getAddress(bookieIndex); BookieSocketAddress newBookie = targetBookieAddresses.get(bookieIndex); bookiesMap.put(oldBookie, newBookie); } return bookiesMap; }
@Override public String toString() { return String.format("Fragment(LedgerID: %d, FirstEntryID: %d[%d], " + "LastKnownEntryID: %d[%d], Host: %s, Closed: %s)", ledgerId, firstEntryId, getFirstStoredEntryId(), lastKnownEntryId, getLastStoredEntryId(), getAddresses(), isLedgerClosed); } }
long percentageOfLedgerFragmentToBeVerified) throws InvalidFragmentException { long firstStored = fragment.getFirstStoredEntryId(bookieIndex); long lastStored = fragment.getLastStoredEntryId(bookieIndex); BookieSocketAddress bookie = fragment.getAddress(bookieIndex); if (null == bookie) { throw new InvalidFragmentException(); ReadManyEntriesCallback manycb = new ReadManyEntriesCallback(1, fragment, cb); bookieClient.readEntry(bookie, fragment.getLedgerId(), firstStored, manycb, null, BookieProtocol.FLAG_NONE); } else { index += lengthOfBucket) { long potentialEntryId = ThreadLocalRandom.current().nextInt((lengthOfBucket)) + index; if (fragment.isStoredEntryId(potentialEntryId, bookieIndex)) { entriesToBeVerified.add(potentialEntryId); if (fragment.isStoredEntryId(firstStored, bookieIndex)) { entriesToBeVerified.add(firstStored); fragment, cb); for (Long entryID: entriesToBeVerified) { bookieClient.readEntry(bookie, fragment.getLedgerId(), entryID, manycb, null, BookieProtocol.FLAG_NONE);
final AsyncCallback.VoidCallback ledgerFragmentMcb, final Set<BookieSocketAddress> newBookies) throws InterruptedException { if (!lf.isClosed()) { LOG.error("Trying to replicate an unclosed fragment;" + " This is not safe {}", lf); return; Long startEntryId = lf.getFirstStoredEntryId(); Long endEntryId = lf.getLastStoredEntryId(); if (endEntryId == null) { LOG.warn("Dead bookie (" + lf.getAddresses() + ") is still part of the current" + " active ensemble for ledgerId: " + lh.getId()); long lastStoredEntryId = lf.getLastStoredEntryId(); for (long i = lf.getFirstStoredEntryId(); i <= lastStoredEntryId; i++) { entriesToReplicate.add(i);
/** * Replicate the Ledger fragment to target Bookie passed. * * @param lh * - ledgerHandle * @param ledgerFragment * - LedgerFragment to replicate */ public void replicateLedgerFragment(LedgerHandle lh, final LedgerFragment ledgerFragment) throws InterruptedException, BKException { Optional<Set<BookieSocketAddress>> excludedBookies = Optional.empty(); Map<Integer, BookieSocketAddress> targetBookieAddresses = getReplacementBookiesByIndexes(lh, ledgerFragment.getEnsemble(), ledgerFragment.getBookiesIndexes(), excludedBookies); replicateLedgerFragment(lh, ledgerFragment, targetBookieAddresses); }
getUnderreplicatedFragments(lh, conf.getAuditorLedgerVerificationPercentage()); for (LedgerFragment fragment : fragments) { if (!fragment.isClosed()) { fragment.getEnsemble(), ledgerId); lh = admin.openLedger(ledgerId); isRecoveryOpen = true;
/** * Return a ledger fragment contains subset of bookies. * * @param subset * subset of bookies. * @return ledger fragment contains subset of bookies */ public LedgerFragment subset(Set<Integer> subset) { return new LedgerFragment(this, subset); }
/** * Gets the first stored entry id of the fragment in failed bookies. * * @return entryId */ public long getFirstStoredEntryId() { Long firstEntry = null; for (int bookieIndex : bookieIndexes) { Long firstStoredEntryForBookie = getFirstStoredEntryId(bookieIndex); if (null == firstEntry) { firstEntry = firstStoredEntryForBookie; } else if (null != firstStoredEntryForBookie) { firstEntry = Math.min(firstEntry, firstStoredEntryForBookie); } } return null == firstEntry ? LedgerHandle.INVALID_ENTRY_ID : firstEntry; }
/** * Gets the last stored entry id of the fragment in failed bookie. * * @return entryId */ public long getLastStoredEntryId() { Long lastEntry = null; for (int bookieIndex : bookieIndexes) { Long lastStoredEntryIdForBookie = getLastStoredEntryId(bookieIndex); if (null == lastEntry) { lastEntry = lastStoredEntryIdForBookie; } else if (null != lastStoredEntryIdForBookie) { lastEntry = Math.max(lastEntry, lastStoredEntryIdForBookie); } } return null == lastEntry ? LedgerHandle.INVALID_ENTRY_ID : lastEntry; }
/** * Verify a ledger fragment to collect bad bookies. * * @param fragment * fragment to verify * @param cb * callback * @throws InvalidFragmentException */ private void verifyLedgerFragment(LedgerFragment fragment, GenericCallback<LedgerFragment> cb, Long percentageOfLedgerFragmentToBeVerified) throws InvalidFragmentException, BKException { Set<Integer> bookiesToCheck = fragment.getBookiesIndexes(); if (bookiesToCheck.isEmpty()) { cb.operationComplete(BKException.Code.OK, fragment); return; } AtomicInteger numBookies = new AtomicInteger(bookiesToCheck.size()); Map<Integer, Integer> badBookies = new HashMap<Integer, Integer>(); for (Integer bookieIndex : bookiesToCheck) { LedgerFragmentCallback lfCb = new LedgerFragmentCallback( fragment, bookieIndex, cb, badBookies, numBookies); verifyLedgerFragment(fragment, bookieIndex, lfCb, percentageOfLedgerFragmentToBeVerified); } }
Set<BookieSocketAddress> bookies = Sets.newHashSet(); for (LedgerFragment f : fragments) { bookies.addAll(f.getAddresses());
private void replicateLedgerFragment(LedgerHandle lh, final LedgerFragment ledgerFragment, final Map<Integer, BookieSocketAddress> targetBookieAddresses) throws InterruptedException, BKException { CompletableFuture<Void> result = new CompletableFuture<>(); ResultCallBack resultCallBack = new ResultCallBack(result); SingleFragmentCallback cb = new SingleFragmentCallback( resultCallBack, lh, bkc.getLedgerManager(), ledgerFragment.getFirstEntryId(), getReplacementBookiesMap(ledgerFragment, targetBookieAddresses)); Set<BookieSocketAddress> targetBookieSet = Sets.newHashSet(); targetBookieSet.addAll(targetBookieAddresses.values()); asyncRecoverLedgerFragment(lh, ledgerFragment, cb, targetBookieSet); try { SyncCallbackUtils.waitForResult(result); } catch (BKException err) { throw BKException.create(bkc.getReturnRc(err.getCode())); } }
if (!ledgerFragment.isClosed()) { foundOpenFragments = true; continue;
bookieIndexes.add(i); fragments.add(new LedgerFragment(lh, curEntryId, e.getKey() - 1, bookieIndexes)); bookieIndexes.add(i); final LedgerFragment lastLedgerFragment = new LedgerFragment(lh, curEntryId, lastEntry, bookieIndexes);
bkc.getLedgerManager(), startEntryId, getReplacementBookiesMap(ensemble, targetBookieAddresses)); LedgerFragment ledgerFragment = new LedgerFragment(lh, startEntryId, endEntryId, targetBookieAddresses.keySet()); asyncRecoverLedgerFragment(lh, ledgerFragment, cb,