[MDEV-8204] Executing a CREATE EVENT query causes the embedded library to leak memory Created: 2015-05-21  Updated: 2015-05-22  Resolved: 2015-05-22

Status: Closed
Project: MariaDB Server
Component/s: Embedded Server, Parser
Affects Version/s: 10.0.19
Fix Version/s: N/A

Type: Bug Priority: Major
Reporter: markus makela Assignee: Sergei Golubchik
Resolution: Not a Bug Votes: 0
Labels: None
Environment:

Fedora 21


Issue Links:
Blocks
blocks MXS-166 Memory leak when creating a new event Closed

 Description   

Executing the following query causes a memory leak of 8,224 bytes in the embedded library.

CREATE EVENT myevent ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO UPDATE t1 SET id = id + 1;

The output of Valgrind at the time of the leak.

==29961== 153,504 (+25,584) (49,344 (+8,224) direct, 104,160 (+17,360) indirect) bytes in 6 (+1) blocks are definitely lost in loss record 399 of 406
==29961==    at 0x4C29BCF: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==29961==    by 0x72D426: my_malloc (in /home/markus/build/bin/maxscale)
==29961==    by 0x71941F: init_alloc_root (in /home/markus/build/bin/maxscale)
==29961==    by 0x601BC4: init_sql_alloc(st_mem_root*, unsigned int, unsigned int, unsigned long) (in /home/markus/build/bin/maxscale)
==29961==    by	0x5B2FD5: sp_head::operator new(unsigned long) (in /home/markus/build/bin/maxscale)
==29961==    by 0x7EFDA2: MYSQLparse(THD*) (in /home/markus/build/bin/maxscale)
==29961==    by 0x6DC766: parse_sql(THD*, Parser_state*, Object_creation_ctx*, bool) (in /home/markus/build/bin/maxscale)
==29961==    by 0x1C54271A: create_parse_tree(THD*) (query_classifier.cc:380)
==29961==    by 0x1C542186: parse_query (query_classifier.cc:199)
==29961==    by 0x1C541ED0: query_classifier_get_type (query_classifier.cc:110)
==29961==    by 0x1C330A61: route_single_stmt (readwritesplit.c:2081)
==29961==    by 0x1C3303FB: routeQuery (readwritesplit.c:1976)
==29961==
==29961== LEAK SUMMARY:
==29961==    definitely lost: 49,376 (+8,224) bytes in 7 (+1) blocks
==29961==    indirectly lost: 104,160 (+17,360) bytes in 54 (+9) blocks
==29961==      possibly lost: 270,928,208 (-60,840) bytes in 215 (-21) blocks
==29961==    still reachable: 1,280,312 (+0) bytes in 1,004 (+0) blocks
==29961==         suppressed: 0 (+0) bytes in 0 (+0) blocks
==29961== Reachable blocks (those to which a pointer was found) are not shown.
==29961== To see them, add 'reachable any' args to leak_check
 

MaxScale uses the embedded library only to parse queries and it seems to leak the memory when the free_embedded_thd function for the THD is called when MaxScale is done with it.



 Comments   
Comment by markus makela [ 2015-05-21 ]

CREATE TRIGGER and CREATE PROCEDURE seem to cause the same behavior.

Query

CREATE TRIGGER trg2 AFTER DELETE ON t1 FOR EACH ROW INSERT INTO t1 VALUES (1);
 

Valgrind output

 25,584 (8,224 direct, 17,360 indirect) bytes in 1 blocks are definitely lost in loss record 353 of 368
==31075==    at 0x4C29BCF: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==31075==    by 0x72D426: my_malloc (in /home/markus/build/bin/maxscale)
==31075==    by 0x71941F: init_alloc_root (in /home/markus/build/bin/maxscale)
==31075==    by 0x601BC4: init_sql_alloc(st_mem_root*, unsigned int, unsigned int, unsigned long) (in /home/markus/build/bin/maxscale)
==31075==    by 0x5B2FD5: sp_head::operator new(unsigned long) (in /home/markus/build/bin/maxscale)
==31075==    by 0x7FF35F: MYSQLparse(THD*) (in /home/markus/build/bin/maxscale)
==31075==    by 0x6DC766: parse_sql(THD*, Parser_state*, Object_creation_ctx*, bool) (in /home/markus/build/bin/maxscale)
==31075==    by 0x1C54271A: create_parse_tree(THD*) (query_classifier.cc:380)
==31075==    by 0x1C542186: parse_query (query_classifier.cc:199)
==31075==    by 0x1C541ED0: query_classifier_get_type (query_classifier.cc:110)
==31075==    by 0x1C330A61: route_single_stmt (readwritesplit.c:2081)
==31075==    by 0x1C3303FB: routeQuery (readwritesplit.c:1976)
==31075==
==31075== LEAK SUMMARY:
==31075==    definitely lost: 8,256 bytes in 2 blocks
==31075==    indirectly lost: 17,360 bytes in 9 blocks
==31075==      possibly lost: 270,926,872 bytes in 211 blocks
==31075==    still reachable: 1,279,273 bytes in 975 blocks
==31075==         suppressed: 0 bytes in 0 blocks
==31075== Reachable blocks (those to which a pointer was found) are not shown.
==31075== To see them, add 'reachable any' args to leak_check
 

Query

CREATE PROCEDURE simpleproc (OUT param1 INT)
    -> BEGIN
    -> SELECT COUNT(*) INTO param1 FROM t1;
    -> END//
 

Valgrind output

 
==31259== 26,464 (8,224 direct, 18,240 indirect) bytes in 1 blocks are definitely lost in loss record 360 of 375
==31259==    at 0x4C29BCF: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==31259==    by 0x72D426: my_malloc (in /home/markus/build/bin/maxscale)
==31259==    by 0x71941F: init_alloc_root (in /home/markus/build/bin/maxscale)
==31259==    by 0x601BC4: init_sql_alloc(st_mem_root*, unsigned int, unsigned int, unsigned long) (in /home/markus/build/bin/maxscale)
==31259==    by 0x5B2FD5: sp_head::operator new(unsigned long) (in /home/markus/build/bin/maxscale)
==31259==    by 0x7FFCD4: MYSQLparse(THD*) (in /home/markus/build/bin/maxscale)
==31259==    by 0x6DC766: parse_sql(THD*, Parser_state*, Object_creation_ctx*, bool) (in /home/markus/build/bin/maxscale)
==31259==    by 0x1C54271A: create_parse_tree(THD*) (query_classifier.cc:380)
==31259==    by 0x1C542186: parse_query (query_classifier.cc:199)
==31259==    by 0x1C541ED0: query_classifier_get_type (query_classifier.cc:110)
==31259==    by 0x1C330A61: route_single_stmt (readwritesplit.c:2081)
==31259==    by 0x1C3303FB: routeQuery (readwritesplit.c:1976)
==31259==
==31259== LEAK SUMMARY:
==31259==    definitely lost: 8,256 bytes in 2 blocks
==31259==    indirectly lost: 18,240 bytes in 15 blocks
==31259==      possibly lost: 270,926,872 bytes in 211 blocks
==31259==    still reachable: 1,279,305 bytes in 976 blocks
==31259==         suppressed: 0 bytes in 0 blocks
==31259== Reachable blocks (those to which a pointer was found) are not shown.
==31259== To see them, add 'reachable any' args to leak_check
 

Comment by Elena Stepanova [ 2015-05-22 ]

I don't see it happen lets say with MTR running with --embedded and --valgrind, not sure if it means that the problem is specific to this particular usage (for parsing only), or there is another reason.

Comment by Sergei Golubchik [ 2015-05-22 ]

Doesn't look like a bug. A server explicitly releases this memory, it has

    delete lex->sphead;
    lex->sphead= NULL;

at the end of “create event" code. As you invoke the parser directly, you have to free this memory manually after every statement.

Generated at Thu Feb 08 07:25:25 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.