[Commits] 67d7277d7c7: MDEV-7914 spider/bg.ha, spider/bg.ha_part fail sporadically in buildbot

jacob.mathew at mariadb.com jacob.mathew at mariadb.com
Thu Jun 29 05:14:23 EEST 2017


revision-id: 67d7277d7c7dc67a97ffb65e7621f2909cfcedf3 (mariadb-10.2.6-55-g67d7277d7c7)
parent(s): 0cf993c24f482663ba1685ecf97a23ab44f6912e
author: Jacob Mathew
committer: Jacob Mathew
timestamp: 2017-06-28 18:42:20 -0700
message:

MDEV-7914 spider/bg.ha, spider/bg.ha_part fail sporadically in buildbot

Fixed the problem by adding a Spider shutdown indicator and a Spider memory
lock.  Spider shutdown acquires the lock for write access and
all other requestors acquire the lock for read access.

---
 storage/spider/ha_spider.cc       |  70 ++++++++++-
 storage/spider/spd_conn.cc        | 107 +++++++++++++----
 storage/spider/spd_copy_tables.cc |  13 +++
 storage/spider/spd_direct_sql.cc  |  18 +++
 storage/spider/spd_table.cc       | 239 ++++++++++++++++++++++++++++++++++----
 storage/spider/spd_table.h        |   4 +
 storage/spider/spd_trx.cc         |  50 +++++++-
 7 files changed, 450 insertions(+), 51 deletions(-)

diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc
index d6a5a20df8f..6ca2797db1d 100644
--- a/storage/spider/ha_spider.cc
+++ b/storage/spider/ha_spider.cc
@@ -55,6 +55,10 @@
 #define SPIDER_CAN_BG_UPDATE (LL(1) << 39)
 #endif
 
+extern bool is_spider_shutdown();
+extern int  spider_memory_rdlock();
+extern int  spider_memory_unlock();
+
 extern handlerton *spider_hton_ptr;
 extern SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE];
 #ifdef SPIDER_HAS_HASH_VALUE_TYPE
@@ -343,6 +347,10 @@ int ha_spider::open(
 
   dup_key_idx = (uint) -1;
   conn_kinds = SPIDER_CONN_KIND_MYSQL;
+
+  if (spider_memory_rdlock())
+    DBUG_RETURN(ER_PLUGIN_IS_NOT_LOADED);
+
   if (!spider_get_share(name, table, thd, this, &error_num))
     goto error_get_share;
   thr_lock_data_init(&share->lock,&lock,NULL);
@@ -584,6 +592,7 @@ int ha_spider::open(
     goto error_reset;
   }
 
+  spider_memory_unlock();
   DBUG_RETURN(0);
 
 error_reset:
@@ -636,6 +645,8 @@ int ha_spider::open(
     spider_free(spider_current_trx, conn_keys, MYF(0));
     conn_keys = NULL;
   }
+
+  spider_memory_unlock();
   DBUG_RETURN(error_num);
 }
 
@@ -650,6 +661,9 @@ int ha_spider::close()
   DBUG_ENTER("ha_spider::close");
   DBUG_PRINT("info",("spider this=%p", this));
 
+  if (spider_memory_rdlock())
+    DBUG_RETURN(ER_PLUGIN_IS_NOT_LOADED);
+
 #ifdef HA_MRR_USE_DEFAULT_IMPL
   if (multi_range_keys)
   {
@@ -822,6 +836,7 @@ int ha_spider::close()
   trx = NULL;
   conns = NULL;
 
+  spider_memory_unlock();
   DBUG_RETURN(error_num);
 }
 
@@ -1245,7 +1260,7 @@ int ha_spider::external_lock(
   }
 
   DBUG_PRINT("info",("spider sql_command=%d", sql_command));
-  DBUG_ASSERT(trx == spider_get_trx(thd, TRUE, &error_num));
+
 #ifdef HA_CAN_BULK_ACCESS
   external_lock_cnt++;
 #endif
@@ -1254,8 +1269,23 @@ int ha_spider::external_lock(
     sql_command != SQLCOM_UNLOCK_TABLES
   )
     DBUG_RETURN(0);
+
+  if (spider_memory_rdlock())
+    DBUG_RETURN(ER_PLUGIN_IS_NOT_LOADED);
+
+  SPIDER_TRX *tmp_trx = spider_get_trx(thd, TRUE, &error_num);
+  if (error_num)
+  {
+    spider_memory_unlock();
+    DBUG_RETURN(error_num);
+  }
+  DBUG_ASSERT(trx == tmp_trx);
+
   if (store_error_num)
+  {
+    spider_memory_unlock();
     DBUG_RETURN(store_error_num);
+  }
 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
   if ((conn_kinds & SPIDER_CONN_KIND_MYSQL))
   {
@@ -1271,10 +1301,12 @@ int ha_spider::external_lock(
           ER_SPIDER_ALTER_BEFORE_UNLOCK_STR, MYF(0));
         DBUG_RETURN(ER_SPIDER_ALTER_BEFORE_UNLOCK_NUM);
       }
+      spider_memory_unlock();
       DBUG_RETURN(0);
     }
     if (!conns[search_link_idx])
     {
+      spider_memory_unlock();
       my_message(ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM,
         ER_SPIDER_REMOTE_SERVER_GONE_AWAY_STR, MYF(0));
       DBUG_RETURN(ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM);
@@ -1289,7 +1321,10 @@ int ha_spider::external_lock(
         SPIDER_LINK_STATUS_RECOVERY)
     ) {
       if (sql_command == SQLCOM_TRUNCATE)
+      {
+        spider_memory_unlock();
         DBUG_RETURN(0);
+      }
       else if (sql_command != SQLCOM_UNLOCK_TABLES)
       {
         DBUG_PRINT("info",("spider conns[%d]->join_trx=%u",
@@ -1319,6 +1354,7 @@ int ha_spider::external_lock(
                 TRUE
               );
           }
+          spider_memory_unlock();
           DBUG_RETURN(check_error_mode(error_num));
         }
         result_list.lock_type = lock_type;
@@ -1372,6 +1408,7 @@ int ha_spider::external_lock(
                     TRUE
                   );
               }
+              spider_memory_unlock();
               DBUG_RETURN(check_error_mode(error_num));
             }
           }
@@ -1405,6 +1442,7 @@ int ha_spider::external_lock(
               );
           }
           conns[roop_count]->table_lock = 0;
+          spider_memory_unlock();
           DBUG_RETURN(check_error_mode(error_num));
         }
         if (conns[roop_count]->table_lock == 2)
@@ -1439,6 +1477,7 @@ int ha_spider::external_lock(
                   TRUE
                 );
             }
+            spider_memory_unlock();
             DBUG_RETURN(check_error_mode(error_num));
           }
         }
@@ -1533,6 +1572,8 @@ int ha_spider::external_lock(
     }
   }
 #endif
+
+  spider_memory_unlock();
   DBUG_RETURN(0);
 }
 
@@ -10594,6 +10635,10 @@ int ha_spider::create(
     sql_command == SQLCOM_DROP_INDEX
   )
     DBUG_RETURN(0);
+
+  if (spider_memory_rdlock())
+    DBUG_RETURN(ER_PLUGIN_IS_NOT_LOADED);
+
   if (!(trx = spider_get_trx(thd, TRUE, &error_num)))
     goto error_get_trx;
   if (
@@ -10746,6 +10791,8 @@ int ha_spider::create(
   if (tmp_share.static_key_cardinality)
     spider_free(spider_current_trx, tmp_share.static_key_cardinality, MYF(0));
   spider_free_share_alloc(&tmp_share);
+
+  spider_memory_unlock();
   DBUG_RETURN(0);
 
 error:
@@ -10759,6 +10806,7 @@ int ha_spider::create(
   spider_free_share_alloc(&tmp_share);
 error_alter_before_unlock:
 error_get_trx:
+  spider_memory_unlock();
   DBUG_RETURN(error_num);
 }
 
@@ -10817,6 +10865,10 @@ int ha_spider::rename_table(
     sql_command == SQLCOM_DROP_INDEX
   )
     DBUG_RETURN(0);
+
+  if (spider_memory_rdlock())
+    DBUG_RETURN(ER_PLUGIN_IS_NOT_LOADED);
+
   if (!(trx = spider_get_trx(thd, TRUE, &error_num)))
     goto error;
   if (
@@ -10982,6 +11034,8 @@ int ha_spider::rename_table(
   }
   pthread_mutex_unlock(&spider_lgtm_tblhnd_share_mutex);
   spider_delete_init_error_table(from);
+
+  spider_memory_unlock();
   DBUG_RETURN(0);
 
 error:
@@ -10999,6 +11053,8 @@ int ha_spider::rename_table(
   if (to_lgtm_tblhnd_share)
     spider_free_lgtm_tblhnd_share_alloc(to_lgtm_tblhnd_share, TRUE);
   pthread_mutex_unlock(&spider_lgtm_tblhnd_share_mutex);
+
+  spider_memory_unlock();
   DBUG_RETURN(error_num);
 }
 
@@ -11025,6 +11081,10 @@ int ha_spider::delete_table(
     sql_command == SQLCOM_DROP_INDEX
   )
     DBUG_RETURN(0);
+
+  if (spider_memory_rdlock())
+    DBUG_RETURN(ER_PLUGIN_IS_NOT_LOADED);
+
   if (!(trx = spider_get_trx(thd, TRUE, &error_num)))
     goto error;
   if (
@@ -11064,8 +11124,10 @@ int ha_spider::delete_table(
         (uchar*) name, name_len)) &&
 #endif
       alter_table->now_create
-    )
+    ) {
+      spider_memory_unlock();
       DBUG_RETURN(0);
+    }
 
     DBUG_PRINT("info",
       ("spider alter_info.flags=%u", thd->lex->alter_info.flags));
@@ -11117,12 +11179,16 @@ int ha_spider::delete_table(
   }
 
   spider_delete_init_error_table(name);
+
+  spider_memory_unlock();
   DBUG_RETURN(0);
 
 error:
   if (table_tables)
     spider_close_sys_table(current_thd, table_tables,
       &open_tables_backup, need_lock);
+
+  spider_memory_unlock();
   DBUG_RETURN(error_num);
 }
 
diff --git a/storage/spider/spd_conn.cc b/storage/spider/spd_conn.cc
index 5c96fe321bd..e956c6f85b6 100644
--- a/storage/spider/spd_conn.cc
+++ b/storage/spider/spd_conn.cc
@@ -37,6 +37,10 @@
 #include "spd_ping_table.h"
 #include "spd_malloc.h"
 
+extern bool is_spider_shutdown();
+extern int  spider_memory_rdlock();
+extern int  spider_memory_unlock();
+
 extern handlerton *spider_hton_ptr;
 extern SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE];
 pthread_mutex_t spider_conn_id_mutex;
@@ -2251,6 +2255,7 @@ void *spider_bg_conn_action(
   void *arg
 ) {
   int error_num;
+  bool do_kill = FALSE;
   SPIDER_CONN *conn = (SPIDER_CONN*) arg;
   SPIDER_TRX *trx;
   ha_spider *spider;
@@ -2272,12 +2277,18 @@ void *spider_bg_conn_action(
 #endif
   thd->thread_stack = (char*) &thd;
   thd->store_globals();
-  if (!(trx = spider_get_trx(thd, FALSE, &error_num)))
-  {
+  if (spider_memory_rdlock())
+    do_kill = TRUE;
+  if (
+    do_kill ||
+    !(trx = spider_get_trx(thd, FALSE, &error_num))
+  ) {
     delete thd;
     pthread_mutex_lock(&conn->bg_conn_sync_mutex);
     pthread_cond_signal(&conn->bg_conn_sync_cond);
     pthread_mutex_unlock(&conn->bg_conn_sync_mutex);
+    if (!do_kill)
+      spider_memory_unlock();
 #if !defined(MYSQL_DYNAMIC_PLUGIN) || !defined(_WIN32)
     my_pthread_setspecific_ptr(THR_THD, NULL);
 #endif
@@ -2301,7 +2312,10 @@ void *spider_bg_conn_action(
       conn->bg_conn_chain_mutex_ptr = NULL;
     }
     thd->clear_error();
+    spider_memory_unlock();
     pthread_cond_wait(&conn->bg_conn_cond, &conn->bg_conn_mutex);
+    if (spider_memory_rdlock())
+      do_kill = TRUE;
     DBUG_PRINT("info",("spider bg roop start"));
 #ifndef DBUG_OFF
     DBUG_PRINT("info",("spider conn->thd=%p", conn->thd));
@@ -2310,24 +2324,27 @@ void *spider_bg_conn_action(
       DBUG_PRINT("info",("spider query_id=%lld", conn->thd->query_id));
     }
 #endif
-    if (conn->bg_caller_sync_wait)
+    if (!do_kill)
     {
-      pthread_mutex_lock(&conn->bg_conn_sync_mutex);
-      if (conn->bg_direct_sql)
-        conn->bg_get_job_stack_off = TRUE;
-      pthread_cond_signal(&conn->bg_conn_sync_cond);
-      pthread_mutex_unlock(&conn->bg_conn_sync_mutex);
-      if (conn->bg_conn_chain_mutex_ptr)
+      if (conn->bg_caller_sync_wait)
       {
-        pthread_mutex_lock(conn->bg_conn_chain_mutex_ptr);
-        if ((&conn->bg_conn_chain_mutex) != conn->bg_conn_chain_mutex_ptr)
+        pthread_mutex_lock(&conn->bg_conn_sync_mutex);
+        if (conn->bg_direct_sql)
+          conn->bg_get_job_stack_off = TRUE;
+        pthread_cond_signal(&conn->bg_conn_sync_cond);
+        pthread_mutex_unlock(&conn->bg_conn_sync_mutex);
+        if (conn->bg_conn_chain_mutex_ptr)
         {
-          pthread_mutex_unlock(conn->bg_conn_chain_mutex_ptr);
-          conn->bg_conn_chain_mutex_ptr = NULL;
+          pthread_mutex_lock(conn->bg_conn_chain_mutex_ptr);
+          if ((&conn->bg_conn_chain_mutex) != conn->bg_conn_chain_mutex_ptr)
+          {
+            pthread_mutex_unlock(conn->bg_conn_chain_mutex_ptr);
+            conn->bg_conn_chain_mutex_ptr = NULL;
+          }
         }
       }
     }
-    if (conn->bg_kill)
+    if (conn->bg_kill || do_kill)
     {
       DBUG_PRINT("info",("spider bg kill start"));
       if (conn->bg_conn_chain_mutex_ptr)
@@ -2342,6 +2359,8 @@ void *spider_bg_conn_action(
       pthread_cond_signal(&conn->bg_conn_sync_cond);
       pthread_mutex_unlock(&conn->bg_conn_mutex);
       pthread_mutex_unlock(&conn->bg_conn_sync_mutex);
+      if (!do_kill)
+        spider_memory_unlock();
 #if !defined(MYSQL_DYNAMIC_PLUGIN) || !defined(_WIN32)
       my_pthread_setspecific_ptr(THR_THD, NULL);
 #endif
@@ -2700,6 +2719,7 @@ void *spider_bg_sts_action(
   SPIDER_SHARE *share = (SPIDER_SHARE*) arg;
   SPIDER_TRX *trx;
   int error_num = 0, roop_count;
+  bool do_kill = FALSE;
   ha_spider spider;
 #if defined(_MSC_VER) || defined(__SUNPRO_CC)
   int *need_mons;
@@ -2782,13 +2802,19 @@ void *spider_bg_sts_action(
 #endif
   thd->thread_stack = (char*) &thd;
   thd->store_globals();
-  if (!(trx = spider_get_trx(thd, FALSE, &error_num)))
-  {
+  if (spider_memory_rdlock())
+    do_kill = TRUE;
+  if (
+    do_kill ||
+    !(trx = spider_get_trx(thd, FALSE, &error_num))
+  ) {
     delete thd;
     share->bg_sts_thd_wait = FALSE;
     share->bg_sts_kill = FALSE;
     share->bg_sts_init = FALSE;
     pthread_mutex_unlock(&share->sts_mutex);
+    if (!do_kill)
+      spider_memory_unlock();
 #if !defined(MYSQL_DYNAMIC_PLUGIN) || !defined(_WIN32)
     my_pthread_setspecific_ptr(THR_THD, NULL);
 #endif
@@ -2863,12 +2889,15 @@ void *spider_bg_sts_action(
 #endif
     DBUG_RETURN(NULL);
   }
+  spider_memory_unlock();
   /* init end */
 
   while (TRUE)
   {
     DBUG_PRINT("info",("spider bg sts roop start"));
-    if (share->bg_sts_kill)
+    if (spider_memory_rdlock())
+      do_kill = TRUE;
+    if (share->bg_sts_kill || do_kill)
     {
       DBUG_PRINT("info",("spider bg sts kill start"));
       for (roop_count = SPIDER_DBTON_SIZE - 1; roop_count >= 0; --roop_count)
@@ -2885,6 +2914,8 @@ void *spider_bg_sts_action(
       delete thd;
       pthread_cond_signal(&share->bg_sts_sync_cond);
       pthread_mutex_unlock(&share->sts_mutex);
+      if (!do_kill)
+        spider_memory_unlock();
 #if !defined(MYSQL_DYNAMIC_PLUGIN) || !defined(_WIN32)
       my_pthread_setspecific_ptr(THR_THD, NULL);
 #endif
@@ -2995,6 +3026,7 @@ void *spider_bg_sts_action(
     }
     memset(need_mons, 0, sizeof(int) * share->link_count);
     share->bg_sts_thd_wait = TRUE;
+    spider_memory_unlock();
     pthread_cond_wait(&share->bg_sts_cond, &share->sts_mutex);
   }
 }
@@ -3078,6 +3110,7 @@ void *spider_bg_crd_action(
   SPIDER_SHARE *share = (SPIDER_SHARE*) arg;
   SPIDER_TRX *trx;
   int error_num = 0, roop_count;
+  bool do_kill = FALSE;
   ha_spider spider;
   TABLE table;
 #if defined(_MSC_VER) || defined(__SUNPRO_CC)
@@ -3161,13 +3194,19 @@ void *spider_bg_crd_action(
 #endif
   thd->thread_stack = (char*) &thd;
   thd->store_globals();
-  if (!(trx = spider_get_trx(thd, FALSE, &error_num)))
-  {
+  if (spider_memory_rdlock())
+    do_kill = TRUE;
+  if (
+    do_kill ||
+    !(trx = spider_get_trx(thd, FALSE, &error_num))
+  ) {
     delete thd;
     share->bg_crd_thd_wait = FALSE;
     share->bg_crd_kill = FALSE;
     share->bg_crd_init = FALSE;
     pthread_mutex_unlock(&share->crd_mutex);
+    if (!do_kill)
+      spider_memory_unlock();
 #if !defined(MYSQL_DYNAMIC_PLUGIN) || !defined(_WIN32)
     my_pthread_setspecific_ptr(THR_THD, NULL);
 #endif
@@ -3237,6 +3276,7 @@ void *spider_bg_crd_action(
     share->bg_crd_kill = FALSE;
     share->bg_crd_init = FALSE;
     pthread_mutex_unlock(&share->crd_mutex);
+    spider_memory_unlock();
 #if !defined(MYSQL_DYNAMIC_PLUGIN) || !defined(_WIN32)
     my_pthread_setspecific_ptr(THR_THD, NULL);
 #endif
@@ -3246,12 +3286,15 @@ void *spider_bg_crd_action(
 #endif
     DBUG_RETURN(NULL);
   }
+  spider_memory_unlock();
   /* init end */
 
   while (TRUE)
   {
     DBUG_PRINT("info",("spider bg crd roop start"));
-    if (share->bg_crd_kill)
+    if (spider_memory_rdlock())
+      do_kill = TRUE;
+    if (share->bg_crd_kill || do_kill)
     {
       DBUG_PRINT("info",("spider bg crd kill start"));
       for (roop_count = SPIDER_DBTON_SIZE - 1; roop_count >= 0; --roop_count)
@@ -3268,6 +3311,8 @@ void *spider_bg_crd_action(
       delete thd;
       pthread_cond_signal(&share->bg_crd_sync_cond);
       pthread_mutex_unlock(&share->crd_mutex);
+      if (!do_kill)
+        spider_memory_unlock();
 #if !defined(MYSQL_DYNAMIC_PLUGIN) || !defined(_WIN32)
       my_pthread_setspecific_ptr(THR_THD, NULL);
 #endif
@@ -3378,6 +3423,7 @@ void *spider_bg_crd_action(
     }
     memset(need_mons, 0, sizeof(int) * share->link_count);
     share->bg_crd_thd_wait = TRUE;
+    spider_memory_unlock();
     pthread_cond_wait(&share->bg_crd_cond, &share->crd_mutex);
   }
 }
@@ -3628,6 +3674,7 @@ void *spider_bg_mon_action(
   SPIDER_SHARE *share = link_pack->share;
   SPIDER_TRX *trx;
   int error_num, link_idx = link_pack->link_idx;
+  bool do_kill = FALSE;
   THD *thd;
   my_thread_init();
   DBUG_ENTER("spider_bg_mon_action");
@@ -3647,13 +3694,19 @@ void *spider_bg_mon_action(
 #endif
   thd->thread_stack = (char*) &thd;
   thd->store_globals();
-  if (!(trx = spider_get_trx(thd, FALSE, &error_num)))
-  {
+  if (spider_memory_rdlock())
+    do_kill = TRUE;
+  if (
+    do_kill ||
+    !(trx = spider_get_trx(thd, FALSE, &error_num))
+  ) {
     delete thd;
     share->bg_mon_kill = FALSE;
     share->bg_mon_init = FALSE;
     pthread_cond_signal(&share->bg_mon_conds[link_idx]);
     pthread_mutex_unlock(&share->bg_mon_mutexes[link_idx]);
+    if (!do_kill)
+      spider_memory_unlock();
 #if !defined(MYSQL_DYNAMIC_PLUGIN) || !defined(_WIN32)
     my_pthread_setspecific_ptr(THR_THD, NULL);
 #endif
@@ -3665,13 +3718,16 @@ void *spider_bg_mon_action(
 /*
   pthread_mutex_unlock(&share->bg_mon_mutexes[link_idx]);
 */
+  spider_memory_unlock();
   /* init end */
 
   while (TRUE)
   {
     DBUG_PRINT("info",("spider bg mon sleep %lld",
       share->monitoring_bg_interval[link_idx]));
-    if (!share->bg_mon_kill)
+    if (spider_memory_rdlock())
+      do_kill = TRUE;
+    if (!share->bg_mon_kill && !do_kill)
     {
       struct timespec abstime;
       set_timespec_nsec(abstime,
@@ -3683,7 +3739,7 @@ void *spider_bg_mon_action(
 */
     }
     DBUG_PRINT("info",("spider bg mon roop start"));
-    if (share->bg_mon_kill)
+    if (share->bg_mon_kill || do_kill)
     {
       DBUG_PRINT("info",("spider bg mon kill start"));
 /*
@@ -3693,6 +3749,8 @@ void *spider_bg_mon_action(
       pthread_mutex_unlock(&share->bg_mon_mutexes[link_idx]);
       spider_free_trx(trx, TRUE);
       delete thd;
+      if (!do_kill)
+        spider_memory_unlock();
 #if !defined(MYSQL_DYNAMIC_PLUGIN) || !defined(_WIN32)
       my_pthread_setspecific_ptr(THR_THD, NULL);
 #endif
@@ -3719,6 +3777,7 @@ void *spider_bg_mon_action(
       );
       lex_end(thd->lex);
     }
+    spider_memory_unlock();
   }
 }
 #endif
diff --git a/storage/spider/spd_copy_tables.cc b/storage/spider/spd_copy_tables.cc
index d29ea635d97..2fc72af72da 100644
--- a/storage/spider/spd_copy_tables.cc
+++ b/storage/spider/spd_copy_tables.cc
@@ -40,6 +40,10 @@
 #include "spd_udf.h"
 #include "spd_malloc.h"
 
+extern bool is_spider_shutdown();
+extern int  spider_memory_rdlock();
+extern int  spider_memory_unlock();
+
 extern handlerton *spider_hton_ptr;
 extern SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE];
 
@@ -835,6 +839,7 @@ long long spider_copy_tables_body(
   char *error
 ) {
   int error_num, roop_count, all_link_cnt = 0, use_table_charset;
+  bool do_spider_memory_unlock = FALSE;
   SPIDER_COPY_TABLES *copy_tables = NULL;
   THD *thd = current_thd;
   TABLE_LIST *table_list = NULL;
@@ -912,6 +917,10 @@ long long spider_copy_tables_body(
     }
     goto error;
   }
+  
+  if (spider_memory_rdlock())
+    goto error;
+  do_spider_memory_unlock = TRUE;
 
   if (!(copy_tables = (SPIDER_COPY_TABLES *)
     spider_bulk_malloc(spider_current_trx, 27, MYF(MY_WME | MY_ZEROFILL),
@@ -1239,6 +1248,8 @@ long long spider_copy_tables_body(
     delete [] tmp_sql;
   spider_udf_free_copy_tables_alloc(copy_tables);
 
+  if (do_spider_memory_unlock)
+    spider_memory_unlock();
   DBUG_RETURN(1);
 
 error_db_udf_copy_tables:
@@ -1306,6 +1317,8 @@ long long spider_copy_tables_body(
   {
     spider_udf_free_copy_tables_alloc(copy_tables);
   }
+  if (do_spider_memory_unlock)
+    spider_memory_unlock();
   *error = 1;
   DBUG_RETURN(0);
 }
diff --git a/storage/spider/spd_direct_sql.cc b/storage/spider/spd_direct_sql.cc
index dc1786796e6..b1a600a2e5b 100644
--- a/storage/spider/spd_direct_sql.cc
+++ b/storage/spider/spd_direct_sql.cc
@@ -44,6 +44,10 @@
 #define SPIDER_NEED_INIT_ONE_TABLE_FOR_FIND_TEMPORARY_TABLE
 #endif
 
+extern bool is_spider_shutdown();
+extern int  spider_memory_rdlock();
+extern int  spider_memory_unlock();
+
 extern const char **spd_defaults_extra_file;
 extern const char **spd_defaults_file;
 
@@ -1529,6 +1533,7 @@ long long spider_direct_sql_body(
   my_bool bg
 ) {
   int error_num, roop_count;
+  bool do_spider_memory_unlock = FALSE;
   SPIDER_DIRECT_SQL *direct_sql = NULL, *tmp_direct_sql;
   THD *thd = current_thd;
   SPIDER_TRX *trx;
@@ -1543,6 +1548,11 @@ long long spider_direct_sql_body(
 #endif
   DBUG_ENTER("spider_direct_sql_body");
   SPIDER_BACKUP_DASTATUS;
+
+  if (spider_memory_rdlock())
+    goto error;
+  do_spider_memory_unlock = TRUE;
+
   if (!(direct_sql = (SPIDER_DIRECT_SQL *)
     spider_bulk_malloc(spider_current_trx, 34, MYF(MY_WME | MY_ZEROFILL),
       &direct_sql, sizeof(SPIDER_DIRECT_SQL),
@@ -1737,6 +1747,9 @@ long long spider_direct_sql_body(
 #ifndef WITHOUT_SPIDER_BG_SEARCH
   }
 #endif
+
+  if (do_spider_memory_unlock)
+    spider_memory_unlock();
   DBUG_RETURN(1);
 
 error:
@@ -1748,10 +1761,15 @@ long long spider_direct_sql_body(
     ) {
       SPIDER_RESTORE_DASTATUS;
       spider_udf_free_direct_sql_alloc(direct_sql, bg);
+      if (do_spider_memory_unlock)
+        spider_memory_unlock();
       DBUG_RETURN(1);
     }
     spider_udf_free_direct_sql_alloc(direct_sql, bg);
   }
+
+  if (do_spider_memory_unlock)
+    spider_memory_unlock();
   *error = 1;
   DBUG_RETURN(0);
 }
diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc
index 56931f47f24..2c650eb388a 100644
--- a/storage/spider/spd_table.cc
+++ b/storage/spider/spd_table.cc
@@ -54,6 +54,137 @@ const char **spd_defaults_extra_file;
 const char **spd_defaults_file;
 bool volatile *spd_abort_loop;
 
+// Set to TRUE when Spider plugin uninstall begins
+longlong spider_shutdown_thd;
+
+void set_spider_shutdown(THD *thd)
+{
+  my_atomic_store64(&spider_shutdown_thd, (longlong) thd);
+}
+
+void clear_spider_shutdown()
+{
+  my_atomic_store64(&spider_shutdown_thd, (longlong) NULL);
+}
+
+THD *get_spider_shutdown_thd()
+{
+  return (THD *) my_atomic_load64(&spider_shutdown_thd);
+}
+
+bool is_spider_shutdown()
+{
+  return (bool) my_atomic_load64(&spider_shutdown_thd);
+}
+
+int spider_memory_implicit_rdlock_count;
+
+/*
+  Lock for accessing allocated Spider memory
+
+  Spider plugin uninstall acquires a WR lock
+  Other threads acquire a RD lock
+*/
+mysql_rwlock_t spider_memory_lock;
+#ifdef HAVE_PSI_INTERFACE
+PSI_rwlock_key spider_memory_lock_key;
+static PSI_rwlock_info spider_memory_lock_info =
+  { &spider_memory_lock_key, "spider_memory_lock", PSI_FLAG_GLOBAL };
+#endif
+
+int spider_memory_lock_init()
+{
+  clear_spider_shutdown();
+  my_atomic_store32(&spider_memory_implicit_rdlock_count, 0);
+#ifdef HAVE_PSI_INTERFACE
+  mysql_rwlock_register("spider", &spider_memory_lock_info, 1);
+#endif
+  return mysql_rwlock_init(spider_memory_lock_key, &spider_memory_lock);
+}
+
+int spider_memory_unlock()
+{
+  THD *shutdown_thd = get_spider_shutdown_thd();
+  if (shutdown_thd)
+  {
+    if (shutdown_thd == current_thd)
+    {
+      // Current thread is the Spider shutdown thread
+      if (my_atomic_load32(&spider_memory_implicit_rdlock_count))
+      {
+        // Release an implicit read-lock
+        my_atomic_add32(&spider_memory_implicit_rdlock_count, -1);
+        return 0;
+      }
+    }
+  }
+  return mysql_rwlock_unlock(&spider_memory_lock);
+}
+
+int spider_memory_rdlock()
+{
+  THD *shutdown_thd = get_spider_shutdown_thd();
+  if (shutdown_thd)
+  {
+    if (shutdown_thd == current_thd)
+    {
+      /*
+        Current thread is the Spider shutdown thread and
+        already holds a write lock for Spider shutdown,
+        so grant an implicit read-lock
+      */
+      my_atomic_add32(&spider_memory_implicit_rdlock_count, 1);
+      return 0;
+    }
+    // Spider shutdown is in progress, so deny the lock request
+    return ER_PLUGIN_IS_NOT_LOADED;
+  }
+
+  // Acquire the read-lock
+  int result = mysql_rwlock_rdlock(&spider_memory_lock);
+  if (!result)
+  {
+    if (is_spider_shutdown())
+    {
+      spider_memory_unlock();
+      result = ER_PLUGIN_IS_NOT_LOADED;
+    }
+  }
+  return result;
+}
+
+int spider_memory_wrlock()
+{
+  return mysql_rwlock_wrlock(&spider_memory_lock);
+}
+
+int spider_memory_lock_destroy()
+{
+  return mysql_rwlock_destroy(&spider_memory_lock);
+}
+
+int spider_shutdown_lock(THD *thd)
+{
+  set_spider_shutdown(thd);
+
+  // Acquire the write-lock
+  int result = spider_memory_wrlock();
+  if (result)
+  {
+    fprintf(stderr, "\nWrite-lock request on spider memory failed\n");
+    fflush(stderr);
+  }
+  return result;
+}
+
+void spider_shutdown_unlock()
+{
+  spider_memory_unlock();
+  // Do not destroy the spider memory lock as another thread
+  // may try to acquire it after completion of plugin deinit
+  // spider_memory_lock_destroy();
+}
+
 handlerton *spider_hton_ptr;
 SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE];
 extern SPIDER_DBTON spider_dbton_mysql;
@@ -5989,36 +6120,56 @@ int spider_close_connection(
   handlerton* hton,
   THD* thd
 ) {
-  int roop_count = 0;
-  SPIDER_CONN *conn;
   SPIDER_TRX *trx;
   DBUG_ENTER("spider_close_connection");
+
+  if (spider_memory_rdlock())
+    DBUG_RETURN(ER_PLUGIN_IS_NOT_LOADED);
+
   if (!(trx = (SPIDER_TRX*) *thd_ha_data(thd, spider_hton_ptr)))
+  {
+    spider_memory_unlock();
     DBUG_RETURN(0); /* transaction is not started */
+  }
+
+  DBUG_ASSERT(thd == trx->thd);
+  spider_close_trx_connection(trx);
+  spider_free_trx(trx, TRUE);
+
+  spider_memory_unlock();
+  DBUG_RETURN(0);
+}
+
+int spider_close_trx_connection(
+  SPIDER_TRX *trx
+) {
+  THD* thd = trx->thd;
+  SPIDER_CONN *conn;
+  DBUG_ENTER("spider_close_trx_connection");
 
   trx->tmp_spider->conns = &conn;
-  while ((conn = (SPIDER_CONN*) my_hash_element(&trx->trx_conn_hash,
-    roop_count)))
+  for (ulong i = 0; i < trx->trx_conn_hash.records; i++)
   {
-    SPIDER_BACKUP_DASTATUS;
-    DBUG_PRINT("info",("spider conn->table_lock=%d", conn->table_lock));
-    if (conn->table_lock > 0)
+    conn = (SPIDER_CONN*) my_hash_element(&trx->trx_conn_hash, i);
+    if (conn)
     {
-      if (!conn->trx_start)
-        conn->disable_reconnect = FALSE;
-      if (conn->table_lock != 2)
+      SPIDER_BACKUP_DASTATUS;
+      DBUG_PRINT("info", ("spider conn->table_lock=%d", conn->table_lock));
+      if (conn->table_lock > 0)
       {
-        spider_db_unlock_tables(trx->tmp_spider, 0);
+        if (!conn->trx_start)
+          conn->disable_reconnect = FALSE;
+        if (conn->table_lock != 2)
+        {
+          spider_db_unlock_tables(trx->tmp_spider, 0);
+        }
+        conn->table_lock = 0;
       }
-      conn->table_lock = 0;
+      SPIDER_CONN_RESTORE_DASTATUS;
     }
-    roop_count++;
-    SPIDER_CONN_RESTORE_DASTATUS;
   }
 
   spider_rollback(spider_hton_ptr, thd, TRUE);
-  spider_free_trx(trx, TRUE);
-
   DBUG_RETURN(0);
 }
 
@@ -6048,6 +6199,8 @@ int spider_db_done(
   void *p
 ) {
   int roop_count;
+  int error_num;
+  bool do_delete_thd;
   THD *thd = current_thd, *tmp_thd;
   SPIDER_CONN *conn;
   SPIDER_INIT_ERROR_TABLE *spider_init_error_table;
@@ -6055,6 +6208,29 @@ int spider_db_done(
   SPIDER_LGTM_TBLHND_SHARE *lgtm_tblhnd_share;
   DBUG_ENTER("spider_db_done");
 
+  if (thd)
+    do_delete_thd = FALSE;
+  else
+  {
+    do_delete_thd = TRUE;
+    my_thread_init();
+    if (!(thd = new THD(next_thread_id())))
+    {
+      my_thread_end();
+      DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+    }
+#ifdef HAVE_PSI_INTERFACE
+    mysql_thread_set_psi_id(thd->thread_id);
+#endif
+    thd->thread_stack = (char*) &thd;
+    thd->store_globals();
+  }
+
+  // Begin Spider plugin deinit
+  error_num = spider_shutdown_lock(thd);
+  if (error_num)
+    DBUG_RETURN(error_num);
+
 #ifndef WITHOUT_SPIDER_BG_SEARCH
   spider_free_trx(spider_global_trx, TRUE);
 #endif
@@ -6097,21 +6273,28 @@ int spider_db_done(
     pthread_mutex_destroy(&spider_udf_table_mon_mutexes[roop_count]);
   spider_free(NULL, spider_udf_table_mon_mutexes, MYF(0));
 
-  if (thd && thd_sql_command(thd) == SQLCOM_UNINSTALL_PLUGIN) {
-    pthread_mutex_lock(&spider_allocated_thds_mutex);
-    while ((tmp_thd = (THD *) my_hash_element(&spider_allocated_thds, 0)))
+  pthread_mutex_lock(&spider_allocated_thds_mutex);
+  for (ulong i = 0; i < spider_allocated_thds.records;)
+  {
+    tmp_thd = (THD *) my_hash_element(&spider_allocated_thds, i);
+    if (tmp_thd)
     {
       SPIDER_TRX *trx = (SPIDER_TRX *) *thd_ha_data(tmp_thd, spider_hton_ptr);
       if (trx)
       {
         DBUG_ASSERT(tmp_thd == trx->thd);
+        spider_close_trx_connection(trx);
         spider_free_trx(trx, FALSE);
         *thd_ha_data(tmp_thd, spider_hton_ptr) = (void *) NULL;
-      } else
+      }
+      else
         my_hash_delete(&spider_allocated_thds, (uchar *) tmp_thd);
     }
-    pthread_mutex_unlock(&spider_allocated_thds_mutex);
+    else
+      i++;
   }
+  pthread_mutex_unlock(&spider_allocated_thds_mutex);
+
 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
   pthread_mutex_lock(&spider_hs_w_conn_mutex);
   while ((conn = (SPIDER_CONN*) my_hash_element(&spider_hs_w_conn_hash, 0)))
@@ -6260,10 +6443,16 @@ int spider_db_done(
         spider_current_alloc_mem[roop_count] ? "NG" : "OK"
       ));
   }
+
+  // End Spider plugin deinit
+  spider_shutdown_unlock();
+  if (do_delete_thd)
+    delete thd;
+
 /*
 DBUG_ASSERT(0);
 */
-  DBUG_RETURN(0);
+  DBUG_RETURN(error_num);
 }
 
 int spider_panic(
@@ -6281,6 +6470,12 @@ int spider_db_init(
   uint dbton_id = 0;
   handlerton *spider_hton = (handlerton *)p;
   DBUG_ENTER("spider_db_init");
+  if (spider_memory_lock_init())
+  {
+    error_num = HA_ERR_OUT_OF_MEM;
+    DBUG_RETURN(error_num);
+  }
+
   spider_hton_ptr = spider_hton;
 
   spider_hton->state = SHOW_OPTION_YES;
diff --git a/storage/spider/spd_table.h b/storage/spider/spd_table.h
index 6140f5bbdc7..8190a305070 100644
--- a/storage/spider/spd_table.h
+++ b/storage/spider/spd_table.h
@@ -265,6 +265,10 @@ int spider_close_connection(
   THD* thd
 );
 
+int spider_close_trx_connection(
+  SPIDER_TRX *trx
+);
+
 void spider_drop_database(
   handlerton *hton,
   char* path
diff --git a/storage/spider/spd_trx.cc b/storage/spider/spd_trx.cc
index 8ba46774cfb..00f88a7a978 100644
--- a/storage/spider/spd_trx.cc
+++ b/storage/spider/spd_trx.cc
@@ -57,6 +57,10 @@ ulonglong spider_thread_id = 1;
 extern PSI_mutex_key spd_key_mutex_udf_table;
 #endif
 
+extern bool is_spider_shutdown();
+extern int  spider_memory_rdlock();
+extern int  spider_memory_unlock();
+
 extern HASH spider_allocated_thds;
 extern uint spider_allocated_thds_id;
 extern const char *spider_allocated_thds_func_name;
@@ -1145,6 +1149,14 @@ SPIDER_TRX *spider_get_trx(
   pthread_mutex_t *udf_table_mutexes;
   DBUG_ENTER("spider_get_trx");
 
+  if (spider_memory_rdlock())
+  {
+    *error_num = ER_PLUGIN_IS_NOT_LOADED;
+    DBUG_RETURN(NULL);
+  }
+
+  *error_num = 0;
+
   if (
     !thd ||
     !(trx = (SPIDER_TRX*) *thd_ha_data(thd, spider_hton_ptr))
@@ -1399,6 +1411,7 @@ SPIDER_TRX *spider_get_trx(
     }
   }
 
+  spider_memory_unlock();
   DBUG_PRINT("info",("spider trx=%p", trx));
   DBUG_RETURN(trx);
 
@@ -1502,6 +1515,7 @@ SPIDER_TRX *spider_get_trx(
   free_root(&trx->mem_root, MYF(0));
   spider_free(NULL, trx, MYF(0));
 error_alloc_trx:
+  spider_memory_unlock();
   *error_num = HA_ERR_OUT_OF_MEM;
   DBUG_RETURN(NULL);
 }
@@ -1511,7 +1525,8 @@ int spider_free_trx(
   bool need_lock
 ) {
   DBUG_ENTER("spider_free_trx");
-  if (trx->thd)
+  THD *thd = trx->thd;
+  if (thd)
   {
     if (trx->registed_allocated_thds)
     {
@@ -1519,9 +1534,9 @@ int spider_free_trx(
         pthread_mutex_lock(&spider_allocated_thds_mutex);
 #ifdef HASH_UPDATE_WITH_HASH_VALUE
       my_hash_delete_with_hash_value(&spider_allocated_thds,
-        trx->thd_hash_value, (uchar*) trx->thd);
+        trx->thd_hash_value, (uchar*) thd);
 #else
-      my_hash_delete(&spider_allocated_thds, (uchar*) trx->thd);
+      my_hash_delete(&spider_allocated_thds, (uchar*) thd);
 #endif
       if (need_lock)
         pthread_mutex_unlock(&spider_allocated_thds_mutex);
@@ -1793,6 +1808,9 @@ int spider_internal_start_trx(
   time_t tmp_time = (time_t) time((time_t*) 0);
   DBUG_ENTER("spider_internal_start_trx");
 
+  if (spider_memory_rdlock())
+    DBUG_RETURN(ER_PLUGIN_IS_NOT_LOADED);
+
   if (
     conn->server_lost ||
     difftime(tmp_time, conn->ping_time) >= ping_interval_at_trx_start
@@ -1967,11 +1985,14 @@ int spider_internal_start_trx(
     conn->c_big = NULL;
     trx->join_trx_top = conn;
   }
+
+  spider_memory_unlock();
   DBUG_RETURN(0);
 
 error:
   if (xa_lock)
     spider_xa_unlock(&trx->internal_xid_state);
+  spider_memory_unlock();
   DBUG_RETURN(error_num);
 }
 
@@ -3299,8 +3320,14 @@ int spider_commit(
   SPIDER_CONN *conn;
   DBUG_ENTER("spider_commit");
 
+  if (spider_memory_rdlock())
+    DBUG_RETURN(ER_PLUGIN_IS_NOT_LOADED);
+
   if (!(trx = (SPIDER_TRX*) *thd_ha_data(thd, spider_hton_ptr)))
+  {
+    spider_memory_unlock();
     DBUG_RETURN(0); /* transaction is not started */
+  }
 
 #ifdef HA_CAN_BULK_ACCESS
   DBUG_PRINT("info",("spider trx->bulk_access_conn_first=%p",
@@ -3329,6 +3356,7 @@ int spider_commit(
 /*
             }
 */
+            spider_memory_unlock();
             DBUG_RETURN(error_num);
           }
           trx->trx_xa_prepared = TRUE;
@@ -3376,6 +3404,8 @@ int spider_commit(
     trx->trx_consistent_snapshot = FALSE;
   }
   spider_merge_mem_calc(trx, FALSE);
+
+  spider_memory_unlock();
   DBUG_RETURN(error_num);
 }
 
@@ -3389,8 +3419,14 @@ int spider_rollback(
   SPIDER_CONN *conn;
   DBUG_ENTER("spider_rollback");
 
+  if (spider_memory_rdlock())
+    DBUG_RETURN(ER_PLUGIN_IS_NOT_LOADED);
+
   if (!(trx = (SPIDER_TRX*) *thd_ha_data(thd, spider_hton_ptr)))
+  {
+    spider_memory_unlock();
     DBUG_RETURN(0); /* transaction is not started */
+  }
 
 #ifdef HA_CAN_BULK_ACCESS
   DBUG_PRINT("info",("spider trx->bulk_access_conn_first=%p",
@@ -3448,6 +3484,8 @@ int spider_rollback(
   }
 
   spider_merge_mem_calc(trx, FALSE);
+
+  spider_memory_unlock();
   DBUG_RETURN(error_num);
 }
 
@@ -3572,6 +3610,10 @@ int spider_end_trx(
 ) {
   int error_num = 0, need_mon = 0;
   DBUG_ENTER("spider_end_trx");
+
+  if (spider_memory_rdlock())
+    DBUG_RETURN(ER_PLUGIN_IS_NOT_LOADED);
+
   if (conn->table_lock == 3)
   {
     trx->tmp_spider->conns = &conn;
@@ -3608,6 +3650,8 @@ int spider_end_trx(
   conn->semi_trx_isolation = -2;
   conn->semi_trx_isolation_chk = FALSE;
   conn->semi_trx_chk = FALSE;
+
+  spider_memory_unlock();
   DBUG_RETURN(error_num);
 }
 


More information about the commits mailing list