mirror of
https://github.com/minio/minio.git
synced 2024-12-24 22:25:54 -05:00
fix: hold lock while serializing replication stats (#16007)
This commit is contained in:
parent
797fa7f97b
commit
2894dd4d1a
@ -19,6 +19,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/binary"
|
||||||
"math"
|
"math"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -37,12 +38,12 @@ func (b *BucketReplicationStats) hasReplicationUsage() bool {
|
|||||||
|
|
||||||
// ReplicationStats holds the global in-memory replication stats
|
// ReplicationStats holds the global in-memory replication stats
|
||||||
type ReplicationStats struct {
|
type ReplicationStats struct {
|
||||||
Cache map[string]*BucketReplicationStats
|
Cache map[string]*BucketReplicationStats
|
||||||
UsageCache map[string]*BucketReplicationStats
|
UsageCache map[string]*BucketReplicationStats
|
||||||
mostRecentStats BucketStatsMap
|
mostRecentStats BucketStatsMap
|
||||||
sync.RWMutex // mutex for Cache
|
sync.RWMutex // mutex for Cache
|
||||||
ulock sync.RWMutex // mutex for UsageCache
|
ulock sync.RWMutex // mutex for UsageCache
|
||||||
dlock sync.RWMutex // mutex for mostRecentStats
|
mostRecentStatsMu sync.Mutex // mutex for mostRecentStats
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete deletes in-memory replication statistics for a bucket.
|
// Delete deletes in-memory replication statistics for a bucket.
|
||||||
@ -245,13 +246,24 @@ outer:
|
|||||||
r.ulock.Unlock()
|
r.ulock.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ReplicationStats) getAllCachedLatest() BucketStatsMap {
|
// serializeStats will serialize the current stats.
|
||||||
|
// Will return (nil, nil) if no data.
|
||||||
|
func (r *ReplicationStats) serializeStats() ([]byte, error) {
|
||||||
if r == nil {
|
if r == nil {
|
||||||
return BucketStatsMap{}
|
return nil, nil
|
||||||
}
|
}
|
||||||
r.dlock.RLock()
|
r.mostRecentStatsMu.Lock()
|
||||||
defer r.dlock.RUnlock()
|
defer r.mostRecentStatsMu.Unlock()
|
||||||
return r.mostRecentStats
|
bsm := r.mostRecentStats
|
||||||
|
if len(bsm.Stats) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
data := make([]byte, 4, 4+bsm.Msgsize())
|
||||||
|
// Add the replication stats meta header.
|
||||||
|
binary.LittleEndian.PutUint16(data[0:2], replStatsMetaFormat)
|
||||||
|
binary.LittleEndian.PutUint16(data[2:4], replStatsVersion)
|
||||||
|
// Add data
|
||||||
|
return r.mostRecentStats.MarshalMsg(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ReplicationStats) getAllLatest(bucketsUsage map[string]BucketUsageInfo) (bucketsReplicationStats map[string]BucketReplicationStats) {
|
func (r *ReplicationStats) getAllLatest(bucketsUsage map[string]BucketUsageInfo) (bucketsReplicationStats map[string]BucketReplicationStats) {
|
||||||
@ -356,13 +368,13 @@ func (r *ReplicationStats) calculateBucketReplicationStats(bucket string, u Buck
|
|||||||
// normalize overall stats
|
// normalize overall stats
|
||||||
s.ReplicaSize = int64(math.Max(float64(totReplicaSize), float64(u.ReplicaSize)))
|
s.ReplicaSize = int64(math.Max(float64(totReplicaSize), float64(u.ReplicaSize)))
|
||||||
s.ReplicatedSize = int64(math.Max(float64(s.ReplicatedSize), float64(latestTotReplicatedSize)))
|
s.ReplicatedSize = int64(math.Max(float64(s.ReplicatedSize), float64(latestTotReplicatedSize)))
|
||||||
r.dlock.Lock()
|
r.mostRecentStatsMu.Lock()
|
||||||
if len(r.mostRecentStats.Stats) == 0 {
|
if len(r.mostRecentStats.Stats) == 0 {
|
||||||
r.mostRecentStats = BucketStatsMap{Stats: make(map[string]BucketStats, 1), Timestamp: UTCNow()}
|
r.mostRecentStats = BucketStatsMap{Stats: make(map[string]BucketStats, 1), Timestamp: UTCNow()}
|
||||||
}
|
}
|
||||||
r.mostRecentStats.Stats[bucket] = BucketStats{ReplicationStats: s}
|
r.mostRecentStats.Stats[bucket] = BucketStats{ReplicationStats: s}
|
||||||
r.mostRecentStats.Timestamp = UTCNow()
|
r.mostRecentStats.Timestamp = UTCNow()
|
||||||
r.dlock.Unlock()
|
r.mostRecentStatsMu.Unlock()
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2934,17 +2934,9 @@ func (p *ReplicationPool) saveStats(ctx context.Context) error {
|
|||||||
if !p.initialized() {
|
if !p.initialized() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
bsm := globalReplicationStats.getAllCachedLatest()
|
|
||||||
if len(bsm.Stats) == 0 {
|
data, err := globalReplicationStats.serializeStats()
|
||||||
return nil
|
if data == nil {
|
||||||
}
|
|
||||||
data := make([]byte, 4, 4+bsm.Msgsize())
|
|
||||||
// Add the replication stats meta header.
|
|
||||||
binary.LittleEndian.PutUint16(data[0:2], replStatsMetaFormat)
|
|
||||||
binary.LittleEndian.PutUint16(data[2:4], replStatsVersion)
|
|
||||||
// Add data
|
|
||||||
data, err := bsm.MarshalMsg(data)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return saveConfig(ctx, p.objLayer, getReplicationStatsPath(globalLocalNodeName), data)
|
return saveConfig(ctx, p.objLayer, getReplicationStatsPath(globalLocalNodeName), data)
|
||||||
|
Loading…
Reference in New Issue
Block a user