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

Local connection (sql service) leaks the result set's MEM_ROOT when a statement fails after rows were sent. "Internal memory accounting error" at shutdown

    XMLWordPrintable

Details

    • Bug
    • Status: In Review (View Workflow)
    • Major
    • Resolution: Unresolved
    • 13.1.1
    • 13.3
    • Server
    • None

    Description

      Description

      When a statement run through mysql_real_connect_local() (the sql service used by plugins) fails after the result set metadata and some rows were produced, the half-built result set is never freed. The server then prints this at shutdown:

      Warning: Internal memory accounting error of 8192 bytes
      

      Cause

      • Protocol_local::begin_dataset() (sql/sql_prepare.cc) allocates a MYSQL_DATA with its own MEM_ROOT. The MEM_ROOT has an 8192-byte first block and holds the field definitions and rows.
      • If an error occurs mid-statement, net_send_error_packet() marks that same dataset with the error.
      • mysql_store_result() then fails in loc_read_rows(), which calls embedded_get_error().
      • embedded_get_error() frees the dataset with my_free(data) and never calls free_root(&data->alloc), so the MEM_ROOT blocks stay allocated.
      • The blocks are not thread-specific, so they are counted in global_memory_used and still outstanding at shutdown, which gives the 8192-byte warning.

      How to reproduce

      install plugin test_sql_service soname 'test_sql_service';
      CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY) ENGINE=InnoDB;
      INSERT INTO t1 VALUES (1),(2),(3);
      CREATE FUNCTION f1(i INT) RETURNS INT
      BEGIN
        IF i = 3 THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='row 3 fails'; END IF;
        RETURN i;
      END;
      set global test_sql_service_execute_sql_local= 'SELECT f1(id) FROM test.t1';
      

      plugins.test_sql_service_error_in_resultset [ pass ]     46
      ***Warnings generated in error logs during shutdown after running tests: plugins.test_sql_service_error_in_resultset
       
      Warning: Internal memory accounting error of 8192 bytes
      

      Possible fix

      diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
      index 19c608c3072..ebe01f0c8c5 100644
      --- a/sql/sql_prepare.cc
      +++ b/sql/sql_prepare.cc
      @@ -6574,7 +6574,11 @@ static void embedded_get_error(MYSQL *mysql, MYSQL_DATA *data)
         strmake_buf(net->last_error, ei->info);
         memcpy(net->sqlstate, ei->sqlstate, sizeof(net->sqlstate));
         mysql->server_status= ei->server_status;
      -  my_free(data);
      +  /*
      +    The dataset may have a MEM_ROOT with the fields and the rows sent before
      +    the error, so free_root() it too, not only the dataset itself.
      +  */
      +  free_rows(data);
       }
       
      
      

      Attachments

        Activity

          People

            holyfoot Alexey Botchkov
            valentyn.doroshchuk Val Doroshchuk
            Alexey Botchkov Alexey Botchkov
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:

              Git Integration

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