Bug #47573 MySQL Cluster : Internal blob read buffer not always freed correctly
Submitted: 24 Sep 1:18 Modified: 25 Sep 8:36
Reporter: Frazer Clement
Status: Closed
Category:Server: Cluster Severity:S2 (Serious)
Version:mysql-5.1-telco-6.2 OS:Any
Assigned to: Frazer Clement Target Version:

[24 Sep 1:18] Frazer Clement
Description:
ha_ndbcluster uses a dynamically allocated Blob buffer to store Blob data read from a row
stored in MySQL Cluster.

When an instance of the ndbcluster table handler is recycled (due to table definition
cache pressure, flush tables, alter table, etc.), the code which frees this buffer
contains a bug so that if the last row read contained blobs of zero length, the buffer is
not freed, but the reference to it is lost.  

This results in a memory leak.

How to repeat:
CREATE TABLE bl (a int primary key, b longtext) engine=ndb;
INSERT INTO bl VALUES (1, REPEAT('F', 20000));
INSERT INTO bl VALUES (2, '');

Repeat many times :
  SELECT a, length(b) FROM bl ORDER BY a; # So that the zero-length blob row is last
  FLUSH TABLES; # So that the handler object is recycled.

This will result in a memory leak proportional to the size of the stored Blob value for
each iteration of the loop.

Suggested fix:
Check correct state when deciding whether to free Blob buffer.
[24 Sep 16:22] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/84514

3004 Frazer Clement	2009-09-24
      Bug#47573 MySQL Cluster : Internal blob read buffer not always freed correctly. 
Fix buffer release code and rename some vars to aid understanding
      modified:
        sql/ha_ndbcluster.cc
        sql/ha_ndbcluster.h
[24 Sep 17:19] Frazer Clement
Pushed to 6.2.19, 6.3.27, 7.0.8, 7.1.0
[25 Sep 8:36] Jon Stephens
Documented bugfix in the NDB-6.2.19, 6.3.27, and 7.0.8 changelogs, as follows:

        NDBCLUSTER uses a dynamically-allocated buffer to store BLOB or
        TEXT column data that is read from rows in MySQL Cluster tables.

        When an instance of the NDBCLUSTER table handler was recycled
        (this can happen due to table definition cache pressure or to
        operations such as FLUSH TABLES or ALTER TABLE), if the last row
        read contained blobs of zero length, the buffer was not freed,
        even though the reference to it was lost. This resulted in a
        memory leak. For example, consider the table defined and 
        populated as shown here:

        CREATE TABLE t (a INT PRIMARY KEY, b LONGTEXT) ENGINE=NDB;

        INSERT INTO t VALUES (1, REPEAT('F', 20000));
        INSERT INTO t VALUES (2, '');

        Now execute repeatedly a SELECT on this table, such that the
        zero-length BLOB row is last, followed by a FLUSH TABLES (which
        forces the handler object to be re-used), as shown here:

        SELECT a, length(b) FROM bl ORDER BY a;
        FLUSH TABLES;

        This resulted in a memory leak proportional to the size of the
        stored BLOB value each time these two statements were executed.

Closed.
[30 Sep 10:13] Bugs System
Pushed into 5.1.37-ndb-6.2.19 (revid:frazer@mysql.com-20090929142503-sst6g3fs0vx9fgil)
(version source revid:frazer@mysql.com-20090924142210-nbui9h1hmitwnwai) (merge vers:
5.1.37-ndb-6.2.19) (pib:11)
[30 Sep 10:13] Bugs System
Pushed into 5.1.37-ndb-6.3.28 (revid:jonas@mysql.com-20090930070741-13u316s7s2l7e1ej)
(version source revid:frazer@mysql.com-20090924145421-nu2r7o4sx8imfgfc) (merge vers:
5.1.37-ndb-6.3.27) (pib:11)
[30 Sep 10:14] Bugs System
Pushed into 5.1.37-ndb-7.0.9 (revid:jonas@mysql.com-20090930075942-1q6asjcp0gaeynmj)
(version source revid:frazer@mysql.com-20090924150728-6timxf5546dgg7hs) (merge vers:
5.1.37-ndb-7.0.8) (pib:11)
[30 Sep 10:15] Bugs System
Pushed into 5.1.35-ndb-7.1.0 (revid:jonas@mysql.com-20090930080049-1c8a8cio9qgvhq35)
(version source revid:frazer@mysql.com-20090924150932-93344wrj807ngz09) (merge vers:
5.1.35-ndb-7.1.0) (pib:11)