コード例 #1
0
 private boolean commitPointFileExistsInBlobs(
     CommitPoint.FileInfo fileInfo, ImmutableMap<String, BlobMetaData> blobs) {
   BlobMetaData blobMetaData = blobs.get(fileInfo.name());
   if (blobMetaData != null) {
     if (blobMetaData.length() != fileInfo.length()) {
       return false;
     }
   } else if (blobs.containsKey(fileInfo.name() + ".part0")) {
     // multi part file sum up the size and check
     int part = 0;
     long totalSize = 0;
     while (true) {
       blobMetaData = blobs.get(fileInfo.name() + ".part" + part++);
       if (blobMetaData == null) {
         break;
       }
       totalSize += blobMetaData.length();
     }
     if (totalSize != fileInfo.length()) {
       return false;
     }
   } else {
     // no file, not exact and not multipart
     return false;
   }
   return true;
 }
コード例 #2
0
  private void snapshotFile(
      Directory dir,
      final CommitPoint.FileInfo fileInfo,
      final CountDownLatch latch,
      final List<Throwable> failures)
      throws IOException {
    long chunkBytes = Long.MAX_VALUE;
    if (chunkSize != null) {
      chunkBytes = chunkSize.bytes();
    }

    long totalLength = fileInfo.length();
    long numberOfChunks = totalLength / chunkBytes;
    if (totalLength % chunkBytes > 0) {
      numberOfChunks++;
    }
    if (numberOfChunks == 0) {
      numberOfChunks++;
    }

    final long fNumberOfChunks = numberOfChunks;
    final AtomicLong counter = new AtomicLong(numberOfChunks);
    for (long i = 0; i < fNumberOfChunks; i++) {
      final long partNumber = i;

      IndexInput indexInput = null;
      try {
        indexInput = dir.openInput(fileInfo.physicalName());
        indexInput.seek(partNumber * chunkBytes);
        InputStreamIndexInput is = new ThreadSafeInputStreamIndexInput(indexInput, chunkBytes);

        String blobName = fileInfo.name();
        if (fNumberOfChunks > 1) {
          // if we do chunks, then all of them are in the form of "[xxx].part[N]".
          blobName += ".part" + partNumber;
        }

        final IndexInput fIndexInput = indexInput;
        blobContainer.writeBlob(
            blobName,
            is,
            is.actualSizeToRead(),
            new ImmutableBlobContainer.WriterListener() {
              @Override
              public void onCompleted() {
                try {
                  fIndexInput.close();
                } catch (IOException e) {
                  // ignore
                }
                if (counter.decrementAndGet() == 0) {
                  latch.countDown();
                }
              }

              @Override
              public void onFailure(Throwable t) {
                try {
                  fIndexInput.close();
                } catch (IOException e) {
                  // ignore
                }
                failures.add(t);
                if (counter.decrementAndGet() == 0) {
                  latch.countDown();
                }
              }
            });
      } catch (Exception e) {
        if (indexInput != null) {
          try {
            indexInput.close();
          } catch (IOException e1) {
            // ignore
          }
        }
        failures.add(e);
        latch.countDown();
      }
    }
  }
コード例 #3
0
  private void recoverIndex(CommitPoint commitPoint, ImmutableMap<String, BlobMetaData> blobs)
      throws Exception {
    int numberOfFiles = 0;
    long totalSize = 0;
    int numberOfReusedFiles = 0;
    long reusedTotalSize = 0;

    List<CommitPoint.FileInfo> filesToRecover = Lists.newArrayList();
    for (CommitPoint.FileInfo fileInfo : commitPoint.indexFiles()) {
      String fileName = fileInfo.physicalName();
      StoreFileMetaData md = null;
      try {
        md = store.metaData(fileName);
      } catch (Exception e) {
        // no file
      }
      // we don't compute checksum for segments, so always recover them
      if (!fileName.startsWith("segments") && md != null && fileInfo.isSame(md)) {
        numberOfFiles++;
        totalSize += md.length();
        numberOfReusedFiles++;
        reusedTotalSize += md.length();
        if (logger.isTraceEnabled()) {
          logger.trace(
              "not_recovering [{}], exists in local store and is same", fileInfo.physicalName());
        }
      } else {
        if (logger.isTraceEnabled()) {
          if (md == null) {
            logger.trace(
                "recovering [{}], does not exists in local store", fileInfo.physicalName());
          } else {
            logger.trace(
                "recovering [{}], exists in local store but is different", fileInfo.physicalName());
          }
        }
        numberOfFiles++;
        totalSize += fileInfo.length();
        filesToRecover.add(fileInfo);
      }
    }

    recoveryStatus.index().files(numberOfFiles, totalSize, numberOfReusedFiles, reusedTotalSize);
    if (filesToRecover.isEmpty()) {
      logger.trace("no files to recover, all exists within the local store");
    }

    if (logger.isTraceEnabled()) {
      logger.trace(
          "recovering_files [{}] with total_size [{}], reusing_files [{}] with reused_size [{}]",
          numberOfFiles,
          new ByteSizeValue(totalSize),
          numberOfReusedFiles,
          new ByteSizeValue(reusedTotalSize));
    }

    final CountDownLatch latch = new CountDownLatch(filesToRecover.size());
    final CopyOnWriteArrayList<Throwable> failures = new CopyOnWriteArrayList<Throwable>();

    for (final CommitPoint.FileInfo fileToRecover : filesToRecover) {
      recoverFile(fileToRecover, blobs, latch, failures);
    }

    try {
      latch.await();
    } catch (InterruptedException e) {
      throw new IndexShardGatewayRecoveryException(
          shardId, "Interrupted while recovering index", e);
    }

    if (!failures.isEmpty()) {
      throw new IndexShardGatewayRecoveryException(
          shardId, "Failed to recover index", failures.get(0));
    }

    // read the gateway data persisted
    long version = -1;
    try {
      if (IndexReader.indexExists(store.directory())) {
        version = IndexReader.getCurrentVersion(store.directory());
      }
    } catch (IOException e) {
      throw new IndexShardGatewayRecoveryException(
          shardId(), "Failed to fetch index version after copying it over", e);
    }
    recoveryStatus.index().updateVersion(version);

    /// now, go over and clean files that are in the store, but were not in the gateway
    try {
      for (String storeFile : store.directory().listAll()) {
        if (!commitPoint.containPhysicalIndexFile(storeFile)) {
          try {
            store.directory().deleteFile(storeFile);
          } catch (Exception e) {
            // ignore
          }
        }
      }
    } catch (Exception e) {
      // ignore
    }
  }