Below is the list of changes that have just been committed into a local
5.0 repository of sergefp. When sergefp does a push these changes
will be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2008-02-07 05:10:04+03:00, sergefp@stripped +1 -0
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@stripped, 2008-02-07 05:09:59+03:00, sergefp@stripped +10 -2
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
diff -Nrup a/sql/handler.cc b/sql/handler.cc
--- a/sql/handler.cc 2007-11-16 13:46:35 +03:00
+++ b/sql/handler.cc 2008-02-07 05:09:59 +03:00
@@ -1381,6 +1381,13 @@ int ha_delete_table(THD *thd, enum db_ty
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, i
(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;
| Thread |
|---|
| • bk commit into 5.0 tree (sergefp:1.2599) BUG#27732 | Sergey Petrunia | 7 Feb |