Skip to content

Commit e84dabe

Browse files
author
Tor Didriksen
committed
Bug#17757914 MEMORY CORRUPTION/CRASH/ASSERTION FAILED: RECORD_LENGTH == M_RECORD_LENGTH
Merge 5.6 => trunk, the re-implement.
2 parents 5e7dcbc + 24b3aae commit e84dabe

File tree

5 files changed

+17
-37
lines changed

5 files changed

+17
-37
lines changed

sql/filesort.cc

+1-13
Original file line numberDiff line numberDiff line change
@@ -342,19 +342,7 @@ ha_rows filesort(THD *thd, TABLE *table, Filesort *filesort,
342342
ha_rows keys= memory_available / (param.rec_length + sizeof(char*));
343343
// If the table is empty, allocate space for one row.
344344
param.max_keys_per_buffer= (uint) min(num_rows > 0 ? num_rows : 1, keys);
345-
if (table_sort.sort_buffer_size() > 0)
346-
{
347-
// If we have already allocated a buffer, it better have same size!
348-
if (std::make_pair(param.max_keys_per_buffer, param.rec_length) !=
349-
table_sort.sort_buffer_properties())
350-
{
351-
/*
352-
table->sort will still have a pointer to the same buffer,
353-
but that will be overwritten by the assignment below.
354-
*/
355-
table_sort.free_sort_buffer();
356-
}
357-
}
345+
358346
table_sort.alloc_sort_buffer(param.max_keys_per_buffer, param.rec_length);
359347
if (table_sort.sort_buffer_size() > 0)
360348
break;

sql/filesort_utils.cc

+16-5
Original file line numberDiff line numberDiff line change
@@ -93,15 +93,26 @@ uchar *Filesort_buffer::alloc_sort_buffer(uint num_records, uint record_length)
9393
DBUG_EXECUTE_IF("alloc_sort_buffer_fail",
9494
DBUG_SET("+d,simulate_out_of_memory"););
9595

96+
/*
97+
For subqueries we try to re-use the buffer, in order to save
98+
expensive malloc/free calls. Both of the sizing parameters may change:
99+
- num_records due to e.g. different statistics from the engine.
100+
- record_length due to different buffer usage:
101+
a heap table may be flushed to myisam, which allows us to sort by
102+
<key, addon fields> rather than <key, rowid>
103+
If we already have a buffer, but with wrong size, we simply delete it.
104+
*/
96105
if (m_rawmem != NULL)
97106
{
98-
DBUG_ASSERT(num_records == m_num_records);
99-
DBUG_ASSERT(record_length == m_record_length);
100-
return m_rawmem;
107+
if (num_records != m_num_records ||
108+
record_length != m_record_length)
109+
free_sort_buffer();
101110
}
111+
102112
m_size_in_bytes= ALIGN_SIZE(num_records * (record_length + sizeof(uchar*)));
103-
m_rawmem= (uchar*) my_malloc(key_memory_Filesort_buffer_sort_keys,
104-
m_size_in_bytes, MYF(0));
113+
if (m_rawmem == NULL)
114+
m_rawmem= (uchar*) my_malloc(key_memory_Filesort_buffer_sort_keys,
115+
m_size_in_bytes, MYF(0));
105116
if (m_rawmem == NULL)
106117
{
107118
m_size_in_bytes= 0;

sql/filesort_utils.h

-6
Original file line numberDiff line numberDiff line change
@@ -194,12 +194,6 @@ class Filesort_buffer
194194
*/
195195
uchar *alloc_sort_buffer(uint num_records, uint record_length);
196196

197-
/// What is the <num_records, record_length> for the buffer?
198-
std::pair<uint, uint> sort_buffer_properties() const
199-
{
200-
return std::make_pair(m_num_records, m_record_length);
201-
}
202-
203197
/// Frees the buffer.
204198
void free_sort_buffer()
205199
{

sql/sql_sort.h

-3
Original file line numberDiff line numberDiff line change
@@ -491,9 +491,6 @@ class Filesort_info
491491
uchar *alloc_sort_buffer(uint num_records, uint record_length)
492492
{ return filesort_buffer.alloc_sort_buffer(num_records, record_length); }
493493

494-
std::pair<uint, uint> sort_buffer_properties() const
495-
{ return filesort_buffer.sort_buffer_properties(); }
496-
497494
void free_sort_buffer()
498495
{ filesort_buffer.free_sort_buffer(); }
499496

unittest/gunit/filesort_buffer-t.cc

-10
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,6 @@ class FileSortBufferTest : public ::testing::Test
3030
virtual void TearDown()
3131
{
3232
fs_info.free_sort_buffer();
33-
std::pair<uint, uint> buffer_properties= fs_info.sort_buffer_properties();
34-
EXPECT_EQ(0U, buffer_properties.first);
35-
EXPECT_EQ(0U, buffer_properties.second);
3633
EXPECT_TRUE(NULL == fs_info.get_sort_keys());
3734
}
3835

@@ -43,15 +40,8 @@ class FileSortBufferTest : public ::testing::Test
4340
TEST_F(FileSortBufferTest, FileSortBuffer)
4441
{
4542
const char letters[10]= "abcdefghi";
46-
std::pair<uint, uint> buffer_properties= fs_info.sort_buffer_properties();
47-
EXPECT_EQ(0U, buffer_properties.first);
48-
EXPECT_EQ(0U, buffer_properties.second);
4943

5044
uchar *sort_buff= fs_info.alloc_sort_buffer(10, sizeof(char));
51-
buffer_properties= fs_info.sort_buffer_properties();
52-
EXPECT_EQ(10U, buffer_properties.first);
53-
EXPECT_EQ(sizeof(char), buffer_properties.second);
54-
5545

5646
const uchar *null_sort_buff= NULL;
5747
const uchar **null_sort_keys= NULL;

0 commit comments

Comments
 (0)