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

Memory Leak in init_io_cache_ext upon SHUTDOWN

Details

    Description

      INSTALL PLUGIN Spider SONAME 'ha_spider.so';
      CREATE TABLE t (c INT) ENGINE=Spider;
      CREATE PROCEDURE p() CONTAINS SQL READS SQL DATA SELECT * FROM t INTO OUTFILE 'foo.txt';
      CALL p();
      SHUTDOWN;
      

      Leads to:

      CS 11.2.6 66b8d32b7514f46b1467d404d3f9ad688bbfeb4f (Optimized, UBASAN)

      2024-11-04 10:36:23 0 [Note] /test/UBASAN_MD171024-mariadb-11.2.6-linux-x86_64-opt/bin/mariadbd: Shutdown complete
       
      Warning: Memory not freed: 131192
       
      =================================================================
      ==1094811==ERROR: LeakSanitizer: detected memory leaks
       
      Direct leak of 131096 byte(s) in 1 object(s) allocated from:
          #0 0x561ef72c2087 in malloc (/test/UBASAN_MD171024-mariadb-11.2.6-linux-x86_64-opt/bin/mariadbd+0x836a087)
          #1 0x561efbbda2b4 in my_malloc /test/11.2_opt_san/mysys/my_malloc.c:93
          #2 0x561efbb76f57 in init_io_cache_ext /test/11.2_opt_san/mysys/mf_iocache.c:248
          #3 0x561efbb7781d in init_io_cache /test/11.2_opt_san/mysys/mf_iocache.c:301
          #4 0x561ef787c5e0 in create_file /test/11.2_opt_san/sql/sql_class.cc:3333
          #5 0x561ef78c66ef in select_export::prepare(List<Item>&, st_select_lex_unit*) /test/11.2_opt_san/sql/sql_class.cc:3355
          #6 0x561ef8002244 in JOIN::prepare(TABLE_LIST*, Item*, unsigned int, st_order*, bool, st_order*, Item*, st_order*, st_select_lex*, st_select_lex_unit*) /test/11.2_opt_san/sql/sql_select.cc:1866
          #7 0x561ef80ac457 in mysql_select(THD*, TABLE_LIST*, List<Item>&, Item*, unsigned int, st_order*, st_order*, Item*, st_order*, unsigned long long, select_result*, st_select_lex_unit*, st_select_lex*) /test/11.2_opt_san/sql/sql_select.cc:5333
          #8 0x561ef80ae550 in handle_select(THD*, LEX*, select_result*, unsigned long long) /test/11.2_opt_san/sql/sql_select.cc:642
          #9 0x561ef7be3450 in execute_sqlcom_select /test/11.2_opt_san/sql/sql_parse.cc:6177
          #10 0x561ef7c5375f in mysql_execute_command(THD*, bool) /test/11.2_opt_san/sql/sql_parse.cc:3984
          #11 0x561ef8b2ab3f in sp_instr_stmt::exec_core(THD*, unsigned int*) /test/11.2_opt_san/sql/sp_instr.cc:1050
          #12 0x561ef8b4554a in sp_lex_keeper::reset_lex_and_exec_core(THD*, unsigned int*, bool, sp_instr*, bool) /test/11.2_opt_san/sql/sp_instr.cc:296
          #13 0x561ef8b4deab in sp_lex_keeper::validate_lex_and_exec_core(THD*, unsigned int*, bool, sp_lex_instr*) /test/11.2_opt_san/sql/sp_instr.cc:475
          #14 0x561ef8b5263d in sp_instr_stmt::execute(THD*, unsigned int*) /test/11.2_opt_san/sql/sp_instr.cc:953
          #15 0x561ef761671a in sp_head::execute(THD*, bool) /test/11.2_opt_san/sql/sp_head.cc:1284
          #16 0x561ef76235d0 in sp_head::execute_procedure(THD*, List<Item>*) /test/11.2_opt_san/sql/sp_head.cc:2300
          #17 0x561ef7bde90a in do_execute_sp /test/11.2_opt_san/sql/sql_parse.cc:3064
          #18 0x561ef7bffe1a in Sql_cmd_call::execute(THD*) /test/11.2_opt_san/sql/sql_parse.cc:3309
          #19 0x561ef7c428c4 in mysql_execute_command(THD*, bool) /test/11.2_opt_san/sql/sql_parse.cc:5892
          #20 0x561ef7c64482 in mysql_parse(THD*, char*, unsigned int, Parser_state*) /test/11.2_opt_san/sql/sql_parse.cc:7938
          #21 0x561ef7c760da in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool) /test/11.2_opt_san/sql/sql_parse.cc:1894
          #22 0x561ef7c86486 in do_command(THD*, bool) /test/11.2_opt_san/sql/sql_parse.cc:1407
          #23 0x561ef8659efc in do_handle_one_connection(CONNECT*, bool) /test/11.2_opt_san/sql/sql_connect.cc:1439
          #24 0x561ef865c52c in handle_one_connection /test/11.2_opt_san/sql/sql_connect.cc:1341
          #25 0x154f9e89ca93 in start_thread nptl/pthread_create.c:447
       
      SUMMARY: AddressSanitizer: 131096 byte(s) leaked in 1 allocation(s).
      241104 10:36:25 [ERROR] mysqld got signal 6 ;
      

      CS 11.2.6 66b8d32b7514f46b1467d404d3f9ad688bbfeb4f (Debug, UBASAN)

      2024-11-04 10:36:23 0 [Note] /test/UBASAN_MD171024-mariadb-11.2.6-linux-x86_64-dbg/bin/mariadbd: Shutdown complete
       
      Warning: Memory not freed: 131192
       
      =================================================================
      ==1096914==ERROR: LeakSanitizer: detected memory leaks
       
      Direct leak of 131096 byte(s) in 1 object(s) allocated from:
          #0 0x5579c7b4fa67 in malloc (/test/UBASAN_MD171024-mariadb-11.2.6-linux-x86_64-dbg/bin/mariadbd+0x88b4a67)
          #1 0x5579cc9baca3 in my_malloc /test/11.2_dbg_san/mysys/my_malloc.c:93
          #2 0x5579cc9618f3 in init_io_cache_ext /test/11.2_dbg_san/mysys/mf_iocache.c:248
          #3 0x5579cc9619a5 in init_io_cache /test/11.2_dbg_san/mysys/mf_iocache.c:301
          #4 0x5579c80f9b2b in create_file /test/11.2_dbg_san/sql/sql_class.cc:3333
          #5 0x5579c8149aa1 in select_export::prepare(List<Item>&, st_select_lex_unit*) /test/11.2_dbg_san/sql/sql_class.cc:3355
          #6 0x5579c886cf06 in JOIN::prepare(TABLE_LIST*, Item*, unsigned int, st_order*, bool, st_order*, Item*, st_order*, st_select_lex*, st_select_lex_unit*) /test/11.2_dbg_san/sql/sql_select.cc:1866
          #7 0x5579c8913aa3 in mysql_select(THD*, TABLE_LIST*, List<Item>&, Item*, unsigned int, st_order*, st_order*, Item*, st_order*, unsigned long long, select_result*, st_select_lex_unit*, st_select_lex*) /test/11.2_dbg_san/sql/sql_select.cc:5333
          #8 0x5579c89152d4 in handle_select(THD*, LEX*, select_result*, unsigned long long) /test/11.2_dbg_san/sql/sql_select.cc:642
          #9 0x5579c8468dd9 in execute_sqlcom_select /test/11.2_dbg_san/sql/sql_parse.cc:6177
          #10 0x5579c84cd8fc in mysql_execute_command(THD*, bool) /test/11.2_dbg_san/sql/sql_parse.cc:3984
          #11 0x5579c944707d in sp_instr_stmt::exec_core(THD*, unsigned int*) /test/11.2_dbg_san/sql/sp_instr.cc:1050
          #12 0x5579c9465e62 in sp_lex_keeper::reset_lex_and_exec_core(THD*, unsigned int*, bool, sp_instr*, bool) /test/11.2_dbg_san/sql/sp_instr.cc:296
          #13 0x5579c946e92a in sp_lex_keeper::validate_lex_and_exec_core(THD*, unsigned int*, bool, sp_lex_instr*) /test/11.2_dbg_san/sql/sp_instr.cc:475
          #14 0x5579c94730b3 in sp_instr_stmt::execute(THD*, unsigned int*) /test/11.2_dbg_san/sql/sp_instr.cc:953
          #15 0x5579c7eeceb6 in sp_head::execute(THD*, bool) /test/11.2_dbg_san/sql/sp_head.cc:1284
          #16 0x5579c7ef8c5b in sp_head::execute_procedure(THD*, List<Item>*) /test/11.2_dbg_san/sql/sp_head.cc:2300
          #17 0x5579c846a5c1 in do_execute_sp /test/11.2_dbg_san/sql/sql_parse.cc:3064
          #18 0x5579c8488510 in Sql_cmd_call::execute(THD*) /test/11.2_dbg_san/sql/sql_parse.cc:3309
          #19 0x5579c84efb47 in mysql_execute_command(THD*, bool) /test/11.2_dbg_san/sql/sql_parse.cc:5892
          #20 0x5579c84f8351 in mysql_parse(THD*, char*, unsigned int, Parser_state*) /test/11.2_dbg_san/sql/sql_parse.cc:7938
          #21 0x5579c850829b in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool) /test/11.2_dbg_san/sql/sql_parse.cc:1894
          #22 0x5579c8516b06 in do_command(THD*, bool) /test/11.2_dbg_san/sql/sql_parse.cc:1407
          #23 0x5579c8f3e791 in do_handle_one_connection(CONNECT*, bool) /test/11.2_dbg_san/sql/sql_connect.cc:1439
          #24 0x5579c8f3fcb3 in handle_one_connection /test/11.2_dbg_san/sql/sql_connect.cc:1341
          #25 0x1514d189ca93 in start_thread nptl/pthread_create.c:447
       
      SUMMARY: AddressSanitizer: 131096 byte(s) leaked in 1 allocation(s).
      241104 10:36:25 [ERROR] mysqld got signal 6 ;
      

      Setup:

      Compiled with a recent version of GCC (I use GCC 11.4.0) and:
          -DWITH_ASAN=ON -DWITH_ASAN_SCOPE=ON -DWITH_UBSAN=ON -DWSREP_LIB_WITH_ASAN=ON
      Set before execution:
          export ASAN_OPTIONS=quarantine_size_mb=512:atexit=0:detect_invalid_pointer_pairs=3:dump_instruction_bytes=1:abort_on_error=1:allocator_may_return_null=1
      

      Bug confirmed present in:
      MariaDB: 10.5.27 (dbg), 10.5.27 (opt), 10.6.20 (dbg), 10.6.20 (opt), 10.11.10 (dbg), 10.11.10 (opt), 11.2.6 (dbg), 11.2.6 (opt), 11.4.4 (dbg), 11.4.4 (opt), 11.6.2 (dbg), 11.6.2 (opt), 11.7.0 (dbg), 11.7.0 (opt)

      Issue lightly sporadic, especially on 10.6.

      Attachments

        Activity

          Roel Roel Van de Paar added a comment - - edited

          MTR Testcase:

          --source plugin/spider/spider/include/init_spider.inc
           
          CREATE TABLE t (c INT) ENGINE=Spider;
          CREATE PROCEDURE p() CONTAINS SQL READS SQL DATA SELECT * FROM t INTO OUTFILE 'foo.txt';
          --error ER_CONNECT_TO_FOREIGN_DATA_SOURCE
          CALL p();
          SHUTDOWN;
          

          Roel Roel Van de Paar added a comment - - edited MTR Testcase: --source plugin/spider/spider/include/init_spider.inc   CREATE TABLE t (c INT ) ENGINE=Spider; CREATE PROCEDURE p() CONTAINS SQL READS SQL DATA SELECT * FROM t INTO OUTFILE 'foo.txt' ; --error ER_CONNECT_TO_FOREIGN_DATA_SOURCE CALL p(); SHUTDOWN;
          ycp Yuchen Pei added a comment -

          Strange, it looks like I can only reproduce it once.

          ycp Yuchen Pei added a comment - Strange, it looks like I can only reproduce it once.

          Perhaps due to sporadicity? If it constantly fails to reproduce let me know and I will have another look.

          Roel Roel Van de Paar added a comment - Perhaps due to sporadicity? If it constantly fails to reproduce let me know and I will have another look.
          ycp Yuchen Pei added a comment - - edited

          At 10.5 bf7cfa2535618bfe9962c725555680e799fdcd18 I am able to reliably reproduce this issue with the following test

          --disable_query_log
          --disable_result_log
          --source ../../t/test_init.inc
          --enable_result_log
          --enable_query_log
           
          CREATE TABLE t (c INT) ENGINE=Spider;
          CREATE PROCEDURE p() CONTAINS SQL READS SQL DATA SELECT * FROM t INTO OUTFILE 'foo.txt';
          --error ER_CONNECT_TO_FOREIGN_DATA_SOURCE
          CALL p();
          drop procedure p;
          drop table t;
           
          --disable_query_log
          --disable_result_log
          --source ../../t/test_deinit.inc
          --enable_result_log
          --enable_query_log
          

          Note that the CONTAINS SQL READS SQL DATA is not needed to reproduce.

          ycp Yuchen Pei added a comment - - edited At 10.5 bf7cfa2535618bfe9962c725555680e799fdcd18 I am able to reliably reproduce this issue with the following test --disable_query_log --disable_result_log --source ../../t/test_init.inc --enable_result_log --enable_query_log   CREATE TABLE t (c INT ) ENGINE=Spider; CREATE PROCEDURE p() CONTAINS SQL READS SQL DATA SELECT * FROM t INTO OUTFILE 'foo.txt' ; --error ER_CONNECT_TO_FOREIGN_DATA_SOURCE CALL p(); drop procedure p; drop table t;   --disable_query_log --disable_result_log --source ../../t/test_deinit.inc --enable_result_log --enable_query_log Note that the CONTAINS SQL READS SQL DATA is not needed to reproduce.
          ycp Yuchen Pei added a comment - - edited

          If we make it so that the CALL statement succeeds like the following, then the leak disappears. So it seems like some missing cleanup in failure mode.

          --disable_query_log
          --disable_result_log
          --source ../../t/test_init.inc
          --enable_result_log
          --enable_query_log
           
          set spider_same_server_link= 1;
          evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql
          OPTIONS (SOCKET "$MASTER_MYSOCK", DATABASE 'test',user 'root');
           
          create table t2 (c int);
          CREATE TABLE t (c INT) ENGINE=Spider
          COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"';
          CREATE PROCEDURE p() CONTAINS SQL READS SQL DATA SELECT * FROM t INTO OUTFILE 'foo.txt';
          # --error ER_CONNECT_TO_FOREIGN_DATA_SOURCE
          CALL p();
          drop procedure p;
          drop table t, t2;
           
          drop server srv;
           
          --disable_query_log
          --disable_result_log
          --source ../../t/test_deinit.inc
          --enable_result_log
          --enable_query_log

          More specifically, the stack of the leak suggests it is something happening in creating the outfile that has not been cleaned up:

           0 in my_malloc of /home/ycp/source/mariadb-server/10.5/src/mysys/my_malloc.c:91
           1 in init_io_cache_ext of /home/ycp/source/mariadb-server/10.5/src/mysys/mf_iocache.c:248
           2 in init_io_cache of /home/ycp/source/mariadb-server/10.5/src/mysys/mf_iocache.c:301
           3 in create_file of /home/ycp/source/mariadb-server/10.5/src/sql/sql_class.cc:3300
           4 in select_export::prepare of /home/ycp/source/mariadb-server/10.5/src/sql/sql_class.cc:3322

          In the passing case above, the cleanup happens in exec stage after the GBH execution:

          // in Pushdown_query::execute():
            if ((err= handler->end_scan()))
              goto error_2;
            if (!store_data_in_temp_table && join->result->send_eof())
              DBUG_RETURN(1);                              // Don't send error to client

          Compare that with our testcase, the failure happens in optimizing stage

          // in JOIN::optimize_inner():
            if (unlikely(make_join_statistics(this, select_lex->leaf_tables,
                                              &keyuse)) ||
                unlikely(thd->is_fatal_error))
            {
              DBUG_PRINT("error",("Error: make_join_statistics() failed"));
              DBUG_RETURN(1);
            }

          Without creating and calling a procedure, the leak does not happen either:

          # ...
          CREATE TABLE t (c INT) ENGINE=Spider;
          --error ER_CONNECT_TO_FOREIGN_DATA_SOURCE
          SELECT * FROM t INTO OUTFILE 'foo.txt';
          drop table t;
          # ...

          In this case, the cleanup happens in THD::end_statement which is only called for non-prepared statements:

          // in THD::end_statement():
            delete lex->result;

          So the problem reduces to:

          How to clean up in an sp execution after failing in optimizing stage?

          ycp Yuchen Pei added a comment - - edited If we make it so that the CALL statement succeeds like the following, then the leak disappears. So it seems like some missing cleanup in failure mode. --disable_query_log --disable_result_log --source ../../t/test_init.inc --enable_result_log --enable_query_log   set spider_same_server_link= 1; evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql OPTIONS (SOCKET "$MASTER_MYSOCK" , DATABASE 'test' , user 'root' );   create table t2 (c int ); CREATE TABLE t (c INT ) ENGINE=Spider COMMENT= 'WRAPPER "mysql", srv "srv",TABLE "t2"' ; CREATE PROCEDURE p() CONTAINS SQL READS SQL DATA SELECT * FROM t INTO OUTFILE 'foo.txt' ; # --error ER_CONNECT_TO_FOREIGN_DATA_SOURCE CALL p(); drop procedure p; drop table t, t2;   drop server srv;   --disable_query_log --disable_result_log --source ../../t/test_deinit.inc --enable_result_log --enable_query_log More specifically, the stack of the leak suggests it is something happening in creating the outfile that has not been cleaned up: 0 in my_malloc of /home/ycp/source/mariadb-server/10.5/src/mysys/my_malloc.c:91 1 in init_io_cache_ext of /home/ycp/source/mariadb-server/10.5/src/mysys/mf_iocache.c:248 2 in init_io_cache of /home/ycp/source/mariadb-server/10.5/src/mysys/mf_iocache.c:301 3 in create_file of /home/ycp/source/mariadb-server/10.5/src/sql/sql_class.cc:3300 4 in select_export::prepare of /home/ycp/source/mariadb-server/10.5/src/sql/sql_class.cc:3322 In the passing case above, the cleanup happens in exec stage after the GBH execution: // in Pushdown_query::execute(): if ((err= handler->end_scan())) goto error_2; if (!store_data_in_temp_table && join->result->send_eof()) DBUG_RETURN(1); // Don't send error to client Compare that with our testcase, the failure happens in optimizing stage // in JOIN::optimize_inner(): if (unlikely(make_join_statistics( this , select_lex->leaf_tables, &keyuse)) || unlikely(thd->is_fatal_error)) { DBUG_PRINT( "error" ,( "Error: make_join_statistics() failed" )); DBUG_RETURN(1); } Without creating and calling a procedure, the leak does not happen either: # ... CREATE TABLE t (c INT ) ENGINE=Spider; --error ER_CONNECT_TO_FOREIGN_DATA_SOURCE SELECT * FROM t INTO OUTFILE 'foo.txt' ; drop table t; # ... In this case, the cleanup happens in THD::end_statement which is only called for non-prepared statements: // in THD::end_statement(): delete lex->result; So the problem reduces to: How to clean up in an sp execution after failing in optimizing stage?
          ycp Yuchen Pei added a comment - - edited

          However, if we do this

          modified   sql/sql_select.cc
          @@ -2418,6 +2418,7 @@ JOIN::optimize_inner()
                 unlikely(thd->is_fatal_error))
             {
               DBUG_PRINT("error",("Error: make_join_statistics() failed"));
          +    abort();
               DBUG_RETURN(1);
             }

          And run the main suite, then only three tests fail:

          Completed: Failed 3/1135 tests, 99.74% were successful.
           
          Failing test(s): main.show_explain main.error_simulation main.unsafe_binlog_innodb

          And the failing circumstances are rather unnatural. So perhaps spider is not meant to fail at this point, which in this specific case means spider contacting the data node for stats? Not really, as here the server layer explicitly requests status from spider, which naturally ask for them from the remote table:

          // in TABLE_LIST::fetch_number_of_rows > make_join_statistics:
              error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);

          ycp Yuchen Pei added a comment - - edited However, if we do this modified sql/sql_select.cc @@ -2418,6 +2418,7 @@ JOIN::optimize_inner() unlikely(thd->is_fatal_error)) { DBUG_PRINT("error",("Error: make_join_statistics() failed")); + abort(); DBUG_RETURN(1); } And run the main suite, then only three tests fail: Completed: Failed 3/1135 tests, 99.74% were successful.   Failing test(s): main.show_explain main.error_simulation main.unsafe_binlog_innodb And the failing circumstances are rather unnatural. So perhaps spider is not meant to fail at this point, which in this specific case means spider contacting the data node for stats? Not really, as here the server layer explicitly requests status from spider, which naturally ask for them from the remote table: // in TABLE_LIST::fetch_number_of_rows > make_join_statistics: error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
          ycp Yuchen Pei added a comment - - edited

          A draft patch which satisfies the CI:

          fb45030a567 upstream/bb-10.5-mdev-35326 MDEV-35326 Clean up lex->result after a failing select

          Some remaining questions:

          • Does lex->result being non-NULL imply it is not a select_insert/select_create?
            see also commit 49bd559eb8f041de97e4ef55f280f3806d1b6c42 that introduced select_result::cleanup()
          • Can we come up with a prepared statement testcase?
          • Is this solution too general, for example, would it be better to check lex->result is a select_to_file before calling cleanup()? On the flipside, is it possible to construct a testcase that leak for a lex->result that is not a select_to_file?
          ycp Yuchen Pei added a comment - - edited A draft patch which satisfies the CI: fb45030a567 upstream/bb-10.5-mdev-35326 MDEV-35326 Clean up lex->result after a failing select Some remaining questions: Does lex->result being non-NULL imply it is not a select_insert/select_create? see also commit 49bd559eb8f041de97e4ef55f280f3806d1b6c42 that introduced select_result::cleanup() Can we come up with a prepared statement testcase? Is this solution too general, for example, would it be better to check lex->result is a select_to_file before calling cleanup()? On the flipside, is it possible to construct a testcase that leak for a lex->result that is not a select_to_file?
          ycp Yuchen Pei added a comment -

          With prepared statement e.g.

          # ...
          prepare stmt1 from 'SELECT * FROM t INTO OUTFILE "foo.txt"';
          --error ER_CONNECT_TO_FOREIGN_DATA_SOURCE
          execute stmt1;
          # ...

          The cleanup happens in the destructor of Prepared_statement:

          Prepared_statement::~Prepared_statement()
          {
          //  [... 17 lines elided]
            if (lex)
            {
              sp_head::destroy(lex->sphead);
              delete lex->result;  // cleanup happens
              delete (st_lex_local *) lex;
            }
            free_root(&main_mem_root, MYF(0));
            DBUG_VOID_RETURN;
          }

           0 in end_io_cache of /home/ycp/source/mariadb-server/10.5/src/mysys/mf_iocache.c:1783
           1 in select_to_file::~select_to_file of /home/ycp/source/mariadb-server/10.5/src/sql/sql_class.cc:3229
           2 in select_export::~select_export of /home/ycp/source/mariadb-server/10.5/src/sql/sql_class.cc:3242
           3 in select_export::~select_export of /home/ycp/source/mariadb-server/10.5/src/sql/sql_class.cc:3242
           4 in Prepared_statement::~Prepared_statement of /home/ycp/source/mariadb-server/10.5/src/sql/sql_prepare.cc:4125
           5 in Prepared_statement::~Prepared_statement of /home/ycp/source/mariadb-server/10.5/src/sql/sql_prepare.cc:4130
           6 in delete_statement_as_hash_key of /home/ycp/source/mariadb-server/10.5/src/sql/sql_class.cc:4107
           7 in my_hash_free_elements of /home/ycp/source/mariadb-server/10.5/src/mysys/hash.c:135
           8 in my_hash_reset of /home/ycp/source/mariadb-server/10.5/src/mysys/hash.c:178
           9 in Statement_map::reset of /home/ycp/source/mariadb-server/10.5/src/sql/sql_class.cc:4242
          10 in THD::cleanup of /home/ycp/source/mariadb-server/10.5/src/sql/sql_class.cc:1592
          11 in unlink_thd of /home/ycp/source/mariadb-server/10.5/src/sql/mysqld.cc:2627
          12 in do_handle_one_connection of /home/ycp/source/mariadb-server/10.5/src/sql/sql_connect.cc:1397

          ycp Yuchen Pei added a comment - With prepared statement e.g. # ... prepare stmt1 from 'SELECT * FROM t INTO OUTFILE "foo.txt"' ; --error ER_CONNECT_TO_FOREIGN_DATA_SOURCE execute stmt1; # ... The cleanup happens in the destructor of Prepared_statement: Prepared_statement::~Prepared_statement() { // [... 17 lines elided] if (lex) { sp_head::destroy(lex->sphead); delete lex->result; // cleanup happens delete (st_lex_local *) lex; } free_root(&main_mem_root, MYF(0)); DBUG_VOID_RETURN; } 0 in end_io_cache of /home/ycp/source/mariadb-server/10.5/src/mysys/mf_iocache.c:1783 1 in select_to_file::~select_to_file of /home/ycp/source/mariadb-server/10.5/src/sql/sql_class.cc:3229 2 in select_export::~select_export of /home/ycp/source/mariadb-server/10.5/src/sql/sql_class.cc:3242 3 in select_export::~select_export of /home/ycp/source/mariadb-server/10.5/src/sql/sql_class.cc:3242 4 in Prepared_statement::~Prepared_statement of /home/ycp/source/mariadb-server/10.5/src/sql/sql_prepare.cc:4125 5 in Prepared_statement::~Prepared_statement of /home/ycp/source/mariadb-server/10.5/src/sql/sql_prepare.cc:4130 6 in delete_statement_as_hash_key of /home/ycp/source/mariadb-server/10.5/src/sql/sql_class.cc:4107 7 in my_hash_free_elements of /home/ycp/source/mariadb-server/10.5/src/mysys/hash.c:135 8 in my_hash_reset of /home/ycp/source/mariadb-server/10.5/src/mysys/hash.c:178 9 in Statement_map::reset of /home/ycp/source/mariadb-server/10.5/src/sql/sql_class.cc:4242 10 in THD::cleanup of /home/ycp/source/mariadb-server/10.5/src/sql/sql_class.cc:1592 11 in unlink_thd of /home/ycp/source/mariadb-server/10.5/src/sql/mysqld.cc:2627 12 in do_handle_one_connection of /home/ycp/source/mariadb-server/10.5/src/sql/sql_connect.cc:1397
          ycp Yuchen Pei added a comment -

          Hi sanja, ptal thanks

          3288b896551 upstream/bb-10.5-mdev-35326 MDEV-35326 Clean up lex->result after a failing exec of sp core function
          

          ycp Yuchen Pei added a comment - Hi sanja , ptal thanks 3288b896551 upstream/bb-10.5-mdev-35326 MDEV-35326 Clean up lex->result after a failing exec of sp core function

          It appeared problem of unorganised behaviour of result objects so I took and fixed it)

          sanja Oleksandr Byelkin added a comment - It appeared problem of unorganised behaviour of result objects so I took and fixed it)

          commit d47b1ebc06daa0716de04cd222b59f38d05ed75a (HEAD -> bb-10.5-MDEV-35326, origin/bb-10.5-MDEV-35326)
          Author: Oleksandr Byelkin <sanja@mariadb.com>
          Date:   Mon Dec 23 22:36:01 2024 +0100
           
              MDEV-35326: Memory Leak in init_io_cache_ext upon SHUTDOWN
           
              The problems were that:
              1) resources was freed "asimetric" normal execution in send_eof,
               in case of error in destructor.
              2) destructor was not called in case of SP for result objects.
              (so if the last SP execution ended with error resorces was not
              freeded on reinit before execution (cleanup() called before next
              execution) and destructor also was not called due to lack of
              delete call for the object)
           
              All result method revised and freeing resources made "symetric".
           
              Destructor of result object called for SP.
           
              Added skipped invalidation in case of error in insert.
           
              Removed misleading naming of reset(thd) (could be mixed with
              with reset())
          

          sanja Oleksandr Byelkin added a comment - commit d47b1ebc06daa0716de04cd222b59f38d05ed75a (HEAD -> bb-10.5-MDEV-35326, origin/bb-10.5-MDEV-35326) Author: Oleksandr Byelkin <sanja@mariadb.com> Date: Mon Dec 23 22:36:01 2024 +0100   MDEV-35326: Memory Leak in init_io_cache_ext upon SHUTDOWN   The problems were that: 1) resources was freed "asimetric" normal execution in send_eof, in case of error in destructor. 2) destructor was not called in case of SP for result objects. (so if the last SP execution ended with error resorces was not freeded on reinit before execution (cleanup() called before next execution) and destructor also was not called due to lack of delete call for the object)   All result method revised and freeing resources made "symetric".   Destructor of result object called for SP.   Added skipped invalidation in case of error in insert.   Removed misleading naming of reset(thd) (could be mixed with with reset())

          sanja, multi_update.diff is an example of how to extract the common code out of multi_update. Thoughts?

          serg Sergei Golubchik added a comment - sanja , multi_update.diff is an example of how to extract the common code out of multi_update. Thoughts?

          Yes the diff, looks very good.

          sanja Oleksandr Byelkin added a comment - Yes the diff, looks very good.

          ok to push, after implementing changes as in the review

          serg Sergei Golubchik added a comment - ok to push, after implementing changes as in the review

          People

            sanja Oleksandr Byelkin
            Roel Roel Van de Paar
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Git Integration

                Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.