lib/blockcache: properly remove references to deleted parts

Previously references to deleted parts may remain active as cache.m keys.
This could prevent from proper memory de-allocation.
This could lead to increased memory usage for the following caches starting from v1.73.0:

* indexdb/indexBlocks
* indexdb/dataBlocks
* storage/indexBlocks

Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2242
Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2007

This is a follow-up for 88605a7ea2
This commit is contained in:
Aliaksandr Valialkin 2022-03-18 17:04:43 +02:00
parent 2ae3a9a8a3
commit e3a10b327c
No known key found for this signature in database
GPG Key ID: A72BEC6CD3D0DED1

View File

@ -265,14 +265,10 @@ func (c *cache) cleanByTimeout() {
defer c.mu.Unlock() defer c.mu.Unlock()
for len(c.lah) > 0 { for len(c.lah) > 0 {
e := c.lah[0] if lastAccessTime < c.lah[0].lastAccessTime {
if lastAccessTime < e.lastAccessTime {
break break
} }
c.updateSizeBytes(-e.b.SizeBytes()) c.removeLeastRecentlyAccessedItem()
pes := c.m[e.k.Part]
delete(pes, e.k.Offset)
heap.Pop(&c.lah)
} }
} }
@ -333,14 +329,23 @@ func (c *cache) PutBlock(k Key, b Block) {
c.updateSizeBytes(e.b.SizeBytes()) c.updateSizeBytes(e.b.SizeBytes())
maxSizeBytes := c.getMaxSizeBytes() maxSizeBytes := c.getMaxSizeBytes()
for c.SizeBytes() > maxSizeBytes && len(c.lah) > 0 { for c.SizeBytes() > maxSizeBytes && len(c.lah) > 0 {
e := c.lah[0] c.removeLeastRecentlyAccessedItem()
c.updateSizeBytes(-e.b.SizeBytes())
pes := c.m[e.k.Part]
delete(pes, e.k.Offset)
heap.Pop(&c.lah)
} }
} }
func (c *cache) removeLeastRecentlyAccessedItem() {
e := c.lah[0]
c.updateSizeBytes(-e.b.SizeBytes())
p := e.k.Part
pes := c.m[p]
delete(pes, e.k.Offset)
if len(pes) == 0 {
// Remove reference to p from c.m in order to free up memory occupied by p.
delete(c.m, p)
}
heap.Pop(&c.lah)
}
func (c *cache) Len() int { func (c *cache) Len() int {
c.mu.Lock() c.mu.Lock()
defer c.mu.Unlock() defer c.mu.Unlock()