120120
121121import static java .util .Collections .emptyMap ;
122122import static java .util .Collections .unmodifiableMap ;
123+ import static org .elasticsearch .index .snapshots .blobstore .BlobStoreIndexShardSnapshot .FileInfo .canonicalName ;
123124
124125/**
125126 * BlobStore - based implementation of Snapshot Repository
@@ -780,7 +781,7 @@ private void writeAtomic(final String blobName, final BytesReference bytesRef) t
780781 } catch (IOException ex ) {
781782 // temporary blob creation or move failed - try cleaning up
782783 try {
783- snapshotsBlobContainer .deleteBlob (tempBlobName );
784+ snapshotsBlobContainer .deleteBlobIgnoringIfNotExists (tempBlobName );
784785 } catch (IOException e ) {
785786 ex .addSuppressed (e );
786787 }
@@ -915,13 +916,13 @@ public void delete() {
915916 }
916917 }
917918 // finalize the snapshot and rewrite the snapshot index with the next sequential snapshot index
918- finalize (newSnapshotsList , fileListGeneration + 1 , blobs );
919+ finalize (newSnapshotsList , fileListGeneration + 1 , blobs , "snapshot deletion [" + snapshotId + "]" );
919920 }
920921
921922 /**
922923 * Loads information about shard snapshot
923924 */
924- public BlobStoreIndexShardSnapshot loadSnapshot () {
925+ BlobStoreIndexShardSnapshot loadSnapshot () {
925926 try {
926927 return indexShardSnapshotFormat (version ).read (blobContainer , snapshotId .getUUID ());
927928 } catch (IOException ex ) {
@@ -930,54 +931,57 @@ public BlobStoreIndexShardSnapshot loadSnapshot() {
930931 }
931932
932933 /**
933- * Removes all unreferenced files from the repository and writes new index file
934+ * Writes a new index file for the shard and removes all unreferenced files from the repository.
934935 *
935- * We need to be really careful in handling index files in case of failures to make sure we have index file that
936- * points to files that were deleted.
936+ * We need to be really careful in handling index files in case of failures to make sure we don't
937+ * have index file that points to files that were deleted.
937938 *
938- *
939- * @param snapshots list of active snapshots in the container
939+ * @param snapshots list of active snapshots in the container
940940 * @param fileListGeneration the generation number of the snapshot index file
941- * @param blobs list of blobs in the container
941+ * @param blobs list of blobs in the container
942+ * @param reason a reason explaining why the shard index file is written
942943 */
943- protected void finalize (List <SnapshotFiles > snapshots , int fileListGeneration , Map <String , BlobMetaData > blobs ) {
944- BlobStoreIndexShardSnapshots newSnapshots = new BlobStoreIndexShardSnapshots (snapshots );
945- // delete old index files first
946- for (String blobName : blobs .keySet ()) {
947- if (indexShardSnapshotsFormat .isTempBlobName (blobName ) || blobName .startsWith (SNAPSHOT_INDEX_PREFIX )) {
948- try {
949- blobContainer .deleteBlob (blobName );
950- } catch (IOException e ) {
951- // We cannot delete index file - this is fatal, we cannot continue, otherwise we might end up
952- // with references to non-existing files
953- throw new IndexShardSnapshotFailedException (shardId , "error deleting index file ["
954- + blobName + "] during cleanup" , e );
955- }
944+ protected void finalize (final List <SnapshotFiles > snapshots ,
945+ final int fileListGeneration ,
946+ final Map <String , BlobMetaData > blobs ,
947+ final String reason ) {
948+ final String indexGeneration = Integer .toString (fileListGeneration );
949+ final String currentIndexGen = indexShardSnapshotsFormat .blobName (indexGeneration );
950+
951+ final BlobStoreIndexShardSnapshots updatedSnapshots = new BlobStoreIndexShardSnapshots (snapshots );
952+ try {
953+ // If we deleted all snapshots, we don't need to create a new index file
954+ if (snapshots .size () > 0 ) {
955+ indexShardSnapshotsFormat .writeAtomic (updatedSnapshots , blobContainer , indexGeneration );
956956 }
957- }
958957
959- // now go over all the blobs, and if they don't exist in a snapshot, delete them
960- for (String blobName : blobs .keySet ()) {
961- // delete unused files
962- if (blobName .startsWith (DATA_BLOB_PREFIX )) {
963- if (newSnapshots .findNameFile (BlobStoreIndexShardSnapshot .FileInfo .canonicalName (blobName )) == null ) {
958+ // Delete old index files
959+ for (final String blobName : blobs .keySet ()) {
960+ if (indexShardSnapshotsFormat .isTempBlobName (blobName ) || blobName .startsWith (SNAPSHOT_INDEX_PREFIX )) {
964961 try {
965- blobContainer .deleteBlob (blobName );
962+ blobContainer .deleteBlobIgnoringIfNotExists (blobName );
966963 } catch (IOException e ) {
967- // TODO: don't catch and let the user handle it?
968- logger .debug (() -> new ParameterizedMessage ("[{}] [{}] error deleting blob [{}] during cleanup" , snapshotId , shardId , blobName ), e );
964+ logger .warn (() -> new ParameterizedMessage ("[{}][{}] failed to delete index blob [{}] during finalization" ,
965+ snapshotId , shardId , blobName ), e );
966+ throw e ;
969967 }
970968 }
971969 }
972- }
973970
974- // If we deleted all snapshots - we don't need to create the index file
975- if (snapshots .size () > 0 ) {
976- try {
977- indexShardSnapshotsFormat .writeAtomic (newSnapshots , blobContainer , Integer .toString (fileListGeneration ));
978- } catch (IOException e ) {
979- throw new IndexShardSnapshotFailedException (shardId , "Failed to write file list" , e );
971+ // Delete all blobs that don't exist in a snapshot
972+ for (final String blobName : blobs .keySet ()) {
973+ if (blobName .startsWith (DATA_BLOB_PREFIX ) && (updatedSnapshots .findNameFile (canonicalName (blobName )) == null )) {
974+ try {
975+ blobContainer .deleteBlobIgnoringIfNotExists (blobName );
976+ } catch (IOException e ) {
977+ logger .warn (() -> new ParameterizedMessage ("[{}][{}] failed to delete data blob [{}] during finalization" ,
978+ snapshotId , shardId , blobName ), e );
979+ }
980+ }
980981 }
982+ } catch (IOException e ) {
983+ String message = "Failed to finalize " + reason + " with shard index [" + currentIndexGen + "]" ;
984+ throw new IndexShardSnapshotFailedException (shardId , message , e );
981985 }
982986 }
983987
@@ -1003,7 +1007,7 @@ protected long findLatestFileNameGeneration(Map<String, BlobMetaData> blobs) {
10031007 if (!name .startsWith (DATA_BLOB_PREFIX )) {
10041008 continue ;
10051009 }
1006- name = BlobStoreIndexShardSnapshot . FileInfo . canonicalName (name );
1010+ name = canonicalName (name );
10071011 try {
10081012 long currentGen = Long .parseLong (name .substring (DATA_BLOB_PREFIX .length ()), Character .MAX_RADIX );
10091013 if (currentGen > generation ) {
@@ -1217,7 +1221,7 @@ public void snapshot(final IndexCommit snapshotIndexCommit) {
12171221 newSnapshotsList .add (point );
12181222 }
12191223 // finalize the snapshot and rewrite the snapshot index with the next sequential snapshot index
1220- finalize (newSnapshotsList , fileListGeneration + 1 , blobs );
1224+ finalize (newSnapshotsList , fileListGeneration + 1 , blobs , "snapshot creation [" + snapshotId + "]" );
12211225 snapshotStatus .moveToDone (System .currentTimeMillis ());
12221226
12231227 }
0 commit comments