Bug #96551 Memory leak in mysql server 8.0 ndb nodejs
Submitted: 15 Aug 2019 12:25 Modified: 6 Sep 2023 10:08
Reporter: Xing Ai (OCA) Email Updates:
Status: Won't fix Impact on me:
None 
Category:MySQL Cluster: NDB API Severity:S3 (Non-critical)
Version:8.0 OS:Any
Assigned to: CPU Architecture:Any
Tags: 8.0, memory leak, ndb, NodeJS

[15 Aug 2019 12:25] Xing Ai
Description:
This memory leak problem is found through code review instead of testing.

C++ source file: https://github.com/mysql/mysql-server/blob/8.0/storage/ndb/nodejs/jones-ndb/impl/src/ndb/Q....

From the source file, if we look at code snippet below, the memory of "buffers[level].buffer" is allocated with "new char[]", however in the class's destructor, there is no loop to deallocate such memory.

How to repeat:
Here is the code snippet for the constrctor, destructor and member function "createRowBuffer(...)" which have memory management.

QueryOperation::QueryOperation(int sz) :
  size(sz),
  buffers(new QueryBuffer[sz]),
  // ...
{
  ndbQueryBuilder = NdbQueryBuilder::create();
  DEBUG_PRINT("Size: %d", size);
}

QueryOperation::~QueryOperation() {
  ndbQueryBuilder->destroy();
  delete[] buffers;
  free(results);
}

void QueryOperation::createRowBuffer(int level, Record *record, int parent_table) {
  buffers[level].record = record;
  buffers[level].buffer = new char[record->getBufferSize()];
  buffers[level].size   = record->getBufferSize();
  buffers[level].parent = (short) parent_table;
}

Suggested fix:
The destructor needs to add code to deallocate the memory for "buffers[level].buffer".

QueryOperation::~QueryOperation() {
  ndbQueryBuilder->destroy();
  for (int i = 0; i < size; i++)
  {
    delete[] buffers[i].buffer;
  }
  delete[] buffers;
  free(results);
}
[15 Aug 2019 18:44] MySQL Verification Team
Hi,

Looks like you are right, thanks for the report.

all best
Bogdan
[6 Sep 2023 10:08] Magnus BlÄudd
Posted by developer:
 
Checked latest version 8.0.35 and it looks like there is no memory leak.

The QueryOperation destructor uses array delete on "buffers", since buffers is of type QueryBuffer its destructor will be called and the "buffer" deleted.

QueryOperation::~QueryOperation() {
  ndbQueryBuilder->destroy();
  delete[] buffers; // << This calls ~QueryBuffer
  free(results);
}

~QueryBuffer()  { if(size) delete[] buffer; }

Closing as not a bug.