mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 20:12:31 +01:00
BUG#27732 "Possible memory leak with index_merge"
The bug was that handler::clone/handler::ha_open() call caused allocation of cloned_copy->ref on the handler->table->mem_root. The allocated memory could not be reclaimed until the table is flushed, so it was possible to exhaust memory by repeatedly running index_merge queries without doing table flushes. The fix: - make handler::clone() allocate new_handler->ref on the passed mem_root - make handler::ha_open() not allocate this->ref if it has already been allocated There is no testcase as it is not possible to check small leaks from testsuite. sql/handler.cc: BUG#27732 "Possible memory leak with index_merge" - make handler::clone() allocate new_handler->ref on the passed mem_root - make handler::ha_open() not allocate this->ref if it has already been allocated
This commit is contained in:
parent
65dfdcdfeb
commit
a1e839783e
1 changed files with 10 additions and 2 deletions
|
@ -1381,6 +1381,13 @@ int ha_delete_table(THD *thd, enum db_type table_type, const char *path,
|
|||
handler *handler::clone(MEM_ROOT *mem_root)
|
||||
{
|
||||
handler *new_handler= get_new_handler(table, mem_root, table->s->db_type);
|
||||
/*
|
||||
Allocate handler->ref here because otherwise ha_open will allocate it
|
||||
on this->table->mem_root and we will not be able to reclaim that memory
|
||||
when the clone handler object is destroyed.
|
||||
*/
|
||||
if (!(new_handler->ref= (byte*) alloc_root(mem_root, ALIGN_SIZE(ref_length)*2)))
|
||||
return NULL;
|
||||
if (new_handler && !new_handler->ha_open(table->s->path, table->db_stat,
|
||||
HA_OPEN_IGNORE_IF_LOCKED))
|
||||
return new_handler;
|
||||
|
@ -1420,8 +1427,9 @@ int handler::ha_open(const char *name, int mode, int test_if_locked)
|
|||
(void) extra(HA_EXTRA_NO_READCHECK); // Not needed in SQL
|
||||
|
||||
DBUG_ASSERT(alloc_root_inited(&table->mem_root));
|
||||
|
||||
if (!(ref= (byte*) alloc_root(&table->mem_root, ALIGN_SIZE(ref_length)*2)))
|
||||
/* ref is already allocated for us if we're called from handler::clone() */
|
||||
if (!ref && !(ref= (byte*) alloc_root(&table->mem_root,
|
||||
ALIGN_SIZE(ref_length)*2)))
|
||||
{
|
||||
close();
|
||||
error=HA_ERR_OUT_OF_MEM;
|
||||
|
|
Loading…
Reference in a new issue