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

ASAN: heap-buffer-overflow & stack-buffer-overflow in spider_db_mbase_row::append_to_str | SIGSEGV's in __memmove_avx_unaligned_erms from memcpy in Binary_string::q_append, in Static_binary_string::q_append and my_strntoull10rnd_8bit | Unknown error 12801

Details

    Description

      SET sql_mode='';
      INSTALL PLUGIN Spider SONAME 'ha_spider.so';
      CREATE USER Spider@localhost IDENTIFIED BY 'PWD0';
      CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET '../socket.sock',DATABASE 'test',user 'Spider',PASSWORD 'PWD0');
      CREATE TABLE t (a INT) ENGINE=InnoDB;
      CREATE TABLE t1 (a INT) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"';
      INSERT INTO t1 VALUES (1);
      DROP TABLE IF EXISTS t1;
      CREATE TABLE t1 (a INT KEY) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"';
      SELECT MAX(a),MAX(COALESCE(a)) FROM t1;
      

      Leads to:

      10.11.0 bc563f1a4b0b38de3b41fd0f0d3d8b7f1aacbd8b (Debug)

      Core was generated by `/test/MD190822-mariadb-10.11.0-linux-x86_64-dbg/bin/mysqld --no-defaults --core'.
      Program terminated with signal SIGSEGV, Segmentation fault.
      #0  __memmove_avx_unaligned_erms ()
          at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:383
      [Current thread is 1 (Thread 0x14b750085700 (LWP 4075535))]
      (gdb) bt
      #0  __memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:383
      #1  0x000014b73c159ce3 in memcpy (__len=360330344, __src=0xa5a5a5a5a5a50031, __dest=<optimized out>) at /usr/include/x86_64-linux-gnu/bits/string_fortified.h:34
      #2  Binary_string::q_append (data_len=360330344, data=0xa5a5a5a5a5a50031 <error: Cannot access memory at address 0xa5a5a5a5a5a50031>, this=<optimized out>) at /test/10.11_dbg/sql/sql_string.h:371
      #3  spider_string::q_append (this=this@entry=0x14b750082e90, data=0xa5a5a5a5a5a50031 <error: Cannot access memory at address 0xa5a5a5a5a5a50031>, data_len=360330344) at /test/10.11_dbg/storage/spider/spd_malloc.cc:1112
      #4  0x000014b73c17e760 in spider_db_mbase_row::append_to_str (this=0x14b6c802f730, str=0x14b750082e90) at /test/10.11_dbg/storage/spider/spd_db_mysql.cc:443
      #5  0x000014b73c0f59bd in spider_db_fetch_for_item_sum_func (row=row@entry=0x14b6c802f730, item_sum=0x14b6c80145e0, spider=spider@entry=0x14b6c80a7830) at /test/10.11_dbg/storage/spider/spd_db_conn.cc:2213
      #6  0x000014b73c0f5b1a in spider_db_fetch_for_item_sum_funcs (row=0x14b6c802f730, spider=spider@entry=0x14b6c80a7830) at /test/10.11_dbg/storage/spider/spd_db_conn.cc:2100
      #7  0x000014b73c0f63ce in spider_db_fetch_table (spider=spider@entry=0x14b6c80a7830, buf=buf@entry=0x14b6c80f8cb0 "\377", table=0x14b6c80f7c20, result_list=0x14b6c80a7db0) at /test/10.11_dbg/storage/spider/spd_db_conn.cc:2441
      #8  0x000014b73c0fcc06 in spider_db_fetch (buf=buf@entry=0x14b6c80f8cb0 "\377", spider=0x14b6c80a7830, table=table@entry=0x14b6c80f7c20) at /test/10.11_dbg/storage/spider/spd_db_conn.cc:3940
      #9  0x000014b73c0fe93c in spider_db_seek_next (buf=0x14b6c80f8cb0 "\377", spider=0x14b6c80a7830, link_idx=0, table=0x14b6c80f7c20) at /test/10.11_dbg/storage/spider/spd_db_conn.cc:4419
      #10 0x000014b73c1b3b7e in spider_group_by_handler::next_row (this=0x14b6c8096f40) at /test/10.11_dbg/storage/spider/spd_group_by_handler.cc:1575
      #11 0x0000563a9f5976c8 in Pushdown_query::execute (this=0x14b6c8017770, join=join@entry=0x14b6c80158c8) at /test/10.11_dbg/sql/group_by_handler.cc:64
      #12 0x0000563a9f56a399 in do_select (procedure=<optimized out>, join=0x14b6c80158c8) at /test/10.11_dbg/sql/sql_select.cc:21206
      #13 JOIN::exec_inner (this=this@entry=0x14b6c80158c8) at /test/10.11_dbg/sql/sql_select.cc:4812
      #14 0x0000563a9f56ae28 in JOIN::exec (this=this@entry=0x14b6c80158c8) at /test/10.11_dbg/sql/sql_select.cc:4590
      #15 0x0000563a9f568bac in mysql_select (thd=thd@entry=0x14b6c8000db8, tables=0x14b6c80147a0, fields=@0x14b6c8013f88: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x14b6c80143c0, last = 0x14b6c8014720, elements = 2}, <No data fields>}, conds=0x0, og_num=0, order=0x0, group=0x0, having=0x0, proc_param=0x0, select_options=2164525824, result=0x14b6c80158a0, unit=0x14b6c8004ff0, select_lex=0x14b6c8013ce8) at /test/10.11_dbg/sql/sql_select.cc:5070
      #16 0x0000563a9f5693a2 in handle_select (thd=thd@entry=0x14b6c8000db8, lex=lex@entry=0x14b6c8004f18, result=result@entry=0x14b6c80158a0, setup_tables_done_option=setup_tables_done_option@entry=0) at /test/10.11_dbg/sql/sql_select.cc:581
      #17 0x0000563a9f4d35a6 in execute_sqlcom_select (thd=thd@entry=0x14b6c8000db8, all_tables=0x14b6c80147a0) at /test/10.11_dbg/sql/sql_parse.cc:6261
      #18 0x0000563a9f4df8c7 in mysql_execute_command (thd=thd@entry=0x14b6c8000db8, is_called_from_prepared_stmt=is_called_from_prepared_stmt@entry=false) at /test/10.11_dbg/sql/sql_parse.cc:3945
      #19 0x0000563a9f4cd882 in mysql_parse (thd=thd@entry=0x14b6c8000db8, rawbuf=<optimized out>, length=<optimized out>, parser_state=parser_state@entry=0x14b750084330) at /test/10.11_dbg/sql/sql_parse.cc:8035
      #20 0x0000563a9f4dae6a in dispatch_command (command=command@entry=COM_QUERY, thd=thd@entry=0x14b6c8000db8, packet=packet@entry=0x14b6c800b6e9 "", packet_length=packet_length@entry=38, blocking=blocking@entry=true) at /test/10.11_dbg/sql/sql_class.h:1339
      #21 0x0000563a9f4dd574 in do_command (thd=0x14b6c8000db8, blocking=blocking@entry=true) at /test/10.11_dbg/sql/sql_parse.cc:1407
      #22 0x0000563a9f63f1da in do_handle_one_connection (connect=<optimized out>, connect@entry=0x563aa2b2af18, put_in_cache=put_in_cache@entry=true) at /test/10.11_dbg/sql/sql_connect.cc:1418
      #23 0x0000563a9f63f6e3 in handle_one_connection (arg=0x563aa2b2af18) at /test/10.11_dbg/sql/sql_connect.cc:1312
      #24 0x000014b768cec609 in start_thread (arg=<optimized out>) at pthread_create.c:477
      #25 0x000014b7688d8133 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
      

      10.11.0 bc563f1a4b0b38de3b41fd0f0d3d8b7f1aacbd8b (Optimized)

      Core was generated by `/test/MD190822-mariadb-10.11.0-linux-x86_64-opt/bin/mysqld --no-defaults --core'.
      Program terminated with signal SIGSEGV, Segmentation fault.
      #0  0x0000557d0b4b803c in my_strntoull10rnd_8bit (cs=<optimized out>, 
          str=0x1 <error: Cannot access memory at address 0x1>, 
          length=<optimized out>, unsigned_flag=0, endptr=0x15218ca5d398, 
          error=0x15218ca5d394) at /test/10.11_opt/strings/ctype-simple.c:1644
      [Current thread is 1 (Thread 0x15218ca5f700 (LWP 4075354))]
      (gdb) bt
      #0  0x0000557d0b4b803c in my_strntoull10rnd_8bit (cs=<optimized out>, str=0x1 <error: Cannot access memory at address 0x1>, length=<optimized out>, unsigned_flag=0, endptr=0x15218ca5d398, error=0x15218ca5d394) at /test/10.11_opt/strings/ctype-simple.c:1644
      #1  0x0000557d0afd3608 in charset_info_st::strntoull10rnd (error=0x15218ca5d394, endptr=0x15218ca5d398, unsigned_fl=<optimized out>, length=965, str=0x1 <error: Cannot access memory at address 0x1>, this=0x557d0be6dd60 <my_charset_latin1>) at /test/10.11_opt/include/m_ctype.h:910
      #2  Field_longlong::store (this=0x152148063dd0, from=0x1 <error: Cannot access memory at address 0x1>, len=965, cs=0x557d0be6dd60 <my_charset_latin1>) at /test/10.11_opt/sql/field.cc:4561
      #3  0x000015218c9c0aaf in spider_db_mbase_row::store_to_field (access_charset=0x557d0be6dd60 <my_charset_latin1>, field=0x152148063dd0, this=0x152148082100) at /test/10.11_opt/storage/spider/spd_db_mysql.cc:431
      #4  spider_db_mbase_row::store_to_field (this=0x152148082100, field=0x152148063dd0, access_charset=0x557d0be6dd60 <my_charset_latin1>) at /test/10.11_opt/storage/spider/spd_db_mysql.cc:395
      #5  0x000015218c95cc0c in spider_db_fetch_row (share=share@entry=0x1521480646a8, field=0x152148063dd0, row=0x152148082100, ptr_diff=ptr_diff@entry=0) at /test/10.11_opt/storage/spider/spd_db_conn.cc:2364
      #6  0x000015218c95cd56 in spider_db_fetch_table (spider=spider@entry=0x1521480281f0, buf=<optimized out>, table=0x152148062f90, result_list=result_list@entry=0x152148028770) at /test/10.11_opt/storage/spider/spd_db_conn.cc:2467
      #7  0x000015218c9608a5 in spider_db_fetch (buf=<optimized out>, spider=0x1521480281f0, table=<optimized out>) at /test/10.11_opt/storage/spider/spd_db_conn.cc:3940
      #8  0x000015218c960ba9 in spider_db_seek_next (buf=0x1521480281f0 "(e\240\214!\025", spider=<optimized out>, link_idx=<optimized out>, table=0x1521480123a8) at /test/10.11_opt/storage/spider/spd_db_conn.cc:4419
      #9  0x000015218c9dcdb3 in spider_group_by_handler::next_row (this=0x557d0cf87760) at /test/10.11_opt/storage/spider/spd_group_by_handler.cc:1575
      #10 spider_group_by_handler::next_row (this=0x557d0cf87760) at /test/10.11_opt/storage/spider/spd_group_by_handler.cc:1508
      #11 0x0000557d0ae336ca in Pushdown_query::execute (this=0x152148014140, join=join@entry=0x1521480123a8) at /test/10.11_opt/sql/group_by_handler.cc:64
      #12 0x0000557d0ae155d5 in do_select (procedure=<optimized out>, join=0x1521480123a8) at /test/10.11_opt/sql/sql_select.cc:21206
      #13 JOIN::exec_inner (this=0x1521480123a8) at /test/10.11_opt/sql/sql_select.cc:4812
      #14 0x0000557d0ae15f68 in JOIN::exec (this=this@entry=0x1521480123a8) at /test/10.11_opt/sql/sql_select.cc:4590
      #15 0x0000557d0ae14171 in mysql_select (thd=0x152148000c58, tables=0x152148011280, fields=@0x152148010a68: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x152148010ea0, last = 0x152148011200, elements = 2}, <No data fields>}, conds=0x0, og_num=0, order=0x0, group=0x0, having=0x0, proc_param=0x0, select_options=<optimized out>, result=0x152148012380, unit=0x152148004cd0, select_lex=0x1521480107c8) at /test/10.11_opt/sql/sql_select.cc:5070
      #16 0x0000557d0ae148b7 in handle_select (thd=thd@entry=0x152148000c58, lex=lex@entry=0x152148004bf8, result=result@entry=0x152148012380, setup_tables_done_option=setup_tables_done_option@entry=0) at /test/10.11_opt/sql/sql_select.cc:581
      #17 0x0000557d0ad965b1 in execute_sqlcom_select (thd=0x152148000c58, all_tables=0x152148011280) at /test/10.11_opt/sql/sql_parse.cc:6261
      #18 0x0000557d0ada41f8 in mysql_execute_command (thd=0x152148000c58, is_called_from_prepared_stmt=<optimized out>) at /test/10.11_opt/sql/sql_parse.cc:3945
      #19 0x0000557d0ad917b5 in mysql_parse (rawbuf=<optimized out>, length=<optimized out>, parser_state=<optimized out>, thd=0x152148000c58) at /test/10.11_opt/sql/sql_parse.cc:8035
      #20 mysql_parse (thd=0x152148000c58, rawbuf=<optimized out>, length=<optimized out>, parser_state=<optimized out>) at /test/10.11_opt/sql/sql_parse.cc:7957
      #21 0x0000557d0ad9d2ca in dispatch_command (command=COM_QUERY, thd=0x152148000c58, packet=<optimized out>, packet_length=<optimized out>, blocking=<optimized out>) at /test/10.11_opt/sql/sql_class.h:1339
      #22 0x0000557d0ad9f1f2 in do_command (thd=0x152148000c58, blocking=blocking@entry=true) at /test/10.11_opt/sql/sql_parse.cc:1407
      #23 0x0000557d0aeb746f in do_handle_one_connection (connect=<optimized out>, connect@entry=0x557d0d26f118, put_in_cache=put_in_cache@entry=true) at /test/10.11_opt/sql/sql_connect.cc:1418
      #24 0x0000557d0aeb774d in handle_one_connection (arg=0x557d0d26f118) at /test/10.11_opt/sql/sql_connect.cc:1312
      #25 0x00001521a5ea1609 in start_thread (arg=<optimized out>) at pthread_create.c:477
      #26 0x00001521a5a8d133 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
      

      10.5.18 5fc172fd43375b392a8c8adfb9038c279e578d83 (Debug)

      Core was generated by `/test/MD200822-mariadb-10.5.18-linux-x86_64-dbg/bin/mysqld --no-defaults --core'.
      Program terminated with signal SIGSEGV, Segmentation fault.
      #0  __memmove_avx_unaligned_erms ()
          at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:383
      [Current thread is 1 (Thread 0x14b3eedab700 (LWP 4076735))]
      (gdb) bt
      #0  __memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:383
      #1  0x000014b3eecb67eb in memcpy (__len=360330344, __src=0xa5a5a5a5a5a50031, __dest=<optimized out>) at /usr/include/x86_64-linux-gnu/bits/string_fortified.h:34
      #2  Static_binary_string::q_append (data_len=360330344, data=0xa5a5a5a5a5a50031 <error: Cannot access memory at address 0xa5a5a5a5a5a50031>, this=0x14b3eeda9210) at /test/10.5_dbg/sql/sql_string.h:318
      #3  spider_string::q_append (this=this@entry=0x14b3eeda9200, data=0xa5a5a5a5a5a50031 <error: Cannot access memory at address 0xa5a5a5a5a5a50031>, data_len=360330344) at /test/10.5_dbg/storage/spider/spd_malloc.cc:1132
      #4  0x000014b3eecdc076 in spider_db_mbase_row::append_to_str (this=0x14b38002c400, str=0x14b3eeda9200) at /test/10.5_dbg/storage/spider/spd_db_mysql.cc:454
      #5  0x000014b3eec52c0e in spider_db_fetch_for_item_sum_func (row=row@entry=0x14b38002c400, item_sum=0x14b380014540, spider=spider@entry=0x14b380094120) at /test/10.5_dbg/storage/spider/spd_db_conn.cc:2934
      #6  0x000014b3eec52d6b in spider_db_fetch_for_item_sum_funcs (row=0x14b38002c400, spider=spider@entry=0x14b380094120) at /test/10.5_dbg/storage/spider/spd_db_conn.cc:2803
      #7  0x000014b3eec536a4 in spider_db_fetch_table (spider=spider@entry=0x14b380094120, buf=buf@entry=0x14b3800f0808 "\377", table=0x14b3800ef750, result_list=0x14b3800946b0) at /test/10.5_dbg/storage/spider/spd_db_conn.cc:3213
      #8  0x000014b3eec59eee in spider_db_fetch (buf=buf@entry=0x14b3800f0808 "\377", spider=0x14b380094120, table=table@entry=0x14b3800ef750) at /test/10.5_dbg/storage/spider/spd_db_conn.cc:4987
      #9  0x000014b3eec5bcf0 in spider_db_seek_next (buf=0x14b3800f0808 "\377", spider=0x14b380094120, link_idx=0, table=0x14b3800ef750) at /test/10.5_dbg/storage/spider/spd_db_conn.cc:5505
      #10 0x000014b3eed12846 in spider_group_by_handler::next_row (this=0x14b3800c9730) at /test/10.5_dbg/storage/spider/spd_group_by_handler.cc:1597
      #11 0x000055fdee925244 in Pushdown_query::execute (this=0x14b3800180a0, join=join@entry=0x14b380015868) at /test/10.5_dbg/sql/group_by_handler.cc:64
      #12 0x000055fdee8fa3cf in do_select (procedure=<optimized out>, join=0x14b380015868) at /test/10.5_dbg/sql/sql_select.cc:20396
      #13 JOIN::exec_inner (this=this@entry=0x14b380015868) at /test/10.5_dbg/sql/sql_select.cc:4560
      #14 0x000055fdee8fad98 in JOIN::exec (this=this@entry=0x14b380015868) at /test/10.5_dbg/sql/sql_select.cc:4340
      #15 0x000055fdee8f89fc in mysql_select (thd=thd@entry=0x14b380000db8, tables=0x14b380014720, fields=@0x14b380013cf8: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x14b3800142d8, last = 0x14b3800146a0, elements = 2}, <No data fields>}, conds=0x0, og_num=0, order=0x0, group=0x0, having=0x0, proc_param=0x0, select_options=2147748608, result=0x14b380015840, unit=0x14b380004d60, select_lex=0x14b380013ba8) at /test/10.5_dbg/sql/sql_select.cc:4817
      #16 0x000055fdee8f94ec in handle_select (thd=thd@entry=0x14b380000db8, lex=lex@entry=0x14b380004c98, result=result@entry=0x14b380015840, setup_tables_done_option=setup_tables_done_option@entry=0) at /test/10.5_dbg/sql/sql_select.cc:444
      #17 0x000055fdee877584 in execute_sqlcom_select (thd=thd@entry=0x14b380000db8, all_tables=0x14b380014720) at /test/10.5_dbg/sql/sql_parse.cc:6315
      #18 0x000055fdee88401b in mysql_execute_command (thd=thd@entry=0x14b380000db8) at /test/10.5_dbg/sql/sql_parse.cc:4006
      #19 0x000055fdee8713c0 in mysql_parse (thd=thd@entry=0x14b380000db8, rawbuf=<optimized out>, length=<optimized out>, parser_state=parser_state@entry=0x14b3eedaa340, is_com_multi=is_com_multi@entry=false, is_next_command=is_next_command@entry=false) at /test/10.5_dbg/sql/sql_parse.cc:8101
      #20 0x000055fdee87f39a in dispatch_command (command=command@entry=COM_QUERY, thd=thd@entry=0x14b380000db8, packet=packet@entry=0x14b38000b2b9 "", packet_length=packet_length@entry=38, is_com_multi=is_com_multi@entry=false, is_next_command=is_next_command@entry=false) at /test/10.5_dbg/sql/sql_class.h:1290
      #21 0x000055fdee881eb6 in do_command (thd=0x14b380000db8) at /test/10.5_dbg/sql/sql_parse.cc:1375
      #22 0x000055fdee9c2133 in do_handle_one_connection (connect=<optimized out>, connect@entry=0x55fdf18f9ef8, put_in_cache=put_in_cache@entry=true) at /test/10.5_dbg/sql/sql_connect.cc:1418
      #23 0x000055fdee9c263b in handle_one_connection (arg=0x55fdf18f9ef8) at /test/10.5_dbg/sql/sql_connect.cc:1312
      #24 0x000014b40d2ab609 in start_thread (arg=<optimized out>) at pthread_create.c:477
      #25 0x000014b40ce97133 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
      

      Bug confirmed present in:
      MariaDB: 10.5.18 (dbg), 10.5.18 (opt), 10.6.10 (dbg), 10.6.10 (opt), 10.7.6 (dbg), 10.7.6 (opt), 10.8.5 (dbg), 10.8.5 (opt), 10.9.2 (dbg), 10.9.2 (opt), 10.10.2 (dbg), 10.10.2 (opt), 10.11.0 (dbg), 10.11.0 (opt)

      Bug (or feature/syntax) confirmed not present in:
      MariaDB: 10.4.27 (dbg), 10.4.27 (opt)

      Attachments

        Issue Links

          Activity

            ycp Yuchen Pei added a comment - - edited

            So as of commit 8d1c68d51b1cf739539e2ce401435e36bd1f29f0, the test
            spider.direct_aggregate_part does exercise
            Item_sum_count::direct_add() with a COUNT query, with
            partitioned table of two data nodes. one containing 3 rows, the other
            2 rows, so the count result is 5.

            How it works:

            • no DA:
              • query all rows with select `a` from `auto_test_remote`.`ta_r2` order by `a`", same query for the other table ta_r3
              • then iterate over rows when incrementing count
            • with DA:
              • query for count in each table select count(0),min(`a`) from `auto_test_remote`.`ta_r2`, same query sent to ta_r3
              • then add up the count
              • the min(`a`) looks unnecessary. consider removing
            • the relevant code that happens in sub_select():

              if (rc != NESTED_LOOP_NO_MORE_ROWS)
                {
                  // First read. This is where spider sends queries to data nodes
                  // This is where the Item_sum_count::direct_add() was called
                  error= (*join_tab->read_first_record)(join_tab);
                  ...
                  // First update of count result from the first spider query result.
                  // 1 without DA, and 3 with DA
                  rc= evaluate_join_record(join, join_tab, error);
                }
               
                ...
               
                while (rc == NESTED_LOOP_OK && join->return_tab >= join_tab)
                {
                  ...
                  // Continues reading spider result list
                  // This is also where the Item_sum_count::direct_add() was called
                  error= info->read_record();
               
                  ...
                  // Continues updating count result. slow incrementing to 5 without
                  // DA, and one off incrementing by 2 to 5 with DA
                  rc= evaluate_join_record(join, join_tab, error);
                }

            Item_sum_count::direct_add > spider_db_fetch_for_item_sum_func > spider_db_fetch_for_item_sum_funcs > spider_db_refetch_for_item_sum_funcs > ha_spider::return_record_by_parent > ha_partition::return_top_record > ha_partition::handle_ordered_index_scan > ha_partition::common_first_last > ha_partition::index_first > handler::ha_index_first > join_read_first > sub_select > do_select > JOIN::exec_inner > JOIN::exec > mysql_select > handle_select > execute_sqlcom_select > mysql_execute_command > mysql_parse > dispatch_command > do_command > do_handle_one_connection > handle_one_connection > pfs_spawn_thread

            ycp Yuchen Pei added a comment - - edited So as of commit 8d1c68d51b1cf739539e2ce401435e36bd1f29f0, the test spider.direct_aggregate_part does exercise Item_sum_count::direct_add() with a COUNT query, with partitioned table of two data nodes. one containing 3 rows, the other 2 rows, so the count result is 5. How it works: no DA: query all rows with select `a` from `auto_test_remote`.`ta_r2` order by `a`", same query for the other table ta_r3 then iterate over rows when incrementing count with DA: query for count in each table select count(0),min(`a`) from `auto_test_remote`.`ta_r2` , same query sent to ta_r3 then add up the count the min(`a`) looks unnecessary. consider removing the relevant code that happens in sub_select() : if (rc != NESTED_LOOP_NO_MORE_ROWS) { // First read. This is where spider sends queries to data nodes // This is where the Item_sum_count::direct_add() was called error= (*join_tab->read_first_record)(join_tab); ... // First update of count result from the first spider query result. // 1 without DA, and 3 with DA rc= evaluate_join_record(join, join_tab, error); }   ...   while (rc == NESTED_LOOP_OK && join->return_tab >= join_tab) { ... // Continues reading spider result list // This is also where the Item_sum_count::direct_add() was called error= info->read_record();   ... // Continues updating count result. slow incrementing to 5 without // DA, and one off incrementing by 2 to 5 with DA rc= evaluate_join_record(join, join_tab, error); } Item_sum_count::direct_add > spider_db_fetch_for_item_sum_func > spider_db_fetch_for_item_sum_funcs > spider_db_refetch_for_item_sum_funcs > ha_spider::return_record_by_parent > ha_partition::return_top_record > ha_partition::handle_ordered_index_scan > ha_partition::common_first_last > ha_partition::index_first > handler::ha_index_first > join_read_first > sub_select > do_select > JOIN::exec_inner > JOIN::exec > mysql_select > handle_select > execute_sqlcom_select > mysql_execute_command > mysql_parse > dispatch_command > do_command > do_handle_one_connection > handle_one_connection > pfs_spawn_thread
            ycp Yuchen Pei added a comment -

            I am going to make some hypothesis based on observations.

            The direct aggregate mechanism is only intended to work when otherwise
            a full table scan query will be executed from the spider node and the
            aggregation done at the spider node too. Typically this happens in
            sub_select() as in the previous comment. In the test
            spider.direct_aggregate_part direct aggregate allows to
            send COUNT statements directly to the data nodes and adds up the
            results at the spider node, instead of iterating over the rows one by
            one at the spider node.

            By contrast, the group by handler (GBH) typically sends aggregated queries
            directly to data nodes, in which case DA does not improve the
            situation here.

            That is why we should fix it by disabling DA when GBH is used.

            There are other reasons supporting this change. First, the creation of
            GBH results in a call to change_to_use_tmp_fields() (as opposed to
            setup_copy_fields()) which causes the spider DA function
            spider_db_fetch_for_item_sum_funcs() to work on wrong items.
            Second, the spider DA function only calls direct_add() on the
            items, and the follow-up add() needs to be called by the sql layer
            code. In do_select(), after executing the query with the GBH, it
            seems that the required add() would not necessarily be called.

            Disabling DA when GBH is used does fix the bug[1]. There are a few
            other things that would be good to be done for this ticket:

            1. Add a session variable that allows user to disable DA completely,
            this will help as a temporary measure when further bugs with DA
            emerge.
            2. Move the increment of direct_aggregate_count to the spider DA
            function. Currently this is done in rather bizarre and random
            locations.
            3. Fix the spider_db_mbase_row creation so that the last of its row
            field (sentinel) is NULL. The code is already doing a null check,
            but somehow the sentinel field is on an invalid address, causing
            the segfaults. With a correct implementation of the row creation,
            we can avoid such segfaults.

            [1] https://github.com/MariaDB/server/commit/2de2215cda8

            ycp Yuchen Pei added a comment - I am going to make some hypothesis based on observations. The direct aggregate mechanism is only intended to work when otherwise a full table scan query will be executed from the spider node and the aggregation done at the spider node too. Typically this happens in sub_select() as in the previous comment. In the test spider.direct_aggregate_part direct aggregate allows to send COUNT statements directly to the data nodes and adds up the results at the spider node, instead of iterating over the rows one by one at the spider node. By contrast, the group by handler (GBH) typically sends aggregated queries directly to data nodes, in which case DA does not improve the situation here. That is why we should fix it by disabling DA when GBH is used. There are other reasons supporting this change. First, the creation of GBH results in a call to change_to_use_tmp_fields() (as opposed to setup_copy_fields() ) which causes the spider DA function spider_db_fetch_for_item_sum_funcs() to work on wrong items. Second, the spider DA function only calls direct_add() on the items, and the follow-up add() needs to be called by the sql layer code. In do_select() , after executing the query with the GBH, it seems that the required add() would not necessarily be called. Disabling DA when GBH is used does fix the bug [1] . There are a few other things that would be good to be done for this ticket: 1. Add a session variable that allows user to disable DA completely, this will help as a temporary measure when further bugs with DA emerge. 2. Move the increment of direct_aggregate_count to the spider DA function. Currently this is done in rather bizarre and random locations. 3. Fix the spider_db_mbase_row creation so that the last of its row field (sentinel) is NULL. The code is already doing a null check, but somehow the sentinel field is on an invalid address, causing the segfaults. With a correct implementation of the row creation, we can avoid such segfaults. [1] https://github.com/MariaDB/server/commit/2de2215cda8
            ycp Yuchen Pei added a comment - - edited

            Hi holyfoot, ptal thanks (based on 11.0):

            As usual, I have a corresponding set of changes for the minimum fixversion 10.5:

            Update on [2023-07-26 Wed]: holyfoot I'm not sure whether you
            have looked at these commits yet. In the past few days I've been
            thinking about the changes in the first cleanup commit, about
            spider_conn_before_query() and spider_conn_after_query(). I
            don't think in its current form this clean up gives us much gain,
            and we should either defer this cleanup to a separate task, or
            (better yet) have a discussion on it. In any case, feel free to
            disregard the first commit, and review the second and third only.

            ycp Yuchen Pei added a comment - - edited Hi holyfoot , ptal thanks (based on 11.0): https://github.com/MariaDB/server/commit/3b5cecbacd46ea8607b4e5379633e60a98d71bc5 (cleanup, no change of logic) https://github.com/MariaDB/server/commit/bb7646e7fd6a7256d874b9ab458dcba8b716608f (cleanup, no change of logic) https://github.com/MariaDB/server/commit/4e374f3003bc8e2ad7eecc6d9c4308d4ceb95697 (the actual bugfix, quite small in c++ code change) As usual, I have a corresponding set of changes for the minimum fixversion 10.5: https://github.com/MariaDB/server/commit/753946130a5534fbe6fd8411154c638146170b08 https://github.com/MariaDB/server/commit/39a9467d09ba4730932e772596aec7d23e2f8ac8 https://github.com/MariaDB/server/commit/eb06eeba9c67282bab76078d0c7ac3026fe07d83 Update on [2023-07-26 Wed] : holyfoot I'm not sure whether you have looked at these commits yet. In the past few days I've been thinking about the changes in the first cleanup commit, about spider_conn_before_query() and spider_conn_after_query() . I don't think in its current form this clean up gives us much gain, and we should either defer this cleanup to a separate task, or (better yet) have a discussion on it. In any case, feel free to disregard the first commit, and review the second and third only.

            ok to push.
            Minor comment on the first patch.

            holyfoot Alexey Botchkov added a comment - ok to push. Minor comment on the first patch.
            ycp Yuchen Pei added a comment -

            Pushed the following to 10.5

            68a002071b7 MDEV-29502 Fix some issues with spider direct aggregate

            expected conflicts and solutions:

            • 10.6->10.10 6f31e962c87920ea6695372e5ddc59dcaabf2021
            • 10.6->10.6 ES 296a7a2feefab0c21277dcfa49a863c9bd1db21c
            • 11.2->23.08 ES 49049fe27c52323f6ea652497b9659ca2e69cabd
            ycp Yuchen Pei added a comment - Pushed the following to 10.5 68a002071b7 MDEV-29502 Fix some issues with spider direct aggregate expected conflicts and solutions: 10.6->10.10 6f31e962c87920ea6695372e5ddc59dcaabf2021 10.6->10.6 ES 296a7a2feefab0c21277dcfa49a863c9bd1db21c 11.2->23.08 ES 49049fe27c52323f6ea652497b9659ca2e69cabd

            People

              ycp Yuchen Pei
              Roel Roel Van de Paar
              Votes:
              1 Vote for this issue
              Watchers:
              6 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.