summaryrefslogtreecommitdiff
path: root/sql/sp.cc
diff options
context:
space:
mode:
authorVladislav Vaintroub <wlad@mariadb.com>2021-09-27 17:43:36 +0200
committerVladislav Vaintroub <wlad@mariadb.com>2021-09-27 19:09:37 +0200
commit1f099418b6cce00b72f601288735bd7454d037cd (patch)
tree3a3b50780e621e67b6f5f2b695546825477de266 /sql/sp.cc
parentd7aa81c862b5d813f8fe3440b7e011a555e88d96 (diff)
downloadmariadb-git-1f099418b6cce00b72f601288735bd7454d037cd.tar.gz
MDEV-20699 mysqldump of routines causes MariaDB to get killed by oom-killerbb-10.3-wlad-MDEV-20699
The reason for this behavior is that SP get cached, per connection. The stored_program_cache is size of this cache, which amounts to 256 routines by default. A compiled stored procedure can easily be several megabytes in size. Thus calling SHOW CREATE PROCEDURE for all stored procedures, like mysqldump does, can require significant amount of memory. Fixed by bypassing the cache for "SHOW CREATE". This should normally be fine also perfomance-wise, as cache is meant to be used for repeated execution, not repeated SHOW CREATEs. Added a test to verify that CREATE PROCEDURE + SHOW CREATE PROCEURE do not cache, i.e amount of allocated memory does not change. Note, there is a change in existing behavior in an edge case : If "SHOW CREATE PROCEDURE p1" called from p1, after p1 was altered, now this will now return altered code. Previour behavior - relied on caching and would return old code. The previous behavior might was not necessarily correct.
Diffstat (limited to 'sql/sp.cc')
-rw-r--r--sql/sp.cc16
1 files changed, 7 insertions, 9 deletions
diff --git a/sql/sp.cc b/sql/sp.cc
index a4c4ca58414..fdfd9a79fef 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -1890,8 +1890,6 @@ bool
Sp_handler::sp_show_create_routine(THD *thd,
const Database_qualified_name *name) const
{
- sp_head *sp;
-
DBUG_ENTER("sp_show_create_routine");
DBUG_PRINT("enter", ("type: %s name: %.*s",
type_str(),
@@ -1904,20 +1902,20 @@ Sp_handler::sp_show_create_routine(THD *thd,
It is "safe" to do as long as it doesn't affect the results
of the binary log or the query cache, which currently it does not.
*/
- if (sp_cache_routine(thd, name, false, &sp))
- DBUG_RETURN(TRUE);
-
- if (sp == NULL || sp->show_create_routine(thd, this))
+ sp_head *sp= 0;
+ bool free_sp= db_find_routine(thd, name, &sp) == SP_OK;
+ bool ret= !sp || sp->show_create_routine(thd, this);
+ if (ret)
{
/*
If we have insufficient privileges, pretend the routine
does not exist.
*/
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), type_str(), name->m_name.str);
- DBUG_RETURN(TRUE);
}
-
- DBUG_RETURN(FALSE);
+ if (free_sp)
+ sp_head::destroy(sp);
+ DBUG_RETURN(ret);
}