4005 Jon Olav Hauglid 2012-10-04
Bug#14640599 MEMORY LEAK WHEN EXECUTING STORED ROUTINE EXCEPTION HANDLER
When a SP handler is activated, memory is allocated to hold the
MESSAGE_TEXT for the condition that caused the activation.
The problem was that this memory was allocated on the MEM_ROOT belonging
to the stored program. Since this MEM_ROOT is not freed until the
stored program ends, a stored program that causes lots of handler
activations can start using lots of memory. In 5.1 and earlier the
problem did not exist as no MESSAGE_TEXT was allocated if a condition
was raised with a handler present. However, this behavior lead to
a number of other issues such as Bug#23032.
This patch fixes the problem by allocating enough memory for the
necessary MESSAGE_TEXTs in the SP MEM_ROOT when the SP starts and
then re-using this memory each time a handler is activated.
This is the 5.5 version of the patch.
modified:
sql/sp_rcontext.cc
sql/sp_rcontext.h
sql/sql_signal.cc
4004 Tor Didriksen 2012-10-03
Bug#13713525 CREATE_INITIAL_DB.CMAKE IS FAILING ON WINDOWS, STILL "DEVENV" RETURNS 0
This bug depends on cmake version.
For cmake 2.6 (which is still in use for some pushbuild trees)
the main build would succeed, even if create_initial_db failed.
The problem was the chaining of commands in the CUSTOM_COMMAND
to produce 'initdb.dep'. It first invokes cmake to run mysqld,
then invokes 'touch' to create the file. Moving the 'touch'
command makes the error propagate properly for both cmake 2.6 and 2.8
modified:
cmake/create_initial_db.cmake.in
sql/CMakeLists.txt
=== modified file 'sql/sp_rcontext.cc'
--- a/sql/sp_rcontext.cc 2011-06-30 15:46:53 +0000
+++ b/sql/sp_rcontext.cc 2012-10-04 14:15:13 +0000
@@ -67,19 +67,15 @@ sp_rcontext::~sp_rcontext()
bool sp_rcontext::init(THD *thd)
{
uint handler_count= m_root_parsing_ctx->max_handler_index();
- uint i;
in_sub_stmt= thd->in_sub_stmt;
if (init_var_table(thd) || init_var_items())
return TRUE;
- if (!(m_raised_conditions= new (thd->mem_root) MYSQL_ERROR[handler_count]))
+ if (!(m_raised_conditions= new (thd->mem_root) Sql_condition_info[handler_count]))
return TRUE;
- for (i= 0; i<handler_count; i++)
- m_raised_conditions[i].init(thd->mem_root);
-
return
!(m_handler=
(sp_handler_t*)thd->alloc(handler_count * sizeof(sp_handler_t))) ||
@@ -446,13 +442,12 @@ sp_rcontext::exit_handler()
DBUG_VOID_RETURN;
}
-MYSQL_ERROR*
-sp_rcontext::raised_condition() const
+Sql_condition_info* sp_rcontext::raised_condition() const
{
if (m_ihsp > 0)
{
uint hindex= m_in_handler[m_ihsp - 1].index;
- MYSQL_ERROR *raised= & m_raised_conditions[hindex];
+ Sql_condition_info *raised= & m_raised_conditions[hindex];
return raised;
}
=== modified file 'sql/sp_rcontext.h'
--- a/sql/sp_rcontext.h 2011-06-30 15:46:53 +0000
+++ b/sql/sp_rcontext.h 2012-10-04 14:15:13 +0000
@@ -58,6 +58,46 @@ typedef struct
uint index;
} sp_active_handler_t;
+
+class Sql_condition_info : public Sql_alloc
+{
+public:
+ /** SQL error code. */
+ uint m_sql_errno;
+
+ /** Error level. */
+ MYSQL_ERROR::enum_warning_level m_level;
+
+ /** SQLSTATE. */
+ char m_sql_state[SQLSTATE_LENGTH + 1];
+
+ /** Text message. */
+ char m_message[MYSQL_ERRMSG_SIZE];
+
+ void set(uint sql_errno, const char* sqlstate,
+ MYSQL_ERROR::enum_warning_level level,
+ const char* msg)
+ {
+ m_sql_errno= sql_errno;
+ m_level= level;
+
+ memcpy(m_sql_state, sqlstate, SQLSTATE_LENGTH);
+ m_sql_state[SQLSTATE_LENGTH]= '\0';
+
+ strncpy(m_message, msg, MYSQL_ERRMSG_SIZE);
+ }
+
+ void clear()
+ {
+ m_sql_errno= 0;
+ m_level= MYSQL_ERROR::WARN_LEVEL_ERROR;
+
+ m_sql_state[0]= '\0';
+ m_message[0]= '\0';
+ }
+};
+
+
/*
This class is a runtime context of a Stored Routine. It is used in an
execution and is intended to contain all dynamic objects (i.e. objects, which
@@ -146,8 +186,7 @@ class sp_rcontext : public Sql_alloc
MYSQL_ERROR::enum_warning_level level,
const char *msg);
- MYSQL_ERROR *
- raised_condition() const;
+ Sql_condition_info *raised_condition() const;
void
push_hstack(uint h);
@@ -232,7 +271,7 @@ private:
SQL conditions caught by each handler.
This is an array indexed by handler index.
*/
- MYSQL_ERROR *m_raised_conditions;
+ Sql_condition_info *m_raised_conditions;
uint m_hcount; // Stack pointer for m_handler
uint *m_hstack; // Return stack for continue handlers
=== modified file 'sql/sql_signal.cc'
--- a/sql/sql_signal.cc 2011-06-30 15:46:53 +0000
+++ b/sql/sql_signal.cc 2012-10-04 14:15:13 +0000
@@ -478,7 +478,7 @@ bool Signal_statement::execute(THD *thd)
bool Resignal_statement::execute(THD *thd)
{
- MYSQL_ERROR *signaled;
+ Sql_condition_info *signaled;
int result= TRUE;
DBUG_ENTER("Resignal_statement::execute");
@@ -491,15 +491,21 @@ bool Resignal_statement::execute(THD *th
DBUG_RETURN(result);
}
+ MYSQL_ERROR signaled_err(thd->mem_root);
+ signaled_err.set(signaled->m_sql_errno,
+ signaled->m_sql_state,
+ signaled->m_level,
+ signaled->m_message);
+
if (m_cond == NULL)
{
/* RESIGNAL without signal_value */
- result= raise_condition(thd, signaled);
+ result= raise_condition(thd, &signaled_err);
DBUG_RETURN(result);
}
/* RESIGNAL with signal_value */
- result= raise_condition(thd, signaled);
+ result= raise_condition(thd, &signaled_err);
DBUG_RETURN(result);
}
No bundle (reason: useless for push emails).
| Thread |
|---|
| • bzr push into mysql-5.5 branch (jon.hauglid:4004 to 4005) Bug#14640599 | Jon Olav Hauglid | 4 Oct |