Skip to content

Commit e8c7222

Browse files
committed
MDEV-30603: Wrong result with non-default JOIN_CACHE_LEVEL=[4|5] ...
JOIN_CACHE::alloc_buffer() used wrong logic when calculating the size of all join buffers. Then, it computed the ratio by which JOIN::shrink_join_buffers() should shrink the buffers. shrink_join_buffers() ended up in a situation where buffers would not fit into the total quota after shrinking, which resulted in negative buffer sizes. Due to use of unsigned integers it would cause very large buffers to be used instead. Make JOIN_CACHE::alloc_buffer() use the same logic as JOIN::shrink_join_buffers() when it calculates the total size of all join buffers so far. Also, add a safety check in JOIN::shrink_join_buffers() This patch doesn't include a testcase, because the original test dataset is too big and fragile. We have dbt3_s001.inc but I wasn't able to demonstrate the issue with it.
1 parent a766695 commit e8c7222

File tree

2 files changed

+15
-1
lines changed

2 files changed

+15
-1
lines changed

sql/sql_join_cache.cc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -910,7 +910,12 @@ int JOIN_CACHE::alloc_buffer()
910910
min_buff_size= get_min_join_buffer_size();
911911
buff_size= get_max_join_buffer_size(optimize_buff_size);
912912

913-
for (tab= start_tab; tab!= join_tab;
913+
/*
914+
Compute the total buffer usage for all join buffers up to
915+
and including the current one.
916+
*/
917+
for (tab= first_linear_tab(join, WITHOUT_BUSH_ROOTS, WITHOUT_CONST_TABLES);
918+
tab != join_tab;
914919
tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
915920
{
916921
cache= tab->cache;

sql/sql_select.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4443,6 +4443,15 @@ bool JOIN::shrink_join_buffers(JOIN_TAB *jt,
44434443
}
44444444
buff_size= cache->get_join_buffer_size();
44454445
curr_space-= buff_size;
4446+
if (needed_space < buff_size)
4447+
{
4448+
/*
4449+
Safety: fail if we've exhausted available buffer space with
4450+
reduced join buffers.
4451+
*/
4452+
DBUG_ASSERT(0);
4453+
return TRUE;
4454+
}
44464455
needed_space-= buff_size;
44474456
}
44484457
}

0 commit comments

Comments
 (0)