Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-8204

Executing a CREATE EVENT query causes the embedded library to leak memory

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Not a Bug
    • Affects Version/s: 10.0.19
    • Fix Version/s: N/A
    • Component/s: Embedded Server, Parser
    • Labels:
      None
    • Environment:
      Fedora 21

      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.

        Gliffy Diagrams

          Attachments

            Issue Links

              Activity

              Hide
              markus makela markus makela added a comment - - edited

              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
              
              
              Show
              markus makela markus makela added a comment - - edited 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
              Hide
              elenst Elena Stepanova added a comment -

              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.

              Show
              elenst Elena Stepanova added a comment - 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.
              Hide
              serg Sergei Golubchik added a comment -

              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.

              Show
              serg Sergei Golubchik added a comment - 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.

                People

                • Assignee:
                  serg Sergei Golubchik
                  Reporter:
                  markus makela markus makela
                • Votes:
                  0 Vote for this issue
                  Watchers:
                  3 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved: