Skip to content

Commit 24b3aae

Browse files
author
Tor Didriksen
committed
Bug#17757914 MEMORY CORRUPTION/CRASH/ASSERTION FAILED: RECORD_LENGTH == M_RECORD_LENGTH
Resize the main filesort buffer if properties (num_records, record_length) change.
1 parent e2f5aaf commit 24b3aae

File tree

5 files changed

+19
-39
lines changed

5 files changed

+19
-39
lines changed

sql/filesort.cc

+1-13
Original file line numberDiff line numberDiff line change
@@ -303,19 +303,7 @@ ha_rows filesort(THD *thd, TABLE *table, Filesort *filesort,
303303
{
304304
ha_rows keys= memory_available / (param.rec_length + sizeof(char*));
305305
param.max_keys_per_buffer= (uint) min(num_rows, keys);
306-
if (table_sort.get_sort_keys())
307-
{
308-
// If we have already allocated a buffer, it better have same size!
309-
if (std::make_pair(param.max_keys_per_buffer, param.rec_length) !=
310-
table_sort.sort_buffer_properties())
311-
{
312-
/*
313-
table->sort will still have a pointer to the same buffer,
314-
but that will be overwritten by the assignment below.
315-
*/
316-
table_sort.free_sort_buffer();
317-
}
318-
}
306+
319307
table_sort.alloc_sort_buffer(param.max_keys_per_buffer, param.rec_length);
320308
if (table_sort.get_sort_keys())
321309
break;

sql/filesort_utils.cc

+17-5
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,22 @@ 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+
*/
105+
if (!m_idx_array.is_null())
106+
{
107+
if (num_records != m_idx_array.size() ||
108+
record_length != m_record_length)
109+
free_sort_buffer();
110+
}
111+
96112
if (m_idx_array.is_null())
97113
{
98114
uchar **sort_keys=
@@ -103,11 +119,7 @@ uchar **Filesort_buffer::alloc_sort_buffer(uint num_records, uint record_length)
103119
uchar **start_of_data= m_idx_array.array() + m_idx_array.size();
104120
m_start_of_data= reinterpret_cast<uchar*>(start_of_data);
105121
}
106-
else
107-
{
108-
DBUG_ASSERT(num_records == m_idx_array.size());
109-
DBUG_ASSERT(record_length == m_record_length);
110-
}
122+
111123
DBUG_RETURN(m_idx_array.array());
112124
}
113125

sql/filesort_utils.h

+1-8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved.
1+
/* Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
22
33
This program is free software; you can redistribute it and/or modify
44
it under the terms of the GNU General Public License as published by
@@ -92,13 +92,6 @@ class Filesort_buffer
9292
/// Allocates the buffer, but does *not* initialize pointers.
9393
uchar **alloc_sort_buffer(uint num_records, uint record_length);
9494

95-
/// What is the <num_records, record_length> for the buffer?
96-
std::pair<uint, uint> sort_buffer_properties() const
97-
{
98-
return std::make_pair(static_cast<uint>(m_idx_array.size()),
99-
m_record_length);
100-
}
101-
10295
/// Frees the buffer.
10396
void free_sort_buffer();
10497

sql/table.h

-3
Original file line numberDiff line numberDiff line change
@@ -354,9 +354,6 @@ class Filesort_info
354354
uchar **alloc_sort_buffer(uint num_records, uint record_length)
355355
{ return filesort_buffer.alloc_sort_buffer(num_records, record_length); }
356356

357-
std::pair<uint, uint> sort_buffer_properties() const
358-
{ return filesort_buffer.sort_buffer_properties(); }
359-
360357
void free_sort_buffer()
361358
{ filesort_buffer.free_sort_buffer(); }
362359

unittest/gunit/filesort_buffer-t.cc

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

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

4943
uchar **sort_keys= fs_info.alloc_sort_buffer(10, sizeof(char));
50-
buffer_properties= fs_info.sort_buffer_properties();
51-
EXPECT_EQ(10U, buffer_properties.first);
52-
EXPECT_EQ(sizeof(char), buffer_properties.second);
53-
5444
uchar **null_sort_keys= NULL;
5545
EXPECT_NE(null_sort_keys, sort_keys);
5646
EXPECT_NE(null_sort_keys, fs_info.get_sort_keys());

0 commit comments

Comments
 (0)