mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-09-19 13:00:45 +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:
@@ -964,8 +964,11 @@ func (s3a *S3ApiServer) getSpecificObjectVersion(bucket, object, versionId strin
|
||||
return entry, nil
|
||||
}
|
||||
|
||||
// deleteSpecificObjectVersion deletes a specific version of an object
|
||||
func (s3a *S3ApiServer) deleteSpecificObjectVersion(bucket, object, versionId string) error {
|
||||
// deleteSpecificObjectVersion deletes a specific version of an object.
|
||||
// metadataOnly=true skips per-chunk DeleteFile RPCs at the filer; only
|
||||
// pass true when the live entry's Attributes.TtlSec > 0 so the volume
|
||||
// reclaims chunks on its own.
|
||||
func (s3a *S3ApiServer) deleteSpecificObjectVersion(bucket, object, versionId string, metadataOnly bool) error {
|
||||
// Normalize object path to ensure consistency with toFilerPath behavior
|
||||
normalizedObject := s3_constants.NormalizeObjectKey(object)
|
||||
|
||||
@@ -986,7 +989,7 @@ func (s3a *S3ApiServer) deleteSpecificObjectVersion(bucket, object, versionId st
|
||||
}
|
||||
|
||||
// Delete the regular file
|
||||
deleteErr := s3a.rmObject(bucketDir, normalizedObject, true, false)
|
||||
deleteErr := s3a.rmObject(bucketDir, normalizedObject, !metadataOnly, false)
|
||||
if deleteErr != nil {
|
||||
// Check if file was already deleted by another process
|
||||
if _, checkErr := s3a.getEntry(bucketDir, normalizedObject); checkErr != nil {
|
||||
@@ -1013,7 +1016,7 @@ func (s3a *S3ApiServer) deleteSpecificObjectVersion(bucket, object, versionId st
|
||||
// Attempt to delete the version file
|
||||
// Note: We don't check if the file exists first to avoid race conditions
|
||||
// The deletion operation should be idempotent
|
||||
deleteErr := s3a.rm(versionsDir, versionFile, true, false)
|
||||
deleteErr := s3a.rm(versionsDir, versionFile, !metadataOnly, false)
|
||||
if deleteErr != nil {
|
||||
// Check if file was already deleted by another process (race condition handling)
|
||||
if _, checkErr := s3a.getEntry(versionsDir, versionFile); checkErr != nil {
|
||||
|
||||
Reference in New Issue
Block a user