diff --git a/pkg/local_object_storage/metabase/delete.go b/pkg/local_object_storage/metabase/delete.go index 484dbe41..8e555763 100644 --- a/pkg/local_object_storage/metabase/delete.go +++ b/pkg/local_object_storage/metabase/delete.go @@ -254,9 +254,18 @@ func (db *DB) delete(tx *bbolt.Tx, addr oid.Address, refCounter referenceCounter // unmarshal object, work only with physically stored (raw == true) objects obj, err := db.get(tx, addr, key, false, true, currEpoch) if err != nil { + if client.IsErrObjectNotFound(err) { + addrKey = addressKey(addr, key) + if garbageBKT != nil { + err := garbageBKT.Delete(addrKey) + if err != nil { + return deleteSingleResult{}, fmt.Errorf("could not remove from garbage bucket: %w", err) + } + } + return deleteSingleResult{}, nil + } var siErr *objectSDK.SplitInfoError - - if client.IsErrObjectNotFound(err) || errors.As(err, &siErr) { + if errors.As(err, &siErr) { // if object is virtual (parent) then do nothing, it will be deleted with last child return deleteSingleResult{}, nil } diff --git a/pkg/local_object_storage/metabase/delete_test.go b/pkg/local_object_storage/metabase/delete_test.go index 5a52868d..649c0ebe 100644 --- a/pkg/local_object_storage/metabase/delete_test.go +++ b/pkg/local_object_storage/metabase/delete_test.go @@ -182,6 +182,37 @@ func TestDelete(t *testing.T) { require.Equal(t, 0, len(addrs)) } +func TestDeleteDropsGCMarkIfObjectNotFound(t *testing.T) { + db := newDB(t, meta.WithEpochState(epochState{currEpoch})) + defer func() { require.NoError(t, db.Close()) }() + + addr := oidtest.Address() + + var prm meta.InhumePrm + prm.SetAddresses(addr) + prm.SetGCMark() + _, err := db.Inhume(context.Background(), prm) + require.NoError(t, err) + + var garbageCount int + var itPrm meta.GarbageIterationPrm + itPrm.SetHandler(func(g meta.GarbageObject) error { + garbageCount++ + return nil + }) + require.NoError(t, db.IterateOverGarbage(context.Background(), itPrm)) + require.Equal(t, 1, garbageCount) + + var delPrm meta.DeletePrm + delPrm.SetAddresses(addr) + _, err = db.Delete(context.Background(), delPrm) + require.NoError(t, err) + + garbageCount = 0 + require.NoError(t, db.IterateOverGarbage(context.Background(), itPrm)) + require.Equal(t, 0, garbageCount) +} + func metaDelete(db *meta.DB, addrs ...oid.Address) error { var deletePrm meta.DeletePrm deletePrm.SetAddresses(addrs...)