fix(s3api): delete bucket directory before collection to prevent inconsistent state
Reorder DeleteBucketHandler to remove the bucket directory first, then delete the collection. If collection deletion fails, the bucket is still effectively deleted and can be recreated. Previously, if directory deletion succeeded but collection deletion failed, the bucket was left in an unrecoverable state.
This commit is contained in:
@@ -377,9 +377,18 @@ func (s3a *S3ApiServer) DeleteBucketHandler(w http.ResponseWriter, r *http.Reque
|
||||
}
|
||||
}
|
||||
|
||||
err := s3a.WithFilerClient(false, func(client filer_pb.SeaweedFilerClient) error {
|
||||
// Delete bucket directory first, then collection. This order ensures that if
|
||||
// collection deletion fails, the bucket directory is already gone, preventing
|
||||
// the "collection exists but bucket directory missing" inconsistency that blocks
|
||||
// bucket recreation. An orphaned collection is harmless and will be cleaned up
|
||||
// or reused when the bucket is recreated.
|
||||
err := s3a.rm(s3a.option.BucketsPath, bucket, false, true)
|
||||
if err != nil {
|
||||
s3err.WriteErrorResponse(w, r, s3err.ErrInternalError)
|
||||
return
|
||||
}
|
||||
|
||||
// delete collection
|
||||
err = s3a.WithFilerClient(false, func(client filer_pb.SeaweedFilerClient) error {
|
||||
deleteCollectionRequest := &filer_pb.DeleteCollectionRequest{
|
||||
Collection: s3a.getCollectionName(bucket),
|
||||
}
|
||||
@@ -393,15 +402,9 @@ func (s3a *S3ApiServer) DeleteBucketHandler(w http.ResponseWriter, r *http.Reque
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
s3err.WriteErrorResponse(w, r, s3err.ErrInternalError)
|
||||
return
|
||||
}
|
||||
|
||||
err = s3a.rm(s3a.option.BucketsPath, bucket, false, true)
|
||||
|
||||
if err != nil {
|
||||
s3err.WriteErrorResponse(w, r, s3err.ErrInternalError)
|
||||
return
|
||||
// Log but don't fail — the bucket directory is already removed, so the bucket
|
||||
// is effectively deleted. The orphaned collection will be cleaned up or reused.
|
||||
glog.Errorf("DeleteBucketHandler: failed to delete collection for bucket %s: %v", bucket, err)
|
||||
}
|
||||
|
||||
// Clean up bucket-related caches, locks, and metrics after successful deletion
|
||||
|
||||
Reference in New Issue
Block a user