mirror of
https://github.com/minio/minio.git
synced 2025-02-09 20:58:08 -05:00
hold granular locking for multi-pool PutObject() (#20434)
- PutObject() for multi-pooled was holding large region locks, which was not necessary. This affects almost all slowpoke clients and lengthy uploads. - Re-arrange locks for CompleteMultipart, PutObject to be close to rename()
This commit is contained in:
parent
e47d787adb
commit
5bf41aff17
@ -455,8 +455,11 @@ func (er erasureObjects) newMultipartUpload(ctx context.Context, bucket string,
|
|||||||
}
|
}
|
||||||
fi.DataDir = mustGetUUID()
|
fi.DataDir = mustGetUUID()
|
||||||
|
|
||||||
if userDefined[ReplicationSsecChecksumHeader] != "" {
|
if ckSum := userDefined[ReplicationSsecChecksumHeader]; ckSum != "" {
|
||||||
fi.Checksum, _ = base64.StdEncoding.DecodeString(userDefined[ReplicationSsecChecksumHeader])
|
v, err := base64.StdEncoding.DecodeString(ckSum)
|
||||||
|
if err == nil {
|
||||||
|
fi.Checksum = v
|
||||||
|
}
|
||||||
delete(userDefined, ReplicationSsecChecksumHeader)
|
delete(userDefined, ReplicationSsecChecksumHeader)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1331,16 +1334,6 @@ func (er erasureObjects) CompleteMultipartUpload(ctx context.Context, bucket str
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !opts.NoLock {
|
|
||||||
lk := er.NewNSLock(bucket, object)
|
|
||||||
lkctx, err := lk.GetLock(ctx, globalOperationTimeout)
|
|
||||||
if err != nil {
|
|
||||||
return ObjectInfo{}, err
|
|
||||||
}
|
|
||||||
ctx = lkctx.Context()
|
|
||||||
defer lk.Unlock(lkctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Accept encrypted checksum from incoming request.
|
// Accept encrypted checksum from incoming request.
|
||||||
if opts.UserDefined[ReplicationSsecChecksumHeader] != "" {
|
if opts.UserDefined[ReplicationSsecChecksumHeader] != "" {
|
||||||
if v, err := base64.StdEncoding.DecodeString(opts.UserDefined[ReplicationSsecChecksumHeader]); err == nil {
|
if v, err := base64.StdEncoding.DecodeString(opts.UserDefined[ReplicationSsecChecksumHeader]); err == nil {
|
||||||
@ -1419,6 +1412,16 @@ func (er erasureObjects) CompleteMultipartUpload(ctx context.Context, bucket str
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !opts.NoLock {
|
||||||
|
lk := er.NewNSLock(bucket, object)
|
||||||
|
lkctx, err := lk.GetLock(ctx, globalOperationTimeout)
|
||||||
|
if err != nil {
|
||||||
|
return ObjectInfo{}, err
|
||||||
|
}
|
||||||
|
ctx = lkctx.Context()
|
||||||
|
defer lk.Unlock(lkctx)
|
||||||
|
}
|
||||||
|
|
||||||
er.cleanupMultipartPath(ctx, paths...) // cleanup all part.N.meta, and skipped part.N's before final rename().
|
er.cleanupMultipartPath(ctx, paths...) // cleanup all part.N.meta, and skipped part.N's before final rename().
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
|
@ -1333,12 +1333,12 @@ func (er erasureObjects) putObject(ctx context.Context, bucket string, object st
|
|||||||
if opts.EncryptFn != nil {
|
if opts.EncryptFn != nil {
|
||||||
fi.Checksum = opts.EncryptFn("object-checksum", fi.Checksum)
|
fi.Checksum = opts.EncryptFn("object-checksum", fi.Checksum)
|
||||||
}
|
}
|
||||||
if userDefined[ReplicationSsecChecksumHeader] != "" {
|
if ckSum := userDefined[ReplicationSsecChecksumHeader]; ckSum != "" {
|
||||||
if v, err := base64.StdEncoding.DecodeString(userDefined[ReplicationSsecChecksumHeader]); err == nil {
|
if v, err := base64.StdEncoding.DecodeString(ckSum); err == nil {
|
||||||
fi.Checksum = v
|
fi.Checksum = v
|
||||||
}
|
}
|
||||||
}
|
|
||||||
delete(userDefined, ReplicationSsecChecksumHeader)
|
delete(userDefined, ReplicationSsecChecksumHeader)
|
||||||
|
}
|
||||||
uniqueID := mustGetUUID()
|
uniqueID := mustGetUUID()
|
||||||
tempObj := uniqueID
|
tempObj := uniqueID
|
||||||
|
|
||||||
@ -1436,15 +1436,6 @@ func (er erasureObjects) putObject(ctx context.Context, bucket string, object st
|
|||||||
if opts.IndexCB != nil {
|
if opts.IndexCB != nil {
|
||||||
compIndex = opts.IndexCB()
|
compIndex = opts.IndexCB()
|
||||||
}
|
}
|
||||||
if !opts.NoLock {
|
|
||||||
lk := er.NewNSLock(bucket, object)
|
|
||||||
lkctx, err := lk.GetLock(ctx, globalOperationTimeout)
|
|
||||||
if err != nil {
|
|
||||||
return ObjectInfo{}, err
|
|
||||||
}
|
|
||||||
ctx = lkctx.Context()
|
|
||||||
defer lk.Unlock(lkctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
modTime := opts.MTime
|
modTime := opts.MTime
|
||||||
if opts.MTime.IsZero() {
|
if opts.MTime.IsZero() {
|
||||||
@ -1521,6 +1512,16 @@ func (er erasureObjects) putObject(ctx context.Context, bucket string, object st
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !opts.NoLock {
|
||||||
|
lk := er.NewNSLock(bucket, object)
|
||||||
|
lkctx, err := lk.GetLock(ctx, globalOperationTimeout)
|
||||||
|
if err != nil {
|
||||||
|
return ObjectInfo{}, err
|
||||||
|
}
|
||||||
|
ctx = lkctx.Context()
|
||||||
|
defer lk.Unlock(lkctx)
|
||||||
|
}
|
||||||
|
|
||||||
// Rename the successfully written temporary object to final location.
|
// Rename the successfully written temporary object to final location.
|
||||||
onlineDisks, versions, oldDataDir, err := renameData(ctx, onlineDisks, minioMetaTmpBucket, tempObj, partsMetadata, bucket, object, writeQuorum)
|
onlineDisks, versions, oldDataDir, err := renameData(ctx, onlineDisks, minioMetaTmpBucket, tempObj, partsMetadata, bucket, object, writeQuorum)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1091,18 +1091,7 @@ func (z *erasureServerPools) PutObject(ctx context.Context, bucket string, objec
|
|||||||
return z.serverPools[0].PutObject(ctx, bucket, object, data, opts)
|
return z.serverPools[0].PutObject(ctx, bucket, object, data, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !opts.NoLock {
|
idx, err := z.getPoolIdx(ctx, bucket, object, data.Size())
|
||||||
ns := z.NewNSLock(bucket, object)
|
|
||||||
lkctx, err := ns.GetLock(ctx, globalOperationTimeout)
|
|
||||||
if err != nil {
|
|
||||||
return ObjectInfo{}, err
|
|
||||||
}
|
|
||||||
ctx = lkctx.Context()
|
|
||||||
defer ns.Unlock(lkctx)
|
|
||||||
opts.NoLock = true
|
|
||||||
}
|
|
||||||
|
|
||||||
idx, err := z.getPoolIdxNoLock(ctx, bucket, object, data.Size())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ObjectInfo{}, err
|
return ObjectInfo{}, err
|
||||||
}
|
}
|
||||||
@ -1115,7 +1104,7 @@ func (z *erasureServerPools) PutObject(ctx context.Context, bucket string, objec
|
|||||||
Err: errDataMovementSrcDstPoolSame,
|
Err: errDataMovementSrcDstPoolSame,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Overwrite the object at the right pool
|
|
||||||
return z.serverPools[idx].PutObject(ctx, bucket, object, data, opts)
|
return z.serverPools[idx].PutObject(ctx, bucket, object, data, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user