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:
None 
Category:MySQL Cluster: NDB API Severity:S3 (Non-critical)
Version:7.5.2 OS:Any
Assigned to: CPU Architecture:Any

[21 Jun 2016 8:52] Ole John Aske
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.
[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.