| Bug #47573 | MySQL Cluster : Internal blob read buffer not always freed correctly | ||
|---|---|---|---|
| Submitted: | 23 Sep 2009 23:18 | Modified: | 25 Sep 2009 6:36 |
| Reporter: | Frazer Clement | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Cluster: Cluster (NDB) storage engine | Severity: | S2 (Serious) |
| Version: | mysql-5.1-telco-6.2 | OS: | Any |
| Assigned to: | Frazer Clement | CPU Architecture: | Any |
[24 Sep 2009 14: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 2009 15:19]
Frazer Clement
Pushed to 6.2.19, 6.3.27, 7.0.8, 7.1.0
[25 Sep 2009 6: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 2009 8: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 2009 8: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 2009 8: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 2009 8: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)

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.