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.