diff --git a/mysql-test/suite/compat/oracle/r/sp-package-concurrent-dml-db.result b/mysql-test/suite/compat/oracle/r/sp-package-concurrent-dml-db.result
new file mode 100644
index 00000000000..95f45c25314
--- /dev/null
+++ b/mysql-test/suite/compat/oracle/r/sp-package-concurrent-dml-db.result
@@ -0,0 +1,43 @@
+#
+# MDEV-15070 Crash when doing a CREATE VIEW inside a package routine
+#
+SET @object_type='db';
+#
+# Start of sp-package-concurrent-dml.inc
+#
+SET sql_mode=ORACLE;
+CREATE PACKAGE pkg1 AS
+PROCEDURE p1;
+END;
+$$
+CREATE PACKAGE BODY pkg1 AS
+PROCEDURE p2 AS
+BEGIN
+SELECT 'This is p2' AS msg;
+END;
+PROCEDURE p1 AS
+BEGIN
+SELECT 'This is p1' AS msg;
+DO GET_LOCK('mdev15070',120);
+CALL p2();
+DO RELEASE_LOCK('mdev15070');
+END;
+END;
+$$
+connect  con2,localhost,root;
+connection con2;
+DO GET_LOCK('mdev15070', 120);
+connection default;
+CALL pkg1.p1;
+connection con2;
+CREATE DATABASE test1;
+CREATE FUNCTION test1.f1() RETURNS INT RETURN 10;
+DROP DATABASE test1;
+DO RELEASE_LOCK('mdev15070');
+disconnect con2;
+connection default;
+msg
+This is p1
+msg
+This is p2
+DROP PACKAGE IF EXISTS pkg1;
diff --git a/mysql-test/suite/compat/oracle/r/sp-package-concurrent-dml-package.result b/mysql-test/suite/compat/oracle/r/sp-package-concurrent-dml-package.result
new file mode 100644
index 00000000000..eb7d38a8f67
--- /dev/null
+++ b/mysql-test/suite/compat/oracle/r/sp-package-concurrent-dml-package.result
@@ -0,0 +1,96 @@
+#
+# MDEV-15070 Crash when doing a CREATE VIEW inside a package routine
+#
+SET @object_type='package_replace_pkg1';
+#
+# Start of sp-package-concurrent-dml.inc
+#
+SET sql_mode=ORACLE;
+CREATE PACKAGE pkg1 AS
+PROCEDURE p1;
+END;
+$$
+CREATE PACKAGE BODY pkg1 AS
+PROCEDURE p2 AS
+BEGIN
+SELECT 'This is p2' AS msg;
+END;
+PROCEDURE p1 AS
+BEGIN
+SELECT 'This is p1' AS msg;
+DO GET_LOCK('mdev15070',120);
+CALL p2();
+DO RELEASE_LOCK('mdev15070');
+END;
+END;
+$$
+connect  con2,localhost,root;
+connection con2;
+DO GET_LOCK('mdev15070', 120);
+connection default;
+CALL pkg1.p1;
+connection con2;
+SET sql_mode=ORACLE;
+CREATE OR REPLACE PACKAGE pkg1 AS
+PROCEDURE p1;
+END;
+$$
+DROP PACKAGE pkg1;
+DO RELEASE_LOCK('mdev15070');
+disconnect con2;
+connection default;
+msg
+This is p1
+msg
+This is p2
+DROP PACKAGE IF EXISTS pkg1;
+Warnings:
+Note	1305	PACKAGE test.pkg1 does not exist
+SET @object_type='package_body_replace_pkg1';
+#
+# Start of sp-package-concurrent-dml.inc
+#
+SET sql_mode=ORACLE;
+CREATE PACKAGE pkg1 AS
+PROCEDURE p1;
+END;
+$$
+CREATE PACKAGE BODY pkg1 AS
+PROCEDURE p2 AS
+BEGIN
+SELECT 'This is p2' AS msg;
+END;
+PROCEDURE p1 AS
+BEGIN
+SELECT 'This is p1' AS msg;
+DO GET_LOCK('mdev15070',120);
+CALL p2();
+DO RELEASE_LOCK('mdev15070');
+END;
+END;
+$$
+connect  con2,localhost,root;
+connection con2;
+DO GET_LOCK('mdev15070', 120);
+connection default;
+CALL pkg1.p1;
+connection con2;
+SET sql_mode=ORACLE;
+CREATE OR REPLACE PACKAGE BODY pkg1 AS
+PROCEDURE p1 AS
+BEGIN
+SELECT 'This is p1 version 2' AS msg;
+END;
+END;
+$$
+DROP PACKAGE pkg1;
+DO RELEASE_LOCK('mdev15070');
+disconnect con2;
+connection default;
+msg
+This is p1
+msg
+This is p2
+DROP PACKAGE IF EXISTS pkg1;
+Warnings:
+Note	1305	PACKAGE test.pkg1 does not exist
diff --git a/mysql-test/suite/compat/oracle/r/sp-package-concurrent-dml-trigger.result b/mysql-test/suite/compat/oracle/r/sp-package-concurrent-dml-trigger.result
new file mode 100644
index 00000000000..8181714f59c
--- /dev/null
+++ b/mysql-test/suite/compat/oracle/r/sp-package-concurrent-dml-trigger.result
@@ -0,0 +1,44 @@
+#
+# MDEV-15070 Crash when doing a CREATE VIEW inside a package routine
+#
+SET @object_type='trigger';
+#
+# Start of sp-package-concurrent-dml.inc
+#
+SET sql_mode=ORACLE;
+CREATE PACKAGE pkg1 AS
+PROCEDURE p1;
+END;
+$$
+CREATE PACKAGE BODY pkg1 AS
+PROCEDURE p2 AS
+BEGIN
+SELECT 'This is p2' AS msg;
+END;
+PROCEDURE p1 AS
+BEGIN
+SELECT 'This is p1' AS msg;
+DO GET_LOCK('mdev15070',120);
+CALL p2();
+DO RELEASE_LOCK('mdev15070');
+END;
+END;
+$$
+connect  con2,localhost,root;
+connection con2;
+DO GET_LOCK('mdev15070', 120);
+connection default;
+CALL pkg1.p1;
+connection con2;
+CREATE TABLE t1 (a INT);
+CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW SET NEW.a=1;
+DROP TRIGGER tr1;
+DROP TABLE t1;
+DO RELEASE_LOCK('mdev15070');
+disconnect con2;
+connection default;
+msg
+This is p1
+msg
+This is p2
+DROP PACKAGE IF EXISTS pkg1;
diff --git a/mysql-test/suite/compat/oracle/r/sp-package-concurrent-dml-view.result b/mysql-test/suite/compat/oracle/r/sp-package-concurrent-dml-view.result
new file mode 100644
index 00000000000..b0ceec608a6
--- /dev/null
+++ b/mysql-test/suite/compat/oracle/r/sp-package-concurrent-dml-view.result
@@ -0,0 +1,42 @@
+#
+# MDEV-15070 Crash when doing a CREATE VIEW inside a package routine
+#
+SET @object_type='view';
+#
+# Start of sp-package-concurrent-dml.inc
+#
+SET sql_mode=ORACLE;
+CREATE PACKAGE pkg1 AS
+PROCEDURE p1;
+END;
+$$
+CREATE PACKAGE BODY pkg1 AS
+PROCEDURE p2 AS
+BEGIN
+SELECT 'This is p2' AS msg;
+END;
+PROCEDURE p1 AS
+BEGIN
+SELECT 'This is p1' AS msg;
+DO GET_LOCK('mdev15070',120);
+CALL p2();
+DO RELEASE_LOCK('mdev15070');
+END;
+END;
+$$
+connect  con2,localhost,root;
+connection con2;
+DO GET_LOCK('mdev15070', 120);
+connection default;
+CALL pkg1.p1;
+connection con2;
+CREATE VIEW v1 AS SELECT 1 AS c;
+DROP VIEW v1;
+DO RELEASE_LOCK('mdev15070');
+disconnect con2;
+connection default;
+msg
+This is p1
+msg
+This is p2
+DROP PACKAGE IF EXISTS pkg1;
diff --git a/mysql-test/suite/compat/oracle/t/sp-package-concurrent-dml-db.test b/mysql-test/suite/compat/oracle/t/sp-package-concurrent-dml-db.test
new file mode 100644
index 00000000000..0528e6cbfcd
--- /dev/null
+++ b/mysql-test/suite/compat/oracle/t/sp-package-concurrent-dml-db.test
@@ -0,0 +1,6 @@
+--echo #
+--echo # MDEV-15070 Crash when doing a CREATE VIEW inside a package routine
+--echo #
+
+SET @object_type='db';
+--source sp-package-concurrent-dml.inc
diff --git a/mysql-test/suite/compat/oracle/t/sp-package-concurrent-dml-package.test b/mysql-test/suite/compat/oracle/t/sp-package-concurrent-dml-package.test
new file mode 100644
index 00000000000..0f1a0ef3975
--- /dev/null
+++ b/mysql-test/suite/compat/oracle/t/sp-package-concurrent-dml-package.test
@@ -0,0 +1,10 @@
+--echo #
+--echo # MDEV-15070 Crash when doing a CREATE VIEW inside a package routine
+--echo #
+
+SET @object_type='package_replace_pkg1';
+--source sp-package-concurrent-dml.inc
+
+SET @object_type='package_body_replace_pkg1';
+--source sp-package-concurrent-dml.inc
+
diff --git a/mysql-test/suite/compat/oracle/t/sp-package-concurrent-dml-trigger.test b/mysql-test/suite/compat/oracle/t/sp-package-concurrent-dml-trigger.test
new file mode 100644
index 00000000000..09ba1d70142
--- /dev/null
+++ b/mysql-test/suite/compat/oracle/t/sp-package-concurrent-dml-trigger.test
@@ -0,0 +1,6 @@
+--echo #
+--echo # MDEV-15070 Crash when doing a CREATE VIEW inside a package routine
+--echo #
+
+SET @object_type='trigger';
+--source sp-package-concurrent-dml.inc
diff --git a/mysql-test/suite/compat/oracle/t/sp-package-concurrent-dml-view.test b/mysql-test/suite/compat/oracle/t/sp-package-concurrent-dml-view.test
new file mode 100644
index 00000000000..d2c2041a353
--- /dev/null
+++ b/mysql-test/suite/compat/oracle/t/sp-package-concurrent-dml-view.test
@@ -0,0 +1,6 @@
+--echo #
+--echo # MDEV-15070 Crash when doing a CREATE VIEW inside a package routine
+--echo #
+
+SET @object_type='view';
+--source sp-package-concurrent-dml.inc
diff --git a/mysql-test/suite/compat/oracle/t/sp-package-concurrent-dml.inc b/mysql-test/suite/compat/oracle/t/sp-package-concurrent-dml.inc
new file mode 100644
index 00000000000..8ee96d1ee6a
--- /dev/null
+++ b/mysql-test/suite/compat/oracle/t/sp-package-concurrent-dml.inc
@@ -0,0 +1,107 @@
+--echo #
+--echo # Start of sp-package-concurrent-dml.inc
+--echo #
+
+--source include/count_sessions.inc
+
+let $object_type= `SELECT @object_type`;
+
+SET sql_mode=ORACLE;
+DELIMITER $$;
+CREATE PACKAGE pkg1 AS
+  PROCEDURE p1;
+END;
+$$
+CREATE PACKAGE BODY pkg1 AS
+  PROCEDURE p2 AS
+  BEGIN
+    SELECT 'This is p2' AS msg;
+  END;
+  PROCEDURE p1 AS
+  BEGIN
+    SELECT 'This is p1' AS msg;
+    DO GET_LOCK('mdev15070',120);
+    CALL p2();
+    DO RELEASE_LOCK('mdev15070');
+  END;
+END;
+$$
+DELIMITER ;$$
+
+connect (con2,localhost,root);
+connection con2;
+DO GET_LOCK('mdev15070', 120);
+
+connection default;
+send CALL pkg1.p1;
+
+connection con2;
+let $wait_condition=
+  SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST
+  WHERE state = "User lock" AND info LIKE "%GET_LOCK%mdev15070%";
+--source include/wait_condition.inc
+
+
+if ($object_type==view)
+{
+  CREATE VIEW v1 AS SELECT 1 AS c;
+  DROP VIEW v1;
+}
+
+
+if ($object_type==package_replace_pkg1)
+{
+  SET sql_mode=ORACLE;
+  DELIMITER $$;
+  CREATE OR REPLACE PACKAGE pkg1 AS
+    PROCEDURE p1;
+  END;
+  $$
+  DELIMITER ;$$
+  DROP PACKAGE pkg1;
+}
+
+
+if ($object_type==package_body_replace_pkg1)
+{
+  SET sql_mode=ORACLE;
+  DELIMITER $$;
+  CREATE OR REPLACE PACKAGE BODY pkg1 AS
+    PROCEDURE p1 AS
+    BEGIN
+      SELECT 'This is p1 version 2' AS msg;
+    END;
+  END;
+  $$
+  DELIMITER ;$$
+  DROP PACKAGE pkg1;
+}
+
+
+if ($object_type==trigger)
+{
+  CREATE TABLE t1 (a INT);
+  CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW SET NEW.a=1;
+  DROP TRIGGER tr1;
+  DROP TABLE t1;
+}
+
+
+if ($object_type=='db')
+{
+  CREATE DATABASE test1;
+  CREATE FUNCTION test1.f1() RETURNS INT RETURN 10;
+  DROP DATABASE test1;
+}
+
+
+DO RELEASE_LOCK('mdev15070');
+
+disconnect con2;
+
+connection default;
+reap;
+
+DROP PACKAGE IF EXISTS pkg1;
+
+--source include/wait_until_count_sessions.inc
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 90872854d43..7d24517e564 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -614,6 +614,7 @@ sp_package::sp_package(LEX *top_level_lex,
   m_current_routine(NULL),
   m_top_level_lex(top_level_lex),
   m_rcontext(NULL),
+  m_invoked_subroutine_count(0),
   m_is_instantiated(false),
   m_is_cloning_routine(false)
 {
@@ -1217,6 +1218,8 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
 
   DBUG_ASSERT(!(m_flags & IS_INVOKED));
   m_flags|= IS_INVOKED;
+  if (m_parent)
+    m_parent->m_invoked_subroutine_count++;
   m_first_instance->m_first_free_instance= m_next_cached_sp;
   if (m_next_cached_sp)
   {
@@ -1526,6 +1529,8 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
     err_status|= mysql_change_db(thd, (LEX_CSTRING*) &saved_cur_db_name, TRUE);
   }
   m_flags&= ~IS_INVOKED;
+  if (m_parent)
+    m_parent->m_invoked_subroutine_count--;
   DBUG_PRINT("info",
              ("first free for %p --: %p->%p, level: %lu, flags %x",
               m_first_instance,
diff --git a/sql/sp_head.h b/sql/sp_head.h
index b5de340f069..d1631104e9a 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -203,7 +203,7 @@ class sp_head :private Query_arena,
   /**
     Is this routine being executed?
   */
-  bool is_invoked() const { return m_flags & IS_INVOKED; }
+  virtual bool is_invoked() const { return m_flags & IS_INVOKED; }
 
   /**
     Get the value of the SP cache version, as remembered
@@ -955,6 +955,7 @@ class sp_package: public sp_head
 
   LEX *m_top_level_lex;
   sp_rcontext *m_rcontext;
+  uint m_invoked_subroutine_count;
   bool m_is_instantiated;
   bool m_is_cloning_routine;
 
@@ -973,6 +974,15 @@ class sp_package: public sp_head
            m_routine_implementations.push_back(lex, &main_mem_root);
   }
   sp_package *get_package() { return this; }
+  bool is_invoked() const
+  {
+    /*
+      Cannot flush a package out of the SP cache when:
+      - its initialization block is running
+      - one of its subroutine is running
+    */
+    return sp_head::is_invoked() || m_invoked_subroutine_count > 0;
+  }
   sp_variable *find_package_variable(const LEX_CSTRING *name) const
   {
     /*
