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));
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))

View file

@ -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;

View file

@ -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));

View file

@ -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))
) {

View file

@ -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)();

View file

@ -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())
} 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;
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)
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);
pthread_mutex_unlock(&conn->mta_conn_mutex);
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,
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)
} else /* get from information schema */
{
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())
{
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)))
/* 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);
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));
}
/* 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)
} 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))
{
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))
{
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_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(

View file

@ -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;

View file

@ -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.
*/

View file

@ -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(

View file

@ -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;

View file

@ -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,

View file

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

View file

@ -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++)
/* 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;
roop_count2 += link_count)
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;
}