@@ -399,12 +399,12 @@ public void deleteSnapshot(SnapshotId snapshotId, long repositoryStateId, Action
399
399
final Map <String , BlobContainer > foundIndices ;
400
400
final Set <String > rootBlobs ;
401
401
try {
402
- final RepositoryData repositoryData = getRepositoryData ();
402
+ rootBlobs = blobContainer ().listBlobs ().keySet ();
403
+ final RepositoryData repositoryData = getRepositoryData (latestGeneration (rootBlobs ));
403
404
updatedRepositoryData = repositoryData .removeSnapshot (snapshotId );
404
405
// Cache the indices that were found before writing out the new index-N blob so that a stuck master will never
405
406
// delete an index that was created by another master node after writing this index-N blob.
406
407
foundIndices = blobStore ().blobContainer (basePath ().add ("indices" )).children ();
407
- rootBlobs = blobContainer ().listBlobs ().keySet ();
408
408
writeIndexGen (updatedRepositoryData , repositoryStateId );
409
409
} catch (Exception ex ) {
410
410
listener .onFailure (new RepositoryException (metadata .name (), "failed to delete snapshot [" + snapshotId + "]" , ex ));
@@ -691,7 +691,20 @@ public void endVerification(String seed) {
691
691
@ Override
692
692
public RepositoryData getRepositoryData () {
693
693
try {
694
- final long indexGen = latestIndexBlobId ();
694
+ return getRepositoryData (latestIndexBlobId ());
695
+ } catch (NoSuchFileException ex ) {
696
+ // repository doesn't have an index blob, its a new blank repo
697
+ return RepositoryData .EMPTY ;
698
+ } catch (IOException ioe ) {
699
+ throw new RepositoryException (metadata .name (), "Could not determine repository generation from root blobs" , ioe );
700
+ }
701
+ }
702
+
703
+ private RepositoryData getRepositoryData (long indexGen ) {
704
+ if (indexGen == RepositoryData .EMPTY_REPO_GEN ) {
705
+ return RepositoryData .EMPTY ;
706
+ }
707
+ try {
695
708
final String snapshotsIndexBlobName = INDEX_FILE_PREFIX + Long .toString (indexGen );
696
709
697
710
RepositoryData repositoryData ;
@@ -738,14 +751,14 @@ public boolean isReadOnly() {
738
751
return readOnly ;
739
752
}
740
753
741
- protected void writeIndexGen (final RepositoryData repositoryData , final long repositoryStateId ) throws IOException {
754
+ protected void writeIndexGen (final RepositoryData repositoryData , final long expectedGen ) throws IOException {
742
755
assert isReadOnly () == false ; // can not write to a read only repository
743
- final long currentGen = latestIndexBlobId ();
744
- if (currentGen != repositoryStateId ) {
756
+ final long currentGen = repositoryData . getGenId ();
757
+ if (currentGen != expectedGen ) {
745
758
// the index file was updated by a concurrent operation, so we were operating on stale
746
759
// repository data
747
760
throw new RepositoryException (metadata .name (), "concurrent modification of the index-N file, expected current generation [" +
748
- repositoryStateId + "], actual current generation [" + currentGen +
761
+ expectedGen + "], actual current generation [" + currentGen +
749
762
"] - possibly due to simultaneous snapshot deletion requests" );
750
763
}
751
764
final long newGen = currentGen + 1 ;
@@ -823,14 +836,15 @@ long readSnapshotIndexLatestBlob() throws IOException {
823
836
}
824
837
825
838
private long listBlobsToGetLatestIndexId () throws IOException {
826
- Map <String , BlobMetaData > blobs = blobContainer ().listBlobsByPrefix (INDEX_FILE_PREFIX );
839
+ return latestGeneration (blobContainer ().listBlobsByPrefix (INDEX_FILE_PREFIX ).keySet ());
840
+ }
841
+
842
+ private long latestGeneration (Collection <String > rootBlobs ) {
827
843
long latest = RepositoryData .EMPTY_REPO_GEN ;
828
- if (blobs .isEmpty ()) {
829
- // no snapshot index blobs have been written yet
830
- return latest ;
831
- }
832
- for (final BlobMetaData blobMetaData : blobs .values ()) {
833
- final String blobName = blobMetaData .name ();
844
+ for (String blobName : rootBlobs ) {
845
+ if (blobName .startsWith (INDEX_FILE_PREFIX ) == false ) {
846
+ continue ;
847
+ }
834
848
try {
835
849
final long curr = Long .parseLong (blobName .substring (INDEX_FILE_PREFIX .length ()));
836
850
latest = Math .max (latest , curr );
@@ -865,9 +879,9 @@ public void snapshotShard(Store store, MapperService mapperService, SnapshotId s
865
879
throw new IndexShardSnapshotFailedException (shardId , "failed to list blobs" , e );
866
880
}
867
881
868
- Tuple <BlobStoreIndexShardSnapshots , Integer > tuple = buildBlobStoreIndexShardSnapshots (blobs , shardContainer );
882
+ Tuple <BlobStoreIndexShardSnapshots , Long > tuple = buildBlobStoreIndexShardSnapshots (blobs , shardContainer );
869
883
BlobStoreIndexShardSnapshots snapshots = tuple .v1 ();
870
- int fileListGeneration = tuple .v2 ();
884
+ long fileListGeneration = tuple .v2 ();
871
885
872
886
if (snapshots .snapshots ().stream ().anyMatch (sf -> sf .snapshot ().equals (snapshotId .getName ()))) {
873
887
throw new IndexShardSnapshotFailedException (shardId ,
@@ -1069,9 +1083,9 @@ private void deleteShardSnapshot(IndexId indexId, ShardId snapshotShardId, Snaps
1069
1083
throw new IndexShardSnapshotException (snapshotShardId , "Failed to list content of shard directory" , e );
1070
1084
}
1071
1085
1072
- Tuple <BlobStoreIndexShardSnapshots , Integer > tuple = buildBlobStoreIndexShardSnapshots (blobs , shardContainer );
1086
+ Tuple <BlobStoreIndexShardSnapshots , Long > tuple = buildBlobStoreIndexShardSnapshots (blobs , shardContainer );
1073
1087
BlobStoreIndexShardSnapshots snapshots = tuple .v1 ();
1074
- int fileListGeneration = tuple .v2 ();
1088
+ long fileListGeneration = tuple .v2 ();
1075
1089
1076
1090
try {
1077
1091
indexShardSnapshotFormat .delete (shardContainer , snapshotId .getUUID ());
@@ -1114,9 +1128,9 @@ private BlobStoreIndexShardSnapshot loadShardSnapshot(BlobContainer shardContain
1114
1128
* @param blobs list of blobs in the container
1115
1129
* @param reason a reason explaining why the shard index file is written
1116
1130
*/
1117
- private void finalizeShard (List <SnapshotFiles > snapshots , int fileListGeneration , Map <String , BlobMetaData > blobs ,
1131
+ private void finalizeShard (List <SnapshotFiles > snapshots , long fileListGeneration , Map <String , BlobMetaData > blobs ,
1118
1132
String reason , BlobContainer shardContainer , ShardId shardId , SnapshotId snapshotId ) {
1119
- final String indexGeneration = Integer .toString (fileListGeneration + 1 );
1133
+ final String indexGeneration = Long .toString (fileListGeneration + 1 );
1120
1134
try {
1121
1135
final List <String > blobsToDelete ;
1122
1136
if (snapshots .isEmpty ()) {
@@ -1150,26 +1164,14 @@ private void finalizeShard(List<SnapshotFiles> snapshots, int fileListGeneration
1150
1164
* @param blobs list of blobs in repository
1151
1165
* @return tuple of BlobStoreIndexShardSnapshots and the last snapshot index generation
1152
1166
*/
1153
- private Tuple <BlobStoreIndexShardSnapshots , Integer > buildBlobStoreIndexShardSnapshots (Map <String , BlobMetaData > blobs ,
1167
+ private Tuple <BlobStoreIndexShardSnapshots , Long > buildBlobStoreIndexShardSnapshots (Map <String , BlobMetaData > blobs ,
1154
1168
BlobContainer shardContainer ) {
1155
- int latest = -1 ;
1156
1169
Set <String > blobKeys = blobs .keySet ();
1157
- for (String name : blobKeys ) {
1158
- if (name .startsWith (SNAPSHOT_INDEX_PREFIX )) {
1159
- try {
1160
- int gen = Integer .parseInt (name .substring (SNAPSHOT_INDEX_PREFIX .length ()));
1161
- if (gen > latest ) {
1162
- latest = gen ;
1163
- }
1164
- } catch (NumberFormatException ex ) {
1165
- logger .warn ("failed to parse index file name [{}]" , name );
1166
- }
1167
- }
1168
- }
1170
+ long latest = latestGeneration (blobKeys );
1169
1171
if (latest >= 0 ) {
1170
1172
try {
1171
1173
final BlobStoreIndexShardSnapshots shardSnapshots =
1172
- indexShardSnapshotsFormat .read (shardContainer , Integer .toString (latest ));
1174
+ indexShardSnapshotsFormat .read (shardContainer , Long .toString (latest ));
1173
1175
return new Tuple <>(shardSnapshots , latest );
1174
1176
} catch (IOException e ) {
1175
1177
final String file = SNAPSHOT_INDEX_PREFIX + latest ;
0 commit comments