diff options
author | Yuchen Pei <yuchen.pei@mariadb.com> | 2023-03-23 17:32:09 +1100 |
---|---|---|
committer | Yuchen Pei <yuchen.pei@mariadb.com> | 2023-04-28 10:29:29 +1000 |
commit | b5d317197c6fb154ae3f16eba9674cdbc86bbe4d (patch) | |
tree | 6095ddab49f201242b94169d0572f802b987aaa2 /storage/spider | |
parent | a8dac17a42c246478bf5ac6c45539779a6aa2ce3 (diff) | |
download | mariadb-git-b5d317197c6fb154ae3f16eba9674cdbc86bbe4d.tar.gz |
MDEV-29676 refactored and documented spider_get_share() and friends
Extracted out common subroutines, gave more meaningful names etc,
added comments etc.
Also:
- Documented active servers load balancing reads, and other fields in
SPIDER_SHARE etc.
- Removed commented out code
- Documented and refactored self-reference check
- Removed some unnecessary functions
- Renamed unhelpful roop_count
- Refactored spider_get_{sts,crd}, where we turn get_type into an enum
- Cleaned up spider_mbase_handler::show_table_status() and
spider_mbase_handler::show_index()
Diffstat (limited to 'storage/spider')
-rw-r--r-- | storage/spider/ha_spider.cc | 16 | ||||
-rw-r--r-- | storage/spider/ha_spider.h | 4 | ||||
-rw-r--r-- | storage/spider/spd_conn.cc | 148 | ||||
-rw-r--r-- | storage/spider/spd_copy_tables.cc | 2 | ||||
-rw-r--r-- | storage/spider/spd_db_include.h | 12 | ||||
-rw-r--r-- | storage/spider/spd_db_mysql.cc | 798 | ||||
-rw-r--r-- | storage/spider/spd_include.h | 57 | ||||
-rw-r--r-- | storage/spider/spd_param.cc | 2 | ||||
-rw-r--r-- | storage/spider/spd_param.h | 1 | ||||
-rw-r--r-- | storage/spider/spd_ping_table.cc | 2 | ||||
-rw-r--r-- | storage/spider/spd_sys_table.cc | 107 | ||||
-rw-r--r-- | storage/spider/spd_sys_table.h | 7 | ||||
-rw-r--r-- | storage/spider/spd_table.cc | 2033 | ||||
-rw-r--r-- | storage/spider/spd_table.h | 22 | ||||
-rw-r--r-- | storage/spider/spd_trx.cc | 51 |
15 files changed, 1303 insertions, 1959 deletions
diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc index e5ef9499eda..8af57895b93 100644 --- a/storage/spider/ha_spider.cc +++ b/storage/spider/ha_spider.cc @@ -309,10 +309,10 @@ int ha_spider::open( no_bytes_in_map(table->read_set)); wide_handler_alloc = TRUE; - if (!share && !spider_get_share(name, table, thd, this, &error_num)) - goto error_get_share; + if (!share && !spider_get_share(name, table, thd, this, &error_num)) + goto error_get_share; - wide_share = share->wide_share; + wide_share = share->wide_share; DBUG_PRINT("info",("spider create partition_handler")); DBUG_PRINT("info",("spider table=%p", table)); @@ -6559,13 +6559,6 @@ int ha_spider::info( auto_inc_temporary = FALSE; #endif wide_handler->sql_command = thd_sql_command(thd); -/* - if ( - sql_command == SQLCOM_DROP_TABLE || - sql_command == SQLCOM_ALTER_TABLE || - sql_command == SQLCOM_SHOW_CREATE - ) { -*/ if (flag & HA_STATUS_AUTO) { if (share->lgtm_tblhnd_share->auto_increment_value) @@ -6583,9 +6576,6 @@ int ha_spider::info( wide_handler->sql_command == SQLCOM_ALTER_TABLE ) DBUG_RETURN(0); -/* - } -*/ if (flag & (HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE | HA_STATUS_AUTO)) diff --git a/storage/spider/ha_spider.h b/storage/spider/ha_spider.h index ac865e78f2c..50266739b63 100644 --- a/storage/spider/ha_spider.h +++ b/storage/spider/ha_spider.h @@ -63,8 +63,10 @@ public: char *conn_keys_first_ptr; char **conn_keys; SPIDER_CONN **conns; - /* for active-standby mode */ + /* array of indexes of active servers */ uint *conn_link_idx; + /* A bitmap indicating whether each active server have some higher + numbered server in the same "group" left to try (can fail over) */ uchar *conn_can_fo; void **quick_targets; int *need_mons; diff --git a/storage/spider/spd_conn.cc b/storage/spider/spd_conn.cc index ca556702c65..1baf6a30e7c 100644 --- a/storage/spider/spd_conn.cc +++ b/storage/spider/spd_conn.cc @@ -2992,12 +2992,6 @@ void *spider_bg_sts_action( if (spider.search_link_idx < 0) { spider_trx_set_link_idx_for_all(&spider); -/* - spider.search_link_idx = spider_conn_next_link_idx( - thd, share->link_statuses, share->access_balances, - spider.conn_link_idx, spider.search_link_idx, share->link_count, - SPIDER_LINK_STATUS_OK); -*/ spider.search_link_idx = spider_conn_first_link_idx(thd, share->link_statuses, share->access_balances, spider.conn_link_idx, share->link_count, SPIDER_LINK_STATUS_OK); @@ -3013,32 +3007,6 @@ void *spider_bg_sts_action( share->conn_keys[spider.search_link_idx], trx, &spider, FALSE, FALSE, &error_num); conns[spider.search_link_idx]->error_mode = 0; -/* - if ( - error_num && - share->monitoring_kind[spider.search_link_idx] && - need_mons[spider.search_link_idx] - ) { - lex_start(thd); - error_num = spider_ping_table_mon_from_table( - trx, - thd, - share, - spider.search_link_idx, - (uint32) share->monitoring_sid[spider.search_link_idx], - share->table_name, - share->table_name_length, - spider.conn_link_idx[spider.search_link_idx], - NULL, - 0, - share->monitoring_kind[spider.search_link_idx], - share->monitoring_limit[spider.search_link_idx], - share->monitoring_flag[spider.search_link_idx], - TRUE - ); - lex_end(thd->lex); - } -*/ spider.search_link_idx = -1; } if (spider.search_link_idx != -1 && conns[spider.search_link_idx]) @@ -3049,31 +3017,6 @@ void *spider_bg_sts_action( share->bg_sts_sync, 2, HA_STATUS_CONST | HA_STATUS_VARIABLE)) { -/* - if ( - share->monitoring_kind[spider.search_link_idx] && - need_mons[spider.search_link_idx] - ) { - lex_start(thd); - error_num = spider_ping_table_mon_from_table( - trx, - thd, - share, - spider.search_link_idx, - (uint32) share->monitoring_sid[spider.search_link_idx], - share->table_name, - share->table_name_length, - spider.conn_link_idx[spider.search_link_idx], - NULL, - 0, - share->monitoring_kind[spider.search_link_idx], - share->monitoring_limit[spider.search_link_idx], - share->monitoring_flag[spider.search_link_idx], - TRUE - ); - lex_end(thd->lex); - } -*/ spider.search_link_idx = -1; } } @@ -3316,12 +3259,6 @@ void *spider_bg_crd_action( if (spider.search_link_idx < 0) { spider_trx_set_link_idx_for_all(&spider); -/* - spider.search_link_idx = spider_conn_next_link_idx( - thd, share->link_statuses, share->access_balances, - spider.conn_link_idx, spider.search_link_idx, share->link_count, - SPIDER_LINK_STATUS_OK); -*/ spider.search_link_idx = spider_conn_first_link_idx(thd, share->link_statuses, share->access_balances, spider.conn_link_idx, share->link_count, SPIDER_LINK_STATUS_OK); @@ -3747,6 +3684,24 @@ void *spider_bg_mon_action( } } +/** + Returns a random (active) server with a maximum required link status + + Calculate the sum of balances of all servers whose link status is at + most the specified status ("eligible"), generate a random number + less than this balance, then find the first server cumulatively + exceeding this balance + + @param thd Connection used for generating a random number + @param link_statuses The link statuses of servers + @param access_balances The access balances of servers + @param conn_link_idx Array of indexes to servers + @param link_count Number of servers + @param link_status The maximum required link status + @retval Index to the found server + @retval -1 if no eligible servers + @retval -2 if out of memory +*/ int spider_conn_first_link_idx( THD *thd, long *link_statuses, @@ -3755,35 +3710,35 @@ int spider_conn_first_link_idx( int link_count, int link_status ) { - int roop_count, active_links = 0; - longlong balance_total = 0, balance_val; + int eligible_link_idx, eligible_links = 0; + longlong balance_total = 0, balance_threshold; double rand_val; - int *link_idxs, link_idx; - long *balances; + int *link_idxs, result; DBUG_ENTER("spider_conn_first_link_idx"); char *ptr; - ptr = (char *) my_alloca((sizeof(int) * link_count) + (sizeof(long) * link_count)); + /* Allocate memory for link_idxs */ + ptr = (char *) my_alloca((sizeof(int) * link_count)); if (!ptr) { DBUG_PRINT("info",("spider out of memory")); DBUG_RETURN(-2); } link_idxs = (int *) ptr; - ptr += sizeof(int) * link_count; - balances = (long *) ptr; - for (roop_count = 0; roop_count < link_count; roop_count++) + + /* Filter for eligible servers, store their indexes and calculate + the total balances */ + for (int link_idx = 0; link_idx < link_count; link_idx++) { - DBUG_ASSERT((conn_link_idx[roop_count] - roop_count) % link_count == 0); - if (link_statuses[conn_link_idx[roop_count]] <= link_status) + DBUG_ASSERT((conn_link_idx[link_idx] - link_idx) % link_count == 0); + if (link_statuses[conn_link_idx[link_idx]] <= link_status) { - link_idxs[active_links] = roop_count; - balances[active_links] = access_balances[roop_count]; - balance_total += access_balances[roop_count]; - active_links++; + link_idxs[eligible_links] = link_idx; + balance_total += access_balances[link_idx]; + eligible_links++; } } - if (active_links == 0) + if (eligible_links == 0) { DBUG_PRINT("info",("spider all links are failed")); my_afree(link_idxs); @@ -3793,21 +3748,25 @@ int spider_conn_first_link_idx( DBUG_PRINT("info",("spider thread_id=%lu", thd_get_thread_id(thd))); rand_val = spider_rand(thd->variables.server_id + thd_get_thread_id(thd)); DBUG_PRINT("info",("spider rand_val=%f", rand_val)); - balance_val = (longlong) (rand_val * balance_total); - DBUG_PRINT("info",("spider balance_val=%lld", balance_val)); - for (roop_count = 0; roop_count < active_links - 1; roop_count++) - { + balance_threshold = (longlong) (rand_val * balance_total); + DBUG_PRINT("info",("spider balance_threshold=%lld", balance_threshold)); + /* Since balance_threshold < total balance, this loop WILL break */ + for (eligible_link_idx = 0; + eligible_link_idx < eligible_links; + eligible_link_idx++) + { + result = link_idxs[eligible_link_idx]; + const long balance = access_balances[result]; DBUG_PRINT("info",("spider balances[%d]=%ld", - roop_count, balances[roop_count])); - if (balance_val < balances[roop_count]) + link_idxs[eligible_link_idx], balance)); + if (balance_threshold < balance) break; - balance_val -= balances[roop_count]; + balance_threshold -= balance; } - DBUG_PRINT("info",("spider first link_idx=%d", link_idxs[roop_count])); - link_idx = link_idxs[roop_count]; + DBUG_PRINT("info",("spider first link_idx=%d", result)); my_afree(link_idxs); - DBUG_RETURN(link_idx); + DBUG_RETURN(result); } int spider_conn_next_link_idx( @@ -3842,6 +3801,17 @@ int spider_conn_next_link_idx( DBUG_RETURN(tmp_link_idx); } +/** + Finds the next active server with a maximum required link status + + @param link_statuses The statuses of servers + @param conn_link_idx The array of active servers + @param link_idx The index of the current active server + @param link_count The number of active servers + @param link_status The required maximum link status + @return The next active server whose link status is + at most the required one. +*/ int spider_conn_link_idx_next( long *link_statuses, uint *conn_link_idx, @@ -3854,6 +3824,8 @@ int spider_conn_link_idx_next( link_idx++; if (link_idx >= link_count) break; + /* Asserts that the `link_idx`th active server is in the correct + "group" */ DBUG_ASSERT((conn_link_idx[link_idx] - link_idx) % link_count == 0); } while (link_statuses[conn_link_idx[link_idx]] > link_status); DBUG_PRINT("info",("spider link_idx=%d", link_idx)); diff --git a/storage/spider/spd_copy_tables.cc b/storage/spider/spd_copy_tables.cc index 0d6f05dfdbd..64b86722099 100644 --- a/storage/spider/spd_copy_tables.cc +++ b/storage/spider/spd_copy_tables.cc @@ -398,7 +398,7 @@ int spider_udf_get_copy_tgt_tables( (error_num = spider_get_sys_tables_connect_info( table_tables, tmp_share, 0, mem_root)) || (error_num = spider_get_sys_tables_link_status( - table_tables, tmp_share, 0, mem_root)) || + table_tables, tmp_share->link_statuses, mem_root)) || (error_num = spider_get_sys_tables_link_idx( table_tables, &table_conn->link_idx, mem_root)) ) { diff --git a/storage/spider/spd_db_include.h b/storage/spider/spd_db_include.h index 8b2ebb821df..583299515cb 100644 --- a/storage/spider/spd_db_include.h +++ b/storage/spider/spd_db_include.h @@ -19,12 +19,19 @@ #define SPD_INIT_ALLOC_ROOT(A, B, C, D) \ init_alloc_root(PSI_INSTRUMENT_ME, A, B, C, D) +/** Maximum possible number of `SPIDER_DBTON`s available to use */ #define SPIDER_DBTON_SIZE 15 #ifndef SIZEOF_STORED_DOUBLE #define SIZEOF_STORED_DOUBLE 8 #endif +/** + Possible wrapper values, e.g. for `SPIDER_DBTON::wrapper` and + `SPIDER_SHARE::tgt_wrappers`. + + fixme: change this to enum +*/ #define SPIDER_DB_WRAPPER_MYSQL "mysql" #define SPIDER_DB_WRAPPER_MARIADB "mariadb" @@ -683,6 +690,8 @@ struct st_spider_db_request_key class spider_db_util { public: + /** Same as the `SPIDER_DBTON::dbton_id` of the `SPIDER_DBTON` + containing this `spider_db_util` */ uint dbton_id; spider_db_util() = default; virtual ~spider_db_util() = default; @@ -1683,7 +1692,10 @@ static const LEX_CSTRING maturity_name[] = typedef struct st_spider_dbton { + /** The index of this dbton in `spider_dbton` */ uint dbton_id; + /** The wrapper of this dbton, same possible values as each element + of `SPIDER_SHARE::tgt_wrappers` */ const char *wrapper; enum spider_db_access_type db_access_type; int (*init)(); diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc index 3f3ee266839..f376ae3037f 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -307,6 +307,7 @@ bool spider_mariadb_support_direct_join( DBUG_RETURN(TRUE); } +/** Available `SPIDER_DBTON`s */ SPIDER_DBTON spider_dbton_mysql = { 0, SPIDER_DB_WRAPPER_MYSQL, @@ -803,6 +804,7 @@ SPIDER_DB_ROW *spider_db_mbase_result::fetch_row_from_tmp_table( DBUG_RETURN((SPIDER_DB_ROW *) &row); } +/* Fetches table status into `stat` */ int spider_db_mbase_result::fetch_table_status( int mode, ha_statistics &stat @@ -5302,6 +5304,7 @@ int spider_db_mbase_util::append_sql_mode( DBUG_RETURN(0); } +/** Append `set session time_zone = ...` to a query string */ int spider_db_mbase_util::append_time_zone( spider_string *str, Time_zone *time_zone @@ -5320,6 +5323,14 @@ int spider_db_mbase_util::append_time_zone( DBUG_RETURN(0); } +/** + Append a query for self-referencing check + + The query is setting a user variable `@spider_lc$target_table_path` + to the value of `"$spider_unique_id$spider_table_path-"`, where + $target_table_path is the path to the data node table ("to"), and + $spider_table_path the path to the spider table ("from") +*/ int spider_db_mbase_util::append_loop_check( spider_string *str, SPIDER_CONN *conn @@ -13432,6 +13443,38 @@ int spider_mbase_handler::sts_mode_exchange( DBUG_RETURN(sts_mode); } +/** FIXME: refactor more functions to use spider_setup_for_query() and +spider_teardown_after_query(). */ +void spider_setup_for_query(ha_spider *spider, SPIDER_CONN *conn, int link_idx) +{ + pthread_mutex_assert_not_owner(&conn->mta_conn_mutex); + pthread_mutex_lock(&conn->mta_conn_mutex); + SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos); + conn->need_mon= &spider->need_mons[link_idx]; + DBUG_ASSERT(!conn->mta_conn_mutex_lock_already); + DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later); + conn->mta_conn_mutex_lock_already= TRUE; + conn->mta_conn_mutex_unlock_later= TRUE; + conn->disable_connect_retry= TRUE; +} + +int spider_teardown_after_query(SPIDER_CONN *conn, int error_num, bool clear) +{ + conn->disable_connect_retry= FALSE; + DBUG_ASSERT(conn->mta_conn_mutex_lock_already); + DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); + conn->mta_conn_mutex_lock_already= FALSE; + conn->mta_conn_mutex_unlock_later= FALSE; + if (clear) + { + SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); + pthread_mutex_unlock(&conn->mta_conn_mutex); + } + return error_num; +} +/** + Executes show table status query and stores results in share->stat +*/ int spider_mbase_handler::show_table_status( int link_idx, int sts_mode, @@ -13441,329 +13484,118 @@ int spider_mbase_handler::show_table_status( SPIDER_CONN *conn = spider->conns[link_idx]; SPIDER_DB_RESULT *res; SPIDER_SHARE *share = spider->share; - uint pos = (2 * spider->conn_link_idx[link_idx]); + const uint pos = 2 * spider->conn_link_idx[link_idx] + + (sts_mode == 1 ? 0 : 1); ulonglong auto_increment_value = 0; DBUG_ENTER("spider_mbase_handler::show_table_status"); DBUG_PRINT("info",("spider sts_mode=%d", sts_mode)); - if (sts_mode == 1) + spider_setup_for_query(spider, conn, link_idx); + spider_conn_set_timeout_from_share( + conn, link_idx, spider->wide_handler->trx->thd, share); + if ((error_num = spider_db_set_names(spider, conn, link_idx)) || + /* Executes the `show table status` query */ + (spider_db_query( + conn, + mysql_share->show_table_status[pos].ptr(), + mysql_share->show_table_status[pos].length(), + -1, + &spider->need_mons[link_idx]) && + (error_num = spider_db_errorno(conn)))) { - pthread_mutex_assert_not_owner(&conn->mta_conn_mutex); - pthread_mutex_lock(&conn->mta_conn_mutex); - SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos); - conn->need_mon = &spider->need_mons[link_idx]; - DBUG_ASSERT(!conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = TRUE; - conn->mta_conn_mutex_unlock_later = TRUE; - conn->disable_connect_retry = TRUE; - spider_conn_set_timeout_from_share(conn, link_idx, - spider->wide_handler->trx->thd, - share); - if ( - (error_num = spider_db_set_names(spider, conn, link_idx)) || - ( - spider_db_query( - conn, - mysql_share->show_table_status[0 + pos].ptr(), - mysql_share->show_table_status[0 + pos].length(), - -1, - &spider->need_mons[link_idx]) && - (error_num = spider_db_errorno(conn)) - ) - ) { - if ( - error_num == ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM && - !conn->disable_reconnect + if (error_num == ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM && + !conn->disable_reconnect) + { + /* retry */ + if ((error_num = spider_db_ping(spider, conn, link_idx))) + DBUG_RETURN(spider_teardown_after_query(conn, error_num, true)); + if ((error_num = spider_db_set_names(spider, conn, link_idx))) + DBUG_RETURN(spider_teardown_after_query(conn, error_num, true)); + spider_conn_set_timeout_from_share(conn, link_idx, + spider->wide_handler->trx->thd, + share); + if (spider_db_query( + conn, + mysql_share->show_table_status[pos].ptr(), + mysql_share->show_table_status[pos].length(), + -1, + &spider->need_mons[link_idx]) ) { - /* retry */ - if ((error_num = spider_db_ping(spider, conn, link_idx))) - { - conn->disable_connect_retry = FALSE; - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - DBUG_RETURN(error_num); - } - if ((error_num = spider_db_set_names(spider, conn, link_idx))) - { - conn->disable_connect_retry = FALSE; - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - DBUG_RETURN(error_num); - } - spider_conn_set_timeout_from_share(conn, link_idx, - spider->wide_handler->trx->thd, - share); - if (spider_db_query( - conn, - mysql_share->show_table_status[0 + pos].ptr(), - mysql_share->show_table_status[0 + pos].length(), - -1, - &spider->need_mons[link_idx]) - ) { - conn->disable_connect_retry = FALSE; - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - DBUG_RETURN(spider_db_errorno(conn)); - } - } else { - conn->disable_connect_retry = FALSE; - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - DBUG_RETURN(error_num); + spider_teardown_after_query(conn, 0, false); + DBUG_RETURN(spider_db_errorno(conn)); } - } - st_spider_db_request_key request_key; - request_key.spider_thread_id = spider->wide_handler->trx->spider_thread_id; - request_key.query_id = spider->wide_handler->trx->thd->query_id; - request_key.handler = spider; - request_key.request_id = 1; - request_key.next = NULL; - if (spider_param_dry_access()) - { - conn->disable_connect_retry = FALSE; - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - DBUG_RETURN(0); - } - if (!(res = conn->db_conn->store_result(NULL, &request_key, &error_num))) + } else + DBUG_RETURN(spider_teardown_after_query(conn, error_num, true)); + } + st_spider_db_request_key request_key = { + spider->wide_handler->trx->spider_thread_id, + spider->wide_handler->trx->thd->query_id, spider, 1, NULL}; + if (spider_param_dry_access()) + DBUG_RETURN(spider_teardown_after_query(conn, 0, true)); + if (!(res = conn->db_conn->store_result(NULL, &request_key, &error_num))) + { + if (sts_mode == 1) /* get from status table */ { - conn->disable_connect_retry = FALSE; - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; if (error_num) - { - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); + DBUG_RETURN(spider_teardown_after_query(conn, error_num, true)); + spider_teardown_after_query(conn, 0, false); + if ((error_num = spider_db_errorno(conn))) DBUG_RETURN(error_num); - } - else if ((error_num = spider_db_errorno(conn))) - DBUG_RETURN(error_num); - else { - my_printf_error(ER_SPIDER_REMOTE_TABLE_NOT_FOUND_NUM, + else + { + my_printf_error( + ER_SPIDER_REMOTE_TABLE_NOT_FOUND_NUM, ER_SPIDER_REMOTE_TABLE_NOT_FOUND_STR, MYF(0), mysql_share->db_names_str[spider->conn_link_idx[link_idx]].ptr(), - mysql_share->table_names_str[spider->conn_link_idx[ - link_idx]].ptr()); + mysql_share->table_names_str[spider->conn_link_idx[link_idx]].ptr()); DBUG_RETURN(ER_SPIDER_REMOTE_TABLE_NOT_FOUND_NUM); } - } - conn->disable_connect_retry = FALSE; - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - error_num = res->fetch_table_status( - sts_mode, - share->stat - ); - auto_increment_value = share->stat.auto_increment_value; - res->free_result(); - delete res; - if (error_num) - { - switch (error_num) - { - case ER_SPIDER_REMOTE_TABLE_NOT_FOUND_NUM: - my_printf_error(ER_SPIDER_REMOTE_TABLE_NOT_FOUND_NUM, - ER_SPIDER_REMOTE_TABLE_NOT_FOUND_STR, MYF(0), - mysql_share->db_names_str[spider->conn_link_idx[link_idx]].ptr(), - mysql_share->table_names_str[spider->conn_link_idx[ - link_idx]].ptr()); - break; - case ER_SPIDER_INVALID_REMOTE_TABLE_INFO_NUM: - my_printf_error(ER_SPIDER_INVALID_REMOTE_TABLE_INFO_NUM, - ER_SPIDER_INVALID_REMOTE_TABLE_INFO_STR, MYF(0), - mysql_share->db_names_str[spider->conn_link_idx[link_idx]].ptr(), - mysql_share->table_names_str[spider->conn_link_idx[ - link_idx]].ptr()); - break; - default: - break; - } - DBUG_RETURN(error_num); - } - } else { - pthread_mutex_assert_not_owner(&conn->mta_conn_mutex); - pthread_mutex_lock(&conn->mta_conn_mutex); - SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos); - conn->need_mon = &spider->need_mons[link_idx]; - DBUG_ASSERT(!conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = TRUE; - conn->mta_conn_mutex_unlock_later = TRUE; - conn->disable_connect_retry = TRUE; - spider_conn_set_timeout_from_share(conn, link_idx, - spider->wide_handler->trx->thd, - share); - if ( - (error_num = spider_db_set_names(spider, conn, link_idx)) || - ( - spider_db_query( - conn, - mysql_share->show_table_status[1 + pos].ptr(), - mysql_share->show_table_status[1 + pos].length(), - -1, - &spider->need_mons[link_idx]) && - (error_num = spider_db_errorno(conn)) - ) - ) { - if ( - error_num == ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM && - !conn->disable_reconnect - ) { - /* retry */ - if ((error_num = spider_db_ping(spider, conn, link_idx))) - { - conn->disable_connect_retry = FALSE; - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - DBUG_RETURN(error_num); - } - if ((error_num = spider_db_set_names(spider, conn, link_idx))) - { - conn->disable_connect_retry = FALSE; - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - DBUG_RETURN(error_num); - } - spider_conn_set_timeout_from_share(conn, link_idx, - spider->wide_handler->trx->thd, - share); - if (spider_db_query( - conn, - mysql_share->show_table_status[1 + pos].ptr(), - mysql_share->show_table_status[1 + pos].length(), - -1, - &spider->need_mons[link_idx]) - ) { - conn->disable_connect_retry = FALSE; - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - DBUG_RETURN(spider_db_errorno(conn)); - } - } else { - conn->disable_connect_retry = FALSE; - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - DBUG_RETURN(error_num); - } - } - st_spider_db_request_key request_key; - request_key.spider_thread_id = spider->wide_handler->trx->spider_thread_id; - request_key.query_id = spider->wide_handler->trx->thd->query_id; - request_key.handler = spider; - request_key.request_id = 1; - request_key.next = NULL; - if (spider_param_dry_access()) + } else /* get from information schema */ { - conn->disable_connect_retry = FALSE; - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - DBUG_RETURN(0); - } - if (!(res = conn->db_conn->store_result(NULL, &request_key, &error_num))) - { - conn->disable_connect_retry = FALSE; - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - if (error_num || (error_num = spider_db_errorno(conn))) + spider_teardown_after_query(conn, error_num, false); + if (error_num || (error_num= spider_db_errorno(conn))) DBUG_RETURN(error_num); else DBUG_RETURN(ER_QUERY_ON_FOREIGN_DATA_SOURCE); } - conn->disable_connect_retry = FALSE; - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - error_num = res->fetch_table_status( - sts_mode, - share->stat - ); - auto_increment_value = share->stat.auto_increment_value; - res->free_result(); - delete res; - if (error_num) + } + spider_teardown_after_query(conn, 0, true); + /* Fetches query results into share->stat. */ + error_num = res->fetch_table_status(sts_mode, share->stat); + auto_increment_value = share->stat.auto_increment_value; + res->free_result(); + delete res; + if (error_num) + { + switch (error_num) { - switch (error_num) - { - case ER_SPIDER_REMOTE_TABLE_NOT_FOUND_NUM: - my_printf_error(ER_SPIDER_REMOTE_TABLE_NOT_FOUND_NUM, - ER_SPIDER_REMOTE_TABLE_NOT_FOUND_STR, MYF(0), - mysql_share->db_names_str[spider->conn_link_idx[link_idx]].ptr(), - mysql_share->table_names_str[spider->conn_link_idx[ - link_idx]].ptr()); - break; - case ER_SPIDER_INVALID_REMOTE_TABLE_INFO_NUM: - my_printf_error(ER_SPIDER_INVALID_REMOTE_TABLE_INFO_NUM, - ER_SPIDER_INVALID_REMOTE_TABLE_INFO_STR, MYF(0), - mysql_share->db_names_str[spider->conn_link_idx[link_idx]].ptr(), - mysql_share->table_names_str[spider->conn_link_idx[ - link_idx]].ptr()); - break; - default: - break; - } - DBUG_RETURN(error_num); + case ER_SPIDER_REMOTE_TABLE_NOT_FOUND_NUM: + my_printf_error( + ER_SPIDER_REMOTE_TABLE_NOT_FOUND_NUM, + ER_SPIDER_REMOTE_TABLE_NOT_FOUND_STR, MYF(0), + mysql_share->db_names_str[spider->conn_link_idx[link_idx]].ptr(), + mysql_share->table_names_str[spider->conn_link_idx[link_idx]].ptr()); + break; + case ER_SPIDER_INVALID_REMOTE_TABLE_INFO_NUM: + my_printf_error( + ER_SPIDER_INVALID_REMOTE_TABLE_INFO_NUM, + ER_SPIDER_INVALID_REMOTE_TABLE_INFO_STR, MYF(0), + mysql_share->db_names_str[spider->conn_link_idx[link_idx]].ptr(), + mysql_share->table_names_str[spider->conn_link_idx[link_idx]].ptr()); + break; + default: + break; } + DBUG_RETURN(error_num); } if ((error_num = ((spider_db_mbase *) conn->db_conn)->fetch_and_print_warnings(NULL))) { DBUG_RETURN(error_num); } if (share->static_records_for_status != -1) - { share->stat.records = (ha_rows) share->static_records_for_status; - } if (share->static_mean_rec_length != -1) - { share->stat.mean_rec_length = (ulong) share->static_mean_rec_length; - } if (auto_increment_value > share->lgtm_tblhnd_share->auto_increment_value) { share->lgtm_tblhnd_share->auto_increment_value = auto_increment_value; @@ -13790,314 +13622,96 @@ int spider_mbase_handler::show_index( SPIDER_SHARE *share = spider->share; TABLE *table = spider->get_table(); SPIDER_DB_RESULT *res; - int roop_count; - longlong *tmp_cardinality; - uint pos = (2 * spider->conn_link_idx[link_idx]); + int field; + longlong *tmp_crd; + const uint pos = 2 * spider->conn_link_idx[link_idx] + + (crd_mode == 1 ? 0 : 1); DBUG_ENTER("spider_mbase_handler::show_index"); DBUG_PRINT("info",("spider crd_mode=%d", crd_mode)); - if (crd_mode == 1) + spider_setup_for_query(spider, conn, link_idx); + spider_conn_set_timeout_from_share(conn, link_idx, + spider->wide_handler->trx->thd, share); + if ((error_num = spider_db_set_names(spider, conn, link_idx)) || + (spider_db_query( + conn, + mysql_share->show_index[pos].ptr(), + mysql_share->show_index[pos].length(), + -1, + &spider->need_mons[link_idx]) && + (error_num = spider_db_errorno(conn)))) { - pthread_mutex_assert_not_owner(&conn->mta_conn_mutex); - pthread_mutex_lock(&conn->mta_conn_mutex); - SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos); - conn->need_mon = &spider->need_mons[link_idx]; - DBUG_ASSERT(!conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = TRUE; - conn->mta_conn_mutex_unlock_later = TRUE; - spider_conn_set_timeout_from_share(conn, link_idx, - spider->wide_handler->trx->thd, - share); - if ( - (error_num = spider_db_set_names(spider, conn, link_idx)) || - ( - spider_db_query( - conn, - mysql_share->show_index[0 + pos].ptr(), - mysql_share->show_index[0 + pos].length(), - -1, - &spider->need_mons[link_idx]) && - (error_num = spider_db_errorno(conn)) - ) - ) { - if ( - error_num == ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM && - !conn->disable_reconnect - ) { - /* retry */ - if ((error_num = spider_db_ping(spider, conn, link_idx))) - { - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - DBUG_RETURN(error_num); - } - if ((error_num = spider_db_set_names(spider, conn, link_idx))) - { - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - DBUG_RETURN(error_num); - } - spider_conn_set_timeout_from_share(conn, link_idx, - spider->wide_handler->trx->thd, - share); - if (spider_db_query( - conn, - mysql_share->show_index[0 + pos].ptr(), - mysql_share->show_index[0 + pos].length(), - -1, - &spider->need_mons[link_idx]) - ) { - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - DBUG_RETURN(spider_db_errorno(conn)); - } - } else { - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - DBUG_RETURN(error_num); - } - } - st_spider_db_request_key request_key; - request_key.spider_thread_id = spider->wide_handler->trx->spider_thread_id; - request_key.query_id = spider->wide_handler->trx->thd->query_id; - request_key.handler = spider; - request_key.request_id = 1; - request_key.next = NULL; - if (!(res = conn->db_conn->store_result(NULL, &request_key, &error_num))) + if (error_num == ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM && + !conn->disable_reconnect) { - if (error_num || (error_num = spider_db_errorno(conn))) - { - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - DBUG_RETURN(error_num); - } - /* no record is ok */ - } - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - if (res) - { - error_num = res->fetch_table_cardinality( - crd_mode, - table, - share->cardinality, - share->cardinality_upd, - share->bitmap_size - ); - } - for (roop_count = 0, tmp_cardinality = share->cardinality; - roop_count < (int) table->s->fields; - roop_count++, tmp_cardinality++) - { - if (!spider_bit_is_set(share->cardinality_upd, roop_count)) - { - DBUG_PRINT("info", - ("spider uninitialized column cardinality id=%d", roop_count)); - *tmp_cardinality = -1; - } - } - if (res) - { - res->free_result(); - delete res; - } - if (error_num) - { - switch (error_num) - { - case ER_SPIDER_REMOTE_TABLE_NOT_FOUND_NUM: - my_printf_error(ER_SPIDER_REMOTE_TABLE_NOT_FOUND_NUM, - ER_SPIDER_REMOTE_TABLE_NOT_FOUND_STR, MYF(0), - mysql_share->db_names_str[spider->conn_link_idx[link_idx]].ptr(), - mysql_share->table_names_str[spider->conn_link_idx[ - link_idx]].ptr()); - break; - case ER_SPIDER_INVALID_REMOTE_TABLE_INFO_NUM: - my_printf_error(ER_SPIDER_INVALID_REMOTE_TABLE_INFO_NUM, - ER_SPIDER_INVALID_REMOTE_TABLE_INFO_STR, MYF(0), - mysql_share->db_names_str[spider->conn_link_idx[link_idx]].ptr(), - mysql_share->table_names_str[spider->conn_link_idx[ - link_idx]].ptr()); - break; - default: - break; - } - DBUG_RETURN(error_num); - } - } else { - pthread_mutex_assert_not_owner(&conn->mta_conn_mutex); - pthread_mutex_lock(&conn->mta_conn_mutex); - SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos); - conn->need_mon = &spider->need_mons[link_idx]; - DBUG_ASSERT(!conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = TRUE; - conn->mta_conn_mutex_unlock_later = TRUE; - spider_conn_set_timeout_from_share(conn, link_idx, - spider->wide_handler->trx->thd, - share); - if ( - (error_num = spider_db_set_names(spider, conn, link_idx)) || - ( - spider_db_query( - conn, - mysql_share->show_index[1 + pos].ptr(), - mysql_share->show_index[1 + pos].length(), - -1, - &spider->need_mons[link_idx]) && - (error_num = spider_db_errorno(conn)) - ) - ) { - if ( - error_num == ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM && - !conn->disable_reconnect - ) { - /* retry */ - if ((error_num = spider_db_ping(spider, conn, link_idx))) - { - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - DBUG_RETURN(error_num); - } - if ((error_num = spider_db_set_names(spider, conn, link_idx))) - { - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - DBUG_RETURN(error_num); - } - spider_conn_set_timeout_from_share(conn, link_idx, - spider->wide_handler->trx->thd, - share); - if (spider_db_query( - conn, - mysql_share->show_index[1 + pos].ptr(), - mysql_share->show_index[1 + pos].length(), - -1, - &spider->need_mons[link_idx]) - ) { - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - DBUG_RETURN(spider_db_errorno(conn)); - } - } else { - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - DBUG_RETURN(error_num); - } - } - st_spider_db_request_key request_key; - request_key.spider_thread_id = spider->wide_handler->trx->spider_thread_id; - request_key.query_id = spider->wide_handler->trx->thd->query_id; - request_key.handler = spider; - request_key.request_id = 1; - request_key.next = NULL; - if (!(res = conn->db_conn->store_result(NULL, &request_key, &error_num))) - { - if (error_num || (error_num = spider_db_errorno(conn))) - { - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - DBUG_RETURN(error_num); - } - /* no record is ok */ - } - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - if (res) - { - error_num = res->fetch_table_cardinality( - crd_mode, - table, - share->cardinality, - share->cardinality_upd, - share->bitmap_size - ); - } - for (roop_count = 0, tmp_cardinality = share->cardinality; - roop_count < (int) table->s->fields; - roop_count++, tmp_cardinality++) - { - if (!spider_bit_is_set(share->cardinality_upd, roop_count)) + /* retry */ + if ((error_num = spider_db_ping(spider, conn, link_idx))) + DBUG_RETURN(spider_teardown_after_query(conn, error_num, true)); + if ((error_num = spider_db_set_names(spider, conn, link_idx))) + DBUG_RETURN(spider_teardown_after_query(conn, error_num, true)); + spider_conn_set_timeout_from_share(conn, link_idx, + spider->wide_handler->trx->thd, + share); + if (spider_db_query( + conn, + mysql_share->show_index[pos].ptr(), + mysql_share->show_index[pos].length(), + -1, + &spider->need_mons[link_idx])) { - DBUG_PRINT("info", - ("spider uninitialized column cardinality id=%d", roop_count)); - *tmp_cardinality = -1; + spider_teardown_after_query(conn, 0, false); + DBUG_RETURN(spider_db_errorno(conn)); } - } - if (res) - { - res->free_result(); - delete res; - } - if (error_num) + } else + DBUG_RETURN(spider_teardown_after_query(conn, error_num, true)); + } + st_spider_db_request_key request_key = { + spider->wide_handler->trx->spider_thread_id, + spider->wide_handler->trx->thd->query_id, spider, 1, NULL}; + /* no record is ok */ + if (!(res = conn->db_conn->store_result(NULL, &request_key, &error_num)) && + (error_num || (error_num = spider_db_errorno(conn)))) + DBUG_RETURN(spider_teardown_after_query(conn, error_num, true)); + spider_teardown_after_query(conn, 0, true); + if (res) + error_num = res->fetch_table_cardinality( + crd_mode, table, share->cardinality, share->cardinality_upd, + share->bitmap_size); + for (field = 0, tmp_crd = share->cardinality; + field < (int) table->s->fields; + field++, tmp_crd++) + { + if (!spider_bit_is_set(share->cardinality_upd, field)) { - switch (error_num) - { - case ER_SPIDER_REMOTE_TABLE_NOT_FOUND_NUM: - my_printf_error(ER_SPIDER_REMOTE_TABLE_NOT_FOUND_NUM, - ER_SPIDER_REMOTE_TABLE_NOT_FOUND_STR, MYF(0), - mysql_share->db_names_str[spider->conn_link_idx[link_idx]].ptr(), - mysql_share->table_names_str[spider->conn_link_idx[ - link_idx]].ptr()); - break; - case ER_SPIDER_INVALID_REMOTE_TABLE_INFO_NUM: - my_printf_error(ER_SPIDER_INVALID_REMOTE_TABLE_INFO_NUM, - ER_SPIDER_INVALID_REMOTE_TABLE_INFO_STR, MYF(0), - mysql_share->db_names_str[spider->conn_link_idx[link_idx]].ptr(), - mysql_share->table_names_str[spider->conn_link_idx[ - link_idx]].ptr()); - break; - default: - break; - } - DBUG_RETURN(error_num); + DBUG_PRINT("info", + ("spider uninitialized column cardinality id=%d", field)); + *tmp_crd = -1; } } - DBUG_RETURN(0); + if (res) + { + res->free_result(); + delete res; + } + switch (error_num) + { + case ER_SPIDER_REMOTE_TABLE_NOT_FOUND_NUM: + my_printf_error( + ER_SPIDER_REMOTE_TABLE_NOT_FOUND_NUM, + ER_SPIDER_REMOTE_TABLE_NOT_FOUND_STR, MYF(0), + mysql_share->db_names_str[spider->conn_link_idx[link_idx]].ptr(), + mysql_share->table_names_str[spider->conn_link_idx[link_idx]].ptr()); + break; + case ER_SPIDER_INVALID_REMOTE_TABLE_INFO_NUM: + my_printf_error( + ER_SPIDER_INVALID_REMOTE_TABLE_INFO_NUM, + ER_SPIDER_INVALID_REMOTE_TABLE_INFO_STR, MYF(0), + mysql_share->db_names_str[spider->conn_link_idx[link_idx]].ptr(), + mysql_share->table_names_str[spider->conn_link_idx[link_idx]].ptr()); + break; + default: + break; + } + DBUG_RETURN(error_num); } int spider_mbase_handler::simple_action( diff --git a/storage/spider/spd_include.h b/storage/spider/spd_include.h index 35f348ca999..10675aee3ef 100644 --- a/storage/spider/spd_include.h +++ b/storage/spider/spd_include.h @@ -148,9 +148,14 @@ typedef start_new_trans *SPIDER_Open_tables_backup; #define spider_bit_is_set(BITMAP, BIT) \ (uint) ((BITMAP)[(BIT) / 8] & (1 << ((BIT) & 7))) +/* Change status of the remote backend server link. */ +/* 0 Doesn't change status. */ #define SPIDER_LINK_STATUS_NO_CHANGE 0 +/* 1 Changes status to OK. */ #define SPIDER_LINK_STATUS_OK 1 +/* 2 Changes status to RECOVERY. */ #define SPIDER_LINK_STATUS_RECOVERY 2 +/* 3 Changes status to no more in group communication. */ #define SPIDER_LINK_STATUS_NG 3 #define SPIDER_LINK_MON_OK 0 @@ -699,22 +704,30 @@ typedef struct st_spider_share char *table_name; uint table_name_length; uint use_count; + /** + Probably equals `active_link_count`. See also commit ddff602 of + https://github.com/nayuta-yanagisawa/spider-history + + FIXME: consider removing it and using `active_link_count` instead. + */ uint link_count; + /* Number of all links, i.e. all remote servers for the spider + table. */ uint all_link_count; uint link_bitmap_size; pthread_mutex_t mutex; pthread_mutex_t sts_mutex; pthread_mutex_t crd_mutex; -/* - pthread_mutex_t auto_increment_mutex; -*/ TABLE_SHARE *table_share; SPIDER_LGTM_TBLHND_SHARE *lgtm_tblhnd_share; my_hash_value_type table_name_hash_value; my_hash_value_type table_path_hash_value; + /* Whether the share has been initialised */ volatile bool init; + /* Whether an error occurred in initialisation of this share */ volatile bool init_error; + /* The time of the initialisation error */ volatile time_t init_error_time; volatile bool link_status_init; uchar *table_mon_mutex_bitmap; @@ -770,10 +783,6 @@ typedef struct st_spider_share MEM_ROOT mem_root; -/* - volatile bool auto_increment_init; - volatile ulonglong auto_increment_lclval; -*/ ha_statistics stat; longlong static_records_for_status; @@ -788,17 +797,27 @@ typedef struct st_spider_share longlong additional_table_flags; bool have_recovery_link; + /** See `mysql_sysvar_sts_bg_mode` */ int sts_bg_mode; + /** See `mysql_sysvar_sts_interval` */ double sts_interval; + /** See `mysql_sysvar_sts_mode` */ int sts_mode; + /** See `mysql_sysvar_sts_sync` */ int sts_sync; int store_last_sts; + /** See `mysql_sysvar_load_sts_at_startup` */ int load_sts_at_startup; + /** See `mysql_sysvar_crd_bg_mode` */ int crd_bg_mode; + /** See `mysql_sysvar_crd_interval` */ double crd_interval; + /** See `mysql_sysvar_crd_mode` */ int crd_mode; + /** See `mysql_sysvar_crd_sync` */ int crd_sync; int store_last_crd; + /** See `mysql_sysvar_load_crd_at_startup` */ int load_crd_at_startup; int crd_type; double crd_weight; @@ -836,6 +855,7 @@ typedef struct st_spider_share longlong bgs_second_read; longlong first_read; longlong second_read; + /** See `mysql_sysvar_auto_increment_mode` */ int auto_increment_mode; int use_table_charset; int use_pushdown_udf; @@ -846,6 +866,8 @@ typedef struct st_spider_share int read_only_mode; int error_read_mode; int error_write_mode; + /* Number of active remote servers, for use in load balancing read + connections */ int active_link_count; #ifdef HA_CAN_FORCE_BULK_UPDATE int force_bulk_update; @@ -868,6 +890,8 @@ typedef struct st_spider_share char **tgt_usernames; char **tgt_passwords; char **tgt_sockets; + /** The wrapper of target servers, each element has the same + possible values as `SPIDER_DBTON::wrapper` */ char **tgt_wrappers; char **tgt_ssl_cas; char **tgt_ssl_capaths; @@ -885,6 +909,7 @@ typedef struct st_spider_share char **conn_keys; long *tgt_ports; long *tgt_ssl_vscs; + /* See SPIDER_LINK_STATUS_* in spd_include.h */ long *link_statuses; long *monitoring_bg_flag; long *monitoring_bg_kind; @@ -897,6 +922,7 @@ typedef struct st_spider_share long *connect_timeouts; long *net_read_timeouts; long *net_write_timeouts; + /* Connection load balancing integer weight */ long *access_balances; long *bka_table_name_types; long *strict_group_bys; @@ -988,10 +1014,16 @@ typedef struct st_spider_share uint bka_table_name_types_length; uint strict_group_bys_length; - /* for dbton */ + /* + For dbton. A `SPIDER_SHARE` uses all `SPIDER_DBTON`s with the same + wrappers as any its `tgt_wrappers` + */ + /* Specifies which dbtons of the `spider_dbton` to use */ uchar dbton_bitmap[spider_bitmap_size(SPIDER_DBTON_SIZE)]; spider_db_share *dbton_share[SPIDER_DBTON_SIZE]; + /* Number of `SPIDER_DBTON`s used */ uint use_dbton_count; + /* Index of each `SPIDER_DBTON` in `spider_dbton` to use */ uint use_dbton_ids[SPIDER_DBTON_SIZE]; uint dbton_id_to_seq[SPIDER_DBTON_SIZE]; uint use_sql_dbton_count; @@ -1008,14 +1040,23 @@ typedef struct st_spider_link_pack int link_idx; } SPIDER_LINK_PACK; +/** A struct storing the initialisation error of a table. All +instances are in `spider_init_error_tables` */ typedef struct st_spider_init_error_table { + /* The associated table name */ char *table_name; + /* Length of the associated table name */ uint table_name_length; + /* Hash value of the associated table name for lookup */ my_hash_value_type table_name_hash_value; + /* Whether the error has a message */ bool init_error_with_message; + /* The error message */ char init_error_msg[MYSQL_ERRMSG_SIZE]; + /* The error code */ volatile int init_error; + /* The error time */ volatile time_t init_error_time; } SPIDER_INIT_ERROR_TABLE; diff --git a/storage/spider/spd_param.cc b/storage/spider/spd_param.cc index 0a5d881749c..dfd98b9fbc0 100644 --- a/storage/spider/spd_param.cc +++ b/storage/spider/spd_param.cc @@ -1771,7 +1771,7 @@ int spider_param_sts_mode( /* -1 :use table parameter 0 :No synchronization. - 1 :Table state is synchronized when opening a table. + 1 :Table stat is synchronized when opening a table. Then no synchronization. 2 :Synchronization. */ diff --git a/storage/spider/spd_param.h b/storage/spider/spd_param.h index 6abdca43492..a7573a6fb29 100644 --- a/storage/spider/spd_param.h +++ b/storage/spider/spd_param.h @@ -316,7 +316,6 @@ my_bool spider_param_index_hint_pushdown( ); uint spider_param_max_connections(); uint spider_param_conn_wait_timeout(); -uint spider_param_internal_lock_wait_timeout(); uint spider_param_log_result_errors(); uint spider_param_log_result_error_with_sql(); uint spider_param_internal_xa_id_type( diff --git a/storage/spider/spd_ping_table.cc b/storage/spider/spd_ping_table.cc index 3de30e6a80b..056c21e07ec 100644 --- a/storage/spider/spd_ping_table.cc +++ b/storage/spider/spd_ping_table.cc @@ -505,7 +505,7 @@ SPIDER_TABLE_MON_LIST *spider_get_ping_table_tgt( (*error_num = spider_get_sys_tables_connect_info( table_tables, tmp_share, 0, &mem_root)) || (*error_num = spider_get_sys_tables_link_status( - table_tables, tmp_share, 0, &mem_root)) + table_tables, tmp_share->link_statuses, &mem_root)) ) { table_tables->file->print_error(*error_num, MYF(0)); goto error; diff --git a/storage/spider/spd_sys_table.cc b/storage/spider/spd_sys_table.cc index b42215a2da3..7b96c483d5e 100644 --- a/storage/spider/spd_sys_table.cc +++ b/storage/spider/spd_sys_table.cc @@ -979,6 +979,16 @@ void spider_store_xa_member_info( DBUG_VOID_RETURN; } +/** + Stores the DB and table names in a table + + If `name` starts with "./", separates out db and table names from + `name`. Otherwise stores empty strings as names + + @param table The table to store the info + @param name The name of the table + @param name_length The length of the name +*/ void spider_store_tables_name( TABLE *table, const char *name, @@ -1443,6 +1453,12 @@ void spider_store_binlog_pos_gtid( DBUG_VOID_RETURN; } +/** + Stores sts info in the spider sts table + + Stores all fields except the db name and table name, which are + stored in `spider_store_tables_name()`. +*/ void spider_store_table_sts_info( TABLE *table, ha_statistics *stat @@ -1595,6 +1611,18 @@ int spider_insert_sys_table( DBUG_RETURN(error_num); } +/** + Inserts or updates a row in the spider sts system table + + @param table The spider sts system table + @param name The name of the spider table whose stat will be + inserted / updated in the sts table + @param name_length Length of the name + @param stat The stat of the spider table that will be + inserted / updated in the sts table + + @retval 0 or error +*/ int spider_insert_or_update_table_sts( TABLE *table, const char *name, @@ -2642,31 +2670,22 @@ int spider_get_sys_tables_monitoring_binlog_pos_at_failing( DBUG_RETURN(error_num); } -int spider_get_sys_tables_link_status( - TABLE *table, - SPIDER_SHARE *share, - int link_idx, - MEM_ROOT *mem_root -) { - char *ptr; - int error_num = 0; - DBUG_ENTER("spider_get_sys_tables_link_status"); - if ((ptr = get_field(mem_root, table->field[SPIDER_TABLES_LINK_STATUS_POS]))) - { - share->link_statuses[link_idx] = - (long) my_strtoll10(ptr, (char**) NULL, &error_num); - } else - share->link_statuses[link_idx] = 1; - DBUG_PRINT("info",("spider link_statuses[%d]=%ld", - link_idx, share->link_statuses[link_idx])); - DBUG_RETURN(error_num); -} - +/** + Reads a table field and updates a link_status of a spider share + + @param table The system table (`spider_tables` table) to read the + field from + @param share The share to update its link status with + @param link_idx Which link status to update + @param mem_root MEM_ROOT for allocating + @reval 0 for success, or error num +*/ int spider_get_sys_tables_link_status( TABLE *table, long *link_status, MEM_ROOT *mem_root -) { +) +{ char *ptr; int error_num = 0; DBUG_ENTER("spider_get_sys_tables_link_status"); @@ -2674,7 +2693,6 @@ int spider_get_sys_tables_link_status( *link_status = (long) my_strtoll10(ptr, (char**) NULL, &error_num); else *link_status = 1; - DBUG_PRINT("info",("spider link_statuses=%ld", *link_status)); DBUG_RETURN(error_num); } @@ -2716,6 +2734,14 @@ int spider_get_sys_tables_static_link_id( DBUG_RETURN(error_num); } +/** + Reads the table status from the system sts table + + The result is set into `stat` + + @param table The system sts table + @param stat The stat to read the table status into +*/ void spider_get_sys_table_sts_info( TABLE *table, ha_statistics *stat @@ -3173,6 +3199,15 @@ int spider_get_sys_link_mon_connect_info( DBUG_RETURN(error_num); } +/** + Reads link statuses from the spider_tables system table into a + spider share + + @param table The table to read from + @param share The spider share + @param mem_root MEM_ROOT for allocating + @reval 0 for success, or error code +*/ int spider_get_link_statuses( TABLE *table, SPIDER_SHARE *share, @@ -3191,14 +3226,10 @@ int spider_get_link_statuses( { if ( (error_num == HA_ERR_KEY_NOT_FOUND || error_num == HA_ERR_END_OF_FILE) - ) { -/* - table->file->print_error(error_num, MYF(0)); -*/ + ) DBUG_RETURN(error_num); - } - } else if ((error_num = - spider_get_sys_tables_link_status(table, share, roop_count, mem_root))) + } else if ((error_num = spider_get_sys_tables_link_status( + table, &share->link_statuses[roop_count], mem_root))) { table->file->print_error(error_num, MYF(0)); DBUG_RETURN(error_num); @@ -3207,6 +3238,16 @@ int spider_get_link_statuses( DBUG_RETURN(0); } +/** + Inserts or updates status of a table into the system sts table + + @param thd Connection + @param name Name of the table whose status will be stored + @param name_length Length of `name` + @param stat The table status that will be stored into the + system sts table + @reval 0 for success, or error code +*/ int spider_sys_insert_or_update_table_sts( THD *thd, const char *name, @@ -3345,6 +3386,14 @@ error: DBUG_RETURN(error_num); } +/** + Reads table status of a table from the system sts table. + + @param thd Connection + @param name The name of the table for which to read status of + @param name_length The length of `name` + @param stat The struct to read the status into +*/ int spider_sys_get_table_sts( THD *thd, const char *name, diff --git a/storage/spider/spd_sys_table.h b/storage/spider/spd_sys_table.h index 0ad98893322..6cb6c3957a7 100644 --- a/storage/spider/spd_sys_table.h +++ b/storage/spider/spd_sys_table.h @@ -439,13 +439,6 @@ int spider_get_sys_tables_monitoring_binlog_pos_at_failing( int spider_get_sys_tables_link_status( TABLE *table, - SPIDER_SHARE *share, - int link_idx, - MEM_ROOT *mem_root -); - -int spider_get_sys_tables_link_status( - TABLE *table, long *link_status, MEM_ROOT *mem_root ); diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc index dfdbbf4479c..0a652b7473e 100644 --- a/storage/spider/spd_table.cc +++ b/storage/spider/spd_table.cc @@ -122,6 +122,7 @@ static pthread_mutex_t *spd_LOCK_server_started; static pthread_cond_t *spd_COND_server_started; extern long spider_conn_mutex_id; handlerton *spider_hton_ptr; +/** All `SPIDER_DBTON`s */ SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE]; extern SPIDER_DBTON spider_dbton_mysql; extern SPIDER_DBTON spider_dbton_mariadb; @@ -267,6 +268,20 @@ ha_create_table_option spider_table_option_list[]= { HA_TOPTION_STRING("REMOTE_DATABASE", remote_database), HA_TOPTION_STRING("REMOTE_TABLE", remote_table), HA_TOPTION_END}; +/** + Determines how to populate sts (stat) / crd (cardinality) of a + spider share +*/ +enum ha_sts_crd_get_type +{ + HA_GET_COPY = 0, /* Get by copying from wide_share */ + HA_GET_FETCH = 1, /* Get by executing a sql query */ + HA_GET_AFTER_LOCK = 2, /* Get by executing a sql query after + locking wide_share->sts_mutex. */ + HA_GET_AFTER_TRYLOCK = 3 /* Get by executing a sql query after + trylocking wide_share->sts_mutex. */ +}; + extern HASH spider_open_connections; extern HASH spider_ipport_conns; extern uint spider_open_connections_id; @@ -295,6 +310,7 @@ const char *spider_open_tables_func_name; const char *spider_open_tables_file_name; ulong spider_open_tables_line_no; pthread_mutex_t spider_tbl_mutex; +/** All the `SPIDER_INIT_ERROR_TABLE`s */ HASH spider_init_error_tables; uint spider_init_error_tables_id; const char *spider_init_error_tables_func_name; @@ -342,6 +358,11 @@ extern ulonglong spider_free_mem_count[SPIDER_MEM_CALC_LIST_NUM]; static char spider_wild_many = '%', spider_wild_one = '_', spider_wild_prefix='\\'; +/** + `spider_unique_id` is used for identifying a spider table. It is set + to be a concatenation of the MAC address and the PID, give or take + some separators +*/ static char spider_unique_id_buf[1 + 12 + 1 + (16 * 2) + 1 + 1]; LEX_CSTRING spider_unique_id; @@ -4094,7 +4115,7 @@ void spider_print_keys( int spider_create_conn_keys( SPIDER_SHARE *share ) { - int roop_count, roop_count2; + int roop_count; char *tmp_name, port_str[6]; uint length_base = sizeof(uint) * share->all_link_count; uint *conn_keys_lengths; @@ -4112,70 +4133,79 @@ int spider_create_conn_keys( sql_dbton_ids = (uint *) ptr; share->conn_keys_charlen = 0; - for (roop_count = 0; roop_count < (int) share->all_link_count; roop_count++) + for (int all_link_idx = 0; all_link_idx < (int) share->all_link_count; all_link_idx++) { bool get_sql_id = FALSE; - for (roop_count2 = 0; roop_count2 < SPIDER_DBTON_SIZE; roop_count2++) - { - DBUG_PRINT("info",("spider share->tgt_wrappers[%d]=%s", roop_count, - share->tgt_wrappers[roop_count])); - DBUG_PRINT("info",("spider spider_dbton[%d].wrapper=%s", roop_count2, - spider_dbton[roop_count2].wrapper ? - spider_dbton[roop_count2].wrapper : "NULL")); + /** + Find all `SPIDER_DBTON`s with the same wrapper as the target + server and set the bitmap. Stop at the first `SPIDER_DBTON` whose + db_access_type is sql + + fixme: the logic may be more complicated than the intended + one. For one thing, ALL `SPIDER_DBTON`s have sql access + type. Consider removing everything to do with the db access + type. + */ + for (int dbton_idx = 0; dbton_idx < SPIDER_DBTON_SIZE; dbton_idx++) + { + DBUG_PRINT("info",("spider share->tgt_wrappers[%d]=%s", all_link_idx, + share->tgt_wrappers[all_link_idx])); + DBUG_PRINT("info",("spider spider_dbton[%d].wrapper=%s", dbton_idx, + spider_dbton[dbton_idx].wrapper ? + spider_dbton[dbton_idx].wrapper : "NULL")); if ( - spider_dbton[roop_count2].wrapper && - !strcmp(share->tgt_wrappers[roop_count], - spider_dbton[roop_count2].wrapper) + spider_dbton[dbton_idx].wrapper && + !strcmp(share->tgt_wrappers[all_link_idx], + spider_dbton[dbton_idx].wrapper) ) { - spider_set_bit(share->dbton_bitmap, roop_count2); + spider_set_bit(share->dbton_bitmap, dbton_idx); if ( !get_sql_id && - spider_dbton[roop_count2].db_access_type == SPIDER_DB_ACCESS_TYPE_SQL + spider_dbton[dbton_idx].db_access_type == SPIDER_DB_ACCESS_TYPE_SQL ) { - sql_dbton_ids[roop_count] = roop_count2; + sql_dbton_ids[all_link_idx] = dbton_idx; get_sql_id = TRUE; break; } } } if (!get_sql_id) - sql_dbton_ids[roop_count] = SPIDER_DBTON_SIZE; + sql_dbton_ids[all_link_idx] = SPIDER_DBTON_SIZE; bool tables_on_different_db_are_joinable; if (get_sql_id) { tables_on_different_db_are_joinable = - spider_dbton[sql_dbton_ids[roop_count]].db_util-> + spider_dbton[sql_dbton_ids[all_link_idx]].db_util-> tables_on_different_db_are_joinable(); } else { tables_on_different_db_are_joinable = TRUE; } - conn_keys_lengths[roop_count] + conn_keys_lengths[all_link_idx] = 1 - + share->tgt_wrappers_lengths[roop_count] + 1 - + share->tgt_hosts_lengths[roop_count] + 1 + + share->tgt_wrappers_lengths[all_link_idx] + 1 + + share->tgt_hosts_lengths[all_link_idx] + 1 + 5 + 1 - + share->tgt_sockets_lengths[roop_count] + 1 + + share->tgt_sockets_lengths[all_link_idx] + 1 + (tables_on_different_db_are_joinable ? - 0 : share->tgt_dbs_lengths[roop_count] + 1) - + share->tgt_usernames_lengths[roop_count] + 1 - + share->tgt_passwords_lengths[roop_count] + 1 - + share->tgt_ssl_cas_lengths[roop_count] + 1 - + share->tgt_ssl_capaths_lengths[roop_count] + 1 - + share->tgt_ssl_certs_lengths[roop_count] + 1 - + share->tgt_ssl_ciphers_lengths[roop_count] + 1 - + share->tgt_ssl_keys_lengths[roop_count] + 1 + 0 : share->tgt_dbs_lengths[all_link_idx] + 1) + + share->tgt_usernames_lengths[all_link_idx] + 1 + + share->tgt_passwords_lengths[all_link_idx] + 1 + + share->tgt_ssl_cas_lengths[all_link_idx] + 1 + + share->tgt_ssl_capaths_lengths[all_link_idx] + 1 + + share->tgt_ssl_certs_lengths[all_link_idx] + 1 + + share->tgt_ssl_ciphers_lengths[all_link_idx] + 1 + + share->tgt_ssl_keys_lengths[all_link_idx] + 1 + 1 + 1 - + share->tgt_default_files_lengths[roop_count] + 1 - + share->tgt_default_groups_lengths[roop_count] + 1 - + share->tgt_dsns_lengths[roop_count] + 1 - + share->tgt_filedsns_lengths[roop_count] + 1 - + share->tgt_drivers_lengths[roop_count]; - share->conn_keys_charlen += conn_keys_lengths[roop_count] + 2; + + share->tgt_default_files_lengths[all_link_idx] + 1 + + share->tgt_default_groups_lengths[all_link_idx] + 1 + + share->tgt_dsns_lengths[all_link_idx] + 1 + + share->tgt_filedsns_lengths[all_link_idx] + 1 + + share->tgt_drivers_lengths[all_link_idx]; + share->conn_keys_charlen += conn_keys_lengths[all_link_idx] + 2; } if (!(share->conn_keys = (char **) - spider_bulk_alloc_mem(spider_current_trx, 45, - __func__, __FILE__, __LINE__, MYF(MY_WME | MY_ZEROFILL), + spider_bulk_malloc(spider_current_trx, 45, MYF(MY_WME | MY_ZEROFILL), &share->conn_keys, sizeof(char *) * share->all_link_count, &share->conn_keys_lengths, length_base, &share->conn_keys_hash_value, @@ -4331,15 +4361,15 @@ int spider_create_conn_keys( &spider_open_connections, (uchar*) share->conn_keys[roop_count], share->conn_keys_lengths[roop_count]); } - for (roop_count2 = 0; roop_count2 < SPIDER_DBTON_SIZE; roop_count2++) + for (int dbton_idx = 0; dbton_idx < SPIDER_DBTON_SIZE; dbton_idx++) { - if (spider_bit_is_set(share->dbton_bitmap, roop_count2)) + if (spider_bit_is_set(share->dbton_bitmap, dbton_idx)) { - share->use_sql_dbton_ids[share->use_dbton_count] = roop_count2; - share->sql_dbton_id_to_seq[roop_count2] = share->use_dbton_count; - share->use_sql_dbton_count++; - share->use_dbton_ids[share->use_dbton_count] = roop_count2; - share->dbton_id_to_seq[roop_count2] = share->use_dbton_count; + share->use_sql_dbton_ids[share->use_dbton_count] = dbton_idx; + share->sql_dbton_id_to_seq[dbton_idx] = share->use_dbton_count; + share->use_sql_dbton_count++; + share->use_dbton_ids[share->use_dbton_count] = dbton_idx; + share->dbton_id_to_seq[dbton_idx] = share->use_dbton_count; share->use_dbton_count++; } } @@ -4539,1002 +4569,624 @@ error_alloc_share: DBUG_RETURN(NULL); } -SPIDER_SHARE *spider_get_share( - const char *table_name, - TABLE *table, - THD *thd, - ha_spider *spider, - int *error_num -) { - SPIDER_SHARE *share; - TABLE_SHARE *table_share = table->s; - SPIDER_RESULT_LIST *result_list = &spider->result_list; - uint length, tmp_conn_link_idx = 0, buf_sz; - char *tmp_name; - int roop_count; - double sts_interval; - int sts_mode; - int sts_sync; - int auto_increment_mode; - double crd_interval; - int crd_mode; - int crd_sync; - char first_byte; - int semi_table_lock_conn; - int search_link_idx; - uint sql_command = thd_sql_command(thd); - SPIDER_Open_tables_backup open_tables_backup; - MEM_ROOT mem_root; - TABLE *table_tables = NULL; - bool init_mem_root = FALSE; - bool same_server_link; - int load_sts_at_startup; - int load_crd_at_startup; - user_var_entry *loop_check; - char *loop_check_buf; - TABLE_SHARE *top_share; - LEX_CSTRING lex_str; - DBUG_ENTER("spider_get_share"); - top_share = spider->wide_handler->top_share; - length = (uint) strlen(table_name); - my_hash_value_type hash_value = my_calc_hash(&spider_open_tables, - (uchar*) table_name, length); - if (top_share) - { - lex_str.length = top_share->path.length + SPIDER_SQL_LOP_CHK_PRM_PRF_LEN; - buf_sz = spider_unique_id.length > SPIDER_SQL_LOP_CHK_PRM_PRF_LEN ? - top_share->path.length + spider_unique_id.length + 2 : - lex_str.length + 2; - loop_check_buf = (char *) my_alloca(buf_sz); - if (unlikely(!loop_check_buf)) - { - *error_num = HA_ERR_OUT_OF_MEM; - DBUG_RETURN(NULL); - } - lex_str.str = loop_check_buf + buf_sz - lex_str.length - 2; - memcpy((void *) lex_str.str, - SPIDER_SQL_LOP_CHK_PRM_PRF_STR, SPIDER_SQL_LOP_CHK_PRM_PRF_LEN); - memcpy((void *) (lex_str.str + SPIDER_SQL_LOP_CHK_PRM_PRF_LEN), - top_share->path.str, top_share->path.length); - ((char *) lex_str.str)[lex_str.length] = '\0'; - DBUG_PRINT("info",("spider loop check param name=%s", lex_str.str)); - loop_check = get_variable(&thd->user_vars, &lex_str, FALSE); - if (loop_check && loop_check->type == STRING_RESULT) - { - lex_str.length = top_share->path.length + spider_unique_id.length + 1; - lex_str.str = loop_check_buf + buf_sz - top_share->path.length - - spider_unique_id.length - 2; - memcpy((void *) lex_str.str, spider_unique_id.str, - spider_unique_id.length); - ((char *) lex_str.str)[lex_str.length - 1] = '-'; - ((char *) lex_str.str)[lex_str.length] = '\0'; - DBUG_PRINT("info",("spider loop check key=%s", lex_str.str)); - DBUG_PRINT("info",("spider loop check param value=%s", - loop_check->value)); - if (unlikely(strstr(loop_check->value, lex_str.str))) - { - *error_num = ER_SPIDER_INFINITE_LOOP_NUM; - my_printf_error(*error_num, ER_SPIDER_INFINITE_LOOP_STR, MYF(0), - top_share->db.str, top_share->table_name.str); - my_afree(loop_check_buf); - DBUG_RETURN(NULL); - } +/** + Checks for spider table self-reference + + Get the user variable value (source) and compare it with the user + variable name (target). If the target is a substring of the source, + then there is a self-reference + + @param thd Connection + @param share The table share + @retval 0 for success, or else the error number +*/ +int spider_check_for_self_reference(THD *thd, const TABLE_SHARE *share) +{ + String target(0); + LEX_CSTRING key; + DBUG_ENTER("spider_check_for_self_reference"); + + target.append(STRING_WITH_LEN(SPIDER_SQL_LOP_CHK_PRM_PRF_STR)); + target.append(share->path); + DBUG_PRINT("info",("spider loop check param name=%s", target.c_ptr())); + key = target.to_lex_cstring(); + const user_var_entry *loop_check= get_variable(&thd->user_vars, &key, FALSE); + if (loop_check && loop_check->type == STRING_RESULT) + { + String expected(0); + expected.append(spider_unique_id); + expected.append(share->path); + expected.append(STRING_WITH_LEN("-")); + DBUG_PRINT("info",("spider loop check expected=%s", expected.c_ptr())); + DBUG_PRINT("info",("spider loop check param value=%s", + loop_check->value)); + if (unlikely(strstr(loop_check->value, expected.c_ptr()))) + { + const int error_num = ER_SPIDER_INFINITE_LOOP_NUM; + my_printf_error(error_num, ER_SPIDER_INFINITE_LOOP_STR, MYF(0), + share->db.str, share->table_name.str); + DBUG_RETURN(error_num); } - my_afree(loop_check_buf); } - pthread_mutex_lock(&spider_tbl_mutex); - if (!(share = (SPIDER_SHARE*) my_hash_search_using_hash_value( - &spider_open_tables, hash_value, (uchar*) table_name, length))) - { - if (!(share = spider_create_share( - table_name, table_share, - table->part_info, - hash_value, - error_num - ))) { - goto error_alloc_share; - } + DBUG_RETURN(0); +} - uint old_elements = spider_open_tables.array.max_element; - if (my_hash_insert(&spider_open_tables, (uchar*) share)) +/** Populate the init_errors and init of share and/or free it */ +void spider_share_init_error_free( + SPIDER_SHARE *share, + const bool init, + const bool free_share +) +{ + share->init_error= TRUE; + share->init_error_time= (time_t) time((time_t *) 0); + share->init= TRUE; + if (free_share) + spider_free_share(share); +} + +void spider_lock_udf_table_mon_mutexes(SPIDER_SHARE *share) +{ + pthread_mutex_lock(&share->mutex); + for (int roop_count = 0; + roop_count < (int) spider_udf_table_mon_mutex_count; + roop_count++) { - *error_num = HA_ERR_OUT_OF_MEM; - goto error_hash_insert; + if (spider_bit_is_set(share->table_mon_mutex_bitmap, roop_count)) + pthread_mutex_lock(&spider_udf_table_mon_mutexes[roop_count]); } - if (spider_open_tables.array.max_element > old_elements) +} + +void spider_unlock_udf_table_mon_mutexes(SPIDER_SHARE *share) +{ + for (int roop_count = 0; + roop_count < (int) spider_udf_table_mon_mutex_count; + roop_count++) { - spider_alloc_calc_mem(spider_current_trx, - spider_open_tables, - (spider_open_tables.array.max_element - old_elements) * - spider_open_tables.array.size_of_element); + if (spider_bit_is_set(share->table_mon_mutex_bitmap, roop_count)) + pthread_mutex_unlock(&spider_udf_table_mon_mutexes[roop_count]); } + pthread_mutex_unlock(&share->mutex); +} - spider->share = share; - spider->conn_link_idx = &tmp_conn_link_idx; +/** + Initialises the link_statuses of a spider share + + Open the spider_tables system table, read the link_statuses and + update the spider share, and close the table. Frees share if + failure + + @param thd Connection + @param share The spider share to populate the link_statuses of + @param table_share fixme + @param sql_command The sql command of the thread + @param error_num The error number + @retval true Failure + false Success +*/ +bool spider_share_init_link_statuses( + THD *thd, + SPIDER_SHARE *share, + TABLE_SHARE *table_share, + const int sql_command, + const bool init_share, + int *error_num +) +{ + MEM_ROOT mem_root; + bool init_mem_root= FALSE; + TABLE *table_tables; + SPIDER_Open_tables_backup open_tables_backup; + DBUG_ENTER("spider_share_init_link_statuses"); + /* + The link statuses need to be refreshed from the spider_tables table + if the operation: + - Is not a DROP TABLE on a permanent table; or + - Is an ALTER TABLE. - share->use_count++; - pthread_mutex_unlock(&spider_tbl_mutex); + Note that SHOW CREATE TABLE is not excluded, because the commands + that follow it require up-to-date link statuses. + */ + if ((table_share->tmp_table == NO_TMP_TABLE && + sql_command != SQLCOM_DROP_TABLE) || + /* for alter change link status */ + sql_command == SQLCOM_ALTER_TABLE) + { + SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME)); + init_mem_root = TRUE; - if (!share->link_status_init) + if (!(table_tables = + spider_open_sys_table(thd, SPIDER_SYS_TABLES_TABLE_NAME_STR, + SPIDER_SYS_TABLES_TABLE_NAME_LEN, FALSE, + &open_tables_backup, error_num))) { - pthread_mutex_lock(&share->mutex); - for (roop_count = 0; - roop_count < (int) spider_udf_table_mon_mutex_count; - roop_count++ - ) { - if (spider_bit_is_set(share->table_mon_mutex_bitmap, roop_count)) - pthread_mutex_lock(&spider_udf_table_mon_mutexes[roop_count]); - } - if (!share->link_status_init) + spider_unlock_udf_table_mon_mutexes(share); + spider_share_init_error_free(share, true, true); + free_root(&mem_root, MYF(0)); + DBUG_RETURN(TRUE); + } + if ((*error_num= spider_get_link_statuses(table_tables, share, + &mem_root))) + { + if (*error_num != HA_ERR_KEY_NOT_FOUND && + *error_num != HA_ERR_END_OF_FILE) { - /* - The link statuses need to be refreshed from the spider_tables table - if the operation: - - Is not a DROP TABLE on a permanent table; or - - Is an ALTER TABLE. - - Note that SHOW CREATE TABLE is not excluded, because the commands - that follow it require up-to-date link statuses. - */ - if ((table_share->tmp_table == NO_TMP_TABLE && - sql_command != SQLCOM_DROP_TABLE) || - /* for alter change link status */ - sql_command == SQLCOM_ALTER_TABLE) - { - SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME)); - init_mem_root = TRUE; - - if ( - !(table_tables = spider_open_sys_table( - thd, SPIDER_SYS_TABLES_TABLE_NAME_STR, - SPIDER_SYS_TABLES_TABLE_NAME_LEN, FALSE, &open_tables_backup, - error_num)) - ) { - for (roop_count = 0; - roop_count < (int) spider_udf_table_mon_mutex_count; - roop_count++ - ) { - if (spider_bit_is_set(share->table_mon_mutex_bitmap, roop_count)) - pthread_mutex_unlock(&spider_udf_table_mon_mutexes[roop_count]); - } - pthread_mutex_unlock(&share->mutex); - share->init_error = TRUE; - share->init_error_time = (time_t) time((time_t*) 0); - share->init = TRUE; - spider_free_share(share); - goto error_open_sys_table; - } - *error_num = spider_get_link_statuses(table_tables, share, - &mem_root); - if (*error_num) - { - if ( - *error_num != HA_ERR_KEY_NOT_FOUND && - *error_num != HA_ERR_END_OF_FILE - ) { - for (roop_count = 0; - roop_count < (int) spider_udf_table_mon_mutex_count; - roop_count++ - ) { - if (spider_bit_is_set(share->table_mon_mutex_bitmap, roop_count)) - pthread_mutex_unlock(&spider_udf_table_mon_mutexes[roop_count]); - } - pthread_mutex_unlock(&share->mutex); - share->init_error = TRUE; - share->init_error_time = (time_t) time((time_t*) 0); - share->init = TRUE; - spider_free_share(share); - spider_sys_close_table(thd, &open_tables_backup); - table_tables = NULL; - goto error_open_sys_table; - } - } else { - memcpy(share->alter_table.tmp_link_statuses, share->link_statuses, - sizeof(long) * share->all_link_count); - share->link_status_init = TRUE; - } - spider_sys_close_table(thd, &open_tables_backup); - table_tables = NULL; - } - share->have_recovery_link = spider_conn_check_recovery_link(share); - if (init_mem_root) - { - free_root(&mem_root, MYF(0)); - init_mem_root = FALSE; - } - } - for (roop_count = 0; - roop_count < (int) spider_udf_table_mon_mutex_count; - roop_count++ - ) { - if (spider_bit_is_set(share->table_mon_mutex_bitmap, roop_count)) - pthread_mutex_unlock(&spider_udf_table_mon_mutexes[roop_count]); + spider_unlock_udf_table_mon_mutexes(share); + spider_share_init_error_free(share, init_share, true); + spider_sys_close_table(thd, &open_tables_backup); + free_root(&mem_root, MYF(0)); + DBUG_RETURN(TRUE); } - pthread_mutex_unlock(&share->mutex); - } - - semi_table_lock_conn = spider_param_semi_table_lock_connection(thd, - share->semi_table_lock_conn); - if (semi_table_lock_conn) - first_byte = '0' + - spider_param_semi_table_lock(thd, share->semi_table_lock); - else - first_byte = '0'; - - if (!(spider->wide_handler->trx = spider_get_trx(thd, TRUE, error_num))) + } else { - share->init_error = TRUE; - share->init_error_time = (time_t) time((time_t*) 0); - share->init = TRUE; - spider_free_share(share); - goto error_but_no_delete; + memcpy(share->alter_table.tmp_link_statuses, share->link_statuses, + sizeof(long) * share->all_link_count); + share->link_status_init = TRUE; } - spider->set_error_mode(); + spider_sys_close_table(thd, &open_tables_backup); + } + share->have_recovery_link = spider_conn_check_recovery_link(share); + + if (init_mem_root) + free_root(&mem_root, MYF(0)); + DBUG_RETURN(FALSE); +} - if (!share->sts_spider_init) +/** Creates an `ha_spider` for the sts thread of the spider share. */ +int spider_share_init_sts( + const char* table_name, + ha_spider *spider, + SPIDER_SHARE *share, + const bool init_share +) +{ + DBUG_ENTER("spider_share_init_sts"); + if (int error_num = spider_create_spider_object_for_share( + spider->wide_handler->trx, share, &share->sts_spider)) { - pthread_mutex_lock(&share->mutex); - if (!share->sts_spider_init) - { - if ((*error_num = spider_create_spider_object_for_share( - spider->wide_handler->trx, share, &share->sts_spider))) - { - pthread_mutex_unlock(&share->mutex); - share->init_error = TRUE; - share->init_error_time = (time_t) time((time_t*) 0); - share->init = TRUE; - spider_free_share(share); - goto error_sts_spider_init; - } - share->sts_thread = &spider_table_sts_threads[ - my_calc_hash(&spider_open_tables, (uchar*) table_name, length) % - spider_param_table_sts_thread_count()]; - share->sts_spider_init = TRUE; - } pthread_mutex_unlock(&share->mutex); + spider_share_init_error_free(share, init_share, true); + DBUG_RETURN(error_num); } + share->sts_thread = + &spider_table_sts_threads[my_calc_hash(&spider_open_tables, + (uchar *) table_name, + (uint) strlen(table_name)) % + spider_param_table_sts_thread_count()]; + share->sts_spider_init = TRUE; + DBUG_RETURN(0); +} - if (!share->crd_spider_init) +/** Creates an `ha_spider` for the crd thread of the spider share */ +int spider_share_init_crd( + const char* table_name, + ha_spider *spider, + SPIDER_SHARE *share, + const bool init_share +) +{ + DBUG_ENTER("spider_share_init_crd"); + if (int error_num = spider_create_spider_object_for_share( + spider->wide_handler->trx, share, &share->crd_spider)) { - pthread_mutex_lock(&share->mutex); - if (!share->crd_spider_init) - { - if ((*error_num = spider_create_spider_object_for_share( - spider->wide_handler->trx, share, &share->crd_spider))) - { - pthread_mutex_unlock(&share->mutex); - share->init_error = TRUE; - share->init_error_time = (time_t) time((time_t*) 0); - share->init = TRUE; - spider_free_share(share); - goto error_crd_spider_init; - } - share->crd_thread = &spider_table_crd_threads[ - my_calc_hash(&spider_open_tables, (uchar*) table_name, length) % - spider_param_table_crd_thread_count()]; - share->crd_spider_init = TRUE; - } pthread_mutex_unlock(&share->mutex); + spider_share_init_error_free(share, init_share, true); + DBUG_RETURN(error_num); } + share->crd_thread = + &spider_table_crd_threads[my_calc_hash(&spider_open_tables, + (uchar *) table_name, + (uint) strlen(table_name)) % + spider_param_table_crd_thread_count()]; + share->crd_spider_init = TRUE; + DBUG_RETURN(0); +} - if ( - sql_command != SQLCOM_DROP_TABLE && - sql_command != SQLCOM_ALTER_TABLE && - sql_command != SQLCOM_SHOW_CREATE && - (*error_num = spider_create_mon_threads(spider->wide_handler->trx, - share)) - ) { - share->init_error = TRUE; - share->init_error_time = (time_t) time((time_t*) 0); - share->init = TRUE; - spider_free_share(share); - goto error_but_no_delete; - } - - if (!(spider->conn_keys = (char **) - spider_bulk_alloc_mem(spider_current_trx, 47, - __func__, __FILE__, __LINE__, MYF(MY_WME | MY_ZEROFILL), - &spider->conn_keys, sizeof(char *) * share->link_count, - &tmp_name, sizeof(char) * share->conn_keys_charlen, - &spider->conns, sizeof(SPIDER_CONN *) * share->link_count, - &spider->conn_link_idx, sizeof(uint) * share->link_count, - &spider->conn_can_fo, sizeof(uchar) * share->link_bitmap_size, - &spider->connection_ids, sizeof(ulonglong) * share->link_count, - &spider->db_request_id, sizeof(ulonglong) * share->link_count, - &spider->db_request_phase, sizeof(uchar) * share->link_bitmap_size, - &spider->need_mons, sizeof(int) * share->link_count, - &spider->quick_targets, sizeof(void *) * share->link_count, - &result_list->upd_tmp_tbls, sizeof(TABLE *) * share->link_count, - &result_list->upd_tmp_tbl_prms, - sizeof(TMP_TABLE_PARAM) * share->link_count, - &result_list->tmp_table_join_first, - sizeof(uchar) * share->link_bitmap_size, - &result_list->tmp_table_created, - sizeof(uchar) * share->link_bitmap_size, - &result_list->casual_read, sizeof(int) * share->link_count, - &spider->dbton_handler, - sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE, - NullS)) - ) { - share->init_error = TRUE; - share->init_error_time = (time_t) time((time_t*) 0); - share->init = TRUE; - spider_free_share(share); - goto error_but_no_delete; - } - memcpy(tmp_name, share->conn_keys[0], share->conn_keys_charlen); +void *spider_share_malloc_for_spider( + ha_spider *spider, + SPIDER_SHARE *share, + const uint id, + char** tmp_name, + SPIDER_RESULT_LIST* result_list +) +{ + return spider_bulk_malloc( + spider_current_trx, id, MYF(MY_WME | MY_ZEROFILL), + &spider->conn_keys, sizeof(char *) * share->link_count, + tmp_name, sizeof(char) * share->conn_keys_charlen, + &spider->conns, sizeof(SPIDER_CONN *) * share->link_count, + &spider->conn_link_idx, sizeof(uint) * share->link_count, + &spider->conn_can_fo, sizeof(uchar) * share->link_bitmap_size, + &spider->connection_ids, sizeof(ulonglong) * share->link_count, + &spider->db_request_id, sizeof(ulonglong) * share->link_count, + &spider->db_request_phase, sizeof(uchar) * share->link_bitmap_size, + &spider->need_mons, sizeof(int) * share->link_count, + &spider->quick_targets, sizeof(void *) * share->link_count, + &result_list->upd_tmp_tbls, sizeof(TABLE *) * share->link_count, + &result_list->upd_tmp_tbl_prms, + sizeof(TMP_TABLE_PARAM) * share->link_count, + &result_list->tmp_table_join_first, + sizeof(uchar) * share->link_bitmap_size, + &result_list->tmp_table_created, + sizeof(uchar) * share->link_bitmap_size, + &result_list->casual_read, sizeof(int) * share->link_count, + &spider->dbton_handler, + sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE, + NullS); +} - spider->conn_keys_first_ptr = tmp_name; - for (roop_count = 0; roop_count < (int) share->link_count; roop_count++) +/** + Initialise dbton_handlers of a spider. +*/ +int spider_share_init_spider_dbton_handlers(ha_spider *spider, SPIDER_SHARE *share) +{ + int roop_count, error_num= 0; + for (roop_count = 0; roop_count < (int) share->use_dbton_count; + roop_count++) + { + uint dbton_id = share->use_dbton_ids[roop_count]; + if (!(spider->dbton_handler[dbton_id]= + spider_dbton[dbton_id].create_db_handler(spider, + share->dbton_share[dbton_id]))) { - spider->conn_keys[roop_count] = tmp_name; - *tmp_name = first_byte; - tmp_name += share->conn_keys_lengths[roop_count] + 1; - result_list->upd_tmp_tbl_prms[roop_count].init(); - result_list->upd_tmp_tbl_prms[roop_count].field_count = 1; + error_num = HA_ERR_OUT_OF_MEM; + break; } - spider_trx_set_link_idx_for_all(spider); - - for (roop_count = 0; roop_count < (int) share->use_dbton_count; - roop_count++) + if ((error_num = spider->dbton_handler[dbton_id]->init())) + break; + } + /* Failure: rollback */ + if (roop_count < (int) share->use_dbton_count) + { + for (; roop_count >= 0; roop_count--) { uint dbton_id = share->use_dbton_ids[roop_count]; - if (!(spider->dbton_handler[dbton_id] = - spider_dbton[dbton_id].create_db_handler(spider, - share->dbton_share[dbton_id]))) - { - *error_num = HA_ERR_OUT_OF_MEM; - break; - } - if ((*error_num = spider->dbton_handler[dbton_id]->init())) + if (spider->dbton_handler[dbton_id]) { - break; + delete spider->dbton_handler[dbton_id]; + spider->dbton_handler[dbton_id]= NULL; } } - if (roop_count < (int) share->use_dbton_count) - { - for (; roop_count >= 0; roop_count--) + } + return error_num; +} + +/** Gets or creates connections to all active servers */ +bool spider_share_get_conns(ha_spider *spider, SPIDER_SHARE *share, + int *error_num) +{ + DBUG_ENTER("spider_share_get_conns"); + for (int roop_count = spider_conn_link_idx_next( + share->link_statuses, spider->conn_link_idx, -1, + share->link_count, SPIDER_LINK_STATUS_RECOVERY); + roop_count < (int) share->link_count; + roop_count = spider_conn_link_idx_next( + share->link_statuses, spider->conn_link_idx, roop_count, + share->link_count, SPIDER_LINK_STATUS_RECOVERY)) + { + if (!(spider->conns[roop_count] = + spider_get_conn(share, roop_count, spider->conn_keys[roop_count], + spider->wide_handler->trx, spider, FALSE, TRUE, + error_num))) + { + if (share->monitoring_kind[roop_count] && spider->need_mons[roop_count]) { - uint dbton_id = share->use_dbton_ids[roop_count]; - if (spider->dbton_handler[dbton_id]) - { - delete spider->dbton_handler[dbton_id]; - spider->dbton_handler[dbton_id] = NULL; - } + *error_num = spider_ping_table_mon_from_table( + spider->wide_handler->trx, + spider->wide_handler->trx->thd, + share, + roop_count, + (uint32) share->monitoring_sid[roop_count], + share->table_name, + share->table_name_length, + spider->conn_link_idx[roop_count], + NULL, + 0, + share->monitoring_kind[roop_count], + share->monitoring_limit[roop_count], + share->monitoring_flag[roop_count], + FALSE + ); } - share->init_error = TRUE; - share->init_error_time = (time_t) time((time_t*) 0); - share->init = TRUE; - goto error_after_alloc_conn_keys; + DBUG_RETURN(TRUE); } + spider->conns[roop_count]->error_mode &= spider->error_mode; + } + DBUG_RETURN(FALSE); +} - if ( - sql_command != SQLCOM_DROP_TABLE && - sql_command != SQLCOM_ALTER_TABLE && - sql_command != SQLCOM_SHOW_CREATE - ) { - for ( - roop_count = spider_conn_link_idx_next(share->link_statuses, - spider->conn_link_idx, -1, share->link_count, - SPIDER_LINK_STATUS_RECOVERY); - roop_count < (int) share->link_count; - roop_count = spider_conn_link_idx_next(share->link_statuses, - spider->conn_link_idx, roop_count, share->link_count, - SPIDER_LINK_STATUS_RECOVERY) - ) { - if ( - !(spider->conns[roop_count] = - spider_get_conn(share, roop_count, spider->conn_keys[roop_count], - spider->wide_handler->trx, spider, FALSE, TRUE, - error_num)) - ) { - if ( - share->monitoring_kind[roop_count] && - spider->need_mons[roop_count] - ) { - *error_num = spider_ping_table_mon_from_table( - spider->wide_handler->trx, - spider->wide_handler->trx->thd, - share, - roop_count, - (uint32) share->monitoring_sid[roop_count], - share->table_name, - share->table_name_length, - spider->conn_link_idx[roop_count], - NULL, - 0, - share->monitoring_kind[roop_count], - share->monitoring_limit[roop_count], - share->monitoring_flag[roop_count], - FALSE - ); - } - share->init_error = TRUE; - share->init_error_time = (time_t) time((time_t*) 0); - share->init = TRUE; - goto error_after_alloc_dbton_handler; - } - spider->conns[roop_count]->error_mode &= spider->error_mode; - } - } - search_link_idx = spider_conn_first_link_idx(thd, - share->link_statuses, share->access_balances, spider->conn_link_idx, - share->link_count, SPIDER_LINK_STATUS_OK); - if (search_link_idx == -1) - { - char *db = (char *) my_alloca( - table_share->db.length + 1 + table_share->table_name.length + 1); - if (!db) - { - *error_num = HA_ERR_OUT_OF_MEM; - share->init_error = TRUE; - share->init_error_time = (time_t) time((time_t*) 0); - share->init = TRUE; - goto error_after_alloc_dbton_handler; - } - char *table_name = db + table_share->db.length + 1; - memcpy(db, table_share->db.str, table_share->db.length); - db[table_share->db.length] = '\0'; - memcpy(table_name, table_share->table_name.str, - table_share->table_name.length); - table_name[table_share->table_name.length] = '\0'; - my_printf_error(ER_SPIDER_ALL_LINKS_FAILED_NUM, - ER_SPIDER_ALL_LINKS_FAILED_STR, MYF(0), db, table_name); - my_afree(db); - *error_num = ER_SPIDER_ALL_LINKS_FAILED_NUM; - share->init_error = TRUE; - share->init_error_time = (time_t) time((time_t*) 0); - share->init = TRUE; - goto error_after_alloc_dbton_handler; - } else if (search_link_idx == -2) +/** + Handles a failed search for usable servers + + @param share The spider share to update its init error + @param table_share The table share + @param search_result The search result, either -1 (no usable server) or + -2 (out of memory) + @return Error code associated with the failure +*/ +int spider_share_handle_search_link_failure( + SPIDER_SHARE* share, + TABLE_SHARE* table_share, + const int search_result, + const bool init_share +) +{ + DBUG_ENTER("spider_share_handle_search_link_failure"); + if (likely(search_result == -1)) /* No available servers. */ + { + char *db = (char *) my_alloca( + table_share->db.length + 1 + table_share->table_name.length + 1); + if (unlikely(!db)) { - *error_num = HA_ERR_OUT_OF_MEM; - share->init_error = TRUE; - share->init_error_time = (time_t) time((time_t*) 0); - share->init = TRUE; - goto error_after_alloc_dbton_handler; + spider_share_init_error_free(share, init_share, false); + DBUG_RETURN(HA_ERR_OUT_OF_MEM); } - spider->search_link_idx = search_link_idx; + char *table_name = db + table_share->db.length + 1; + memcpy(db, table_share->db.str, table_share->db.length); + db[table_share->db.length] = '\0'; + memcpy(table_name, table_share->table_name.str, + table_share->table_name.length); + table_name[table_share->table_name.length] = '\0'; + my_printf_error(ER_SPIDER_ALL_LINKS_FAILED_NUM, + ER_SPIDER_ALL_LINKS_FAILED_STR, MYF(0), db, table_name); + my_afree(db); + spider_share_init_error_free(share, init_share, false); + DBUG_RETURN(ER_SPIDER_ALL_LINKS_FAILED_NUM); + } + spider_share_init_error_free(share, init_share, false); + DBUG_RETURN(HA_ERR_OUT_OF_MEM); +} - same_server_link = spider_param_same_server_link(thd); - load_sts_at_startup = - spider_param_load_sts_at_startup(share->load_sts_at_startup); - load_crd_at_startup = - spider_param_load_crd_at_startup(share->load_crd_at_startup); - if ( - sql_command != SQLCOM_DROP_TABLE && - sql_command != SQLCOM_ALTER_TABLE && - sql_command != SQLCOM_SHOW_CREATE && - !spider->error_mode && - ( - !same_server_link || - load_sts_at_startup || - load_crd_at_startup - ) - ) { - SPIDER_INIT_ERROR_TABLE *spider_init_error_table; - sts_interval = spider_param_sts_interval(thd, share->sts_interval); - sts_mode = spider_param_sts_mode(thd, share->sts_mode); - sts_sync = spider_param_sts_sync(thd, share->sts_sync); - auto_increment_mode = spider_param_auto_increment_mode(thd, - share->auto_increment_mode); - if (auto_increment_mode == 1) - sts_sync = 0; - crd_interval = spider_param_crd_interval(thd, share->crd_interval); - crd_mode = spider_param_crd_mode(thd, share->crd_mode); - if (crd_mode == 3) - crd_mode = 1; - crd_sync = spider_param_crd_sync(thd, share->crd_sync); - time_t tmp_time = (time_t) time((time_t*) 0); +/** Gets sts and crd for spider_init_share() */ +bool spider_share_get_sts_crd( + THD *thd, + ha_spider *spider, + SPIDER_SHARE *share, + TABLE *table, + const bool init_share, + /* fixme: do we need this? */ + const bool has_lock, + int *error_num +) +{ + const bool same_server_link = spider_param_same_server_link(thd); + const int load_sts_at_startup = + spider_param_load_sts_at_startup(share->load_sts_at_startup); + const int load_crd_at_startup = + spider_param_load_crd_at_startup(share->load_crd_at_startup); + DBUG_ENTER("spider_share_get_sts_crd"); + if (!spider->error_mode && + (!same_server_link || load_sts_at_startup || load_crd_at_startup)) + { + const double sts_interval = spider_param_sts_interval(thd, share->sts_interval); + const int sts_mode = spider_param_sts_mode(thd, share->sts_mode); + const int auto_increment_mode = spider_param_auto_increment_mode( + thd, share->auto_increment_mode); + const int sts_sync = auto_increment_mode == 1 ? 0 : + spider_param_sts_sync(thd, share->sts_sync); + const double crd_interval = spider_param_crd_interval(thd, share->crd_interval); + int crd_mode = spider_param_crd_mode(thd, share->crd_mode); + /* TODO(MDEV-27996): Delete spider_crd_mode and spider_sts_mode */ + if (crd_mode == 3) + crd_mode = 1; + const int crd_sync = spider_param_crd_sync(thd, share->crd_sync); + + const time_t tmp_time = (time_t) time((time_t*) 0); + if (!has_lock) + { pthread_mutex_lock(&share->sts_mutex); pthread_mutex_lock(&share->crd_mutex); - if ((spider_init_error_table = - spider_get_init_error_table(spider->wide_handler->trx, share, FALSE))) - { - DBUG_PRINT("info",("spider diff1=%f", - difftime(tmp_time, spider_init_error_table->init_error_time))); - if (difftime(tmp_time, - spider_init_error_table->init_error_time) < + } + /* If not enough time has passed since the last init error, abort */ + if (const SPIDER_INIT_ERROR_TABLE *spider_init_error_table = + spider_get_init_error_table(spider->wide_handler->trx, share, FALSE)) + { + DBUG_PRINT("info",("spider diff1=%f", + difftime(tmp_time, spider_init_error_table->init_error_time))); + if (difftime(tmp_time, + spider_init_error_table->init_error_time) < spider_param_table_init_error_interval()) - { - *error_num = spider_init_error_table->init_error; - if (spider_init_error_table->init_error_with_message) - my_message(spider_init_error_table->init_error, - spider_init_error_table->init_error_msg, MYF(0)); - share->init_error = TRUE; - share->init = TRUE; - pthread_mutex_unlock(&share->crd_mutex); - pthread_mutex_unlock(&share->sts_mutex); - goto error_after_alloc_dbton_handler; - } + { + *error_num = spider_init_error_table->init_error; + if (spider_init_error_table->init_error_with_message) + my_message(spider_init_error_table->init_error, + spider_init_error_table->init_error_msg, MYF(0)); + spider_share_init_error_free(share, init_share, false); + pthread_mutex_unlock(&share->crd_mutex); + pthread_mutex_unlock(&share->sts_mutex); + DBUG_RETURN(TRUE); } + } - if ( - ( - !same_server_link || - load_sts_at_startup - ) && + if ((!same_server_link || load_sts_at_startup) && (*error_num = spider_get_sts(share, spider->search_link_idx, tmp_time, - spider, sts_interval, sts_mode, - sts_sync, - 1, HA_STATUS_VARIABLE | HA_STATUS_CONST | HA_STATUS_AUTO)) - ) { - if (*error_num != ER_SPIDER_SYS_TABLE_VERSION_NUM) - { - thd->clear_error(); - } else { - pthread_mutex_unlock(&share->crd_mutex); - pthread_mutex_unlock(&share->sts_mutex); - share->init_error = TRUE; - share->init_error_time = (time_t) time((time_t*) 0); - share->init = TRUE; - goto error_after_alloc_dbton_handler; - } - } - if ( - ( - !same_server_link || - load_crd_at_startup - ) && - (*error_num = spider_get_crd(share, spider->search_link_idx, tmp_time, - spider, table, crd_interval, crd_mode, - crd_sync, - 1)) - ) { - if (*error_num != ER_SPIDER_SYS_TABLE_VERSION_NUM) - { - thd->clear_error(); - } else { - pthread_mutex_unlock(&share->crd_mutex); - pthread_mutex_unlock(&share->sts_mutex); - share->init_error = TRUE; - share->init_error_time = (time_t) time((time_t*) 0); - share->init = TRUE; - goto error_after_alloc_dbton_handler; - } + spider, sts_interval, sts_mode, sts_sync, + 1, HA_STATUS_VARIABLE | HA_STATUS_CONST | HA_STATUS_AUTO)) + ) { + if (*error_num != ER_SPIDER_SYS_TABLE_VERSION_NUM) + thd->clear_error(); + else + { + pthread_mutex_unlock(&share->crd_mutex); + pthread_mutex_unlock(&share->sts_mutex); + spider_share_init_error_free(share, init_share, false); + DBUG_RETURN(TRUE); } - pthread_mutex_unlock(&share->crd_mutex); - pthread_mutex_unlock(&share->sts_mutex); } - share->init = TRUE; - } else { - share->use_count++; - pthread_mutex_unlock(&spider_tbl_mutex); - - int sleep_cnt = 0; - while (!share->init) + if ((!same_server_link || load_crd_at_startup) && + (*error_num = spider_get_crd(share, spider->search_link_idx, tmp_time, + spider, table, crd_interval, crd_mode, + crd_sync, + 1))) { - // avoid for dead loop - if (sleep_cnt++ > 1000) + if (*error_num != ER_SPIDER_SYS_TABLE_VERSION_NUM) + thd->clear_error(); + else { - fprintf(stderr, " [WARN SPIDER RESULT] " - "Wait share->init too long, table_name %s %s %ld\n", - share->table_name, share->tgt_hosts[0], share->tgt_ports[0]); - *error_num = ER_SPIDER_TABLE_OPEN_TIMEOUT_NUM; - my_printf_error(ER_SPIDER_TABLE_OPEN_TIMEOUT_NUM, - ER_SPIDER_TABLE_OPEN_TIMEOUT_STR, MYF(0), - table_share->db.str, table_share->table_name.str); - spider_free_share(share); - goto error_but_no_delete; + pthread_mutex_unlock(&share->crd_mutex); + pthread_mutex_unlock(&share->sts_mutex); + spider_share_init_error_free(share, init_share, false); + DBUG_RETURN(TRUE); } - my_sleep(10000); // wait 10 ms } - - if (!share->link_status_init) + if (!has_lock) { - pthread_mutex_lock(&share->mutex); - for (roop_count = 0; - roop_count < (int) spider_udf_table_mon_mutex_count; - roop_count++ - ) { - if (spider_bit_is_set(share->table_mon_mutex_bitmap, roop_count)) - pthread_mutex_lock(&spider_udf_table_mon_mutexes[roop_count]); - } - if (!share->link_status_init) - { - DBUG_ASSERT(!table_tables); - /* - The link statuses need to be refreshed from the spider_tables table - if the operation: - - Is not a DROP TABLE on a permanent table; or - - Is an ALTER TABLE. - - Note that SHOW CREATE TABLE is not excluded, because the commands - that follow it require up-to-date link statuses. - */ - if ((table_share->tmp_table == NO_TMP_TABLE && - sql_command != SQLCOM_DROP_TABLE) || - /* for alter change link status */ - sql_command == SQLCOM_ALTER_TABLE) - { - SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME)); - init_mem_root = TRUE; - - if ( - !(table_tables = spider_open_sys_table( - thd, SPIDER_SYS_TABLES_TABLE_NAME_STR, - SPIDER_SYS_TABLES_TABLE_NAME_LEN, FALSE, &open_tables_backup, - error_num)) - ) { - for (roop_count = 0; - roop_count < (int) spider_udf_table_mon_mutex_count; - roop_count++ - ) { - if (spider_bit_is_set(share->table_mon_mutex_bitmap, roop_count)) - pthread_mutex_unlock(&spider_udf_table_mon_mutexes[roop_count]); - } - pthread_mutex_unlock(&share->mutex); - spider_free_share(share); - goto error_open_sys_table; - } - *error_num = spider_get_link_statuses(table_tables, share, - &mem_root); - if (*error_num) - { - if ( - *error_num != HA_ERR_KEY_NOT_FOUND && - *error_num != HA_ERR_END_OF_FILE - ) { - for (roop_count = 0; - roop_count < (int) spider_udf_table_mon_mutex_count; - roop_count++ - ) { - if (spider_bit_is_set(share->table_mon_mutex_bitmap, roop_count)) - pthread_mutex_unlock(&spider_udf_table_mon_mutexes[roop_count]); - } - pthread_mutex_unlock(&share->mutex); - spider_free_share(share); - spider_sys_close_table(thd, &open_tables_backup); - table_tables = NULL; - goto error_open_sys_table; - } - } else { - memcpy(share->alter_table.tmp_link_statuses, share->link_statuses, - sizeof(long) * share->all_link_count); - share->link_status_init = TRUE; - } - spider_sys_close_table(thd, &open_tables_backup); - table_tables = NULL; - } - share->have_recovery_link = spider_conn_check_recovery_link(share); - if (init_mem_root) - { - free_root(&mem_root, MYF(0)); - init_mem_root = FALSE; - } - } - for (roop_count = 0; - roop_count < (int) spider_udf_table_mon_mutex_count; - roop_count++ - ) { - if (spider_bit_is_set(share->table_mon_mutex_bitmap, roop_count)) - pthread_mutex_unlock(&spider_udf_table_mon_mutexes[roop_count]); - } - pthread_mutex_unlock(&share->mutex); + pthread_mutex_unlock(&share->crd_mutex); + pthread_mutex_unlock(&share->sts_mutex); } + } + DBUG_RETURN(FALSE); +} - semi_table_lock_conn = spider_param_semi_table_lock_connection(thd, - share->semi_table_lock_conn); - if (semi_table_lock_conn) - first_byte = '0' + - spider_param_semi_table_lock(thd, share->semi_table_lock); - else - first_byte = '0'; +/** Initialises a `SPIDER_SHARE` */ +bool spider_init_share( + const char *table_name, + TABLE *table, + THD *thd, + ha_spider *spider, + int *error_num, + SPIDER_SHARE *share, + TABLE_SHARE *table_share, + const bool new_share +) +{ + char first_byte; + char *tmp_name; + SPIDER_RESULT_LIST *result_list = &spider->result_list; + int search_link_idx; + const uint sql_command = thd_sql_command(thd); + const bool continue_with_sql_command = + sql_command != SQLCOM_DROP_TABLE && + sql_command != SQLCOM_ALTER_TABLE && + sql_command != SQLCOM_SHOW_CREATE; + DBUG_ENTER("spider_init_share"); + if (!share->link_status_init) + { + spider_lock_udf_table_mon_mutexes(share); + if (!share->link_status_init && + spider_share_init_link_statuses(thd, share, table_share, + sql_command, new_share, error_num)) + DBUG_RETURN(TRUE); + spider_unlock_udf_table_mon_mutexes(share); + } + + const int semi_table_lock_conn = + spider_param_semi_table_lock_connection(thd, share->semi_table_lock_conn); + if (semi_table_lock_conn) + first_byte = '0' + + spider_param_semi_table_lock(thd, share->semi_table_lock); + else + first_byte = '0'; + /* fixme: do we need to assign spider->share at different places + depending on new_share? */ + if (!new_share) spider->share = share; - if (!(spider->wide_handler->trx = spider_get_trx(thd, TRUE, error_num))) - { - spider_free_share(share); - goto error_but_no_delete; - } - spider->set_error_mode(); - if (!share->sts_spider_init) - { - pthread_mutex_lock(&share->mutex); - if (!share->sts_spider_init) - { - if ((*error_num = spider_create_spider_object_for_share( - spider->wide_handler->trx, share, &share->sts_spider))) - { - pthread_mutex_unlock(&share->mutex); - spider_free_share(share); - goto error_sts_spider_init; - } - share->sts_thread = &spider_table_sts_threads[ - my_calc_hash(&spider_open_tables, (uchar*) table_name, length) % - spider_param_table_sts_thread_count()]; - share->sts_spider_init = TRUE; - } - pthread_mutex_unlock(&share->mutex); - } + if (!(spider->wide_handler->trx = spider_get_trx(thd, TRUE, error_num))) + { + spider_share_init_error_free(share, new_share, true); + DBUG_RETURN(TRUE); + } + spider->set_error_mode(); - if (!share->crd_spider_init) - { - pthread_mutex_lock(&share->mutex); - if (!share->crd_spider_init) - { - if ((*error_num = spider_create_spider_object_for_share( - spider->wide_handler->trx, share, &share->crd_spider))) - { - pthread_mutex_unlock(&share->mutex); - spider_free_share(share); - goto error_crd_spider_init; - } - share->crd_thread = &spider_table_crd_threads[ - my_calc_hash(&spider_open_tables, (uchar*) table_name, length) % - spider_param_table_crd_thread_count()]; - share->crd_spider_init = TRUE; - } - pthread_mutex_unlock(&share->mutex); - } + if (!share->sts_spider_init) + { + pthread_mutex_lock(&share->mutex); + if (!share->sts_spider_init && + (*error_num= spider_share_init_sts(table_name, spider, share, new_share))) + DBUG_RETURN(TRUE); + pthread_mutex_unlock(&share->mutex); + } - if ( - sql_command != SQLCOM_DROP_TABLE && - sql_command != SQLCOM_ALTER_TABLE && - sql_command != SQLCOM_SHOW_CREATE && + if (!share->crd_spider_init) + { + pthread_mutex_lock(&share->mutex); + if (!share->crd_spider_init && + (*error_num= spider_share_init_crd(table_name, spider, share, new_share))) + DBUG_RETURN(TRUE); + pthread_mutex_unlock(&share->mutex); + } + + if (continue_with_sql_command && (*error_num = spider_create_mon_threads(spider->wide_handler->trx, - share)) - ) { - spider_free_share(share); - goto error_but_no_delete; - } - - if (!(spider->conn_keys = (char **) - spider_bulk_alloc_mem(spider_current_trx, 49, - __func__, __FILE__, __LINE__, MYF(MY_WME | MY_ZEROFILL), - &spider->conn_keys, sizeof(char *) * share->link_count, - &tmp_name, sizeof(char) * share->conn_keys_charlen, - &spider->conns, sizeof(SPIDER_CONN *) * share->link_count, - &spider->conn_link_idx, sizeof(uint) * share->link_count, - &spider->conn_can_fo, sizeof(uchar) * share->link_bitmap_size, - &spider->connection_ids, sizeof(ulonglong) * share->link_count, - &spider->db_request_id, sizeof(ulonglong) * share->link_count, - &spider->db_request_phase, sizeof(uchar) * share->link_bitmap_size, - &spider->need_mons, sizeof(int) * share->link_count, - &spider->quick_targets, sizeof(void *) * share->link_count, - &result_list->upd_tmp_tbls, sizeof(TABLE *) * share->link_count, - &result_list->upd_tmp_tbl_prms, - sizeof(TMP_TABLE_PARAM) * share->link_count, - &result_list->tmp_table_join_first, - sizeof(uchar) * share->link_bitmap_size, - &result_list->tmp_table_created, - sizeof(uchar) * share->link_bitmap_size, - &result_list->casual_read, sizeof(int) * share->link_count, - &spider->dbton_handler, - sizeof(spider_db_handler *) * SPIDER_DBTON_SIZE, - NullS)) - ) { - spider_free_share(share); - goto error_but_no_delete; - } - memcpy(tmp_name, share->conn_keys[0], share->conn_keys_charlen); + share))) + { + spider_share_init_error_free(share, new_share, true); + DBUG_RETURN(TRUE); + } - spider->conn_keys_first_ptr = tmp_name; - for (roop_count = 0; roop_count < (int) share->link_count; roop_count++) - { - spider->conn_keys[roop_count] = tmp_name; - *tmp_name = first_byte; - tmp_name += share->conn_keys_lengths[roop_count] + 1; - result_list->upd_tmp_tbl_prms[roop_count].init(); - result_list->upd_tmp_tbl_prms[roop_count].field_count = 1; - } - spider_trx_set_link_idx_for_all(spider); + if (!(spider_share_malloc_for_spider(spider, share, 47, &tmp_name, + result_list))) + { + spider_share_init_error_free(share, new_share, true); + DBUG_RETURN(TRUE); + } + memcpy(tmp_name, share->conn_keys[0], share->conn_keys_charlen); - for (roop_count = 0; roop_count < (int) share->use_dbton_count; - roop_count++) - { - uint dbton_id = share->use_dbton_ids[roop_count]; - if (!(spider->dbton_handler[dbton_id] = - spider_dbton[dbton_id].create_db_handler(spider, - share->dbton_share[dbton_id]))) - { - *error_num = HA_ERR_OUT_OF_MEM; - break; - } - if ((*error_num = spider->dbton_handler[dbton_id]->init())) - { - break; - } - } - if (roop_count < (int) share->use_dbton_count) - { - for (; roop_count >= 0; roop_count--) - { - uint dbton_id = share->use_dbton_ids[roop_count]; - if (spider->dbton_handler[dbton_id]) - { - delete spider->dbton_handler[dbton_id]; - spider->dbton_handler[dbton_id] = NULL; - } - } - goto error_after_alloc_conn_keys; - } + spider->conn_keys_first_ptr = tmp_name; + for (int link_idx = 0; link_idx < (int) share->link_count; link_idx++) + { + spider->conn_keys[link_idx] = tmp_name; + *tmp_name = first_byte; + tmp_name += share->conn_keys_lengths[link_idx] + 1; + result_list->upd_tmp_tbl_prms[link_idx].init(); + result_list->upd_tmp_tbl_prms[link_idx].field_count = 1; + } + spider_trx_set_link_idx_for_all(spider); - if ( - sql_command != SQLCOM_DROP_TABLE && - sql_command != SQLCOM_ALTER_TABLE && - sql_command != SQLCOM_SHOW_CREATE - ) { - for ( - roop_count = spider_conn_link_idx_next(share->link_statuses, - spider->conn_link_idx, -1, share->link_count, - SPIDER_LINK_STATUS_RECOVERY); - roop_count < (int) share->link_count; - roop_count = spider_conn_link_idx_next(share->link_statuses, - spider->conn_link_idx, roop_count, share->link_count, - SPIDER_LINK_STATUS_RECOVERY) - ) { - if ( - !(spider->conns[roop_count] = - spider_get_conn(share, roop_count, spider->conn_keys[roop_count], - spider->wide_handler->trx, spider, FALSE, TRUE, - error_num)) - ) { - if ( - share->monitoring_kind[roop_count] && - spider->need_mons[roop_count] - ) { - *error_num = spider_ping_table_mon_from_table( - spider->wide_handler->trx, - spider->wide_handler->trx->thd, - share, - roop_count, - (uint32) share->monitoring_sid[roop_count], - share->table_name, - share->table_name_length, - spider->conn_link_idx[roop_count], - NULL, - 0, - share->monitoring_kind[roop_count], - share->monitoring_limit[roop_count], - share->monitoring_flag[roop_count], - FALSE - ); - } - goto error_after_alloc_dbton_handler; - } - spider->conns[roop_count]->error_mode &= spider->error_mode; - } - } - search_link_idx = spider_conn_first_link_idx(thd, - share->link_statuses, share->access_balances, spider->conn_link_idx, - share->link_count, SPIDER_LINK_STATUS_OK); - if (search_link_idx == -1) - { - char *db = (char *) my_alloca( - table_share->db.length + 1 + table_share->table_name.length + 1); - if (!db) - { - *error_num = HA_ERR_OUT_OF_MEM; - goto error_after_alloc_dbton_handler; - } - char *table_name = db + table_share->db.length + 1; - memcpy(db, table_share->db.str, table_share->db.length); - db[table_share->db.length] = '\0'; - memcpy(table_name, table_share->table_name.str, - table_share->table_name.length); - table_name[table_share->table_name.length] = '\0'; - my_printf_error(ER_SPIDER_ALL_LINKS_FAILED_NUM, - ER_SPIDER_ALL_LINKS_FAILED_STR, MYF(0), db, table_name); - my_afree(db); - *error_num = ER_SPIDER_ALL_LINKS_FAILED_NUM; - goto error_after_alloc_dbton_handler; - } else if (search_link_idx == -2) - { - *error_num = HA_ERR_OUT_OF_MEM; - goto error_after_alloc_dbton_handler; - } - spider->search_link_idx = search_link_idx; + if ((*error_num= spider_share_init_spider_dbton_handlers(spider, share))) + { + spider_share_init_error_free(share, new_share, false); + goto error_after_alloc_conn_keys; + } + + if (continue_with_sql_command && + spider_share_get_conns(spider, share, error_num)) + { + spider_share_init_error_free(share, new_share, false); + goto error_after_alloc_dbton_handler; + } + + search_link_idx = + spider_conn_first_link_idx(thd, share->link_statuses, + share->access_balances, + spider->conn_link_idx, share->link_count, + SPIDER_LINK_STATUS_OK); + if (search_link_idx < 0) + { + *error_num= spider_share_handle_search_link_failure( + share, table_share, search_link_idx, new_share); + goto error_after_alloc_dbton_handler; + } + spider->search_link_idx= search_link_idx; + if (new_share) + { + if (continue_with_sql_command && + spider_share_get_sts_crd(thd, spider, share, table, true, false, + error_num)) + goto error_after_alloc_dbton_handler; + } else if (share->init_error) + { + pthread_mutex_lock(&share->sts_mutex); + pthread_mutex_lock(&share->crd_mutex); if (share->init_error) { - pthread_mutex_lock(&share->sts_mutex); - pthread_mutex_lock(&share->crd_mutex); - if (share->init_error) - { - same_server_link = spider_param_same_server_link(thd); - load_sts_at_startup = - spider_param_load_sts_at_startup(share->load_sts_at_startup); - load_crd_at_startup = - spider_param_load_crd_at_startup(share->load_crd_at_startup); - if ( - sql_command != SQLCOM_DROP_TABLE && - sql_command != SQLCOM_ALTER_TABLE && - sql_command != SQLCOM_SHOW_CREATE && - !spider->error_mode && - ( - !same_server_link || - load_sts_at_startup || - load_crd_at_startup - ) - ) { - SPIDER_INIT_ERROR_TABLE *spider_init_error_table; - sts_interval = spider_param_sts_interval(thd, share->sts_interval); - sts_mode = spider_param_sts_mode(thd, share->sts_mode); - sts_sync = spider_param_sts_sync(thd, share->sts_sync); - auto_increment_mode = spider_param_auto_increment_mode(thd, - share->auto_increment_mode); - if (auto_increment_mode == 1) - sts_sync = 0; - crd_interval = spider_param_crd_interval(thd, share->crd_interval); - crd_mode = spider_param_crd_mode(thd, share->crd_mode); - if (crd_mode == 3) - crd_mode = 1; - crd_sync = spider_param_crd_sync(thd, share->crd_sync); - time_t tmp_time = (time_t) time((time_t*) 0); - if ((spider_init_error_table = - spider_get_init_error_table(spider->wide_handler->trx, share, - FALSE))) - { - DBUG_PRINT("info",("spider diff2=%f", - difftime(tmp_time, spider_init_error_table->init_error_time))); - if (difftime(tmp_time, - spider_init_error_table->init_error_time) < - spider_param_table_init_error_interval()) - { - *error_num = spider_init_error_table->init_error; - if (spider_init_error_table->init_error_with_message) - my_message(spider_init_error_table->init_error, - spider_init_error_table->init_error_msg, MYF(0)); - pthread_mutex_unlock(&share->crd_mutex); - pthread_mutex_unlock(&share->sts_mutex); - goto error_after_alloc_dbton_handler; - } - } - - if ( - ( - !same_server_link || - load_sts_at_startup - ) && - (*error_num = spider_get_sts(share, spider->search_link_idx, - tmp_time, spider, sts_interval, sts_mode, - sts_sync, - 1, HA_STATUS_VARIABLE | HA_STATUS_CONST | HA_STATUS_AUTO)) - ) { - if (*error_num != ER_SPIDER_SYS_TABLE_VERSION_NUM) - { - thd->clear_error(); - } else { - pthread_mutex_unlock(&share->crd_mutex); - pthread_mutex_unlock(&share->sts_mutex); - goto error_after_alloc_dbton_handler; - } - } - if ( - ( - !same_server_link || - load_crd_at_startup - ) && - (*error_num = spider_get_crd(share, spider->search_link_idx, - tmp_time, spider, table, crd_interval, crd_mode, - crd_sync, - 1)) - ) { - if (*error_num != ER_SPIDER_SYS_TABLE_VERSION_NUM) - { - thd->clear_error(); - } else { - pthread_mutex_unlock(&share->crd_mutex); - pthread_mutex_unlock(&share->sts_mutex); - goto error_after_alloc_dbton_handler; - } - } - } - share->init_error = FALSE; - } - pthread_mutex_unlock(&share->crd_mutex); - pthread_mutex_unlock(&share->sts_mutex); + if (continue_with_sql_command && + spider_share_get_sts_crd(thd, spider, share, table, FALSE, TRUE, + error_num)) + goto error_after_alloc_dbton_handler; + share->init_error= FALSE; } + pthread_mutex_unlock(&share->crd_mutex); + pthread_mutex_unlock(&share->sts_mutex); } - - DBUG_PRINT("info",("spider share=%p", share)); - DBUG_RETURN(share); + DBUG_RETURN(FALSE); error_after_alloc_dbton_handler: - for (roop_count = 0; roop_count < (int) share->use_dbton_count; ++roop_count) + for (int roop_count = 0; roop_count < (int) share->use_dbton_count; ++roop_count) { uint dbton_id = share->use_dbton_ids[roop_count]; if (spider->dbton_handler[dbton_id]) @@ -5547,21 +5199,102 @@ error_after_alloc_conn_keys: spider_free(spider_current_trx, spider->conn_keys, MYF(0)); spider->conn_keys = NULL; spider_free_share(share); - goto error_but_no_delete; + DBUG_RETURN(TRUE); +} + +/** + Gets or creates a spider share, then initialises it +*/ +SPIDER_SHARE *spider_get_share( + const char *table_name, + TABLE *table, + THD *thd, + ha_spider *spider, + int *error_num +) { + SPIDER_SHARE *share; + TABLE_SHARE *table_share = table->s; + DBUG_ENTER("spider_get_share"); + + const TABLE_SHARE *top_share = spider->wide_handler->top_share; + if (top_share && + (*error_num = spider_check_for_self_reference(thd, top_share))) + DBUG_RETURN(NULL); + + const uint length = (uint) strlen(table_name); + const my_hash_value_type hash_value = + my_calc_hash(&spider_open_tables, (uchar*) table_name, length); + pthread_mutex_lock(&spider_tbl_mutex); + if (!(share = (SPIDER_SHARE*) my_hash_search_using_hash_value( + &spider_open_tables, hash_value, (uchar*) table_name, length))) + { + if (!(share = spider_create_share(table_name, table_share, + table->part_info, hash_value, + error_num))) + goto error_alloc_share; + + uint old_elements = spider_open_tables.array.max_element; + if (my_hash_insert(&spider_open_tables, (uchar*) share)) + { + *error_num = HA_ERR_OUT_OF_MEM; + goto error_hash_insert; + } + if (spider_open_tables.array.max_element > old_elements) + { + spider_alloc_calc_mem(spider_current_trx, + spider_open_tables, + (spider_open_tables.array.max_element - old_elements) * + spider_open_tables.array.size_of_element); + } + + spider->share = share; + uint tmp_conn_link_idx= 0; + spider->conn_link_idx = &tmp_conn_link_idx; + + share->use_count++; + pthread_mutex_unlock(&spider_tbl_mutex); + + if (spider_init_share(table_name, table, thd, spider, error_num, share, + table_share, TRUE)) + DBUG_RETURN(NULL); + + share->init = TRUE; + } else + { + share->use_count++; + pthread_mutex_unlock(&spider_tbl_mutex); + + int sleep_cnt = 0; + while (!share->init) + { + // avoid for dead loop + if (sleep_cnt++ > 1000) + { + fprintf(stderr, " [WARN SPIDER RESULT] " + "Wait share->init too long, table_name %s %s %ld\n", + share->table_name, share->tgt_hosts[0], share->tgt_ports[0]); + *error_num = ER_SPIDER_TABLE_OPEN_TIMEOUT_NUM; + my_printf_error(ER_SPIDER_TABLE_OPEN_TIMEOUT_NUM, + ER_SPIDER_TABLE_OPEN_TIMEOUT_STR, MYF(0), + table_share->db.str, table_share->table_name.str); + spider_free_share(share); + DBUG_RETURN(NULL); + } + my_sleep(10000); // wait 10 ms + } + + if (spider_init_share(table_name, table, thd, spider, error_num, share, + table_share, FALSE)) + DBUG_RETURN(NULL); + } + + DBUG_PRINT("info",("spider share=%p", share)); + DBUG_RETURN(share); error_hash_insert: spider_free_share_resource_only(share); error_alloc_share: pthread_mutex_unlock(&spider_tbl_mutex); -error_open_sys_table: -error_crd_spider_init: -error_sts_spider_init: - if (init_mem_root) - { - free_root(&mem_root, MYF(0)); - init_mem_root = FALSE; - } -error_but_no_delete: DBUG_RETURN(NULL); } @@ -5877,46 +5610,6 @@ int spider_free_wide_share( DBUG_RETURN(0); } -void spider_copy_sts_to_wide_share( - SPIDER_WIDE_SHARE *wide_share, - SPIDER_SHARE *share -) { - DBUG_ENTER("spider_copy_sts_to_pt_share"); - wide_share->stat = share->stat; - DBUG_VOID_RETURN; -} - -void spider_copy_sts_to_share( - SPIDER_SHARE *share, - SPIDER_WIDE_SHARE *wide_share -) { - DBUG_ENTER("spider_copy_sts_to_share"); - share->stat = wide_share->stat; - DBUG_VOID_RETURN; -} - -void spider_copy_crd_to_wide_share( - SPIDER_WIDE_SHARE *wide_share, - SPIDER_SHARE *share, - int fields -) { - DBUG_ENTER("spider_copy_crd_to_wide_share"); - memcpy(wide_share->cardinality, share->cardinality, - sizeof(longlong) * fields); - DBUG_VOID_RETURN; -} - -void spider_copy_crd_to_share( - SPIDER_SHARE *share, - SPIDER_WIDE_SHARE *wide_share, - int fields -) { - DBUG_ENTER("spider_copy_crd_to_share"); - memcpy(share->cardinality, wide_share->cardinality, - sizeof(longlong) * fields); - DBUG_VOID_RETURN; -} - int spider_open_all_tables( SPIDER_TRX *trx, bool lock @@ -6515,7 +6208,7 @@ int spider_db_init( void *p ) { int error_num = HA_ERR_OUT_OF_MEM, roop_count; - uint dbton_id = 0; + uint dbton_id; uchar addr[6]; handlerton *spider_hton = (handlerton *)p; DBUG_ENTER("spider_db_init"); @@ -6795,6 +6488,8 @@ int spider_db_init( } } + /** Populates `spider_dbton` with available `SPIDER_DBTON`s */ + dbton_id = 0; spider_dbton_mysql.dbton_id = dbton_id; spider_dbton_mysql.db_util->dbton_id = dbton_id; spider_dbton[dbton_id] = spider_dbton_mysql; @@ -6803,15 +6498,11 @@ int spider_db_init( spider_dbton_mariadb.db_util->dbton_id = dbton_id; spider_dbton[dbton_id] = spider_dbton_mariadb; ++dbton_id; - for (roop_count = 0; roop_count < SPIDER_DBTON_SIZE; roop_count++) + for (roop_count = 0; roop_count < (int) dbton_id; roop_count++) { - if (spider_dbton[roop_count].init) - { - if ((error_num = spider_dbton[roop_count].init())) - { + if (spider_dbton[roop_count].init && + (error_num = spider_dbton[roop_count].init())) goto error_init_dbton; - } - } } DBUG_RETURN(0); @@ -6819,9 +6510,7 @@ error_init_dbton: for (roop_count--; roop_count >= 0; roop_count--) { if (spider_dbton[roop_count].deinit) - { spider_dbton[roop_count].deinit(); - } } roop_count = spider_param_table_crd_thread_count() - 1; error_init_table_crd_threads: @@ -7067,6 +6756,33 @@ void spider_get_partition_info( DBUG_VOID_RETURN; } +/** Determines the get type for spider_get_sts() */ +enum ha_sts_crd_get_type spider_get_sts_type( + SPIDER_SHARE *share, + double sts_interval, + int sts_sync +) { + if (sts_sync == 0) + return HA_GET_FETCH; + if (!share->wide_share->sts_init) + { + pthread_mutex_lock(&share->wide_share->sts_mutex); + if (!share->wide_share->sts_init) + return HA_GET_AFTER_LOCK; + pthread_mutex_unlock(&share->wide_share->sts_mutex); + return HA_GET_COPY; + } + if (difftime(share->sts_get_time, share->wide_share->sts_get_time) < + sts_interval) + return HA_GET_COPY; + if (!pthread_mutex_trylock(&share->wide_share->sts_mutex)) + return HA_GET_AFTER_TRYLOCK; + return HA_GET_COPY; +} + +/** + Populates share->stat or share->wide_share->stat with table status. +*/ int spider_get_sts( SPIDER_SHARE *share, int link_idx, @@ -7078,85 +6794,50 @@ int spider_get_sts( int sts_sync_level, uint flag ) { - int get_type; int error_num = 0; bool need_to_get = TRUE; DBUG_ENTER("spider_get_sts"); - if ( - sts_sync == 0 - ) { - /* get */ - get_type = 1; - } else if ( - !share->wide_share->sts_init - ) { - pthread_mutex_lock(&share->wide_share->sts_mutex); - if (!share->wide_share->sts_init) - { - /* get after mutex_lock */ - get_type = 2; - } else { - pthread_mutex_unlock(&share->wide_share->sts_mutex); - /* copy */ - get_type = 0; - } - } else if ( - difftime(share->sts_get_time, share->wide_share->sts_get_time) < - sts_interval - ) { - /* copy */ - get_type = 0; - } else if ( - !pthread_mutex_trylock(&share->wide_share->sts_mutex) - ) { - /* get after mutex_trylock */ - get_type = 3; - } else { - /* copy */ - get_type = 0; - } - if ( - !share->sts_init && - share->table_share->tmp_table == NO_TMP_TABLE && - spider_param_load_sts_at_startup(share->load_sts_at_startup) && - (!share->init || share->init_error) - ) { + enum ha_sts_crd_get_type get_type = + spider_get_sts_type(share, sts_interval, sts_sync); + if (!share->sts_init && + share->table_share->tmp_table == NO_TMP_TABLE && + spider_param_load_sts_at_startup(share->load_sts_at_startup) && + (!share->init || share->init_error)) + { error_num = spider_sys_get_table_sts( current_thd, share->lgtm_tblhnd_share->table_name, share->lgtm_tblhnd_share->table_name_length, - &share->stat - ); - if ( - !error_num || - (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE) - ) + &share->stat); + if (!error_num || + (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE)) need_to_get = FALSE; } if (need_to_get) { - if (get_type == 0) - spider_copy_sts_to_share(share, share->wide_share); - else { + if (get_type == HA_GET_COPY) + share->stat = share->wide_share->stat; + else + /* Executes a `show table status` query and store the results in + share->stat */ error_num = spider_db_show_table_status(spider, link_idx, sts_mode, flag); - } } - if (get_type >= 2) + if (get_type >= HA_GET_AFTER_LOCK) pthread_mutex_unlock(&share->wide_share->sts_mutex); + if (error_num) { SPIDER_PARTITION_HANDLER *partition_handler = spider->partition_handler; - if ( - !share->wide_share->sts_init && - sts_sync >= sts_sync_level && - get_type > 1 && - partition_handler && - partition_handler->handlers && - partition_handler->handlers[0] == spider - ) { + if (!share->wide_share->sts_init && + sts_sync >= sts_sync_level && + get_type > HA_GET_FETCH && + partition_handler && + partition_handler->handlers && + partition_handler->handlers[0] == spider) + { int roop_count; ha_spider *tmp_spider; SPIDER_SHARE *tmp_share; @@ -7165,24 +6846,23 @@ int spider_get_sts( int tmp_sts_sync; THD *thd = spider->wide_handler->trx->thd; for (roop_count = 1; - roop_count < (int) partition_handler->no_parts; - roop_count++) + roop_count < (int) partition_handler->no_parts; + roop_count++) { - tmp_spider = - (ha_spider *) partition_handler->handlers[roop_count]; + tmp_spider = (ha_spider *) partition_handler->handlers[roop_count]; tmp_share = tmp_spider->share; tmp_sts_interval = spider_param_sts_interval(thd, share->sts_interval); tmp_sts_mode = spider_param_sts_mode(thd, share->sts_mode); tmp_sts_sync = spider_param_sts_sync(thd, share->sts_sync); - spider_get_sts(tmp_share, tmp_spider->search_link_idx, - tmp_time, tmp_spider, tmp_sts_interval, tmp_sts_mode, tmp_sts_sync, - 1, flag); + spider_get_sts(tmp_share, tmp_spider->search_link_idx, tmp_time, + tmp_spider, tmp_sts_interval, tmp_sts_mode, + tmp_sts_sync, 1, flag); if (share->wide_share->sts_init) { error_num = 0; thd->clear_error(); - get_type = 0; - spider_copy_sts_to_share(share, share->wide_share); + get_type = HA_GET_COPY; + share->stat = share->wide_share->stat; break; } } @@ -7190,9 +6870,10 @@ int spider_get_sts( if (error_num) DBUG_RETURN(error_num); } - if (sts_sync >= sts_sync_level && get_type > 0) + + if (sts_sync >= sts_sync_level && get_type > HA_GET_COPY) { - spider_copy_sts_to_wide_share(share->wide_share, share); + share->wide_share->stat = share->stat; share->wide_share->sts_get_time = tmp_time; share->wide_share->sts_init = TRUE; } @@ -7201,6 +6882,34 @@ int spider_get_sts( DBUG_RETURN(0); } +/** Determines the get type for spider_get_crd() */ +enum ha_sts_crd_get_type spider_get_crd_type( + SPIDER_SHARE *share, + double crd_interval, + int crd_sync +) { + if (crd_sync == 0) + return HA_GET_FETCH; + if (!share->wide_share->crd_init) + { + pthread_mutex_lock(&share->wide_share->crd_mutex); + if (!share->wide_share->crd_init) + return HA_GET_AFTER_LOCK; + pthread_mutex_unlock(&share->wide_share->crd_mutex); + return HA_GET_COPY; + } + if (difftime(share->crd_get_time, share->wide_share->crd_get_time) < + crd_interval) + return HA_GET_COPY; + if (!pthread_mutex_trylock(&share->wide_share->crd_mutex)) + return HA_GET_AFTER_TRYLOCK; + return HA_GET_COPY; +} + +/** + Populates share->cardinality or share->wide_share->cardinality with + table index +*/ int spider_get_crd( SPIDER_SHARE *share, int link_idx, @@ -7212,86 +6921,47 @@ int spider_get_crd( int crd_sync, int crd_sync_level ) { - int get_type; int error_num = 0; bool need_to_get = TRUE; DBUG_ENTER("spider_get_crd"); - if ( - crd_sync == 0 - ) { - /* get */ - get_type = 1; - } else if ( - !share->wide_share->crd_init - ) { - pthread_mutex_lock(&share->wide_share->crd_mutex); - if (!share->wide_share->crd_init) - { - /* get after mutex_lock */ - get_type = 2; - } else { - pthread_mutex_unlock(&share->wide_share->crd_mutex); - /* copy */ - get_type = 0; - } - } else if ( - difftime(share->crd_get_time, share->wide_share->crd_get_time) < - crd_interval - ) { - /* copy */ - get_type = 0; - } else if ( - !pthread_mutex_trylock(&share->wide_share->crd_mutex) - ) { - /* get after mutex_trylock */ - get_type = 3; - } else { - /* copy */ - get_type = 0; - } - if ( - !share->crd_init && - share->table_share->tmp_table == NO_TMP_TABLE && - spider_param_load_sts_at_startup(share->load_crd_at_startup) - ) { + enum ha_sts_crd_get_type get_type = + spider_get_crd_type(share, crd_interval, crd_sync); + if (!share->crd_init && + share->table_share->tmp_table == NO_TMP_TABLE && + spider_param_load_sts_at_startup(share->load_crd_at_startup)) + { error_num = spider_sys_get_table_crd( current_thd, share->lgtm_tblhnd_share->table_name, share->lgtm_tblhnd_share->table_name_length, share->cardinality, - table->s->fields - ); - if ( - !error_num || - (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE) - ) + table->s->fields); + if (!error_num || + (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE)) need_to_get = FALSE; } if (need_to_get) { - if (get_type == 0) - spider_copy_crd_to_share(share, share->wide_share, - table->s->fields); - else { + if (get_type == HA_GET_COPY) + memcpy(share->cardinality, share->wide_share->cardinality, + sizeof(longlong) * table->s->fields); + else error_num = spider_db_show_index(spider, link_idx, table, crd_mode); - } } - if (get_type >= 2) + if (get_type >= HA_GET_AFTER_LOCK) pthread_mutex_unlock(&share->wide_share->crd_mutex); if (error_num) { - SPIDER_PARTITION_HANDLER *partition_handler = - spider->partition_handler; - if ( - !share->wide_share->crd_init && - crd_sync >= crd_sync_level && - get_type > 1 && - partition_handler && - partition_handler->handlers && - partition_handler->handlers[0] == spider - ) { + SPIDER_PARTITION_HANDLER *partition_handler = spider->partition_handler; + if (!share->wide_share->crd_init && + crd_sync >= crd_sync_level && + get_type > HA_GET_FETCH && + partition_handler && + partition_handler->handlers && + partition_handler->handlers[0] == spider) + { int roop_count; ha_spider *tmp_spider; SPIDER_SHARE *tmp_share; @@ -7300,25 +6970,24 @@ int spider_get_crd( int tmp_crd_sync; THD *thd = spider->wide_handler->trx->thd; for (roop_count = 1; - roop_count < (int) partition_handler->no_parts; - roop_count++) + roop_count < (int) partition_handler->no_parts; + roop_count++) { - tmp_spider = - (ha_spider *) partition_handler->handlers[roop_count]; + tmp_spider = (ha_spider *) partition_handler->handlers[roop_count]; tmp_share = tmp_spider->share; tmp_crd_interval = spider_param_crd_interval(thd, share->crd_interval); tmp_crd_mode = spider_param_crd_mode(thd, share->crd_mode); tmp_crd_sync = spider_param_crd_sync(thd, share->crd_sync); - spider_get_crd(tmp_share, tmp_spider->search_link_idx, - tmp_time, tmp_spider, table, tmp_crd_interval, tmp_crd_mode, - tmp_crd_sync, 1); + spider_get_crd(tmp_share, tmp_spider->search_link_idx, tmp_time, + tmp_spider, table, tmp_crd_interval, tmp_crd_mode, + tmp_crd_sync, 1); if (share->wide_share->crd_init) { error_num = 0; thd->clear_error(); - get_type = 0; - spider_copy_crd_to_share(share, share->wide_share, - table->s->fields); + get_type = HA_GET_COPY; + memcpy(share->cardinality, share->wide_share->cardinality, + sizeof(longlong) * table->s->fields); break; } } @@ -7326,10 +6995,10 @@ int spider_get_crd( if (error_num) DBUG_RETURN(error_num); } - if (crd_sync >= crd_sync_level && get_type > 0) + if (crd_sync >= crd_sync_level && get_type > HA_GET_COPY) { - spider_copy_crd_to_wide_share(share->wide_share, share, - table->s->fields); + memcpy(share->wide_share->cardinality, share->cardinality, + sizeof(longlong) * table->s->fields); share->wide_share->crd_get_time = tmp_time; share->wide_share->crd_init = TRUE; } @@ -7374,6 +7043,18 @@ void spider_set_result_list_param( DBUG_VOID_RETURN; } +/** + Gets or creates a `SPIDER_INIT_ERROR_TABLE` with the table name from + a given `SPIDER_SHARE` + + When creating, also add the newly created object to + `spider_init_error_tables` + + @param trx Transaction + @param share The spider share providing the table name + @param create Whether to create a new `SPIDER_INIT_ERROR_TABLE` if one wi th the required table name does not exist yet + @return A `SPIDER_INIT_ERROR_TABLE` or NULL if failure +*/ SPIDER_INIT_ERROR_TABLE *spider_get_init_error_table( SPIDER_TRX *trx, SPIDER_SHARE *share, @@ -7393,11 +7074,10 @@ SPIDER_INIT_ERROR_TABLE *spider_get_init_error_table( pthread_mutex_unlock(&spider_init_error_tbl_mutex); DBUG_RETURN(NULL); } - if (!(spider_init_error_table = (SPIDER_INIT_ERROR_TABLE *) - spider_bulk_malloc(spider_current_trx, 54, MYF(MY_WME | MY_ZEROFILL), + if (!spider_bulk_malloc(spider_current_trx, 54, MYF(MY_WME | MY_ZEROFILL), &spider_init_error_table, (uint) (sizeof(*spider_init_error_table)), &tmp_name, (uint) (share->table_name_length + 1), - NullS)) + NullS) ) { pthread_mutex_unlock(&spider_init_error_tbl_mutex); DBUG_RETURN(NULL); @@ -8404,6 +8084,7 @@ ulong spider_calc_for_sort( DBUG_RETURN(sort); } +/** Generates a random number between 0 and 1 */ double spider_rand( uint32 rand_source ) { diff --git a/storage/spider/spd_table.h b/storage/spider/spd_table.h index 9b6eecb9d56..b5c265aff9d 100644 --- a/storage/spider/spd_table.h +++ b/storage/spider/spd_table.h @@ -493,28 +493,6 @@ int spider_free_wide_share( SPIDER_WIDE_SHARE *wide_share ); -void spider_copy_sts_to_wide_share( - SPIDER_WIDE_SHARE *wide_share, - SPIDER_SHARE *share -); - -void spider_copy_sts_to_share( - SPIDER_SHARE *share, - SPIDER_WIDE_SHARE *wide_share -); - -void spider_copy_crd_to_wide_share( - SPIDER_WIDE_SHARE *wide_share, - SPIDER_SHARE *share, - int fields -); - -void spider_copy_crd_to_share( - SPIDER_SHARE *share, - SPIDER_WIDE_SHARE *wide_share, - int fields -); - int spider_open_all_tables( SPIDER_TRX *trx, bool lock diff --git a/storage/spider/spd_trx.cc b/storage/spider/spd_trx.cc index a6c5ea8f85a..3361f485d58 100644 --- a/storage/spider/spd_trx.cc +++ b/storage/spider/spd_trx.cc @@ -3872,46 +3872,59 @@ void spider_reuse_trx_ha( DBUG_VOID_RETURN; } +/** + Sets link indices for load balancing read connections + + Assuming `spider->share->link_count` is the number of active servers + to use, this function updates `spider->conn_link_idx` with the first + server in the same "modulus group" whose link status is not + `SPIDER_LINK_STATUS_NG`, or if one cannot be found, use the + `link_idx`th server +*/ void spider_trx_set_link_idx_for_all( ha_spider *spider ) { - int roop_count, roop_count2; SPIDER_SHARE *share = spider->share; long *link_statuses = share->link_statuses; uint *conn_link_idx = spider->conn_link_idx; - int link_count = share->link_count; - int all_link_count = share->all_link_count; + uint link_count = share->link_count; + uint all_link_count = share->all_link_count; uchar *conn_can_fo = spider->conn_can_fo; DBUG_ENTER("spider_trx_set_link_idx_for_all"); DBUG_PRINT("info",("spider set link_count=%d", link_count)); DBUG_PRINT("info",("spider set all_link_count=%d", all_link_count)); memset(conn_can_fo, 0, sizeof(uchar) * share->link_bitmap_size); - for (roop_count = 0; roop_count < link_count; roop_count++) - { - for (roop_count2 = roop_count; roop_count2 < all_link_count; - roop_count2 += link_count) + /* We change the name from roop_count and roop_count2 to link_idx + and all_link_idx because the latter are generally used in the + same context. */ + for (uint link_idx = 0; link_idx < link_count; link_idx++) + { + uint all_link_idx; + for (all_link_idx = link_idx; all_link_idx < all_link_count; + all_link_idx += link_count) { - if (link_statuses[roop_count2] <= SPIDER_LINK_STATUS_RECOVERY) + if (link_statuses[all_link_idx] <= SPIDER_LINK_STATUS_RECOVERY) break; } - if (roop_count2 < all_link_count) + if (all_link_idx < all_link_count) { - conn_link_idx[roop_count] = roop_count2; - if (roop_count2 + link_count < all_link_count) - spider_set_bit(conn_can_fo, roop_count); + conn_link_idx[link_idx] = all_link_idx; + if (all_link_idx + link_count < all_link_count) + spider_set_bit(conn_can_fo, link_idx); DBUG_PRINT("info",("spider set conn_link_idx[%d]=%d", - roop_count, roop_count2)); - } else { - conn_link_idx[roop_count] = roop_count; + link_idx, all_link_idx)); + } else + { + conn_link_idx[link_idx] = link_idx; DBUG_PRINT("info",("spider set2 conn_link_idx[%d]=%d", - roop_count, roop_count)); + link_idx, link_idx)); } - spider->conn_keys[roop_count] = + spider->conn_keys[link_idx] = ADD_TO_PTR(spider->conn_keys_first_ptr, - PTR_BYTE_DIFF(share->conn_keys[conn_link_idx[roop_count]], + PTR_BYTE_DIFF(share->conn_keys[conn_link_idx[link_idx]], share->conn_keys[0]), char*); DBUG_PRINT("info",("spider conn_keys[%d]=%s", - roop_count, spider->conn_keys[roop_count])); + link_idx, spider->conn_keys[link_idx])); } DBUG_VOID_RETURN; } |