diff options
author | Jacob Mathew <jacob.mathew@mariadb.com> | 2017-06-28 18:42:20 -0700 |
---|---|---|
committer | Jacob Mathew <jacob.mathew@mariadb.com> | 2017-06-28 18:42:20 -0700 |
commit | 67d7277d7c7dc67a97ffb65e7621f2909cfcedf3 (patch) | |
tree | 53642937c74b2720d01dd061f5ba49bcafe52cd6 | |
parent | 0cf993c24f482663ba1685ecf97a23ab44f6912e (diff) | |
download | mariadb-git-bb-10.2-MDEV-7914.tar.gz |
MDEV-7914 spider/bg.ha, spider/bg.ha_part fail sporadically in buildbotbb-10.2-MDEV-7914
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.
-rw-r--r-- | storage/spider/ha_spider.cc | 70 | ||||
-rw-r--r-- | storage/spider/spd_conn.cc | 107 | ||||
-rw-r--r-- | storage/spider/spd_copy_tables.cc | 13 | ||||
-rw-r--r-- | storage/spider/spd_direct_sql.cc | 18 | ||||
-rw-r--r-- | storage/spider/spd_table.cc | 239 | ||||
-rw-r--r-- | storage/spider/spd_table.h | 4 | ||||
-rw-r--r-- | 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 @@ error_get_share: 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 @@ error: 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 @@ error: 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 @@ error: { 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 @@ error: ) { 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 @@ error_init_udf_table_mutex: 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); } |