Bug #59463 Segfault in memcpy during merge_buffers() in filesort.cc on LIMIT 0 query
Submitted: 13 Jan 2011 8:47 Modified: 24 Jan 2011 13:48
Reporter: John Embretsen Email Updates:
Status: Not a Bug Impact on me:
None 
Category:MySQL Server: Optimizer Severity:S1 (Critical)
Version:5.6.2_trunk OS:Any
Assigned to: John Embretsen CPU Architecture:Any
Tags: wl1393

[13 Jan 2011 8:47] John Embretsen
Description:
While executing a SELECT ... LIMIT 0 query against patched trunk (to disable PQ filesort optimization, aka. WL#1393), the MySQL server crashed as follows:

Offending query:

SELECT SQL_CALC_FOUND_ROWS `col_varchar_10` AS field1 FROM H AS table1 ORDER BY field1 LIMIT 0;

where table H is an InnoDB table with 100 000 rows.

Stacktrace:

=>[3] my_write_core(sig = 11), line 423 in "stacktrace.c"
  [4] handle_segfault(sig = 11), line 2511 in "mysqld.cc"
  [5] __sighndlr(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xfffffd7fff27b076
  [6] call_user_handler(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xfffffd7fff26dfaf
  [7] sigacthandler(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xfffffd7fff26e1be
  ---- called from signal handler with signal 11 (SIGSEGV) ------
  [8] memcpy(0x5c569da, 0xfffffd7fff08dfff, 0xfffffd7fff08e010, 0x5c569eb, 0x11, 0x5c73e90), at 0xfffffd7fff1e6f58
  [9] merge_buffers(param = 0xfffffd7fff0898c8, from_file = 0xfffffd7fff089a80, to_file = 0x59e5040, sort_buffer = 0x5a53b70 "P¨­^E", lastbuff = 0x5c73e90, Fb = 0x5c73e90, Tb = 0x5c73ec0, flag = 1), line 1507 in "filesort.cc"
  [10] merge_index(param = 0xfffffd7fff0898c8, sort_buffer = 0x5a53b70 "P¨­^E", buffpek = 0x5c73e90, maxbuffer = 1U, tempfile = 0xfffffd7fff089a80, outfile = 0x59e5040), line 1602 in "filesort.cc"
  [11] filesort(thd = 0x5994990, table = 0x5a12430, sortorder = 0x59e2b28, s_length = 1U, select = 0x59e2998, max_rows = 0, sort_positions = false, examined_rows = 0xfffffd7fff089d20, found_rows = 0xfffffd7fff089d18), line 322 in "filesort.cc"
  [12] create_sort_index(thd = 0x5994990, join = 0x59e19b0, order = 0x59e18c0, filesort_limit = 0, select_limit = 18446744073709551615ULL, is_order_by = true), line 20223 in "sql_select.cc"
  [13] JOIN::exec(this = 0x59e19b0), line 3296 in "sql_select.cc"
  [14] mysql_select(thd = 0x5994990, rref_pointer_array = 0x5996db0, tables = 0x59e1270, wild_num = 0, fields = CLASS, conds = (nil), og_num = 1U, order = 0x59e18c0, group = (nil), having = (nil), proc_param = (nil), select_options = 2147748640ULL, result = 0x59e1990, unit = 0x5996590, select_lex = 0x5996bc8), line 3554 in "sql_select.cc"
  [15] handle_select(thd = 0x5994990, lex = 0x59964e0, result = 0x59e1990, setup_tables_done_option = 0), line 311 in "sql_select.cc"
  [16] execute_sqlcom_select(thd = 0x5994990, all_tables = 0x59e1270), line 4513 in "sql_parse.cc"
  [17] mysql_execute_command(thd = 0x5994990), line 2096 in "sql_parse.cc"
  [18] mysql_parse(thd = 0x5994990, rawbuf = 0x59e0fe0 "SELECT SQL_CALC_FOUND_ROWS `col_varchar_10` AS field1 FROM H AS table1  ORDER BY field1 LIMIT 0", length = 95U, parser_state = 0xfffffd7fff08d960), line 5550 in "sql_parse.cc"
  [19] dispatch_command(command = COM_QUERY, thd = 0x5994990, packet = 0x59d8f91 "SELECT SQL_CALC_FOUND_ROWS `col_varchar_10` AS field1 FROM H AS table1  ORDER BY field1 LIMIT 0", packet_length = 95U), line 1078 in "sql_parse.cc"
  [20] do_command(thd = 0x5994990), line 815 in "sql_parse.cc"
  [21] do_handle_one_connection(thd_arg = 0x5994990), line 748 in "sql_connect.cc"
  [22] handle_one_connection(arg = 0x5994990), line 684 in "sql_connect.cc" 

How to repeat:
Patch against trunk:

=== modified file 'sql/filesort.cc'
--- sql/filesort.cc     2011-01-11 09:09:21 +0000
+++ sql/filesort.cc     2011-01-11 14:42:26 +0000
@@ -1146,6 +1146,9 @@
 { 
   DBUG_ENTER("check_if_pq_applicable");

+  /* Fully disable PQ for testing without WL#1393. */
+  DBUG_RETURN(false);
+  
   /*
     How much Priority Queue sort is slower than qsort.
     Measurements (see unit test) indicate that PQ is roughly 3 times slower.

Crashing query:

SELECT SQL_CALC_FOUND_ROWS `col_varchar_10` AS field1 FROM H AS table1 ORDER BY field1 LIMIT 0;

Details about the dataset may be made available later.
[24 Jan 2011 13:48] John Embretsen
Issue not seen with proper builds, closing as "Not a bug".
With patched builds, the additional change may possibly eliminate the issue (according to Tor D.):

=== modified file 'sql/filesort.cc'
--- sql/filesort.cc     2011-01-11 09:09:21 +0000
+++ sql/filesort.cc     2011-01-13 12:12:44 +0000
@@ -278,7 +278,7 @@
     goto err;
 
   maxbuffer= (uint) (my_b_tell(&buffpek_pointers)/sizeof(*buffpek));
-  if (maxbuffer == 0)                  // The whole set is in memory
+  if (maxbuffer == 0 || num_rows == 0)                 // The whole set is in memory
   {
     if (save_index(&param, sort_keys, (uint) num_rows, &table_sort))
       goto err;