forked from TrueCloudLab/frostfs-node
[#47] shard: Switch container size metric from physical to logical capacity
Signed-off-by: Artem Tataurov <a.tataurov@yadro.com>
This commit is contained in:
parent
901d62567d
commit
362f24953a
6 changed files with 78 additions and 8 deletions
|
@ -11,6 +11,7 @@ Changelog for FrostFS Node
|
|||
- Add command `frostfs-adm morph netmap-candidates` (#1889)
|
||||
|
||||
### Changed
|
||||
- Change `frostfs_node_engine_container_size` to counting sizes of logical objects
|
||||
- `common.PrintVerbose` prints via `cobra.Command.Printf` (#1962)
|
||||
- Env prefix in configuration changed to `FROSTFS_*` (#43)
|
||||
- Link object is broadcast throughout the whole container now (#57)
|
||||
|
|
|
@ -23,6 +23,7 @@ type DeleteRes struct {
|
|||
rawRemoved uint64
|
||||
availableRemoved uint64
|
||||
sizes []uint64
|
||||
availableSizes []uint64
|
||||
}
|
||||
|
||||
// AvailableObjectsRemoved returns the number of removed available
|
||||
|
@ -36,11 +37,16 @@ func (d DeleteRes) RawObjectsRemoved() uint64 {
|
|||
return d.rawRemoved
|
||||
}
|
||||
|
||||
// RemovedObjectSizes returns the sizes of removed objects.
|
||||
func (d DeleteRes) RemovedObjectSizes() []uint64 {
|
||||
// RemovedPhysicalObjectSizes returns the sizes of removed physical objects.
|
||||
func (d DeleteRes) RemovedPhysicalObjectSizes() []uint64 {
|
||||
return d.sizes
|
||||
}
|
||||
|
||||
// RemovedLogicalObjectSizes returns the sizes of removed logical objects.
|
||||
func (d DeleteRes) RemovedLogicalObjectSizes() []uint64 {
|
||||
return d.availableSizes
|
||||
}
|
||||
|
||||
// SetAddresses is a Delete option to set the addresses of the objects to delete.
|
||||
//
|
||||
// Option is required.
|
||||
|
@ -73,10 +79,11 @@ func (db *DB) Delete(prm DeletePrm) (DeleteRes, error) {
|
|||
var availableRemoved uint64
|
||||
var err error
|
||||
var sizes = make([]uint64, len(prm.addrs))
|
||||
var availableSizes = make([]uint64, len(prm.addrs))
|
||||
|
||||
err = db.boltDB.Update(func(tx *bbolt.Tx) error {
|
||||
// We need to clear slice because tx can try to execute multiple times.
|
||||
rawRemoved, availableRemoved, err = db.deleteGroup(tx, prm.addrs, sizes)
|
||||
rawRemoved, availableRemoved, err = db.deleteGroup(tx, prm.addrs, sizes, availableSizes)
|
||||
return err
|
||||
})
|
||||
if err == nil {
|
||||
|
@ -90,6 +97,7 @@ func (db *DB) Delete(prm DeletePrm) (DeleteRes, error) {
|
|||
rawRemoved: rawRemoved,
|
||||
availableRemoved: availableRemoved,
|
||||
sizes: sizes,
|
||||
availableSizes: availableSizes,
|
||||
}, err
|
||||
}
|
||||
|
||||
|
@ -99,7 +107,7 @@ func (db *DB) Delete(prm DeletePrm) (DeleteRes, error) {
|
|||
// objects that were stored. The second return value is a logical objects
|
||||
// removed number: objects that were available (without Tombstones, GCMarks
|
||||
// non-expired, etc.)
|
||||
func (db *DB) deleteGroup(tx *bbolt.Tx, addrs []oid.Address, sizes []uint64) (uint64, uint64, error) {
|
||||
func (db *DB) deleteGroup(tx *bbolt.Tx, addrs []oid.Address, sizes []uint64, availableSizes []uint64) (uint64, uint64, error) {
|
||||
refCounter := make(referenceCounter, len(addrs))
|
||||
currEpoch := db.epochState.CurrentEpoch()
|
||||
|
||||
|
@ -119,6 +127,7 @@ func (db *DB) deleteGroup(tx *bbolt.Tx, addrs []oid.Address, sizes []uint64) (ui
|
|||
|
||||
if available {
|
||||
availableDeleted++
|
||||
availableSizes[i] = size
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
|
||||
"github.com/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
|
||||
apistatus "github.com/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
||||
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"go.etcd.io/bbolt"
|
||||
|
@ -23,10 +24,17 @@ type InhumePrm struct {
|
|||
forceRemoval bool
|
||||
}
|
||||
|
||||
// DeletionInfo contains details on deleted object.
|
||||
type DeletionInfo struct {
|
||||
Size uint64
|
||||
CID cid.ID
|
||||
}
|
||||
|
||||
// InhumeRes encapsulates results of Inhume operation.
|
||||
type InhumeRes struct {
|
||||
deletedLockObj []oid.Address
|
||||
availableImhumed uint64
|
||||
deletionDetails []DeletionInfo
|
||||
}
|
||||
|
||||
// AvailableInhumed return number of available object
|
||||
|
@ -42,6 +50,27 @@ func (i InhumeRes) DeletedLockObjects() []oid.Address {
|
|||
return i.deletedLockObj
|
||||
}
|
||||
|
||||
// GetDeletionInfoLength returns amount of stored elements
|
||||
// in deleted sizes array.
|
||||
func (i InhumeRes) GetDeletionInfoLength() int {
|
||||
return len(i.deletionDetails)
|
||||
}
|
||||
|
||||
// GetDeletionInfoByIndex returns both deleted object sizes and
|
||||
// associated container ID by index.
|
||||
func (i InhumeRes) GetDeletionInfoByIndex(target int) DeletionInfo {
|
||||
return i.deletionDetails[target]
|
||||
}
|
||||
|
||||
// StoreDeletionInfo stores size of deleted object and associated container ID
|
||||
// in corresponding arrays.
|
||||
func (i *InhumeRes) storeDeletionInfo(containerID cid.ID, deletedSize uint64) {
|
||||
i.deletionDetails = append(i.deletionDetails, DeletionInfo{
|
||||
Size: deletedSize,
|
||||
CID: containerID,
|
||||
})
|
||||
}
|
||||
|
||||
// SetAddresses sets a list of object addresses that should be inhumed.
|
||||
func (p *InhumePrm) SetAddresses(addrs ...oid.Address) {
|
||||
p.target = addrs
|
||||
|
@ -164,10 +193,10 @@ func (db *DB) Inhume(prm InhumePrm) (res InhumeRes, err error) {
|
|||
obj, err := db.get(tx, prm.target[i], buf, false, true, currEpoch)
|
||||
targetKey := addressKey(prm.target[i], buf)
|
||||
if err == nil {
|
||||
containerID, _ := obj.ContainerID()
|
||||
if inGraveyardWithKey(targetKey, graveyardBKT, garbageBKT) == 0 {
|
||||
// object is available, decrement the
|
||||
// logical counter
|
||||
inhumed++
|
||||
res.storeDeletionInfo(containerID, obj.PayloadSize())
|
||||
}
|
||||
|
||||
// if object is stored, and it is regular object then update bucket
|
||||
|
|
|
@ -83,9 +83,12 @@ func (s *Shard) delete(prm DeletePrm) (DeleteRes, error) {
|
|||
s.decObjectCounterBy(physical, res.RawObjectsRemoved())
|
||||
s.decObjectCounterBy(logical, res.AvailableObjectsRemoved())
|
||||
for i := range prm.addr {
|
||||
removedPayload := res.RemovedObjectSizes()[i]
|
||||
removedPayload := res.RemovedPhysicalObjectSizes()[i]
|
||||
totalRemovedPayload += removedPayload
|
||||
s.addToContainerSize(prm.addr[i].Container().EncodeToString(), -int64(removedPayload))
|
||||
logicalRemovedPayload := res.RemovedLogicalObjectSizes()[i]
|
||||
if logicalRemovedPayload > 0 {
|
||||
s.addToContainerSize(prm.addr[i].Container().EncodeToString(), -int64(logicalRemovedPayload))
|
||||
}
|
||||
}
|
||||
s.addToPayloadSize(-int64(totalRemovedPayload))
|
||||
|
||||
|
|
|
@ -268,6 +268,13 @@ func (s *Shard) collectExpiredObjects(ctx context.Context, e Event) {
|
|||
}
|
||||
|
||||
s.decObjectCounterBy(logical, res.AvailableInhumed())
|
||||
|
||||
i := 0
|
||||
for i < res.GetDeletionInfoLength() {
|
||||
delInfo := res.GetDeletionInfoByIndex(i)
|
||||
s.addToContainerSize(delInfo.CID.EncodeToString(), -int64(delInfo.Size))
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Shard) collectExpiredTombstones(ctx context.Context, e Event) {
|
||||
|
@ -408,6 +415,13 @@ func (s *Shard) HandleExpiredTombstones(tss []meta.TombstonedObject) {
|
|||
|
||||
s.decObjectCounterBy(logical, res.AvailableInhumed())
|
||||
|
||||
i := 0
|
||||
for i < res.GetDeletionInfoLength() {
|
||||
delInfo := res.GetDeletionInfoByIndex(i)
|
||||
s.addToContainerSize(delInfo.CID.EncodeToString(), -int64(delInfo.Size))
|
||||
i++
|
||||
}
|
||||
|
||||
// drop just processed expired tombstones
|
||||
// from graveyard
|
||||
err = s.metaBase.DropGraves(tss)
|
||||
|
@ -446,6 +460,13 @@ func (s *Shard) HandleExpiredLocks(lockers []oid.Address) {
|
|||
}
|
||||
|
||||
s.decObjectCounterBy(logical, res.AvailableInhumed())
|
||||
|
||||
i := 0
|
||||
for i < res.GetDeletionInfoLength() {
|
||||
delInfo := res.GetDeletionInfoByIndex(i)
|
||||
s.addToContainerSize(delInfo.CID.EncodeToString(), -int64(delInfo.Size))
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
// HandleDeletedLocks unlocks all objects which were locked by lockers.
|
||||
|
|
|
@ -111,6 +111,13 @@ func (s *Shard) Inhume(prm InhumePrm) (InhumeRes, error) {
|
|||
|
||||
s.decObjectCounterBy(logical, res.AvailableInhumed())
|
||||
|
||||
i := 0
|
||||
for i < res.GetDeletionInfoLength() {
|
||||
delInfo := res.GetDeletionInfoByIndex(i)
|
||||
s.addToContainerSize(delInfo.CID.EncodeToString(), -int64(delInfo.Size))
|
||||
i++
|
||||
}
|
||||
|
||||
if deletedLockObjs := res.DeletedLockObjects(); len(deletedLockObjs) != 0 {
|
||||
s.deletedLockCallBack(context.Background(), deletedLockObjs)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue