120
120
121
121
import static java .util .Collections .emptyMap ;
122
122
import static java .util .Collections .unmodifiableMap ;
123
+ import static org .elasticsearch .index .snapshots .blobstore .BlobStoreIndexShardSnapshot .FileInfo .canonicalName ;
123
124
124
125
/**
125
126
* BlobStore - based implementation of Snapshot Repository
@@ -797,7 +798,7 @@ private void writeAtomic(final String blobName, final BytesReference bytesRef) t
797
798
} catch (IOException ex ) {
798
799
// temporary blob creation or move failed - try cleaning up
799
800
try {
800
- snapshotsBlobContainer .deleteBlob (tempBlobName );
801
+ snapshotsBlobContainer .deleteBlobIgnoringIfNotExists (tempBlobName );
801
802
} catch (IOException e ) {
802
803
ex .addSuppressed (e );
803
804
}
@@ -932,13 +933,13 @@ public void delete() {
932
933
}
933
934
}
934
935
// finalize the snapshot and rewrite the snapshot index with the next sequential snapshot index
935
- finalize (newSnapshotsList , fileListGeneration + 1 , blobs );
936
+ finalize (newSnapshotsList , fileListGeneration + 1 , blobs , "snapshot deletion [" + snapshotId + "]" );
936
937
}
937
938
938
939
/**
939
940
* Loads information about shard snapshot
940
941
*/
941
- public BlobStoreIndexShardSnapshot loadSnapshot () {
942
+ BlobStoreIndexShardSnapshot loadSnapshot () {
942
943
try {
943
944
return indexShardSnapshotFormat (version ).read (blobContainer , snapshotId .getUUID ());
944
945
} catch (IOException ex ) {
@@ -947,54 +948,57 @@ public BlobStoreIndexShardSnapshot loadSnapshot() {
947
948
}
948
949
949
950
/**
950
- * Removes all unreferenced files from the repository and writes new index file
951
+ * Writes a new index file for the shard and removes all unreferenced files from the repository.
951
952
*
952
- * We need to be really careful in handling index files in case of failures to make sure we have index file that
953
- * points to files that were deleted.
953
+ * We need to be really careful in handling index files in case of failures to make sure we don't
954
+ * have index file that points to files that were deleted.
954
955
*
955
- *
956
- * @param snapshots list of active snapshots in the container
956
+ * @param snapshots list of active snapshots in the container
957
957
* @param fileListGeneration the generation number of the snapshot index file
958
- * @param blobs list of blobs in the container
958
+ * @param blobs list of blobs in the container
959
+ * @param reason a reason explaining why the shard index file is written
959
960
*/
960
- protected void finalize (List <SnapshotFiles > snapshots , int fileListGeneration , Map <String , BlobMetaData > blobs ) {
961
- BlobStoreIndexShardSnapshots newSnapshots = new BlobStoreIndexShardSnapshots (snapshots );
962
- // delete old index files first
963
- for (String blobName : blobs .keySet ()) {
964
- if (indexShardSnapshotsFormat .isTempBlobName (blobName ) || blobName .startsWith (SNAPSHOT_INDEX_PREFIX )) {
965
- try {
966
- blobContainer .deleteBlob (blobName );
967
- } catch (IOException e ) {
968
- // We cannot delete index file - this is fatal, we cannot continue, otherwise we might end up
969
- // with references to non-existing files
970
- throw new IndexShardSnapshotFailedException (shardId , "error deleting index file ["
971
- + blobName + "] during cleanup" , e );
972
- }
961
+ protected void finalize (final List <SnapshotFiles > snapshots ,
962
+ final int fileListGeneration ,
963
+ final Map <String , BlobMetaData > blobs ,
964
+ final String reason ) {
965
+ final String indexGeneration = Integer .toString (fileListGeneration );
966
+ final String currentIndexGen = indexShardSnapshotsFormat .blobName (indexGeneration );
967
+
968
+ final BlobStoreIndexShardSnapshots updatedSnapshots = new BlobStoreIndexShardSnapshots (snapshots );
969
+ try {
970
+ // If we deleted all snapshots, we don't need to create a new index file
971
+ if (snapshots .size () > 0 ) {
972
+ indexShardSnapshotsFormat .writeAtomic (updatedSnapshots , blobContainer , indexGeneration );
973
973
}
974
- }
975
974
976
- // now go over all the blobs, and if they don't exist in a snapshot, delete them
977
- for (String blobName : blobs .keySet ()) {
978
- // delete unused files
979
- if (blobName .startsWith (DATA_BLOB_PREFIX )) {
980
- if (newSnapshots .findNameFile (BlobStoreIndexShardSnapshot .FileInfo .canonicalName (blobName )) == null ) {
975
+ // Delete old index files
976
+ for (final String blobName : blobs .keySet ()) {
977
+ if (indexShardSnapshotsFormat .isTempBlobName (blobName ) || blobName .startsWith (SNAPSHOT_INDEX_PREFIX )) {
981
978
try {
982
- blobContainer .deleteBlob (blobName );
979
+ blobContainer .deleteBlobIgnoringIfNotExists (blobName );
983
980
} catch (IOException e ) {
984
- // TODO: don't catch and let the user handle it?
985
- logger .debug (() -> new ParameterizedMessage ("[{}] [{}] error deleting blob [{}] during cleanup" , snapshotId , shardId , blobName ), e );
981
+ logger .warn (() -> new ParameterizedMessage ("[{}][{}] failed to delete index blob [{}] during finalization" ,
982
+ snapshotId , shardId , blobName ), e );
983
+ throw e ;
986
984
}
987
985
}
988
986
}
989
- }
990
987
991
- // If we deleted all snapshots - we don't need to create the index file
992
- if (snapshots .size () > 0 ) {
993
- try {
994
- indexShardSnapshotsFormat .writeAtomic (newSnapshots , blobContainer , Integer .toString (fileListGeneration ));
995
- } catch (IOException e ) {
996
- throw new IndexShardSnapshotFailedException (shardId , "Failed to write file list" , e );
988
+ // Delete all blobs that don't exist in a snapshot
989
+ for (final String blobName : blobs .keySet ()) {
990
+ if (blobName .startsWith (DATA_BLOB_PREFIX ) && (updatedSnapshots .findNameFile (canonicalName (blobName )) == null )) {
991
+ try {
992
+ blobContainer .deleteBlobIgnoringIfNotExists (blobName );
993
+ } catch (IOException e ) {
994
+ logger .warn (() -> new ParameterizedMessage ("[{}][{}] failed to delete data blob [{}] during finalization" ,
995
+ snapshotId , shardId , blobName ), e );
996
+ }
997
+ }
997
998
}
999
+ } catch (IOException e ) {
1000
+ String message = "Failed to finalize " + reason + " with shard index [" + currentIndexGen + "]" ;
1001
+ throw new IndexShardSnapshotFailedException (shardId , message , e );
998
1002
}
999
1003
}
1000
1004
@@ -1020,7 +1024,7 @@ protected long findLatestFileNameGeneration(Map<String, BlobMetaData> blobs) {
1020
1024
if (!name .startsWith (DATA_BLOB_PREFIX )) {
1021
1025
continue ;
1022
1026
}
1023
- name = BlobStoreIndexShardSnapshot . FileInfo . canonicalName (name );
1027
+ name = canonicalName (name );
1024
1028
try {
1025
1029
long currentGen = Long .parseLong (name .substring (DATA_BLOB_PREFIX .length ()), Character .MAX_RADIX );
1026
1030
if (currentGen > generation ) {
@@ -1234,7 +1238,7 @@ public void snapshot(final IndexCommit snapshotIndexCommit) {
1234
1238
newSnapshotsList .add (point );
1235
1239
}
1236
1240
// finalize the snapshot and rewrite the snapshot index with the next sequential snapshot index
1237
- finalize (newSnapshotsList , fileListGeneration + 1 , blobs );
1241
+ finalize (newSnapshotsList , fileListGeneration + 1 , blobs , "snapshot creation [" + snapshotId + "]" );
1238
1242
snapshotStatus .moveToDone (System .currentTimeMillis ());
1239
1243
1240
1244
}
0 commit comments