| Bug #81945 | API memory leaks after destructing a Ndb object with open NdbTransactions | ||
|---|---|---|---|
| Submitted: | 21 Jun 2016 8:52 | Modified: | 27 Jun 2016 16:35 |
| Reporter: | Ole John Aske | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Cluster: NDB API | Severity: | S3 (Non-critical) |
| Version: | 7.5.2 | OS: | Any |
| Assigned to: | CPU Architecture: | Any | |
[27 Jun 2016 16:35]
Jon Stephens
Documented fix in the NDB 7.5.4 changelog as follows:
NDB API objects are allocated in the context of an Ndb object,
or of an NdbTransaction object which is itself owned by an Ndb
object. When a given Ndb object is destroyed, all remaining
NdbTransaction objects are terminated, and all NDB API objects
related to this Ndb object should be released at this time as
well. It was found, when there remained unclosed NdbTransaction
objects when their parent Ndb object was destroyed, leaks of
objects allocated from the NdbTransaction objects could occur.
(However, the NdbTransaction objects themselves did not leak.)
While it is advisable (and recommended) to close an NdbTransaction
explicitly as soon as its lifetime ends, the destruction of the
parent Ndb object should be sufficient to release whatever
objects are dependent on it. Now in cases such as described
previously, the Ndb destructor checks to ensure that all objects
derived from a given Ndb instance are truly released.
Closed.

Description: All Ndb-API objects are allocated in the context of either a Ndb object, or a NdbTransaction object, which itself is 'owned' by a Ndb object. When the Ndb object is destructed, all remaining NdbTransactions are terminated, and all API objects related to this Ndb object should be released. However, if there are NdbTransactions still not 'closed' when the Ndb objects is destructed, we find that there could be leaks of objects allocated from these NdbTransaction. (Ndb<foo>Operations, and NdbLockHandle). Note: NdbTransaction objects itself did not leak. Our API guide generally advices that a NdbTransaction should be closed when it lifetime ends. This is still a good practice in order to clean up not needed resources as soon as possible. However, we should still not leak API memory in case of sloppy programing, hard to write error handling, unclear documentation or incorrect perception of the API, caused us to not explicitly close the NdbTransaction. Destructing the owning Ndb objects should be sufficient to release whatever owned by it. NOTE: These leaks materialized as an assert in: template<class T> inline Ndb_free_list_t<T>::~Ndb_free_list_t() { T* obj = m_free_list; while(obj) { T* curr = obj; obj = static_cast<T*>(obj->next()); delete curr; assert(m_free_cnt-- > 0); } assert(m_free_cnt == 0); assert(m_used_cnt == 0); <<<< Here !!! } That assert checks that all objects managed by this Ndb_free_list had been released back to the Free_list before the Ndb object managing the free lists is destructed. Failing to release will leak that object. How to repeat: Test program will be provided as part of patch. Suggested fix: Ensure that the Ndb d'tor release any remaining NdbTransaction and all the API objects owned by these transactions.