mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-19 04:24:28 +02:00
feat(s3/lifecycle): metadata-only delete when entry TtlSec > 0 (Phase 2b) (#9390)
* refactor(s3): thread metadataOnly into delete helpers Add a metadataOnly bool to deleteUnversionedObjectWithClient and deleteSpecificObjectVersion. When true the helper sends IsDeleteData= false to the filer's DeleteEntry RPC so per-chunk DeleteFile RPCs are skipped — the volume server reclaims chunks on its own at TTL drop. Non-lifecycle callers (DELETE handlers, batch delete) pass false to preserve today's eager-chunk-delete behavior; only the lifecycle handler in the next commit will pass true. * feat(s3/lifecycle): metadata-only delete when entry TtlSec > 0 Per-write TTL stamping (PR 9377) sets Attributes.TtlSec on every lifecycle-fitting entry. When the live entry the LifecycleDelete handler fetched carries TtlSec > 0 the volume server is guaranteed to reclaim chunks at TTL drop, so the filer can skip per-chunk DeleteFile RPCs and just remove the entry record. lifecycleDispatch now computes metadataOnly from the live entry and threads it through the unversioned, suspended-null, and noncurrent/expired-marker delete paths. createDeleteMarker is unaffected — it creates a marker, never deletes chunks.
This commit is contained in:
1 parent
255e9cd0f7
commit
bb0c7c779f
4 files changed
+93
-13
No files matched your search
@@ -125,7 +125,7 @@ func (s3a *S3ApiServer) deleteVersionedObject(r *http.Request, bucket, object, v
|
||||
glog.V(2).Infof("deleteVersionedObject: object lock check failed for %s/%s version %s: %v", bucket, object, versionId, err)
|
||||
return result, s3err.ErrAccessDenied
|
||||
}
|
||||
if err := s3a.deleteSpecificObjectVersion(bucket, object, versionId); err != nil {
|
||||
if err := s3a.deleteSpecificObjectVersion(bucket, object, versionId, false); err != nil {
|
||||
glog.Errorf("deleteVersionedObject: failed to delete specific version %s for %s/%s: %v", versionId, bucket, object, err)
|
||||
return result, s3err.ErrInternalError
|
||||
}
|
||||
@@ -148,7 +148,7 @@ func (s3a *S3ApiServer) deleteVersionedObject(r *http.Request, bucket, object, v
|
||||
glog.V(2).Infof("deleteVersionedObject: object lock check failed for %s/%s null version: %v", bucket, object, err)
|
||||
return result, s3err.ErrAccessDenied
|
||||
}
|
||||
if err := s3a.deleteSpecificObjectVersion(bucket, object, "null"); err != nil {
|
||||
if err := s3a.deleteSpecificObjectVersion(bucket, object, "null", false); err != nil {
|
||||
glog.Errorf("deleteVersionedObject: failed to delete null version for %s/%s: %v", bucket, object, err)
|
||||
return result, s3err.ErrInternalError
|
||||
}
|
||||
@@ -166,10 +166,15 @@ func (s3a *S3ApiServer) deleteVersionedObject(r *http.Request, bucket, object, v
|
||||
return result, s3err.ErrInternalError
|
||||
}
|
||||
|
||||
func (s3a *S3ApiServer) deleteUnversionedObjectWithClient(client filer_pb.SeaweedFilerClient, bucket, object string) error {
|
||||
// deleteUnversionedObjectWithClient removes the bare object entry. When
|
||||
// metadataOnly is true the filer skips per-chunk DeleteFile RPCs and
|
||||
// relies on the volume's natural TTL to reclaim chunks; pass true only
|
||||
// when the entry's Attributes.TtlSec > 0 so the volume is guaranteed to
|
||||
// drop the chunks on its own.
|
||||
func (s3a *S3ApiServer) deleteUnversionedObjectWithClient(client filer_pb.SeaweedFilerClient, bucket, object string, metadataOnly bool) error {
|
||||
target := util.NewFullPath(s3a.bucketDir(bucket), object)
|
||||
dir, name := target.DirAndName()
|
||||
return deleteObjectEntry(client, dir, name, true, false)
|
||||
return deleteObjectEntry(client, dir, name, !metadataOnly, false)
|
||||
}
|
||||
|
||||
func (s3a *S3ApiServer) DeleteObjectHandler(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -228,7 +233,7 @@ func (s3a *S3ApiServer) DeleteObjectHandler(w http.ResponseWriter, r *http.Reque
|
||||
}
|
||||
|
||||
if err := s3a.WithFilerClient(false, func(client filer_pb.SeaweedFilerClient) error {
|
||||
return s3a.deleteUnversionedObjectWithClient(client, bucket, object)
|
||||
return s3a.deleteUnversionedObjectWithClient(client, bucket, object, false)
|
||||
}); err != nil {
|
||||
glog.Errorf("DeleteObjectHandler: failed to delete %s/%s: %v", bucket, object, err)
|
||||
return s3err.ErrInternalError
|
||||
@@ -370,7 +375,7 @@ func (s3a *S3ApiServer) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *h
|
||||
return s3err.ErrAccessDenied
|
||||
}
|
||||
|
||||
if err := s3a.deleteUnversionedObjectWithClient(client, bucket, object.Key); err != nil {
|
||||
if err := s3a.deleteUnversionedObjectWithClient(client, bucket, object.Key, false); err != nil {
|
||||
glog.Errorf("DeleteMultipleObjectsHandler: failed to delete %s/%s: %v", bucket, object.Key, err)
|
||||
return s3err.ErrInternalError
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user