forked from TrueCloudLab/frostfs-node
[#1008] metabase: Do not update storageID on put
There may be a race condition between put an object and flushing the writecache: 1. Put object to the writecache 2. Writecache flushes object to the blobstore and sets blobstore's storageID 3. Put object to the metabase, set writecache's storageID Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
This commit is contained in:
parent
2ad433dbcb
commit
918613546f
3 changed files with 36 additions and 23 deletions
|
@ -137,7 +137,7 @@ func (db *DB) updateObj(tx *bbolt.Tx, obj *objectSDK.Object, id []byte, si *obje
|
|||
// When storage engine moves objects between different sub-storages,
|
||||
// it calls metabase.Put method with new storage ID, thus triggering this code.
|
||||
if !isParent && id != nil {
|
||||
return updateStorageID(tx, objectCore.AddressOf(obj), id)
|
||||
return setStorageID(tx, objectCore.AddressOf(obj), id, true)
|
||||
}
|
||||
|
||||
// when storage already has last object in split hierarchy and there is
|
||||
|
@ -236,12 +236,7 @@ func putUniqueIndexes(
|
|||
|
||||
// index storageID if it is present
|
||||
if id != nil {
|
||||
err = putUniqueIndexItem(tx, namedBucketItem{
|
||||
name: smallBucketName(cnr, bucketName),
|
||||
key: objKey,
|
||||
val: id,
|
||||
})
|
||||
if err != nil {
|
||||
if err = setStorageID(tx, objectCore.AddressOf(obj), id, false); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -483,16 +478,19 @@ func getVarUint(data []byte) (uint64, int, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// updateStorageID for existing objects if they were moved from one
|
||||
// setStorageID for existing objects if they were moved from one
|
||||
// storage location to another.
|
||||
func updateStorageID(tx *bbolt.Tx, addr oid.Address, id []byte) error {
|
||||
func setStorageID(tx *bbolt.Tx, addr oid.Address, id []byte, override bool) error {
|
||||
key := make([]byte, bucketKeySize)
|
||||
bkt, err := createBucketLikelyExists(tx, smallBucketName(addr.Container(), key))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return bkt.Put(objectKey(addr.Object(), key), id)
|
||||
key = objectKey(addr.Object(), key)
|
||||
if override || bkt.Get(key) == nil {
|
||||
return bkt.Put(key, id)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// updateSpliInfo for existing objects if storage filled with extra information
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue