This is an automated email from the ASF dual-hosted git repository. hanahmily pushed a commit to branch bug/mempart-leak in repository https://gitbox.apache.org/repos/asf/skywalking-banyandb.git
commit e387a6a1d0469ec30a366e701dc85a81756a6312 Author: Hongtao Gao <[email protected]> AuthorDate: Tue Mar 17 12:05:25 2026 +0000 fix(measure,stream,trace): fix memPart leak in Close and prevent double-release in FinishSync Transfer ownership by nil-ing s.memPart before mustAddMemPart so Close does not double-release on the success path; call releaseMemPart in Close on the error path where FinishSync was never reached. --- CHANGES.md | 1 + banyand/measure/write_data.go | 9 +++++++-- banyand/stream/write_data.go | 9 +++++++-- banyand/trace/write_data.go | 5 ++++- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 6c7d98d6b..55bd0b4fe 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -45,6 +45,7 @@ Release Notes. - Ignore take snapshot when no data. - Fix measure standalone write handler resetting accumulated groups on error, which dropped all successfully processed events in the batch. - Fix memory part reference leak in mustAddMemPart when tsTable loop closes. +- Fix memory part leak in syncPartContext Close and prevent double-release in FinishSync. ### Document diff --git a/banyand/measure/write_data.go b/banyand/measure/write_data.go index b83ff65f6..026ad9bf7 100644 --- a/banyand/measure/write_data.go +++ b/banyand/measure/write_data.go @@ -43,7 +43,9 @@ func (s *syncPartContext) NewPartType(_ *queue.ChunkedSyncPartContext) error { } func (s *syncPartContext) FinishSync() error { - s.tsTable.mustAddMemPart(s.memPart) + mp := s.memPart + s.memPart = nil + s.tsTable.mustAddMemPart(mp) return s.Close() } @@ -51,7 +53,10 @@ func (s *syncPartContext) Close() error { s.writers.MustClose() releaseWriters(s.writers) s.writers = nil - s.memPart = nil + if s.memPart != nil { + releaseMemPart(s.memPart) + s.memPart = nil + } s.tsTable = nil return nil } diff --git a/banyand/stream/write_data.go b/banyand/stream/write_data.go index e9bd52cc1..85876fa40 100644 --- a/banyand/stream/write_data.go +++ b/banyand/stream/write_data.go @@ -42,7 +42,9 @@ func (s *syncPartContext) NewPartType(_ *queue.ChunkedSyncPartContext) error { } func (s *syncPartContext) FinishSync() error { - s.tsTable.mustAddMemPart(s.memPart) + mp := s.memPart + s.memPart = nil + s.tsTable.mustAddMemPart(mp) return s.Close() } @@ -50,7 +52,10 @@ func (s *syncPartContext) Close() error { s.writers.MustClose() releaseWriters(s.writers) s.writers = nil - s.memPart = nil + if s.memPart != nil { + releaseMemPart(s.memPart) + s.memPart = nil + } s.tsTable = nil return nil } diff --git a/banyand/trace/write_data.go b/banyand/trace/write_data.go index 6e44cbb7a..164035796 100644 --- a/banyand/trace/write_data.go +++ b/banyand/trace/write_data.go @@ -87,11 +87,13 @@ func (s *syncPartContext) FinishSync() error { } if s.memPart != nil { + mp := s.memPart + s.memPart = nil sidxPartContexts := make(map[string]*sidx.MemPart, len(s.sidxPartContexts)) for _, sidxPartContext := range s.sidxPartContexts { sidxPartContexts[sidxPartContext.Name()] = sidxPartContext.GetMemPart() } - s.tsTable.mustAddMemPart(s.memPart, sidxPartContexts) + s.tsTable.mustAddMemPart(mp, sidxPartContexts) } return s.Close() } @@ -103,6 +105,7 @@ func (s *syncPartContext) Close() error { s.writers = nil } if s.memPart != nil { + releaseMemPart(s.memPart) s.memPart = nil } if s.sidxPartContexts != nil {
