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

Server crash upon inserting into Mroonga table with compressed column

Details

    Description

      INSTALL SONAME 'ha_mroonga';
      CREATE TABLE t (a VARCHAR(128) COMPRESSED) ENGINE=Mroonga;
      INSERT INTO t VALUES (REPEAT('a',128));
       
      # Cleanup
      DROP TABLE t;
      UNINSTALL SONAME 'ha_mroonga';
      

      10.4 900c4d69

      #3  <signal handler called>
      #4  0x0000558da26e2597 in Binary_string::alloc (this=0x8, arg_length=128) at /data/src/11.1/sql/sql_string.h:790
      #5  0x0000558da329f81e in uncompress_zlib (to=0x0, from=0x61900009cecb "\200KL\034X", from_length=7, field_length=129) at /data/src/11.1/sql/field_comp.cc:110
      #6  0x0000558da326c916 in Field_longstr::uncompress (this=0x61900009d010, val_buffer=0x0, val_ptr=0x7f89f2d79c50, from=0x61900009ceca "\211\200KL\034X", from_length=8) at /data/src/11.1/sql/field.cc:8468
      #7  0x0000558da326cd9d in Field_varstring_compressed::val_str (this=0x61900009d010, val_buffer=0x0, val_ptr=0x7f89f2d79c50) at /data/src/11.1/sql/field.cc:8510
      #8  0x00007f89f161ba9a in ha_mroonga::generic_store_bulk_variable_size_string (this=0x622000037938, field=0x61900009d010, buf=0x7f89f2d7a880) at /data/src/11.1/storage/mroonga/ha_mroonga.cpp:10343
      #9  0x00007f89f1622965 in ha_mroonga::generic_store_bulk (this=0x622000037938, field=0x61900009d010, buf=0x7f89f2d7a880) at /data/src/11.1/storage/mroonga/ha_mroonga.cpp:10798
      #10 0x00007f89f15dd43a in ha_mroonga::storage_write_row (this=0x622000037938, buf=0x61900009cec8 "\376\b\211\200KL\034X") at /data/src/11.1/storage/mroonga/ha_mroonga.cpp:6111
      #11 0x00007f89f15e25b3 in ha_mroonga::write_row (this=0x622000037938, buf=0x61900009cec8 "\376\b\211\200KL\034X") at /data/src/11.1/storage/mroonga/ha_mroonga.cpp:6434
      #12 0x0000558da32ff74a in handler::ha_write_row (this=0x622000037938, buf=0x61900009cec8 "\376\b\211\200KL\034X") at /data/src/11.1/sql/handler.cc:7804
      #13 0x0000558da2907715 in write_record (thd=0x62b00007e218, table=0x61900009c998, info=0x7f89f2d7eb30, sink=0x0) at /data/src/11.1/sql/sql_insert.cc:2204
      #14 0x0000558da28fea47 in mysql_insert (thd=0x62b00007e218, table_list=0x6290000e6358, fields=..., values_list=..., update_fields=..., update_values=..., duplic=DUP_ERROR, ignore=false, result=0x0) at /data/src/11.1/sql/sql_insert.cc:1154
      #15 0x0000558da29c798f in mysql_execute_command (thd=0x62b00007e218, is_called_from_prepared_stmt=false) at /data/src/11.1/sql/sql_parse.cc:4449
      #16 0x0000558da29de717 in mysql_parse (thd=0x62b00007e218, rawbuf=0x6290000e6238 "INSERT INTO t VALUES (REPEAT('a',128))", length=38, parser_state=0x7f89f2d7f9f0) at /data/src/11.1/sql/sql_parse.cc:7774
      #17 0x0000558da29b6cba in dispatch_command (command=COM_QUERY, thd=0x62b00007e218, packet=0x629000258219 "INSERT INTO t VALUES (REPEAT('a',128))", packet_length=38, blocking=true) at /data/src/11.1/sql/sql_parse.cc:1892
      #18 0x0000558da29b39f7 in do_command (thd=0x62b00007e218, blocking=true) at /data/src/11.1/sql/sql_parse.cc:1405
      #19 0x0000558da2e74af0 in do_handle_one_connection (connect=0x608000002eb8, put_in_cache=true) at /data/src/11.1/sql/sql_connect.cc:1416
      #20 0x0000558da2e744b1 in handle_one_connection (arg=0x608000002e38) at /data/src/11.1/sql/sql_connect.cc:1318
      #21 0x0000558da3a707b2 in pfs_spawn_thread (arg=0x617000005b98) at /data/src/11.1/storage/perfschema/pfs.cc:2201
      #22 0x00007f89fa8a7fd4 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
      #23 0x00007f89fa9285bc in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
      

      Reproducible on all existing versions, debug- and non-debug builds with only slight differences in stack traces.

      Attachments

        Activity

          kou Kouhei Sutou added a comment -

          Does this work?

          diff --git a/storage/mroonga/ha_mroonga.cpp b/storage/mroonga/ha_mroonga.cpp
          index 85d6473ded3..5d4b1490397 100644
          --- a/storage/mroonga/ha_mroonga.cpp
          +++ b/storage/mroonga/ha_mroonga.cpp
          @@ -10339,8 +10339,9 @@ int ha_mroonga::generic_store_bulk_variable_size_string(Field *field,
           {
             MRN_DBUG_ENTER_METHOD();
             int error = 0;
          +  StringBuffer<MAX_FIELD_WIDTH> buffer(field->charset());
             String value;
          -  field->val_str(NULL, &value);
          +  field->val_str(&buffer, &value);
             grn_obj_reinit(ctx, buf, GRN_DB_SHORT_TEXT, 0);
             DBUG_PRINT("info", ("mroonga: length=%" MRN_FORMAT_STRING_LENGTH,
                                 value.length()));
          
          

          kou Kouhei Sutou added a comment - Does this work? diff --git a/storage/mroonga/ha_mroonga.cpp b/storage/mroonga/ha_mroonga.cpp index 85d6473ded3..5d4b1490397 100644 --- a/storage/mroonga/ha_mroonga.cpp +++ b/storage/mroonga/ha_mroonga.cpp @@ -10339,8 +10339,9 @@ int ha_mroonga::generic_store_bulk_variable_size_string(Field *field, { MRN_DBUG_ENTER_METHOD(); int error = 0; + StringBuffer<MAX_FIELD_WIDTH> buffer(field->charset()); String value; - field->val_str(NULL, &value); + field->val_str(&buffer, &value); grn_obj_reinit(ctx, buf, GRN_DB_SHORT_TEXT, 0); DBUG_PRINT("info", ("mroonga: length=%" MRN_FORMAT_STRING_LENGTH, value.length()));

          Thanks. That helped. Even better would be something like

          --- a/storage/mroonga/ha_mroonga.cpp
          +++ b/storage/mroonga/ha_mroonga.cpp
          @@ -10366,13 +10366,13 @@ int ha_mroonga::generic_store_bulk_variable_size_string(Field *field,
           {
             MRN_DBUG_ENTER_METHOD();
             int error = 0;
          -  String value;
          -  field->val_str(NULL, &value);
          +  StringBuffer<MAX_FIELD_WIDTH> buffer(field->charset());
          +  String *value= field->val_str(&buffer, &buffer);
             grn_obj_reinit(ctx, buf, GRN_DB_SHORT_TEXT, 0);
             DBUG_PRINT("info", ("mroonga: length=%" MRN_FORMAT_STRING_LENGTH,
          -                      value.length()));
          -  DBUG_PRINT("info", ("mroonga: value=%s", value.c_ptr_safe()));
          -  GRN_TEXT_SET(ctx, buf, value.ptr(), value.length());
          +                      value->length()));
          +  DBUG_PRINT("info", ("mroonga: value=%s", value->c_ptr_safe()));
          +  GRN_TEXT_SET(ctx, buf, value->ptr(), value->length());
             DBUG_RETURN(error);
           }
          

          because technically field->val_str() is not required to return any of its arguments.

          Do you want me to apply this fix to Mroonga in MariaDB 10.4 or you do prefer to fix upstream and let us pull the fixed Mroonga before the next release (which will be around the end of October)?

          serg Sergei Golubchik added a comment - Thanks. That helped. Even better would be something like --- a/storage/mroonga/ha_mroonga.cpp +++ b/storage/mroonga/ha_mroonga.cpp @@ -10366,13 +10366,13 @@ int ha_mroonga::generic_store_bulk_variable_size_string(Field *field, { MRN_DBUG_ENTER_METHOD(); int error = 0; - String value; - field->val_str(NULL, &value); + StringBuffer<MAX_FIELD_WIDTH> buffer(field->charset()); + String *value= field->val_str(&buffer, &buffer); grn_obj_reinit(ctx, buf, GRN_DB_SHORT_TEXT, 0); DBUG_PRINT("info", ("mroonga: length=%" MRN_FORMAT_STRING_LENGTH, - value.length())); - DBUG_PRINT("info", ("mroonga: value=%s", value.c_ptr_safe())); - GRN_TEXT_SET(ctx, buf, value.ptr(), value.length()); + value->length())); + DBUG_PRINT("info", ("mroonga: value=%s", value->c_ptr_safe())); + GRN_TEXT_SET(ctx, buf, value->ptr(), value->length()); DBUG_RETURN(error); } because technically field->val_str() is not required to return any of its arguments. Do you want me to apply this fix to Mroonga in MariaDB 10.4 or you do prefer to fix upstream and let us pull the fixed Mroonga before the next release (which will be around the end of October)?
          kou Kouhei Sutou added a comment -

          Thanks.

          Could you apply the fix to Mroonga in MariaDB?
          I'll apply the same fix to upstream Mroonga but I can't send a pull request to merge upstream Mroonga to MariaDB by the next release.

          kou Kouhei Sutou added a comment - Thanks. Could you apply the fix to Mroonga in MariaDB? I'll apply the same fix to upstream Mroonga but I can't send a pull request to merge upstream Mroonga to MariaDB by the next release.
          kou Kouhei Sutou added a comment -

          We have a similar problem for TEXT COMPRESSED too. Could you also apply this?

          diff --git a/storage/mroonga/ha_mroonga.cpp b/storage/mroonga/ha_mroonga.cpp
          index 85d6473ded3..ffdad4037ff 100644
          --- a/storage/mroonga/ha_mroonga.cpp
          +++ b/storage/mroonga/ha_mroonga.cpp
          @@ -10712,9 +10712,8 @@ int ha_mroonga::generic_store_bulk_blob(Field *field, grn_obj *buf)
           {
             MRN_DBUG_ENTER_METHOD();
             int error = 0;
          -  String buffer;
          -  Field_blob *blob = (Field_blob *)field;
          -  String *value = blob->val_str(0, &buffer);
          +  StringBuffer<MAX_FIELD_WIDTH> buffer(field->charset());
          +  auto value = field->val_str(&buffer, &buffer);
             grn_obj_reinit(ctx, buf, GRN_DB_TEXT, 0);
             GRN_TEXT_SET(ctx, buf, value->ptr(), value->length());
             DBUG_RETURN(error);
          

          kou Kouhei Sutou added a comment - We have a similar problem for TEXT COMPRESSED too. Could you also apply this? diff --git a/storage/mroonga/ha_mroonga.cpp b/storage/mroonga/ha_mroonga.cpp index 85d6473ded3..ffdad4037ff 100644 --- a/storage/mroonga/ha_mroonga.cpp +++ b/storage/mroonga/ha_mroonga.cpp @@ -10712,9 +10712,8 @@ int ha_mroonga::generic_store_bulk_blob(Field *field, grn_obj *buf) { MRN_DBUG_ENTER_METHOD(); int error = 0; - String buffer; - Field_blob *blob = (Field_blob *)field; - String *value = blob->val_str(0, &buffer); + StringBuffer<MAX_FIELD_WIDTH> buffer(field->charset()); + auto value = field->val_str(&buffer, &buffer); grn_obj_reinit(ctx, buf, GRN_DB_TEXT, 0); GRN_TEXT_SET(ctx, buf, value->ptr(), value->length()); DBUG_RETURN(error);

          People

            serg Sergei Golubchik
            elenst Elena Stepanova
            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.