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()
This commit is contained in:
Yuchen Pei 2023-03-23 17:32:09 +11:00
parent a8dac17a42
commit b5d317197c
No known key found for this signature in database
GPG key ID: 3DD1B35105743563
15 changed files with 1319 additions and 1975 deletions

View file

@ -309,10 +309,10 @@ int ha_spider::open(
no_bytes_in_map(table->read_set)); no_bytes_in_map(table->read_set));
wide_handler_alloc = TRUE; wide_handler_alloc = TRUE;
if (!share && !spider_get_share(name, table, thd, this, &error_num)) if (!share && !spider_get_share(name, table, thd, this, &error_num))
goto error_get_share; 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 create partition_handler"));
DBUG_PRINT("info",("spider table=%p", table)); DBUG_PRINT("info",("spider table=%p", table));
@ -6559,13 +6559,6 @@ int ha_spider::info(
auto_inc_temporary = FALSE; auto_inc_temporary = FALSE;
#endif #endif
wide_handler->sql_command = thd_sql_command(thd); 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 (flag & HA_STATUS_AUTO)
{ {
if (share->lgtm_tblhnd_share->auto_increment_value) if (share->lgtm_tblhnd_share->auto_increment_value)
@ -6583,9 +6576,6 @@ int ha_spider::info(
wide_handler->sql_command == SQLCOM_ALTER_TABLE wide_handler->sql_command == SQLCOM_ALTER_TABLE
) )
DBUG_RETURN(0); DBUG_RETURN(0);
/*
}
*/
if (flag & if (flag &
(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE | HA_STATUS_AUTO)) (HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE | HA_STATUS_AUTO))

View file

@ -63,8 +63,10 @@ public:
char *conn_keys_first_ptr; char *conn_keys_first_ptr;
char **conn_keys; char **conn_keys;
SPIDER_CONN **conns; SPIDER_CONN **conns;
/* for active-standby mode */ /* array of indexes of active servers */
uint *conn_link_idx; 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; uchar *conn_can_fo;
void **quick_targets; void **quick_targets;
int *need_mons; int *need_mons;

View file

@ -2992,12 +2992,6 @@ void *spider_bg_sts_action(
if (spider.search_link_idx < 0) if (spider.search_link_idx < 0)
{ {
spider_trx_set_link_idx_for_all(&spider); 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, spider.search_link_idx = spider_conn_first_link_idx(thd,
share->link_statuses, share->access_balances, spider.conn_link_idx, share->link_statuses, share->access_balances, spider.conn_link_idx,
share->link_count, SPIDER_LINK_STATUS_OK); share->link_count, SPIDER_LINK_STATUS_OK);
@ -3013,32 +3007,6 @@ void *spider_bg_sts_action(
share->conn_keys[spider.search_link_idx], trx, share->conn_keys[spider.search_link_idx], trx,
&spider, FALSE, FALSE, &error_num); &spider, FALSE, FALSE, &error_num);
conns[spider.search_link_idx]->error_mode = 0; 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; spider.search_link_idx = -1;
} }
if (spider.search_link_idx != -1 && conns[spider.search_link_idx]) if (spider.search_link_idx != -1 && conns[spider.search_link_idx])
@ -3049,31 +3017,6 @@ void *spider_bg_sts_action(
share->bg_sts_sync, share->bg_sts_sync,
2, HA_STATUS_CONST | HA_STATUS_VARIABLE)) 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; spider.search_link_idx = -1;
} }
} }
@ -3316,12 +3259,6 @@ void *spider_bg_crd_action(
if (spider.search_link_idx < 0) if (spider.search_link_idx < 0)
{ {
spider_trx_set_link_idx_for_all(&spider); 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, spider.search_link_idx = spider_conn_first_link_idx(thd,
share->link_statuses, share->access_balances, spider.conn_link_idx, share->link_statuses, share->access_balances, spider.conn_link_idx,
share->link_count, SPIDER_LINK_STATUS_OK); 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( int spider_conn_first_link_idx(
THD *thd, THD *thd,
long *link_statuses, long *link_statuses,
@ -3755,35 +3710,35 @@ int spider_conn_first_link_idx(
int link_count, int link_count,
int link_status int link_status
) { ) {
int roop_count, active_links = 0; int eligible_link_idx, eligible_links = 0;
longlong balance_total = 0, balance_val; longlong balance_total = 0, balance_threshold;
double rand_val; double rand_val;
int *link_idxs, link_idx; int *link_idxs, result;
long *balances;
DBUG_ENTER("spider_conn_first_link_idx"); DBUG_ENTER("spider_conn_first_link_idx");
char *ptr; 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) if (!ptr)
{ {
DBUG_PRINT("info",("spider out of memory")); DBUG_PRINT("info",("spider out of memory"));
DBUG_RETURN(-2); DBUG_RETURN(-2);
} }
link_idxs = (int *) ptr; link_idxs = (int *) ptr;
ptr += sizeof(int) * link_count;
balances = (long *) ptr; /* Filter for eligible servers, store their indexes and calculate
for (roop_count = 0; roop_count < link_count; roop_count++) 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); DBUG_ASSERT((conn_link_idx[link_idx] - link_idx) % link_count == 0);
if (link_statuses[conn_link_idx[roop_count]] <= link_status) if (link_statuses[conn_link_idx[link_idx]] <= link_status)
{ {
link_idxs[active_links] = roop_count; link_idxs[eligible_links] = link_idx;
balances[active_links] = access_balances[roop_count]; balance_total += access_balances[link_idx];
balance_total += access_balances[roop_count]; eligible_links++;
active_links++;
} }
} }
if (active_links == 0) if (eligible_links == 0)
{ {
DBUG_PRINT("info",("spider all links are failed")); DBUG_PRINT("info",("spider all links are failed"));
my_afree(link_idxs); 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))); 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)); rand_val = spider_rand(thd->variables.server_id + thd_get_thread_id(thd));
DBUG_PRINT("info",("spider rand_val=%f", rand_val)); DBUG_PRINT("info",("spider rand_val=%f", rand_val));
balance_val = (longlong) (rand_val * balance_total); balance_threshold = (longlong) (rand_val * balance_total);
DBUG_PRINT("info",("spider balance_val=%lld", balance_val)); DBUG_PRINT("info",("spider balance_threshold=%lld", balance_threshold));
for (roop_count = 0; roop_count < active_links - 1; roop_count++) /* 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", DBUG_PRINT("info",("spider balances[%d]=%ld",
roop_count, balances[roop_count])); link_idxs[eligible_link_idx], balance));
if (balance_val < balances[roop_count]) if (balance_threshold < balance)
break; break;
balance_val -= balances[roop_count]; balance_threshold -= balance;
} }
DBUG_PRINT("info",("spider first link_idx=%d", link_idxs[roop_count])); DBUG_PRINT("info",("spider first link_idx=%d", result));
link_idx = link_idxs[roop_count];
my_afree(link_idxs); my_afree(link_idxs);
DBUG_RETURN(link_idx); DBUG_RETURN(result);
} }
int spider_conn_next_link_idx( int spider_conn_next_link_idx(
@ -3842,6 +3801,17 @@ int spider_conn_next_link_idx(
DBUG_RETURN(tmp_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( int spider_conn_link_idx_next(
long *link_statuses, long *link_statuses,
uint *conn_link_idx, uint *conn_link_idx,
@ -3854,6 +3824,8 @@ int spider_conn_link_idx_next(
link_idx++; link_idx++;
if (link_idx >= link_count) if (link_idx >= link_count)
break; 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); DBUG_ASSERT((conn_link_idx[link_idx] - link_idx) % link_count == 0);
} while (link_statuses[conn_link_idx[link_idx]] > link_status); } while (link_statuses[conn_link_idx[link_idx]] > link_status);
DBUG_PRINT("info",("spider link_idx=%d", link_idx)); DBUG_PRINT("info",("spider link_idx=%d", link_idx));

View file

@ -398,7 +398,7 @@ int spider_udf_get_copy_tgt_tables(
(error_num = spider_get_sys_tables_connect_info( (error_num = spider_get_sys_tables_connect_info(
table_tables, tmp_share, 0, mem_root)) || table_tables, tmp_share, 0, mem_root)) ||
(error_num = spider_get_sys_tables_link_status( (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( (error_num = spider_get_sys_tables_link_idx(
table_tables, &table_conn->link_idx, mem_root)) table_tables, &table_conn->link_idx, mem_root))
) { ) {

View file

@ -19,12 +19,19 @@
#define SPD_INIT_ALLOC_ROOT(A, B, C, D) \ #define SPD_INIT_ALLOC_ROOT(A, B, C, D) \
init_alloc_root(PSI_INSTRUMENT_ME, 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 #define SPIDER_DBTON_SIZE 15
#ifndef SIZEOF_STORED_DOUBLE #ifndef SIZEOF_STORED_DOUBLE
#define SIZEOF_STORED_DOUBLE 8 #define SIZEOF_STORED_DOUBLE 8
#endif #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_MYSQL "mysql"
#define SPIDER_DB_WRAPPER_MARIADB "mariadb" #define SPIDER_DB_WRAPPER_MARIADB "mariadb"
@ -683,6 +690,8 @@ struct st_spider_db_request_key
class spider_db_util class spider_db_util
{ {
public: public:
/** Same as the `SPIDER_DBTON::dbton_id` of the `SPIDER_DBTON`
containing this `spider_db_util` */
uint dbton_id; uint dbton_id;
spider_db_util() = default; spider_db_util() = default;
virtual ~spider_db_util() = default; virtual ~spider_db_util() = default;
@ -1683,7 +1692,10 @@ static const LEX_CSTRING maturity_name[] =
typedef struct st_spider_dbton typedef struct st_spider_dbton
{ {
/** The index of this dbton in `spider_dbton` */
uint dbton_id; uint dbton_id;
/** The wrapper of this dbton, same possible values as each element
of `SPIDER_SHARE::tgt_wrappers` */
const char *wrapper; const char *wrapper;
enum spider_db_access_type db_access_type; enum spider_db_access_type db_access_type;
int (*init)(); int (*init)();

View file

@ -307,6 +307,7 @@ bool spider_mariadb_support_direct_join(
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
/** Available `SPIDER_DBTON`s */
SPIDER_DBTON spider_dbton_mysql = { SPIDER_DBTON spider_dbton_mysql = {
0, 0,
SPIDER_DB_WRAPPER_MYSQL, 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); DBUG_RETURN((SPIDER_DB_ROW *) &row);
} }
/* Fetches table status into `stat` */
int spider_db_mbase_result::fetch_table_status( int spider_db_mbase_result::fetch_table_status(
int mode, int mode,
ha_statistics &stat ha_statistics &stat
@ -5302,6 +5304,7 @@ int spider_db_mbase_util::append_sql_mode(
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/** Append `set session time_zone = ...` to a query string */
int spider_db_mbase_util::append_time_zone( int spider_db_mbase_util::append_time_zone(
spider_string *str, spider_string *str,
Time_zone *time_zone Time_zone *time_zone
@ -5320,6 +5323,14 @@ int spider_db_mbase_util::append_time_zone(
DBUG_RETURN(0); 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( int spider_db_mbase_util::append_loop_check(
spider_string *str, spider_string *str,
SPIDER_CONN *conn SPIDER_CONN *conn
@ -13432,6 +13443,38 @@ int spider_mbase_handler::sts_mode_exchange(
DBUG_RETURN(sts_mode); 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 spider_mbase_handler::show_table_status(
int link_idx, int link_idx,
int sts_mode, int sts_mode,
@ -13441,329 +13484,118 @@ int spider_mbase_handler::show_table_status(
SPIDER_CONN *conn = spider->conns[link_idx]; SPIDER_CONN *conn = spider->conns[link_idx];
SPIDER_DB_RESULT *res; SPIDER_DB_RESULT *res;
SPIDER_SHARE *share = spider->share; 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; ulonglong auto_increment_value = 0;
DBUG_ENTER("spider_mbase_handler::show_table_status"); DBUG_ENTER("spider_mbase_handler::show_table_status");
DBUG_PRINT("info",("spider sts_mode=%d", sts_mode)); 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); if (error_num == ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM &&
pthread_mutex_lock(&conn->mta_conn_mutex); !conn->disable_reconnect)
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos); {
conn->need_mon = &spider->need_mons[link_idx]; /* retry */
DBUG_ASSERT(!conn->mta_conn_mutex_lock_already); if ((error_num = spider_db_ping(spider, conn, link_idx)))
DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later); DBUG_RETURN(spider_teardown_after_query(conn, error_num, true));
conn->mta_conn_mutex_lock_already = TRUE; if ((error_num = spider_db_set_names(spider, conn, link_idx)))
conn->mta_conn_mutex_unlock_later = TRUE; DBUG_RETURN(spider_teardown_after_query(conn, error_num, true));
conn->disable_connect_retry = TRUE; spider_conn_set_timeout_from_share(conn, link_idx,
spider_conn_set_timeout_from_share(conn, link_idx, spider->wide_handler->trx->thd,
spider->wide_handler->trx->thd, share);
share); if (spider_db_query(
if ( conn,
(error_num = spider_db_set_names(spider, conn, link_idx)) || mysql_share->show_table_status[pos].ptr(),
( mysql_share->show_table_status[pos].length(),
spider_db_query( -1,
conn, &spider->need_mons[link_idx])
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
) { ) {
/* retry */ spider_teardown_after_query(conn, 0, false);
if ((error_num = spider_db_ping(spider, conn, link_idx))) DBUG_RETURN(spider_db_errorno(conn));
{
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);
} }
} } else
st_spider_db_request_key request_key; DBUG_RETURN(spider_teardown_after_query(conn, error_num, true));
request_key.spider_thread_id = spider->wide_handler->trx->spider_thread_id; }
request_key.query_id = spider->wide_handler->trx->thd->query_id; st_spider_db_request_key request_key = {
request_key.handler = spider; spider->wide_handler->trx->spider_thread_id,
request_key.request_id = 1; spider->wide_handler->trx->thd->query_id, spider, 1, NULL};
request_key.next = NULL; if (spider_param_dry_access())
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;
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) if (error_num)
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
{ {
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); my_printf_error(
pthread_mutex_unlock(&conn->mta_conn_mutex); ER_SPIDER_REMOTE_TABLE_NOT_FOUND_NUM,
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,
ER_SPIDER_REMOTE_TABLE_NOT_FOUND_STR, MYF(0), ER_SPIDER_REMOTE_TABLE_NOT_FOUND_STR, MYF(0),
mysql_share->db_names_str[spider->conn_link_idx[link_idx]].ptr(), mysql_share->db_names_str[spider->conn_link_idx[link_idx]].ptr(),
mysql_share->table_names_str[spider->conn_link_idx[ mysql_share->table_names_str[spider->conn_link_idx[link_idx]].ptr());
link_idx]].ptr());
DBUG_RETURN(ER_SPIDER_REMOTE_TABLE_NOT_FOUND_NUM); DBUG_RETURN(ER_SPIDER_REMOTE_TABLE_NOT_FOUND_NUM);
} }
} } 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);
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) spider_teardown_after_query(conn, error_num, false);
{ if (error_num || (error_num= spider_db_errorno(conn)))
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())
{
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)))
DBUG_RETURN(error_num); DBUG_RETURN(error_num);
else else
DBUG_RETURN(ER_QUERY_ON_FOREIGN_DATA_SOURCE); DBUG_RETURN(ER_QUERY_ON_FOREIGN_DATA_SOURCE);
} }
conn->disable_connect_retry = FALSE; }
DBUG_ASSERT(conn->mta_conn_mutex_lock_already); spider_teardown_after_query(conn, 0, true);
DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); /* Fetches query results into share->stat. */
conn->mta_conn_mutex_lock_already = FALSE; error_num = res->fetch_table_status(sts_mode, share->stat);
conn->mta_conn_mutex_unlock_later = FALSE; auto_increment_value = share->stat.auto_increment_value;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); res->free_result();
pthread_mutex_unlock(&conn->mta_conn_mutex); delete res;
error_num = res->fetch_table_status( if (error_num)
sts_mode, {
share->stat switch (error_num)
);
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(
case ER_SPIDER_REMOTE_TABLE_NOT_FOUND_NUM: 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),
ER_SPIDER_REMOTE_TABLE_NOT_FOUND_STR, MYF(0), mysql_share->db_names_str[spider->conn_link_idx[link_idx]].ptr(),
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[ break;
link_idx]].ptr()); case ER_SPIDER_INVALID_REMOTE_TABLE_INFO_NUM:
break; my_printf_error(
case ER_SPIDER_INVALID_REMOTE_TABLE_INFO_NUM: 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),
ER_SPIDER_INVALID_REMOTE_TABLE_INFO_STR, MYF(0), mysql_share->db_names_str[spider->conn_link_idx[link_idx]].ptr(),
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[ break;
link_idx]].ptr()); default:
break; break;
default:
break;
}
DBUG_RETURN(error_num);
} }
DBUG_RETURN(error_num);
} }
if ((error_num = ((spider_db_mbase *) conn->db_conn)->fetch_and_print_warnings(NULL))) if ((error_num = ((spider_db_mbase *) conn->db_conn)->fetch_and_print_warnings(NULL)))
{ {
DBUG_RETURN(error_num); DBUG_RETURN(error_num);
} }
if (share->static_records_for_status != -1) if (share->static_records_for_status != -1)
{
share->stat.records = (ha_rows) share->static_records_for_status; share->stat.records = (ha_rows) share->static_records_for_status;
}
if (share->static_mean_rec_length != -1) if (share->static_mean_rec_length != -1)
{
share->stat.mean_rec_length = (ulong) share->static_mean_rec_length; share->stat.mean_rec_length = (ulong) share->static_mean_rec_length;
}
if (auto_increment_value > share->lgtm_tblhnd_share->auto_increment_value) if (auto_increment_value > share->lgtm_tblhnd_share->auto_increment_value)
{ {
share->lgtm_tblhnd_share->auto_increment_value = 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; SPIDER_SHARE *share = spider->share;
TABLE *table = spider->get_table(); TABLE *table = spider->get_table();
SPIDER_DB_RESULT *res; SPIDER_DB_RESULT *res;
int roop_count; int field;
longlong *tmp_cardinality; longlong *tmp_crd;
uint pos = (2 * spider->conn_link_idx[link_idx]); const uint pos = 2 * spider->conn_link_idx[link_idx] +
(crd_mode == 1 ? 0 : 1);
DBUG_ENTER("spider_mbase_handler::show_index"); DBUG_ENTER("spider_mbase_handler::show_index");
DBUG_PRINT("info",("spider crd_mode=%d", crd_mode)); 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); if (error_num == ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM &&
pthread_mutex_lock(&conn->mta_conn_mutex); !conn->disable_reconnect)
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 || (error_num = spider_db_errorno(conn))) /* 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_ASSERT(conn->mta_conn_mutex_lock_already); spider_teardown_after_query(conn, 0, false);
DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); DBUG_RETURN(spider_db_errorno(conn));
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 */ } else
} DBUG_RETURN(spider_teardown_after_query(conn, error_num, true));
DBUG_ASSERT(conn->mta_conn_mutex_lock_already); }
DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); st_spider_db_request_key request_key = {
conn->mta_conn_mutex_lock_already = FALSE; spider->wide_handler->trx->spider_thread_id,
conn->mta_conn_mutex_unlock_later = FALSE; spider->wide_handler->trx->thd->query_id, spider, 1, NULL};
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); /* no record is ok */
pthread_mutex_unlock(&conn->mta_conn_mutex); if (!(res = conn->db_conn->store_result(NULL, &request_key, &error_num)) &&
if (res) (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))
{ {
error_num = res->fetch_table_cardinality( DBUG_PRINT("info",
crd_mode, ("spider uninitialized column cardinality id=%d", field));
table, *tmp_crd = -1;
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))
{
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);
} }
} }
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( int spider_mbase_handler::simple_action(

View file

@ -148,9 +148,14 @@ typedef start_new_trans *SPIDER_Open_tables_backup;
#define spider_bit_is_set(BITMAP, BIT) \ #define spider_bit_is_set(BITMAP, BIT) \
(uint) ((BITMAP)[(BIT) / 8] & (1 << ((BIT) & 7))) (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 #define SPIDER_LINK_STATUS_NO_CHANGE 0
/* 1 Changes status to OK. */
#define SPIDER_LINK_STATUS_OK 1 #define SPIDER_LINK_STATUS_OK 1
/* 2 Changes status to RECOVERY. */
#define SPIDER_LINK_STATUS_RECOVERY 2 #define SPIDER_LINK_STATUS_RECOVERY 2
/* 3 Changes status to no more in group communication. */
#define SPIDER_LINK_STATUS_NG 3 #define SPIDER_LINK_STATUS_NG 3
#define SPIDER_LINK_MON_OK 0 #define SPIDER_LINK_MON_OK 0
@ -699,22 +704,30 @@ typedef struct st_spider_share
char *table_name; char *table_name;
uint table_name_length; uint table_name_length;
uint use_count; 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; uint link_count;
/* Number of all links, i.e. all remote servers for the spider
table. */
uint all_link_count; uint all_link_count;
uint link_bitmap_size; uint link_bitmap_size;
pthread_mutex_t mutex; pthread_mutex_t mutex;
pthread_mutex_t sts_mutex; pthread_mutex_t sts_mutex;
pthread_mutex_t crd_mutex; pthread_mutex_t crd_mutex;
/*
pthread_mutex_t auto_increment_mutex;
*/
TABLE_SHARE *table_share; TABLE_SHARE *table_share;
SPIDER_LGTM_TBLHND_SHARE *lgtm_tblhnd_share; SPIDER_LGTM_TBLHND_SHARE *lgtm_tblhnd_share;
my_hash_value_type table_name_hash_value; my_hash_value_type table_name_hash_value;
my_hash_value_type table_path_hash_value; my_hash_value_type table_path_hash_value;
/* Whether the share has been initialised */
volatile bool init; volatile bool init;
/* Whether an error occurred in initialisation of this share */
volatile bool init_error; volatile bool init_error;
/* The time of the initialisation error */
volatile time_t init_error_time; volatile time_t init_error_time;
volatile bool link_status_init; volatile bool link_status_init;
uchar *table_mon_mutex_bitmap; uchar *table_mon_mutex_bitmap;
@ -770,10 +783,6 @@ typedef struct st_spider_share
MEM_ROOT mem_root; MEM_ROOT mem_root;
/*
volatile bool auto_increment_init;
volatile ulonglong auto_increment_lclval;
*/
ha_statistics stat; ha_statistics stat;
longlong static_records_for_status; longlong static_records_for_status;
@ -788,17 +797,27 @@ typedef struct st_spider_share
longlong additional_table_flags; longlong additional_table_flags;
bool have_recovery_link; bool have_recovery_link;
/** See `mysql_sysvar_sts_bg_mode` */
int sts_bg_mode; int sts_bg_mode;
/** See `mysql_sysvar_sts_interval` */
double sts_interval; double sts_interval;
/** See `mysql_sysvar_sts_mode` */
int sts_mode; int sts_mode;
/** See `mysql_sysvar_sts_sync` */
int sts_sync; int sts_sync;
int store_last_sts; int store_last_sts;
/** See `mysql_sysvar_load_sts_at_startup` */
int load_sts_at_startup; int load_sts_at_startup;
/** See `mysql_sysvar_crd_bg_mode` */
int crd_bg_mode; int crd_bg_mode;
/** See `mysql_sysvar_crd_interval` */
double crd_interval; double crd_interval;
/** See `mysql_sysvar_crd_mode` */
int crd_mode; int crd_mode;
/** See `mysql_sysvar_crd_sync` */
int crd_sync; int crd_sync;
int store_last_crd; int store_last_crd;
/** See `mysql_sysvar_load_crd_at_startup` */
int load_crd_at_startup; int load_crd_at_startup;
int crd_type; int crd_type;
double crd_weight; double crd_weight;
@ -836,6 +855,7 @@ typedef struct st_spider_share
longlong bgs_second_read; longlong bgs_second_read;
longlong first_read; longlong first_read;
longlong second_read; longlong second_read;
/** See `mysql_sysvar_auto_increment_mode` */
int auto_increment_mode; int auto_increment_mode;
int use_table_charset; int use_table_charset;
int use_pushdown_udf; int use_pushdown_udf;
@ -846,6 +866,8 @@ typedef struct st_spider_share
int read_only_mode; int read_only_mode;
int error_read_mode; int error_read_mode;
int error_write_mode; int error_write_mode;
/* Number of active remote servers, for use in load balancing read
connections */
int active_link_count; int active_link_count;
#ifdef HA_CAN_FORCE_BULK_UPDATE #ifdef HA_CAN_FORCE_BULK_UPDATE
int force_bulk_update; int force_bulk_update;
@ -868,6 +890,8 @@ typedef struct st_spider_share
char **tgt_usernames; char **tgt_usernames;
char **tgt_passwords; char **tgt_passwords;
char **tgt_sockets; char **tgt_sockets;
/** The wrapper of target servers, each element has the same
possible values as `SPIDER_DBTON::wrapper` */
char **tgt_wrappers; char **tgt_wrappers;
char **tgt_ssl_cas; char **tgt_ssl_cas;
char **tgt_ssl_capaths; char **tgt_ssl_capaths;
@ -885,6 +909,7 @@ typedef struct st_spider_share
char **conn_keys; char **conn_keys;
long *tgt_ports; long *tgt_ports;
long *tgt_ssl_vscs; long *tgt_ssl_vscs;
/* See SPIDER_LINK_STATUS_* in spd_include.h */
long *link_statuses; long *link_statuses;
long *monitoring_bg_flag; long *monitoring_bg_flag;
long *monitoring_bg_kind; long *monitoring_bg_kind;
@ -897,6 +922,7 @@ typedef struct st_spider_share
long *connect_timeouts; long *connect_timeouts;
long *net_read_timeouts; long *net_read_timeouts;
long *net_write_timeouts; long *net_write_timeouts;
/* Connection load balancing integer weight */
long *access_balances; long *access_balances;
long *bka_table_name_types; long *bka_table_name_types;
long *strict_group_bys; long *strict_group_bys;
@ -988,10 +1014,16 @@ typedef struct st_spider_share
uint bka_table_name_types_length; uint bka_table_name_types_length;
uint strict_group_bys_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)]; uchar dbton_bitmap[spider_bitmap_size(SPIDER_DBTON_SIZE)];
spider_db_share *dbton_share[SPIDER_DBTON_SIZE]; spider_db_share *dbton_share[SPIDER_DBTON_SIZE];
/* Number of `SPIDER_DBTON`s used */
uint use_dbton_count; uint use_dbton_count;
/* Index of each `SPIDER_DBTON` in `spider_dbton` to use */
uint use_dbton_ids[SPIDER_DBTON_SIZE]; uint use_dbton_ids[SPIDER_DBTON_SIZE];
uint dbton_id_to_seq[SPIDER_DBTON_SIZE]; uint dbton_id_to_seq[SPIDER_DBTON_SIZE];
uint use_sql_dbton_count; uint use_sql_dbton_count;
@ -1008,14 +1040,23 @@ typedef struct st_spider_link_pack
int link_idx; int link_idx;
} SPIDER_LINK_PACK; } 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 typedef struct st_spider_init_error_table
{ {
/* The associated table name */
char *table_name; char *table_name;
/* Length of the associated table name */
uint table_name_length; uint table_name_length;
/* Hash value of the associated table name for lookup */
my_hash_value_type table_name_hash_value; my_hash_value_type table_name_hash_value;
/* Whether the error has a message */
bool init_error_with_message; bool init_error_with_message;
/* The error message */
char init_error_msg[MYSQL_ERRMSG_SIZE]; char init_error_msg[MYSQL_ERRMSG_SIZE];
/* The error code */
volatile int init_error; volatile int init_error;
/* The error time */
volatile time_t init_error_time; volatile time_t init_error_time;
} SPIDER_INIT_ERROR_TABLE; } SPIDER_INIT_ERROR_TABLE;

View file

@ -1771,7 +1771,7 @@ int spider_param_sts_mode(
/* /*
-1 :use table parameter -1 :use table parameter
0 :No synchronization. 0 :No synchronization.
1 :Table state is synchronized when opening a table. 1 :Table stat is synchronized when opening a table.
Then no synchronization. Then no synchronization.
2 :Synchronization. 2 :Synchronization.
*/ */

View file

@ -316,7 +316,6 @@ my_bool spider_param_index_hint_pushdown(
); );
uint spider_param_max_connections(); uint spider_param_max_connections();
uint spider_param_conn_wait_timeout(); uint spider_param_conn_wait_timeout();
uint spider_param_internal_lock_wait_timeout();
uint spider_param_log_result_errors(); uint spider_param_log_result_errors();
uint spider_param_log_result_error_with_sql(); uint spider_param_log_result_error_with_sql();
uint spider_param_internal_xa_id_type( uint spider_param_internal_xa_id_type(

View file

@ -505,7 +505,7 @@ SPIDER_TABLE_MON_LIST *spider_get_ping_table_tgt(
(*error_num = spider_get_sys_tables_connect_info( (*error_num = spider_get_sys_tables_connect_info(
table_tables, tmp_share, 0, &mem_root)) || table_tables, tmp_share, 0, &mem_root)) ||
(*error_num = spider_get_sys_tables_link_status( (*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)); table_tables->file->print_error(*error_num, MYF(0));
goto error; goto error;

View file

@ -979,6 +979,16 @@ void spider_store_xa_member_info(
DBUG_VOID_RETURN; 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( void spider_store_tables_name(
TABLE *table, TABLE *table,
const char *name, const char *name,
@ -1443,6 +1453,12 @@ void spider_store_binlog_pos_gtid(
DBUG_VOID_RETURN; 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( void spider_store_table_sts_info(
TABLE *table, TABLE *table,
ha_statistics *stat ha_statistics *stat
@ -1595,6 +1611,18 @@ int spider_insert_sys_table(
DBUG_RETURN(error_num); 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( int spider_insert_or_update_table_sts(
TABLE *table, TABLE *table,
const char *name, const char *name,
@ -2642,31 +2670,22 @@ int spider_get_sys_tables_monitoring_binlog_pos_at_failing(
DBUG_RETURN(error_num); DBUG_RETURN(error_num);
} }
int spider_get_sys_tables_link_status( /**
TABLE *table, Reads a table field and updates a link_status of a spider share
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);
}
@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( int spider_get_sys_tables_link_status(
TABLE *table, TABLE *table,
long *link_status, long *link_status,
MEM_ROOT *mem_root MEM_ROOT *mem_root
) { )
{
char *ptr; char *ptr;
int error_num = 0; int error_num = 0;
DBUG_ENTER("spider_get_sys_tables_link_status"); 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); *link_status = (long) my_strtoll10(ptr, (char**) NULL, &error_num);
else else
*link_status = 1; *link_status = 1;
DBUG_PRINT("info",("spider link_statuses=%ld", *link_status));
DBUG_RETURN(error_num); DBUG_RETURN(error_num);
} }
@ -2716,6 +2734,14 @@ int spider_get_sys_tables_static_link_id(
DBUG_RETURN(error_num); 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( void spider_get_sys_table_sts_info(
TABLE *table, TABLE *table,
ha_statistics *stat ha_statistics *stat
@ -3173,6 +3199,15 @@ int spider_get_sys_link_mon_connect_info(
DBUG_RETURN(error_num); 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( int spider_get_link_statuses(
TABLE *table, TABLE *table,
SPIDER_SHARE *share, SPIDER_SHARE *share,
@ -3191,14 +3226,10 @@ int spider_get_link_statuses(
{ {
if ( if (
(error_num == HA_ERR_KEY_NOT_FOUND || error_num == HA_ERR_END_OF_FILE) (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); DBUG_RETURN(error_num);
} } else if ((error_num = spider_get_sys_tables_link_status(
} else if ((error_num = table, &share->link_statuses[roop_count], mem_root)))
spider_get_sys_tables_link_status(table, share, roop_count, mem_root)))
{ {
table->file->print_error(error_num, MYF(0)); table->file->print_error(error_num, MYF(0));
DBUG_RETURN(error_num); DBUG_RETURN(error_num);
@ -3207,6 +3238,16 @@ int spider_get_link_statuses(
DBUG_RETURN(0); 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( int spider_sys_insert_or_update_table_sts(
THD *thd, THD *thd,
const char *name, const char *name,
@ -3345,6 +3386,14 @@ error:
DBUG_RETURN(error_num); 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( int spider_sys_get_table_sts(
THD *thd, THD *thd,
const char *name, const char *name,

View file

@ -437,13 +437,6 @@ int spider_get_sys_tables_monitoring_binlog_pos_at_failing(
MEM_ROOT *mem_root MEM_ROOT *mem_root
); );
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( int spider_get_sys_tables_link_status(
TABLE *table, TABLE *table,
long *link_status, long *link_status,

File diff suppressed because it is too large Load diff

View file

@ -493,28 +493,6 @@ int spider_free_wide_share(
SPIDER_WIDE_SHARE *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( int spider_open_all_tables(
SPIDER_TRX *trx, SPIDER_TRX *trx,
bool lock bool lock

View file

@ -3872,46 +3872,59 @@ void spider_reuse_trx_ha(
DBUG_VOID_RETURN; 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( void spider_trx_set_link_idx_for_all(
ha_spider *spider ha_spider *spider
) { ) {
int roop_count, roop_count2;
SPIDER_SHARE *share = spider->share; SPIDER_SHARE *share = spider->share;
long *link_statuses = share->link_statuses; long *link_statuses = share->link_statuses;
uint *conn_link_idx = spider->conn_link_idx; uint *conn_link_idx = spider->conn_link_idx;
int link_count = share->link_count; uint link_count = share->link_count;
int all_link_count = share->all_link_count; uint all_link_count = share->all_link_count;
uchar *conn_can_fo = spider->conn_can_fo; uchar *conn_can_fo = spider->conn_can_fo;
DBUG_ENTER("spider_trx_set_link_idx_for_all"); DBUG_ENTER("spider_trx_set_link_idx_for_all");
DBUG_PRINT("info",("spider set link_count=%d", link_count)); DBUG_PRINT("info",("spider set link_count=%d", link_count));
DBUG_PRINT("info",("spider set all_link_count=%d", all_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); memset(conn_can_fo, 0, sizeof(uchar) * share->link_bitmap_size);
for (roop_count = 0; roop_count < link_count; roop_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++)
{ {
for (roop_count2 = roop_count; roop_count2 < all_link_count; uint all_link_idx;
roop_count2 += link_count) 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; break;
} }
if (roop_count2 < all_link_count) if (all_link_idx < all_link_count)
{ {
conn_link_idx[roop_count] = roop_count2; conn_link_idx[link_idx] = all_link_idx;
if (roop_count2 + link_count < all_link_count) if (all_link_idx + link_count < all_link_count)
spider_set_bit(conn_can_fo, roop_count); spider_set_bit(conn_can_fo, link_idx);
DBUG_PRINT("info",("spider set conn_link_idx[%d]=%d", DBUG_PRINT("info",("spider set conn_link_idx[%d]=%d",
roop_count, roop_count2)); link_idx, all_link_idx));
} else { } else
conn_link_idx[roop_count] = roop_count; {
conn_link_idx[link_idx] = link_idx;
DBUG_PRINT("info",("spider set2 conn_link_idx[%d]=%d", 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, 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*); share->conn_keys[0]), char*);
DBUG_PRINT("info",("spider conn_keys[%d]=%s", 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; DBUG_VOID_RETURN;
} }