Bug #85301 The ALTER TABLE ... REBUILD PARTITION command leaks memory
Submitted: 3 Mar 2017 23:22 Modified: 6 Mar 2017 6:55
Reporter: Jay Edgar Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: DDL Severity:S3 (Non-critical)
Version:5.6.35 OS:Any
Assigned to: CPU Architecture:Any
Tags: Leak, partition, rebuild

[3 Mar 2017 23:22] Jay Edgar
Description:
When executing ALTER TABLE ... REBUILD PARTITION a new handlerton is constructed but never destructed (though the memory may possible be freed some way).  Valgrind doesn't detect this problem but adding a small amount of code allows it to report an error.

This was detected in MyRocks as memory allocated as member variables of the handlerton was showing as leaking.

How to repeat:
Create a test using the following commands:

CREATE TABLE t1 (i INT PRIMARY KEY) ENGINE=INNODB PARTITION BY KEY(i) PARTITIONS 4;
INSERT INTO t1 VALUES(1);
ALTER TABLE t1 REBUILD PARTITION p0;
DROP TABLE IF EXISTS t1;

Running this test with Valgrind shows no errors, but making the following modifications to your code and then running again with Valgrind will show an error.  The 'm_test' member variable of the handlerton allocates some memory that should get freed when the handlerton is destructed but isn't.

diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 3f4e4f8..1abb75e 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -3138,7 +3138,7 @@ ha_innobase::ha_innobase(
        start_of_scan(0),
        num_write_row(0),
        ha_partition_stats(NULL)
-{}
+{ m_test.append("Hello"); }

 /*********************************************************************//**
 Destruct ha_innobase handler. */
diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h
index fdedcd0..a77ce7f 100644
--- a/storage/innobase/handler/ha_innodb.h
+++ b/storage/innobase/handler/ha_innodb.h
@@ -82,6 +82,7 @@ class ha_innobase: public handler
        uint            num_write_row;  /*!< number of write_row() calls */
        ha_statistics*  ha_partition_stats; /*!< stats of the partition owner
                                        handler (if there is one) */
+  String m_test;

        uint store_key_val_for_row(uint keynr, char* buff, uint buff_len,
                                    const uchar* record);

Suggested fix:
I don't know what the fix should be.  I do know that in the partition handlerton, the m_file array holds the original handlertons and the m_new_file array holds the new handlertons where they are being change.  I'm guessing that for those being changed the original needs to be freed and "m_file[changed_part] = m_new_file[changed_part];' should be called for the changed partitions so that the new handlertons get freed automatically.
[6 Mar 2017 6:55] MySQL Verification Team
Hello Jay Edgar,

Thank you for the report and feedback.

Thanks,
Umesh
[6 Mar 2017 6:56] MySQL Verification Team
test results

Attachment: 85301.results (application/octet-stream, text), 7.33 KiB.