On 11/29/2010 12:21 PM, Tor Didriksen wrote:
> #At file:///export/home/didrik/repo/next-mr-opt-team-wl1393-merge/ based on
> revid:tor.didriksen@stripped
>
> 3250 Tor Didriksen 2010-11-29
> WL#1393 Optimizing filesort with small limit
>
> Many web customers have to do
> "SELECT ... ORDER BY non_index_column LIMIT X",
>
> When X *<Row Size> is smaller than sort_buff_size we can use
> the following algoritm to speed up the sort:
>
> - Create a queue to hold 'limit' keys.
> - Scan through the table and store the first (last if DESC) keys in the queue
> - Return values from queue
Bug found:
if (param.max_rows != HA_POS_ERROR &&
check_if_pq_applicable(¶m, &table_sort,
table, num_rows, memory_available))
{
DBUG_PRINT("info", ("filesort PQ is applicable"));
const size_t compare_length= param.sort_length;
if (pq.init(param.max_rows,
true, // max_at_top
NULL, // compare_function
compare_length,
&make_sortkey, ¶m, table_sort.sort_keys))
{
// If failed to init pq, fall back to merge-sort.
DBUG_PRINT("info", ("failed to allocate PQ, fallback to sort-merge"));
my_free(table_sort.sort_keys);
table_sort.sort_keys= NULL;
}
}
No test case to reproduce this, but if you make pq.init() return 1,
table_sort.sort_keys is set to NULL and is never reinitialized. Thus, we end up
with a SEGFAULT once we try to use it:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff0eeb710 (LWP 3848)]
0x000000000076531d in find_all_keys (param=0x7ffff0ee7fc0, select=0x19f3140,
sort_keys=0x0, buffpek_pointers=0x7ffff0ee8170, tempfile=0x7ffff0ee82d0,
pq=0x0, found_rows=0x7ffff0ee8508)
at
/home/jl208045/mysql/wl1393-review/next-mr-opt-team-wl1393-merge/sql/filesort.cc:674
674 make_sortkey(param, sort_keys[idx++], ref_pos);
--
Jørgen Løland | Senior Software Engineer | +47 73842138
Oracle MySQL
Trondheim, Norway