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
@@ -780,7 +781,7 @@ private void writeAtomic(final String blobName, final BytesReference bytesRef) t
780
781
} catch (IOException ex ) {
781
782
// temporary blob creation or move failed - try cleaning up
782
783
try {
783
- snapshotsBlobContainer .deleteBlob (tempBlobName );
784
+ snapshotsBlobContainer .deleteBlobIgnoringIfNotExists (tempBlobName );
784
785
} catch (IOException e ) {
785
786
ex .addSuppressed (e );
786
787
}
@@ -915,13 +916,13 @@ public void delete() {
915
916
}
916
917
}
917
918
// 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 + "]" );
919
920
}
920
921
921
922
/**
922
923
* Loads information about shard snapshot
923
924
*/
924
- public BlobStoreIndexShardSnapshot loadSnapshot () {
925
+ BlobStoreIndexShardSnapshot loadSnapshot () {
925
926
try {
926
927
return indexShardSnapshotFormat (version ).read (blobContainer , snapshotId .getUUID ());
927
928
} catch (IOException ex ) {
@@ -930,54 +931,57 @@ public BlobStoreIndexShardSnapshot loadSnapshot() {
930
931
}
931
932
932
933
/**
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.
934
935
*
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.
937
938
*
938
- *
939
- * @param snapshots list of active snapshots in the container
939
+ * @param snapshots list of active snapshots in the container
940
940
* @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
942
943
*/
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 );
956
956
}
957
- }
958
957
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 )) {
964
961
try {
965
- blobContainer .deleteBlob (blobName );
962
+ blobContainer .deleteBlobIgnoringIfNotExists (blobName );
966
963
} 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 ;
969
967
}
970
968
}
971
969
}
972
- }
973
970
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
+ }
980
981
}
982
+ } catch (IOException e ) {
983
+ String message = "Failed to finalize " + reason + " with shard index [" + currentIndexGen + "]" ;
984
+ throw new IndexShardSnapshotFailedException (shardId , message , e );
981
985
}
982
986
}
983
987
@@ -1003,7 +1007,7 @@ protected long findLatestFileNameGeneration(Map<String, BlobMetaData> blobs) {
1003
1007
if (!name .startsWith (DATA_BLOB_PREFIX )) {
1004
1008
continue ;
1005
1009
}
1006
- name = BlobStoreIndexShardSnapshot . FileInfo . canonicalName (name );
1010
+ name = canonicalName (name );
1007
1011
try {
1008
1012
long currentGen = Long .parseLong (name .substring (DATA_BLOB_PREFIX .length ()), Character .MAX_RADIX );
1009
1013
if (currentGen > generation ) {
@@ -1217,7 +1221,7 @@ public void snapshot(final IndexCommit snapshotIndexCommit) {
1217
1221
newSnapshotsList .add (point );
1218
1222
}
1219
1223
// 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 + "]" );
1221
1225
snapshotStatus .moveToDone (System .currentTimeMillis ());
1222
1226
1223
1227
}
0 commit comments