mariadb/storage/spider/spd_ping_table.cc

1861 lines
63 KiB
C++
Raw Normal View History

/* Copyright (C) 2009-2019 Kentoku Shiba
Copyright (C) 2019 MariaDB corp
2014-03-25 04:23:24 +09:00
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
2019-05-11 22:19:05 +03:00
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
2014-03-25 04:23:24 +09:00
#define MYSQL_SERVER 1
#include <my_global.h>
2014-03-25 04:23:24 +09:00
#include "mysql_version.h"
#include "sql_priv.h"
#include "probes_mysql.h"
#include "sql_class.h"
#include "sql_partition.h"
#include "sql_acl.h"
#include "spd_err.h"
#include "spd_param.h"
#include "spd_db_include.h"
#include "spd_include.h"
#include "ha_spider.h"
#include "spd_db_conn.h"
#include "spd_trx.h"
#include "spd_conn.h"
#include "spd_sys_table.h"
#include "spd_table.h"
#include "spd_ping_table.h"
#include "spd_direct_sql.h"
#include "spd_udf.h"
#include "spd_malloc.h"
extern bool volatile *spd_abort_loop;
2014-03-25 04:23:24 +09:00
extern handlerton *spider_hton_ptr;
#ifdef HAVE_PSI_INTERFACE
extern PSI_mutex_key spd_key_mutex_mon_list_caller;
extern PSI_mutex_key spd_key_mutex_mon_list_receptor;
extern PSI_mutex_key spd_key_mutex_mon_list_monitor;
extern PSI_mutex_key spd_key_mutex_mon_list_update_status;
extern PSI_mutex_key spd_key_mutex_mon_table_cache;
#endif
/* Array (of size `spider_udf_table_mon_mutex_count') of hashes of
`SPIDER_TABLE_MON_LIST'. */
2014-03-25 04:23:24 +09:00
HASH *spider_udf_table_mon_list_hash;
uint spider_udf_table_mon_list_hash_id;
const char *spider_udf_table_mon_list_hash_func_name;
const char *spider_udf_table_mon_list_hash_file_name;
ulong spider_udf_table_mon_list_hash_line_no;
pthread_mutex_t *spider_udf_table_mon_mutexes;
pthread_cond_t *spider_udf_table_mon_conds;
pthread_mutex_t spider_mon_table_cache_mutex;
/* A cache to store distinct SPIDER_MON_KEYs with db name, table name
and link id read from mysql.spider_link_mon_servers table. Initialised
and populated in spider_init_ping_table_mon_cache(), and used in
spider_ping_table_cache_compare(). The udf
spider_flush_table_mon_cache is used to flag a initialisation. */
2014-03-25 04:23:24 +09:00
DYNAMIC_ARRAY spider_mon_table_cache;
uint spider_mon_table_cache_id;
const char *spider_mon_table_cache_func_name;
const char *spider_mon_table_cache_file_name;
ulong spider_mon_table_cache_line_no;
/* The mon table cache version, initialised at 0, and always no
greater than spider_mon_table_cache_version_req. When the inequality
is strict, an initialisation of spider_mon_table_cache will be
triggered. */
MDEV-33661 MENT-1591 Keep spider in memory until exit in ASAN builds Same as MDEV-29579. For some reason, libodbc does not clean up properly if unloaded too early with the dlclose() of spider. So we add UNIQUE symbols to spider so the spider does not reload in dlclose(). This change, however, uncovers some hidden problems in the spider codebase, for which we move the initialisation of some spider global variables into the initialisation of spider itself. Spider has some global variables. Their initialisation should be done in the initialisation of spider itself, otherwise, if spider were re-initialised without these symbol being unloaded, the values could be inconsistent and causing issues. One such issue is caused by the variables spider_mon_table_cache_version and spider_mon_table_cache_version_req. They are used for resetting the spider monitoring table cache and have initial values of 0 and 1 respectively. We have that always spider_mon_table_cache_version_req >= spider_mon_table_cache_version, and when the relation is strict, the cache is reset, spider_mon_table_cache_version is brought to be equal to spider_mon_table_cache_version_req, and the cache is searched for matching table_name, db_name and link_idx. If the relation is equal, no reset would happen and the cache would be searched directly. When spider is re-inited without resetting the values of spider_mon_table_cache_version and spider_mon_table_cache_version_req that were set to be equal in the previous cache reset action, the cache was emptied in the previous spider deinit, which would result in HA_ERR_KEY_NOT_FOUND unexpectedly. An alternative way to fix this issue would be to call the spider udf spider_flush_mon_cache_table(), which increments spider_mon_table_cache_version_req thus making sure the inequality is strict. However, there's no reason for spider to initialise these global variables on dlopen(), rather than on spider init, which is cleaner and "purer". To reproduce this issue, simply revert the changes involving the two variables and then run: mtr --no-reorder spider.ha{,_part}
2024-03-13 13:11:15 +11:00
volatile ulonglong spider_mon_table_cache_version;
/* The required mon table cache version, incremented by one by the
udf spider_flush_table_mon_cache */
MDEV-33661 MENT-1591 Keep spider in memory until exit in ASAN builds Same as MDEV-29579. For some reason, libodbc does not clean up properly if unloaded too early with the dlclose() of spider. So we add UNIQUE symbols to spider so the spider does not reload in dlclose(). This change, however, uncovers some hidden problems in the spider codebase, for which we move the initialisation of some spider global variables into the initialisation of spider itself. Spider has some global variables. Their initialisation should be done in the initialisation of spider itself, otherwise, if spider were re-initialised without these symbol being unloaded, the values could be inconsistent and causing issues. One such issue is caused by the variables spider_mon_table_cache_version and spider_mon_table_cache_version_req. They are used for resetting the spider monitoring table cache and have initial values of 0 and 1 respectively. We have that always spider_mon_table_cache_version_req >= spider_mon_table_cache_version, and when the relation is strict, the cache is reset, spider_mon_table_cache_version is brought to be equal to spider_mon_table_cache_version_req, and the cache is searched for matching table_name, db_name and link_idx. If the relation is equal, no reset would happen and the cache would be searched directly. When spider is re-inited without resetting the values of spider_mon_table_cache_version and spider_mon_table_cache_version_req that were set to be equal in the previous cache reset action, the cache was emptied in the previous spider deinit, which would result in HA_ERR_KEY_NOT_FOUND unexpectedly. An alternative way to fix this issue would be to call the spider udf spider_flush_mon_cache_table(), which increments spider_mon_table_cache_version_req thus making sure the inequality is strict. However, there's no reason for spider to initialise these global variables on dlopen(), rather than on spider init, which is cleaner and "purer". To reproduce this issue, simply revert the changes involving the two variables and then run: mtr --no-reorder spider.ha{,_part}
2024-03-13 13:11:15 +11:00
volatile ulonglong spider_mon_table_cache_version_req;
2014-03-25 04:23:24 +09:00
/* Get or create a `SPIDER_TABLE_MON_LIST' for a key `str' */
2014-03-25 04:23:24 +09:00
SPIDER_TABLE_MON_LIST *spider_get_ping_table_mon_list(
SPIDER_TRX *trx,
THD *thd,
spider_string *str, /* The key to search in
`spider_udf_table_mon_list_hash',
usually in the format of
"./$db_name/$table_name000000000$link_idx" */
2014-03-25 04:23:24 +09:00
uint conv_name_length,
int link_idx,
char *static_link_id,
uint static_link_id_length,
uint32 server_id, /* The server id of the monitor
server, used for creating a new
table mon list having a
`SPIDER_TABLE_MON' corresponding to
the server id as the `current'
field */
2014-03-25 04:23:24 +09:00
bool need_lock,
int *error_num
) {
uint mutex_hash;
SPIDER_TABLE_MON_LIST *table_mon_list;
MEM_ROOT mem_root;
ulonglong mon_table_cache_version;
my_hash_value_type hash_value;
DBUG_ENTER("spider_get_ping_table_mon_list");
/* Reset the cache if the version does not match the requirement */
2014-03-25 04:23:24 +09:00
if (spider_mon_table_cache_version != spider_mon_table_cache_version_req)
{
SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME));
if ((*error_num = spider_init_ping_table_mon_cache(thd, &mem_root,
need_lock)))
{
free_root(&mem_root, MYF(0));
goto error;
}
free_root(&mem_root, MYF(0));
}
/* Search for the table mon list in the hash, if one is not found or
if it is found but has the wrong cache version, create and
initialise a new one. */
mutex_hash=
spider_udf_calc_hash(str->c_ptr(), spider_udf_table_mon_mutex_count);
2014-03-25 04:23:24 +09:00
DBUG_PRINT("info",("spider hash key=%s", str->c_ptr()));
DBUG_PRINT("info",("spider hash key length=%u", str->length()));
hash_value = my_calc_hash(
&spider_udf_table_mon_list_hash[mutex_hash],
(uchar*) str->c_ptr(), str->length());
pthread_mutex_lock(&spider_udf_table_mon_mutexes[mutex_hash]);
mon_table_cache_version = (ulonglong) spider_mon_table_cache_version;
if (!(table_mon_list = (SPIDER_TABLE_MON_LIST *)
my_hash_search_using_hash_value(
&spider_udf_table_mon_list_hash[mutex_hash], hash_value,
(uchar*) str->c_ptr(), str->length())) ||
table_mon_list->mon_table_cache_version != mon_table_cache_version
)
{
/* If table_mon_list is found but the cache version does not
match, remove it from the hash and free it. */
2014-03-25 04:23:24 +09:00
if (
table_mon_list &&
table_mon_list->mon_table_cache_version != mon_table_cache_version
)
spider_release_ping_table_mon_list_loop(mutex_hash, table_mon_list);
/* create and initialise `table_mon_list' and insert it into the
hash */
2014-03-25 04:23:24 +09:00
if (!(table_mon_list = spider_get_ping_table_tgt(thd, str->c_ptr(),
conv_name_length, link_idx, static_link_id, static_link_id_length,
server_id, str, need_lock, error_num)))
2014-03-25 04:23:24 +09:00
{
pthread_mutex_unlock(&spider_udf_table_mon_mutexes[mutex_hash]);
goto error;
}
table_mon_list->mutex_hash = mutex_hash;
table_mon_list->mon_table_cache_version = mon_table_cache_version;
uint old_elements =
spider_udf_table_mon_list_hash[mutex_hash].array.max_element;
table_mon_list->key_hash_value = hash_value;
if (my_hash_insert(&spider_udf_table_mon_list_hash[mutex_hash],
(uchar*) table_mon_list))
{
spider_ping_table_free_mon_list(table_mon_list);
*error_num = HA_ERR_OUT_OF_MEM;
my_error(HA_ERR_OUT_OF_MEM, MYF(0));
pthread_mutex_unlock(&spider_udf_table_mon_mutexes[mutex_hash]);
goto error;
}
if (spider_udf_table_mon_list_hash[mutex_hash].array.max_element >
old_elements)
{
spider_alloc_calc_mem(spider_current_trx,
spider_udf_table_mon_list_hash,
(spider_udf_table_mon_list_hash[mutex_hash].array.max_element -
old_elements) *
spider_udf_table_mon_list_hash[mutex_hash].array.size_of_element);
}
}
table_mon_list->use_count++;
DBUG_PRINT("info",("spider table_mon_list->use_count=%d",
table_mon_list->use_count));
pthread_mutex_unlock(&spider_udf_table_mon_mutexes[mutex_hash]);
DBUG_RETURN(table_mon_list);
error:
DBUG_RETURN(NULL);
}
void spider_free_ping_table_mon_list(
SPIDER_TABLE_MON_LIST *table_mon_list
) {
DBUG_ENTER("spider_free_ping_table_mon_list");
pthread_mutex_lock(&spider_udf_table_mon_mutexes[
table_mon_list->mutex_hash]);
table_mon_list->use_count--;
DBUG_PRINT("info",("spider table_mon_list->use_count=%d", table_mon_list->use_count));
if (!table_mon_list->use_count)
pthread_cond_broadcast(&spider_udf_table_mon_conds[
table_mon_list->mutex_hash]);
pthread_mutex_unlock(&spider_udf_table_mon_mutexes[
table_mon_list->mutex_hash]);
DBUG_VOID_RETURN;
}
void spider_release_ping_table_mon_list_loop(
uint mutex_hash,
SPIDER_TABLE_MON_LIST *table_mon_list
) {
DBUG_ENTER("spider_release_ping_table_mon_list_loop");
my_hash_delete(&spider_udf_table_mon_list_hash[mutex_hash],
(uchar*) table_mon_list);
while (TRUE)
{
if (table_mon_list->use_count)
pthread_cond_wait(&spider_udf_table_mon_conds[mutex_hash],
&spider_udf_table_mon_mutexes[mutex_hash]);
else {
spider_ping_table_free_mon_list(table_mon_list);
break;
}
}
DBUG_VOID_RETURN;
}
int spider_release_ping_table_mon_list(
2014-03-25 04:23:24 +09:00
const char *conv_name,
uint conv_name_length,
int link_idx
) {
uint mutex_hash;
SPIDER_TABLE_MON_LIST *table_mon_list;
char link_idx_str[SPIDER_CONNECT_INFO_MAX_LEN + 1];
2014-03-25 04:23:24 +09:00
int link_idx_str_length;
DBUG_ENTER("spider_release_ping_table_mon_list");
DBUG_PRINT("info", ("spider conv_name=%s", conv_name));
DBUG_PRINT("info", ("spider conv_name_length=%u", conv_name_length));
DBUG_PRINT("info", ("spider link_idx=%d", link_idx));
link_idx_str_length = my_sprintf(link_idx_str, (link_idx_str, "%010d",
link_idx));
char *buf = (char *) my_alloca(conv_name_length + link_idx_str_length + 1);
if (!buf)
{
my_error(HA_ERR_OUT_OF_MEM, MYF(0));
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
2014-03-25 04:23:24 +09:00
spider_string conv_name_str(buf, conv_name_length + link_idx_str_length + 1,
system_charset_info);
conv_name_str.init_calc_mem(SPD_MID_RELEASE_PING_TABLE_MON_LIST_1);
2014-03-25 04:23:24 +09:00
conv_name_str.length(0);
conv_name_str.q_append(conv_name, conv_name_length);
conv_name_str.q_append(link_idx_str, link_idx_str_length);
mutex_hash= spider_udf_calc_hash(conv_name_str.c_ptr_safe(),
spider_udf_table_mon_mutex_count);
2014-03-25 04:23:24 +09:00
my_hash_value_type hash_value = my_calc_hash(
&spider_udf_table_mon_list_hash[mutex_hash],
(uchar*) conv_name_str.c_ptr(), conv_name_str.length());
pthread_mutex_lock(&spider_udf_table_mon_mutexes[mutex_hash]);
if ((table_mon_list = (SPIDER_TABLE_MON_LIST *)
my_hash_search_using_hash_value(
&spider_udf_table_mon_list_hash[mutex_hash], hash_value,
(uchar*) conv_name_str.c_ptr(), conv_name_str.length())))
spider_release_ping_table_mon_list_loop(mutex_hash, table_mon_list);
pthread_mutex_unlock(&spider_udf_table_mon_mutexes[mutex_hash]);
my_afree(buf);
DBUG_RETURN(0);
2014-03-25 04:23:24 +09:00
}
/*
Look for a `SPIDER_MON_KEY` in `spider_mon_table_cache' whose db and
table name and link_idx matching `name' and `link_idx' with wild
card matching. If a match is found, create `SPIDER_TABLE_MON's from
all rows in mysql.spider_link_mon_servers that match the info in the
`SPIDER_MON_KEY' and populate the `table_mon_list' with these
`SPIDER_TABLE_MON's.
*/
2014-03-25 04:23:24 +09:00
int spider_get_ping_table_mon(
THD *thd,
SPIDER_TABLE_MON_LIST *table_mon_list,
char *name,
uint name_length,
int link_idx,
uint32 server_id,
MEM_ROOT *mem_root,
bool need_lock
) {
int error_num;
TABLE *table_link_mon = NULL;
SPIDER_Open_tables_backup open_tables_backup;
2014-03-25 04:23:24 +09:00
char table_key[MAX_KEY_LENGTH];
SPIDER_TABLE_MON *table_mon, *table_mon_prev = NULL;
SPIDER_SHARE *tmp_share;
char **tmp_connect_info, *tmp_ptr;
uint *tmp_connect_info_length;
long *tmp_long;
longlong *tmp_longlong;
int list_size = 0;
DBUG_ENTER("spider_get_ping_table_mon");
if (
!(table_link_mon = spider_open_sys_table(
thd, SPIDER_SYS_LINK_MON_TABLE_NAME_STR,
SPIDER_SYS_LINK_MON_TABLE_NAME_LEN, FALSE, &open_tables_backup,
&error_num))
2014-03-25 04:23:24 +09:00
) {
my_error(error_num, MYF(0));
goto error;
}
if (table_mon_list->share->static_link_ids[0])
{
spider_store_tables_name(table_link_mon, name, name_length);
spider_store_tables_link_idx_str(table_link_mon,
table_mon_list->share->static_link_ids[0],
table_mon_list->share->static_link_ids_lengths[0]);
if (!(error_num = spider_ping_table_cache_compare(table_link_mon, mem_root)))
goto create_table_mon;
if (error_num == HA_ERR_OUT_OF_MEM)
goto error;
if ((tmp_ptr = strstr(name, "#P#")))
{
*tmp_ptr = '\0';
spider_store_tables_name(table_link_mon, name, strlen(name));
*tmp_ptr = '#';
if (!(error_num = spider_ping_table_cache_compare(table_link_mon,
mem_root)))
goto create_table_mon;
if (error_num == HA_ERR_OUT_OF_MEM)
goto error;
}
}
2014-03-25 04:23:24 +09:00
spider_store_tables_name(table_link_mon, name, name_length);
spider_store_tables_link_idx(table_link_mon, link_idx);
if (!(error_num = spider_ping_table_cache_compare(table_link_mon, mem_root)))
goto create_table_mon;
if (error_num == HA_ERR_OUT_OF_MEM)
goto error;
if ((tmp_ptr = strstr(name, "#P#")))
{
*tmp_ptr = '\0';
spider_store_tables_name(table_link_mon, name, strlen(name));
*tmp_ptr = '#';
if (!(error_num = spider_ping_table_cache_compare(table_link_mon,
mem_root)))
goto create_table_mon;
if (error_num == HA_ERR_OUT_OF_MEM)
goto error;
}
error_num = HA_ERR_KEY_NOT_FOUND;
table_link_mon->file->print_error(error_num, MYF(0));
goto error;
create_table_mon:
/* Find the first row in mysql.spider_link_mon_servers matching the
db name, table name and link_idx */
2014-03-25 04:23:24 +09:00
if ((error_num = spider_get_sys_table_by_idx(table_link_mon, table_key,
table_link_mon->s->primary_key, 3)))
{
table_link_mon->file->print_error(error_num, MYF(0));
goto error;
}
/* create one `SPIDER_TABLE_MON' per row in
mysql.spider_link_mon_servers with matching db name, table name and
link_idx, and add it to `table_mon_list'. */
2014-03-25 04:23:24 +09:00
do {
if (!(table_mon = (SPIDER_TABLE_MON *)
spider_bulk_malloc(spider_current_trx, SPD_MID_GET_PING_TABLE_MON_1, MYF(MY_WME | MY_ZEROFILL),
&table_mon, (uint) (sizeof(SPIDER_TABLE_MON)),
&tmp_share, (uint) (sizeof(SPIDER_SHARE)),
&tmp_connect_info,
(uint) (sizeof(char *) * SPIDER_TMP_SHARE_CHAR_PTR_COUNT),
&tmp_connect_info_length,
(uint) (sizeof(uint) * SPIDER_TMP_SHARE_UINT_COUNT),
&tmp_long, (uint) (sizeof(long) * SPIDER_TMP_SHARE_LONG_COUNT),
&tmp_longlong,
(uint) (sizeof(longlong) * SPIDER_TMP_SHARE_LONGLONG_COUNT),
2014-03-25 04:23:24 +09:00
NullS))
) {
spider_sys_index_end(table_link_mon);
error_num = HA_ERR_OUT_OF_MEM;
my_error(HA_ERR_OUT_OF_MEM, MYF(0));
goto error;
}
spider_set_tmp_share_pointer(tmp_share, tmp_connect_info,
tmp_connect_info_length, tmp_long, tmp_longlong);
tmp_share->link_statuses[0] = -1;
table_mon->share = tmp_share;
table_mon->parent = table_mon_list;
2014-03-25 04:23:24 +09:00
if (table_mon_prev)
table_mon_prev->next = table_mon;
else
table_mon_list->first = table_mon;
table_mon_prev = table_mon;
if (
(error_num = spider_get_sys_link_mon_server_id(
table_link_mon, &table_mon->server_id, mem_root)) ||
(error_num = spider_get_sys_link_mon_connect_info(
table_link_mon, tmp_share, mem_root))
2014-03-25 04:23:24 +09:00
) {
table_link_mon->file->print_error(error_num, MYF(0));
spider_sys_index_end(table_link_mon);
goto error;
}
if (
(error_num = spider_set_connect_info_default(
tmp_share,
NULL,
NULL,
NULL
)) ||
(error_num = spider_set_connect_info_default_dbtable(
tmp_share, name, name_length
)) ||
(error_num = spider_create_conn_keys(tmp_share))
) {
spider_sys_index_end(table_link_mon);
goto error;
}
DBUG_PRINT("info",("spider table_mon->server_id=%u",
table_mon->server_id));
DBUG_PRINT("info",("spider server_id=%u", server_id));
if (table_mon->server_id == server_id)
table_mon_list->current = table_mon;
list_size++;
error_num = spider_sys_index_next_same(table_link_mon, table_key);
} while (error_num == 0);
spider_sys_index_end(table_link_mon);
spider_sys_close_table(thd, &open_tables_backup);
2014-03-25 04:23:24 +09:00
table_link_mon = NULL;
table_mon_list->list_size = list_size;
if (!table_mon_list->current)
{
error_num = ER_SPIDER_UDF_PING_TABLE_NO_SERVER_ID_NUM;
my_printf_error(ER_SPIDER_UDF_PING_TABLE_NO_SERVER_ID_NUM,
ER_SPIDER_UDF_PING_TABLE_NO_SERVER_ID_STR, MYF(0));
goto error;
}
DBUG_RETURN(0);
error:
if (table_link_mon)
spider_sys_close_table(thd, &open_tables_backup);
2014-03-25 04:23:24 +09:00
table_mon = table_mon_list->first;
table_mon_list->first = NULL;
table_mon_list->current = NULL;
while (table_mon)
{
spider_free_tmp_share_alloc(table_mon->share);
table_mon_prev = table_mon->next;
spider_free(spider_current_trx, table_mon, MYF(0));
table_mon = table_mon_prev;
}
DBUG_RETURN(error_num);
}
/*
creates and return table_mon_list associated with table with `name'
and `link_idx'th link.
*/
2014-03-25 04:23:24 +09:00
SPIDER_TABLE_MON_LIST *spider_get_ping_table_tgt(
THD *thd,
char *name, /* The table name, usually fully qualified */
2014-03-25 04:23:24 +09:00
uint name_length,
int link_idx,
char *static_link_id,
uint static_link_id_length,
uint32 server_id, /* The server_id will determine the
`current' field of the returned
`SPIDER_TABLE_MON_LIST'. */
spider_string *str, /* str->c_ptr() == name */
2014-03-25 04:23:24 +09:00
bool need_lock,
int *error_num
) {
TABLE *table_tables = NULL;
SPIDER_Open_tables_backup open_tables_backup;
2014-03-25 04:23:24 +09:00
char table_key[MAX_KEY_LENGTH];
SPIDER_TABLE_MON_LIST *table_mon_list = NULL;
SPIDER_SHARE *tmp_share;
char **tmp_connect_info;
uint *tmp_connect_info_length;
long *tmp_long;
longlong *tmp_longlong;
char *key_str;
MEM_ROOT mem_root;
DBUG_ENTER("spider_get_ping_table_tgt");
SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME));
if (!(table_mon_list = (SPIDER_TABLE_MON_LIST *)
spider_bulk_malloc(spider_current_trx, SPD_MID_GET_PING_TABLE_TGT_1, MYF(MY_WME | MY_ZEROFILL),
&table_mon_list, (uint) (sizeof(SPIDER_TABLE_MON_LIST)),
&tmp_share, (uint) (sizeof(SPIDER_SHARE)),
&tmp_connect_info,
(uint) (sizeof(char *) * SPIDER_TMP_SHARE_CHAR_PTR_COUNT),
&tmp_connect_info_length,
(uint) (sizeof(uint) * SPIDER_TMP_SHARE_UINT_COUNT),
&tmp_long,
(uint) (sizeof(long) * SPIDER_TMP_SHARE_LONG_COUNT),
&tmp_longlong,
(uint) (sizeof(longlong) * SPIDER_TMP_SHARE_LONGLONG_COUNT),
&key_str, (uint) (str->length() + 1),
2014-03-25 04:23:24 +09:00
NullS))
) {
my_error(HA_ERR_OUT_OF_MEM, MYF(0));
goto error;
}
spider_set_tmp_share_pointer(tmp_share, tmp_connect_info,
tmp_connect_info_length, tmp_long, tmp_longlong);
table_mon_list->share = tmp_share;
table_mon_list->key = key_str;
table_mon_list->key_length = str->length();
memcpy(key_str, str->ptr(), table_mon_list->key_length);
tmp_share->access_charset = thd->variables.character_set_client;
/* Open mysql.spider_tables */
2014-03-25 04:23:24 +09:00
if (
!(table_tables = spider_open_sys_table(
thd, SPIDER_SYS_TABLES_TABLE_NAME_STR,
SPIDER_SYS_TABLES_TABLE_NAME_LEN, FALSE, &open_tables_backup,
2014-03-25 04:23:24 +09:00
error_num))
) {
my_error(*error_num, MYF(0));
goto error;
}
/* store db and table names and link idx in mysql.spider_tables for
reading */
2014-03-25 04:23:24 +09:00
spider_store_tables_name(table_tables, name, name_length);
if (static_link_id)
{
spider_store_tables_static_link_id(table_tables,
static_link_id, static_link_id_length);
if (
(*error_num = spider_get_sys_table_by_idx(table_tables, table_key, 2,
SPIDER_SYS_TABLES_UIDX1_COL_CNT)) ||
(*error_num = spider_get_sys_tables_link_idx(
table_tables, &link_idx, &mem_root))
) {
table_tables->file->print_error(*error_num, MYF(0));
goto error;
}
} else {
spider_store_tables_link_idx(table_tables, link_idx);
if (
(*error_num = spider_check_sys_table(table_tables, table_key))
) {
table_tables->file->print_error(*error_num, MYF(0));
goto error;
}
}
/* Populate tmp_share with info read from mysql.spider_tables */
2014-03-25 04:23:24 +09:00
if (
(*error_num = spider_get_sys_tables_connect_info(
table_tables, tmp_share, &mem_root)) ||
2014-03-25 04:23:24 +09:00
(*error_num = spider_get_sys_tables_link_status(
table_tables, tmp_share->link_statuses, &mem_root))
2014-03-25 04:23:24 +09:00
) {
table_tables->file->print_error(*error_num, MYF(0));
goto error;
}
spider_sys_close_table(thd, &open_tables_backup);
2014-03-25 04:23:24 +09:00
table_tables = NULL;
if (
(*error_num = spider_set_connect_info_default(
tmp_share,
NULL,
NULL,
NULL
)) ||
(*error_num = spider_set_connect_info_default_dbtable(
tmp_share, name, name_length
)) ||
(*error_num = spider_create_conn_keys(tmp_share)) ||
/* Pinally, populate `table_mon_list' with newly created
`SPIDER_TABLE_MON's */
2014-03-25 04:23:24 +09:00
(*error_num = spider_get_ping_table_mon(
thd, table_mon_list, name, name_length, link_idx, server_id, &mem_root,
need_lock))
)
goto error;
if (tmp_share->link_statuses[0] == SPIDER_LINK_STATUS_NG)
table_mon_list->mon_status = SPIDER_LINK_MON_NG;
if (mysql_mutex_init(spd_key_mutex_mon_list_caller,
&table_mon_list->caller_mutex, MY_MUTEX_INIT_FAST))
{
*error_num = HA_ERR_OUT_OF_MEM;
goto error_caller_mutex_init;
}
if (mysql_mutex_init(spd_key_mutex_mon_list_receptor,
&table_mon_list->receptor_mutex, MY_MUTEX_INIT_FAST))
{
*error_num = HA_ERR_OUT_OF_MEM;
goto error_receptor_mutex_init;
}
if (mysql_mutex_init(spd_key_mutex_mon_list_monitor,
&table_mon_list->monitor_mutex, MY_MUTEX_INIT_FAST))
{
*error_num = HA_ERR_OUT_OF_MEM;
goto error_monitor_mutex_init;
}
if (mysql_mutex_init(spd_key_mutex_mon_list_update_status,
&table_mon_list->update_status_mutex, MY_MUTEX_INIT_FAST))
{
*error_num = HA_ERR_OUT_OF_MEM;
goto error_update_status_mutex_init;
}
free_root(&mem_root, MYF(0));
DBUG_RETURN(table_mon_list);
error_update_status_mutex_init:
pthread_mutex_destroy(&table_mon_list->monitor_mutex);
error_monitor_mutex_init:
pthread_mutex_destroy(&table_mon_list->receptor_mutex);
error_receptor_mutex_init:
pthread_mutex_destroy(&table_mon_list->caller_mutex);
error_caller_mutex_init:
error:
if (table_tables)
spider_sys_close_table(thd, &open_tables_backup);
2014-03-25 04:23:24 +09:00
free_root(&mem_root, MYF(0));
if (table_mon_list)
{
spider_free_tmp_share_alloc(table_mon_list->share);
spider_free(spider_current_trx, table_mon_list, MYF(0));
}
DBUG_RETURN(NULL);
}
SPIDER_CONN *spider_get_ping_table_tgt_conn(
SPIDER_TRX *trx,
SPIDER_SHARE *share,
int *error_num
) {
SPIDER_CONN *conn;
DBUG_ENTER("spider_get_ping_table_tgt_conn");
if (!(conn= spider_get_conn(share, 0, share->conn_keys[0], trx, NULL, FALSE,
FALSE, error_num)))
{
2014-03-25 04:23:24 +09:00
my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0),
share->server_names[0]);
*error_num = ER_CONNECT_TO_FOREIGN_DATA_SOURCE;
goto error;
}
2015-10-29 07:34:53 +09:00
#ifndef DBUG_OFF
DBUG_PRINT("info",("spider conn->thd=%p", conn->thd));
if (conn->thd)
{
DBUG_PRINT("info",("spider query_id=%lld", conn->thd->query_id));
}
#endif
2014-03-25 04:23:24 +09:00
conn->error_mode = 0;
DBUG_RETURN(conn);
error:
DBUG_RETURN(NULL);
}
int spider_get_ping_table_gtid_pos(
SPIDER_TRX *trx,
THD *thd,
spider_string *str,
uint conv_name_length,
int failed_link_idx,
uint32 server_id,
bool need_lock,
spider_string *tmp_str
) {
int error_num, source_link_idx, need_mon;
char table_key[MAX_KEY_LENGTH];
TABLE *table_tables, *table_gtid_pos;
SPIDER_Open_tables_backup open_tables_backup_tables;
#ifdef SPIDER_REQUIRE_DEFINE_FOR_SECONDARY_OPEN_TABLES_BACKUP
SPIDER_Open_tables_backup open_tables_backup_gtid_pos;
#endif
MEM_ROOT mem_root;
long link_status;
long monitoring_binlog_pos_at_failing;
SPIDER_TABLE_MON_LIST *table_mon_list;
SPIDER_CONN *ping_conn = NULL;
char *static_link_id;
uint static_link_id_length;
DBUG_ENTER("spider_get_ping_table_gtid_pos");
/*
select * from
mysql.spider_tables
where
db_name = setted db_name and
table_name = setted table_name
*/
#ifdef SPIDER_REQUIRE_DEFINE_FOR_SECONDARY_OPEN_TABLES_BACKUP
if (
!(table_tables = spider_open_sys_table(
thd, SPIDER_SYS_TABLES_TABLE_NAME_STR,
SPIDER_SYS_TABLES_TABLE_NAME_LEN, FALSE, &open_tables_backup_tables,
need_lock, &error_num))
)
goto error_open_table_tables;
if (
!(table_gtid_pos = spider_open_sys_table(
thd, SPIDER_SYS_POS_FOR_RECOVERY_TABLE_NAME_STR,
SPIDER_SYS_POS_FOR_RECOVERY_TABLE_NAME_LEN, TRUE,
&open_tables_backup_gtid_pos, need_lock, &error_num))
)
goto error_open_table_gtid_pos;
#else
TABLE_LIST tables_tables;
TABLE_LIST tables_gtid_pos;
TABLE_LIST *tables = &tables_tables;
LEX_CSTRING db_name =
{
"mysql",
sizeof("mysql") - 1
};
LEX_CSTRING tbl_name_tables =
{
SPIDER_SYS_TABLES_TABLE_NAME_STR,
SPIDER_SYS_TABLES_TABLE_NAME_LEN
};
LEX_CSTRING tbl_name_gtid_pos =
{
SPIDER_SYS_POS_FOR_RECOVERY_TABLE_NAME_STR,
SPIDER_SYS_POS_FOR_RECOVERY_TABLE_NAME_LEN
};
tables_tables.init_one_table(&db_name, &tbl_name_tables, 0, TL_READ);
tables_gtid_pos.init_one_table(&db_name, &tbl_name_gtid_pos, 0, TL_READ);
MDL_REQUEST_INIT(&tables_tables.mdl_request, MDL_key::TABLE,
SPIDER_TABLE_LIST_db_str(&tables_tables),
SPIDER_TABLE_LIST_table_name_str(&tables_tables),
MDL_SHARED_READ, MDL_TRANSACTION);
MDL_REQUEST_INIT(&tables_gtid_pos.mdl_request, MDL_key::TABLE,
SPIDER_TABLE_LIST_db_str(&tables_gtid_pos),
SPIDER_TABLE_LIST_table_name_str(&tables_gtid_pos),
MDL_SHARED_READ, MDL_TRANSACTION);
tables_tables.next_global = &tables_gtid_pos;
if (spider_sys_open_and_lock_tables(thd, &tables,
&open_tables_backup_tables))
{
2020-08-26 22:25:26 +09:00
error_num = my_errno;
goto error_open_table_tables;
}
table_tables = tables_tables.table;
table_gtid_pos = tables_gtid_pos.table;
#endif
table_tables->use_all_columns();
table_gtid_pos->use_all_columns();
spider_store_tables_name(table_tables, str->ptr(), conv_name_length);
spider_store_tables_name(table_gtid_pos, str->ptr(), conv_name_length);
spider_store_binlog_pos_failed_link_idx(table_gtid_pos, failed_link_idx);
if ((error_num = spider_get_sys_table_by_idx(table_tables, table_key, 0,
SPIDER_SYS_TABLES_PK_COL_CNT - 1)))
{
if (error_num == HA_ERR_KEY_NOT_FOUND || error_num == HA_ERR_END_OF_FILE)
{
error_num = 0;
}
goto error_get_sys_table_by_idx;
}
SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME));
do {
if (
(error_num = spider_get_sys_tables_link_status(table_tables,
&link_status, &mem_root)) ||
(error_num = spider_get_sys_tables_static_link_id(table_tables,
&static_link_id, &static_link_id_length, &mem_root)) ||
(error_num = spider_get_sys_tables_monitoring_binlog_pos_at_failing(
table_tables, &monitoring_binlog_pos_at_failing, &mem_root))
) {
goto error_get_sys_tables_link_status;
}
if (link_status == 1 && monitoring_binlog_pos_at_failing > 0)
{
if ((error_num = spider_get_sys_tables_link_idx(table_tables,
&source_link_idx, &mem_root)))
{
goto error_get_sys_tables_link_idx;
}
if (
(table_mon_list = spider_get_ping_table_mon_list(
trx,
thd,
str,
conv_name_length,
source_link_idx,
static_link_id,
static_link_id_length,
server_id,
need_lock,
&error_num
))
) {
SPIDER_DB_RESULT *res1 = NULL;
SPIDER_DB_RESULT *res2 = NULL;
if (
(ping_conn = spider_get_ping_table_tgt_conn(trx,
table_mon_list->share, &error_num
)) &&
!(error_num = ping_conn->db_conn->show_master_status(
trx, table_mon_list->share, 0, &need_mon, table_gtid_pos, tmp_str,
monitoring_binlog_pos_at_failing == 1 ? 0 : 1, &res1, &res2))
) {
spider_store_binlog_pos_source_link_idx(
table_gtid_pos, source_link_idx);
spider_insert_sys_table(table_gtid_pos);
}
if (res1)
{
res1->free_result();
delete res1;
}
if (res2)
{
res2->free_result();
delete res2;
}
spider_free_ping_table_mon_list(table_mon_list);
}
}
error_num = spider_sys_index_next_same(table_tables, table_key);
} while (error_num == 0);
free_root(&mem_root, MYF(0));
if ((error_num = spider_sys_index_end(table_tables)))
{
goto error_sys_index_end;
}
#ifdef SPIDER_REQUIRE_DEFINE_FOR_SECONDARY_OPEN_TABLES_BACKUP
spider_sys_close_table(thd, table_gtid_pos,
&open_tables_backup_gtid_pos, need_lock);
#endif
spider_sys_close_table(thd, &open_tables_backup_tables);
DBUG_RETURN(0);
error_get_sys_tables_link_idx:
error_get_sys_tables_link_status:
free_root(&mem_root, MYF(0));
spider_sys_index_end(table_tables);
error_sys_index_end:
error_get_sys_table_by_idx:
#ifdef SPIDER_REQUIRE_DEFINE_FOR_SECONDARY_OPEN_TABLES_BACKUP
spider_sys_close_table(thd, table_gtid_pos,
&open_tables_backup_gtid_pos,
need_lock);
error_open_table_gtid_pos:
#endif
spider_sys_close_table(thd, &open_tables_backup_tables);
error_open_table_tables:
DBUG_RETURN(error_num);
}
/*
Initialise `spider_mon_table_cache' by scanning the
mysql.spider_link_mon_servers table, creating distinct
`SPIDER_MON_KEY's with the info and inserting them into the cache.
*/
2014-03-25 04:23:24 +09:00
int spider_init_ping_table_mon_cache(
THD *thd,
MEM_ROOT *mem_root,
bool need_lock
) {
int error_num, same;
uint old_elements;
2014-03-25 04:23:24 +09:00
TABLE *table_link_mon = NULL;
SPIDER_Open_tables_backup open_tables_backup;
2014-03-25 04:23:24 +09:00
SPIDER_MON_KEY mon_key;
DBUG_ENTER("spider_init_ping_table_mon_cache");
if (
!(table_link_mon = spider_open_sys_table(
thd, SPIDER_SYS_LINK_MON_TABLE_NAME_STR,
SPIDER_SYS_LINK_MON_TABLE_NAME_LEN, FALSE, &open_tables_backup,
&error_num))
2014-03-25 04:23:24 +09:00
) {
my_error(error_num, MYF(0));
goto error_open_sys_table;
}
pthread_mutex_lock(&spider_mon_table_cache_mutex);
if (spider_mon_table_cache_version != spider_mon_table_cache_version_req)
{
/* reset */
spider_mon_table_cache.elements = 0;
/* start at the first row */
2014-03-25 04:23:24 +09:00
if ((error_num = spider_sys_index_first(table_link_mon,
table_link_mon->s->primary_key)))
{
if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE)
{
table_link_mon->file->print_error(error_num, MYF(0));
goto error_sys_index_first;
}
}
if (!error_num)
{
mon_key.db_name_length = SPIDER_SYS_LINK_MON_TABLE_DB_NAME_SIZE + 1;
mon_key.table_name_length = SPIDER_SYS_LINK_MON_TABLE_TABLE_NAME_SIZE + 1;
mon_key.link_id_length = SPIDER_SYS_LINK_MON_TABLE_LINK_ID_SIZE + 1;
do {
/* update content of `mon_key' */
2014-03-25 04:23:24 +09:00
if ((error_num = spider_get_sys_link_mon_key(table_link_mon, &mon_key,
mem_root, &same)))
goto error_get_sys_link_mon_key;
/* `mon_key' has changed content. since
mysql.spider_link_mon_servers is indexed by db_name,
table_name, link_idx, and server_id, it is possible that
different server_ids share the same mon_key which only has
db_name, table_name, link_idx */
2014-03-25 04:23:24 +09:00
if (!same)
{
mon_key.sort = spider_calc_for_sort(3, mon_key.db_name,
mon_key.table_name, mon_key.link_id);
old_elements = spider_mon_table_cache.max_element;
2014-03-25 04:23:24 +09:00
if (push_dynamic(&spider_mon_table_cache, (uchar *) &mon_key))
{
error_num = HA_ERR_OUT_OF_MEM;
goto error_push_dynamic;
}
if (spider_mon_table_cache.max_element != old_elements)
{
spider_free_mem_calc(spider_current_trx,
spider_mon_table_cache_id,
old_elements *
spider_mon_table_cache.size_of_element);
spider_alloc_calc_mem(spider_current_trx,
spider_mon_table_cache,
spider_mon_table_cache.max_element *
spider_mon_table_cache.size_of_element);
}
2014-03-25 04:23:24 +09:00
}
if ((error_num = spider_sys_index_next(table_link_mon)))
{
if (
error_num != HA_ERR_KEY_NOT_FOUND &&
error_num != HA_ERR_END_OF_FILE
) {
table_link_mon->file->print_error(error_num, MYF(0));
goto error_sys_index_next;
}
}
} while (!error_num);
spider_sys_index_end(table_link_mon);
}
my_qsort(
(uchar *) dynamic_element(&spider_mon_table_cache, 0, SPIDER_MON_KEY *),
spider_mon_table_cache.elements, sizeof(SPIDER_MON_KEY),
(qsort_cmp) spider_compare_for_sort);
old_elements = spider_mon_table_cache.max_element;
2014-03-25 04:23:24 +09:00
freeze_size(&spider_mon_table_cache);
if (spider_mon_table_cache.max_element != old_elements)
2014-03-25 04:23:24 +09:00
{
spider_free_mem_calc(spider_current_trx,
spider_mon_table_cache_id,
old_elements *
spider_mon_table_cache.size_of_element);
spider_alloc_calc_mem(spider_current_trx,
spider_mon_table_cache,
2014-03-25 04:23:24 +09:00
spider_mon_table_cache.max_element *
spider_mon_table_cache.size_of_element);
}
spider_mon_table_cache_version = spider_mon_table_cache_version_req;
}
pthread_mutex_unlock(&spider_mon_table_cache_mutex);
spider_sys_close_table(thd, &open_tables_backup);
2014-03-25 04:23:24 +09:00
DBUG_RETURN(0);
error_push_dynamic:
error_get_sys_link_mon_key:
error_sys_index_next:
spider_sys_index_end(table_link_mon);
error_sys_index_first:
pthread_mutex_unlock(&spider_mon_table_cache_mutex);
spider_sys_close_table(thd, &open_tables_backup);
2014-03-25 04:23:24 +09:00
error_open_sys_table:
DBUG_RETURN(error_num);
}
/*
Read from msyql.spider_link_mon_servers table fields the db name,
table name and link_id and search for them with wild card matching
in `spider_mon_table_cache'. store the db name, table name, and
link_id of the matching `SPIDER_MON_KEY' back to the table field on
success.
*/
2014-03-25 04:23:24 +09:00
int spider_ping_table_cache_compare(
TABLE *table,
MEM_ROOT *mem_root
) {
uint32 roop_count;
SPIDER_MON_KEY *mon_key;
char *db_name, *table_name, *link_id;
DBUG_ENTER("spider_ping_table_cache_compare");
if (!(db_name = get_field(mem_root, table->field[0])))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
if (!(table_name = get_field(mem_root, table->field[1])))
2014-03-25 04:23:24 +09:00
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
if (!(link_id = get_field(mem_root, table->field[2])))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
2014-03-25 04:23:24 +09:00
DBUG_PRINT("info", ("spider db_name=%s", db_name));
DBUG_PRINT("info", ("spider table_name=%s", table_name));
DBUG_PRINT("info", ("spider link_id=%s", link_id));
pthread_mutex_lock(&spider_mon_table_cache_mutex);
for (roop_count = 0; roop_count < spider_mon_table_cache.elements;
roop_count++)
{
mon_key = dynamic_element(&spider_mon_table_cache, roop_count,
SPIDER_MON_KEY *);
DBUG_PRINT("info", ("spider roop_count=%d", roop_count));
DBUG_PRINT("info", ("spider mon_key.db_name=%s", mon_key->db_name));
DBUG_PRINT("info", ("spider mon_key.table_name=%s", mon_key->table_name));
DBUG_PRINT("info", ("spider mon_key.link_id=%s", mon_key->link_id));
if (
!wild_case_compare(system_charset_info, db_name, mon_key->db_name) &&
!wild_case_compare(system_charset_info, table_name,
mon_key->table_name) &&
!wild_case_compare(system_charset_info, link_id, mon_key->link_id)
) {
spider_store_db_and_table_name(
table,
mon_key->db_name,
mon_key->db_name_length,
mon_key->table_name,
mon_key->table_name_length
);
spider_store_tables_link_idx_str(
table,
mon_key->link_id,
mon_key->link_id_length
);
pthread_mutex_unlock(&spider_mon_table_cache_mutex);
DBUG_PRINT("info", ("spider found"));
DBUG_RETURN(0);
}
}
pthread_mutex_unlock(&spider_mon_table_cache_mutex);
DBUG_PRINT("info", ("spider not found"));
DBUG_RETURN(1);
}
long long spider_ping_table_body(
UDF_INIT *initid,
UDF_ARGS *args,
unsigned char *is_null,
unsigned char *error
2014-03-25 04:23:24 +09:00
) {
int error_num = 0, link_idx, flags, full_mon_count, current_mon_count,
success_count, fault_count, tmp_error_num = 0;
uint32 first_sid, server_id;
2014-03-25 04:23:24 +09:00
longlong limit, tmp_sid = -1;
SPIDER_MON_TABLE_RESULT *mon_table_result =
(SPIDER_MON_TABLE_RESULT *) initid->ptr;
SPIDER_TRX *trx = mon_table_result->trx;
THD *thd = trx->thd;
SPIDER_CONN *ping_conn = NULL, *mon_conn;
char *where_clause;
SPIDER_TABLE_MON_LIST *table_mon_list;
SPIDER_TABLE_MON *table_mon;
char buf[MAX_FIELD_WIDTH], buf2[MAX_FIELD_WIDTH];
2014-03-25 04:23:24 +09:00
spider_string conv_name(buf, sizeof(buf), system_charset_info);
spider_string tmp_str(buf2, sizeof(buf2), system_charset_info);
2014-03-25 04:23:24 +09:00
int conv_name_length;
char link_idx_str[SPIDER_CONNECT_INFO_MAX_LEN + 1];
2014-03-25 04:23:24 +09:00
int link_idx_str_length;
char *static_link_id = NULL;
int static_link_id_length = 0;
bool get_lock = FALSE, status_changed_to_ng = FALSE;
2014-03-25 04:23:24 +09:00
DBUG_ENTER("spider_ping_table_body");
conv_name.init_calc_mem(SPD_MID_PING_TABLE_BODY_1);
tmp_str.init_calc_mem(SPD_MID_PING_TABLE_BODY_2);
2014-03-25 04:23:24 +09:00
conv_name.length(0);
server_id = global_system_variables.server_id;
2014-03-25 04:23:24 +09:00
if (
thd->open_tables != 0 ||
thd->handler_tables_hash.records != 0 ||
thd->derived_tables != 0 ||
thd->lock != 0 ||
thd->locked_tables_list.locked_tables() ||
thd->locked_tables_mode != LTM_NONE
) {
if (thd->open_tables != 0)
{
my_printf_error(ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_NUM,
ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_STR_WITH_PTR, MYF(0),
"thd->open_tables", thd->open_tables);
} else if (thd->handler_tables_hash.records != 0)
{
my_printf_error(ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_NUM,
ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_STR_WITH_NUM, MYF(0),
"thd->handler_tables_hash.records",
(longlong) thd->handler_tables_hash.records);
} else if (thd->derived_tables != 0)
{
my_printf_error(ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_NUM,
ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_STR_WITH_PTR, MYF(0),
"thd->derived_tables", thd->derived_tables);
} else if (thd->lock != 0)
{
my_printf_error(ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_NUM,
ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_STR_WITH_PTR, MYF(0),
"thd->lock", thd->lock);
} else if (thd->locked_tables_list.locked_tables())
{
my_printf_error(ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_NUM,
ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_STR_WITH_PTR, MYF(0),
"thd->locked_tables_list.locked_tables()",
thd->locked_tables_list.locked_tables());
} else if (thd->locked_tables_mode != LTM_NONE)
{
my_printf_error(ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_NUM,
ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_STR_WITH_NUM, MYF(0),
"thd->locked_tables_mode", (longlong) thd->locked_tables_mode);
}
goto error;
}
if (
args->lengths[0] > SPIDER_CONNECT_INFO_MAX_LEN
) {
my_printf_error(ER_SPIDER_UDF_PARAM_TOO_LONG_NUM,
ER_SPIDER_UDF_PARAM_TOO_LONG_STR, MYF(0), "table name");
2014-03-25 04:23:24 +09:00
goto error;
}
if (
args->lengths[0] == 0
) {
my_printf_error(ER_SPIDER_UDF_PARAM_REQIRED_NUM,
ER_SPIDER_UDF_PARAM_REQIRED_STR, MYF(0), "table name");
2014-03-25 04:23:24 +09:00
goto error;
}
if (args->arg_type[1] == STRING_RESULT)
{
if (
!args->args[1]
) {
my_printf_error(ER_SPIDER_UDF_PARAM_REQIRED_NUM,
ER_SPIDER_UDF_PARAM_REQIRED_STR, MYF(0), "link id");
goto error;
}
if (
args->lengths[1] > SPIDER_CONNECT_INFO_MAX_LEN
) {
my_printf_error(ER_SPIDER_UDF_PARAM_TOO_LONG_NUM,
ER_SPIDER_UDF_PARAM_TOO_LONG_STR, MYF(0), "link id");
goto error;
}
link_idx_str_length = args->lengths[1];
memcpy(link_idx_str, args->args[1], link_idx_str_length + 1);
if (link_idx_str[0] >= '0' && link_idx_str[0] <= '9')
{
link_idx = atoi(link_idx_str);
} else {
link_idx = -1;
static_link_id = link_idx_str;
static_link_id_length = link_idx_str_length;
}
} else {
link_idx = (int) (args->args[1] ? *((longlong *) args->args[1]) : 0);
link_idx_str_length = my_sprintf(link_idx_str, (link_idx_str, "%010d",
link_idx));
}
2014-03-25 04:23:24 +09:00
flags = (int) (args->args[2] ? *((longlong *) args->args[2]) : 0);
limit = args->args[3] ? *((longlong *) args->args[3]) : 0;
where_clause = args->args[4] ? args->args[4] : (char *) "";
if (conv_name.append(args->args[0], args->lengths[0],
trx->thd->variables.character_set_client))
{
my_error(HA_ERR_OUT_OF_MEM, MYF(0));
goto error;
}
conv_name_length = conv_name.length();
if (conv_name.reserve(link_idx_str_length + 1))
{
my_error(HA_ERR_OUT_OF_MEM, MYF(0));
goto error;
}
conv_name.q_append(link_idx_str, link_idx_str_length + 1);
conv_name.length(conv_name.length() - 1);
if (!(table_mon_list = spider_get_ping_table_mon_list(trx, trx->thd,
&conv_name, conv_name_length, link_idx,
static_link_id, static_link_id_length,
server_id, TRUE, &error_num)))
2014-03-25 04:23:24 +09:00
goto error;
if (table_mon_list->mon_status == SPIDER_LINK_MON_NG)
{
mon_table_result->result_status = SPIDER_LINK_MON_NG;
DBUG_PRINT("info",
("spider mon_table_result->result_status=SPIDER_LINK_MON_NG 1"));
goto end;
}
if (args->args[5])
tmp_sid = *((longlong *) args->args[5]);
if (tmp_sid >= 0)
{
first_sid = (uint32) tmp_sid;
full_mon_count = (int) (args->args[6] ? *((longlong *) args->args[6]) : 0);
current_mon_count =
(int) (args->args[7] ? *((longlong *) args->args[7]) + 1 : 1);
if (full_mon_count != table_mon_list->list_size)
{
my_printf_error(ER_SPIDER_UDF_PING_TABLE_DIFFERENT_MON_NUM,
ER_SPIDER_UDF_PING_TABLE_DIFFERENT_MON_STR, MYF(0));
goto error_with_free_table_mon_list;
}
} else {
first_sid = server_id;
2014-03-25 04:23:24 +09:00
full_mon_count = table_mon_list->list_size;
current_mon_count = 1;
}
success_count = (int) (args->args[8] ? *((longlong *) args->args[8]) : 0);
fault_count = (int) (args->args[9] ? *((longlong *) args->args[9]) : 0);
if (
table_mon_list->mon_status != SPIDER_LINK_MON_NG &&
!(ping_conn = spider_get_ping_table_tgt_conn(trx,
table_mon_list->share, &error_num))
) {
if (error_num == HA_ERR_OUT_OF_MEM)
goto error_with_free_table_mon_list;
else
thd->clear_error();
}
if (
table_mon_list->mon_status == SPIDER_LINK_MON_NG ||
error_num ||
(tmp_error_num = spider_db_udf_ping_table(table_mon_list, table_mon_list->share, trx,
ping_conn, where_clause, args->lengths[4],
(flags & SPIDER_UDF_PING_TABLE_PING_ONLY),
(flags & SPIDER_UDF_PING_TABLE_USE_WHERE),
limit
))
) {
2015-10-29 07:34:53 +09:00
DBUG_PRINT("info",("spider table_mon_list->mon_status == SPIDER_LINK_MON_NG:%s",
table_mon_list->mon_status == SPIDER_LINK_MON_NG ? "TRUE" : "FALSE"));
DBUG_PRINT("info",("spider error_num=%d", error_num));
DBUG_PRINT("info",("spider tmp_error_num=%d", tmp_error_num));
2014-03-25 04:23:24 +09:00
if (tmp_error_num == HA_ERR_OUT_OF_MEM)
goto error_with_free_table_mon_list;
else if(tmp_error_num)
thd->clear_error();
2015-10-29 07:34:53 +09:00
if (tmp_error_num != ER_CON_COUNT_ERROR)
2014-03-25 04:23:24 +09:00
{
2015-10-29 07:34:53 +09:00
fault_count++;
error_num = 0;
if (
!(flags & SPIDER_UDF_PING_TABLE_USE_ALL_MONITORING_NODES) &&
fault_count > full_mon_count / 2
) {
mon_table_result->result_status = SPIDER_LINK_MON_NG;
DBUG_PRINT("info",("spider mon_table_result->result_status=SPIDER_LINK_MON_NG 2"));
2014-03-25 04:23:24 +09:00
if (table_mon_list->mon_status != SPIDER_LINK_MON_NG)
{
2015-10-29 07:34:53 +09:00
pthread_mutex_lock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]);
if (table_mon_list->mon_status != SPIDER_LINK_MON_NG)
{
table_mon_list->mon_status = SPIDER_LINK_MON_NG;
table_mon_list->share->link_statuses[0] = SPIDER_LINK_STATUS_NG;
spider_update_link_status_for_share(conv_name.c_ptr(),
conv_name_length, link_idx, SPIDER_LINK_STATUS_NG);
spider_sys_update_tables_link_status(trx->thd,
conv_name.c_ptr(), conv_name_length, link_idx,
SPIDER_LINK_STATUS_NG);
2015-10-29 07:34:53 +09:00
spider_sys_log_tables_link_failed(trx->thd,
conv_name.c_ptr(), conv_name_length, link_idx);
status_changed_to_ng = TRUE;
2015-10-29 07:34:53 +09:00
}
pthread_mutex_unlock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]);
if (status_changed_to_ng)
{
bool is_error = trx->thd->is_error();
spider_get_ping_table_gtid_pos(trx, trx->thd,
&conv_name, conv_name_length, link_idx, server_id, TRUE,
&tmp_str);
if (!is_error && trx->thd->is_error())
trx->thd->clear_error();
}
2014-03-25 04:23:24 +09:00
}
2015-10-29 07:34:53 +09:00
goto end;
2014-03-25 04:23:24 +09:00
}
}
} else {
success_count++;
2015-10-29 07:34:53 +09:00
if (
!(flags & SPIDER_UDF_PING_TABLE_USE_ALL_MONITORING_NODES) &&
success_count > full_mon_count / 2
) {
2014-03-25 04:23:24 +09:00
mon_table_result->result_status = SPIDER_LINK_MON_OK;
DBUG_PRINT("info",("spider mon_table_result->result_status=SPIDER_LINK_MON_OK 1"));
goto end;
}
}
if (tmp_sid < 0)
{
if (!pthread_mutex_trylock(&table_mon_list->receptor_mutex))
get_lock = TRUE;
}
if (
tmp_sid >= 0 ||
get_lock
) {
table_mon = table_mon_list->current->next;
while (TRUE)
{
if (!table_mon)
table_mon = table_mon_list->first;
if (
table_mon->server_id == first_sid ||
current_mon_count > full_mon_count
) {
2015-10-29 07:34:53 +09:00
if (
(flags & SPIDER_UDF_PING_TABLE_USE_ALL_MONITORING_NODES) &&
fault_count > full_mon_count / 2
) {
mon_table_result->result_status = SPIDER_LINK_MON_NG;
DBUG_PRINT("info",("spider mon_table_result->result_status=SPIDER_LINK_MON_NG 3"));
if (table_mon_list->mon_status != SPIDER_LINK_MON_NG)
{
pthread_mutex_lock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]);
if (table_mon_list->mon_status != SPIDER_LINK_MON_NG)
{
table_mon_list->mon_status = SPIDER_LINK_MON_NG;
table_mon_list->share->link_statuses[0] = SPIDER_LINK_STATUS_NG;
spider_update_link_status_for_share(conv_name.c_ptr(),
conv_name_length, link_idx, SPIDER_LINK_STATUS_NG);
spider_sys_update_tables_link_status(trx->thd,
conv_name.c_ptr(), conv_name_length, link_idx,
SPIDER_LINK_STATUS_NG);
2015-10-29 07:34:53 +09:00
spider_sys_log_tables_link_failed(trx->thd,
conv_name.c_ptr(), conv_name_length, link_idx);
status_changed_to_ng = TRUE;
2015-10-29 07:34:53 +09:00
}
pthread_mutex_unlock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]);
if (status_changed_to_ng)
{
bool is_error = trx->thd->is_error();
spider_get_ping_table_gtid_pos(trx, trx->thd,
&conv_name, conv_name_length, link_idx, server_id, TRUE,
&tmp_str);
if (!is_error && trx->thd->is_error())
trx->thd->clear_error();
}
2015-10-29 07:34:53 +09:00
}
} else if (
(flags & SPIDER_UDF_PING_TABLE_USE_ALL_MONITORING_NODES) &&
success_count > full_mon_count / 2
) {
mon_table_result->result_status = SPIDER_LINK_MON_OK;
DBUG_PRINT("info",("spider mon_table_result->result_status=SPIDER_LINK_MON_OK 2"));
} else if (success_count + fault_count > full_mon_count / 2)
2014-03-25 04:23:24 +09:00
{
mon_table_result->result_status = SPIDER_LINK_MON_DRAW;
DBUG_PRINT("info",(
"spider mon_table_result->result_status=SPIDER_LINK_MON_DRAW 1"));
} else {
mon_table_result->result_status = SPIDER_LINK_MON_DRAW_FEW_MON;
DBUG_PRINT("info",(
"spider mon_table_result->result_status=SPIDER_LINK_MON_DRAW_FEW_MON 1"));
}
table_mon_list->last_receptor_result = mon_table_result->result_status;
break;
}
if ((mon_conn = spider_get_ping_table_tgt_conn(trx,
table_mon->share, &error_num))
) {
if (!spider_db_udf_ping_table_mon_next(
thd, table_mon, mon_conn, mon_table_result, args->args[0],
args->lengths[0], link_idx,
where_clause, args->lengths[4], first_sid, full_mon_count,
current_mon_count, success_count, fault_count, flags, limit))
{
if (
mon_table_result->result_status == SPIDER_LINK_MON_NG &&
table_mon_list->mon_status != SPIDER_LINK_MON_NG
) {
2015-10-29 07:34:53 +09:00
pthread_mutex_lock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]);
2014-03-25 04:23:24 +09:00
if (table_mon_list->mon_status != SPIDER_LINK_MON_NG)
{
table_mon_list->mon_status = SPIDER_LINK_MON_NG;
table_mon_list->share->link_statuses[0] = SPIDER_LINK_STATUS_NG;
2015-10-29 07:34:53 +09:00
spider_update_link_status_for_share(conv_name.c_ptr(),
conv_name_length, link_idx, SPIDER_LINK_STATUS_NG);
2014-03-25 04:23:24 +09:00
spider_sys_update_tables_link_status(trx->thd,
conv_name.c_ptr(), conv_name_length, link_idx,
SPIDER_LINK_STATUS_NG);
2014-03-25 04:23:24 +09:00
spider_sys_log_tables_link_failed(trx->thd,
conv_name.c_ptr(), conv_name_length, link_idx);
status_changed_to_ng = TRUE;
2014-03-25 04:23:24 +09:00
}
2015-10-29 07:34:53 +09:00
pthread_mutex_unlock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]);
if (status_changed_to_ng)
{
bool is_error = trx->thd->is_error();
spider_get_ping_table_gtid_pos(trx, trx->thd,
&conv_name, conv_name_length, link_idx, server_id, TRUE,
&tmp_str);
if (!is_error && trx->thd->is_error())
trx->thd->clear_error();
}
2014-03-25 04:23:24 +09:00
}
table_mon_list->last_receptor_result =
mon_table_result->result_status;
break;
}
}
thd->clear_error();
table_mon = table_mon->next;
current_mon_count++;
}
if (get_lock)
pthread_mutex_unlock(&table_mon_list->receptor_mutex);
} else {
pthread_mutex_lock(&table_mon_list->receptor_mutex);
mon_table_result->result_status = table_mon_list->last_receptor_result;
DBUG_PRINT("info",("spider mon_table_result->result_status=%d 1",
table_mon_list->last_receptor_result));
pthread_mutex_unlock(&table_mon_list->receptor_mutex);
}
end:
spider_free_ping_table_mon_list(table_mon_list);
DBUG_RETURN(mon_table_result->result_status);
error_with_free_table_mon_list:
spider_free_ping_table_mon_list(table_mon_list);
error:
*error = 1;
DBUG_RETURN(0);
}
my_bool spider_ping_table_init_body(
UDF_INIT *initid,
UDF_ARGS *args,
char *message
) {
int error_num;
THD *thd = current_thd;
SPIDER_TRX *trx;
SPIDER_MON_TABLE_RESULT *mon_table_result = NULL;
DBUG_ENTER("spider_ping_table_init_body");
if (args->arg_count != 10)
{
strcpy(message, "spider_ping_table() requires 10 arguments");
goto error;
}
if (
args->arg_type[0] != STRING_RESULT ||
args->arg_type[4] != STRING_RESULT
) {
strcpy(message, "spider_ping_table() requires string 1st "
"and 5th arguments");
goto error;
}
if (
args->arg_type[2] != INT_RESULT ||
args->arg_type[3] != INT_RESULT ||
args->arg_type[5] != INT_RESULT ||
args->arg_type[6] != INT_RESULT ||
args->arg_type[7] != INT_RESULT ||
args->arg_type[8] != INT_RESULT ||
args->arg_type[9] != INT_RESULT
) {
strcpy(message, "spider_ping_table() requires integer 3rd, 4,6,7,8,"
2014-03-25 04:23:24 +09:00
"9th and 10th argument");
goto error;
}
if (
args->arg_type[1] != INT_RESULT &&
args->arg_type[1] != STRING_RESULT
) {
strcpy(message, "spider_ping_table() requires string or integer for "
"2nd argument");
goto error;
}
2014-03-25 04:23:24 +09:00
if (!(trx = spider_get_trx(thd, TRUE, &error_num)))
{
my_error(error_num, MYF(0));
strcpy(message, spider_stmt_da_message(thd));
goto error;
}
if (!(mon_table_result = (SPIDER_MON_TABLE_RESULT *)
spider_malloc(spider_current_trx, SPD_MID_PING_TABLE_INIT_BODY_1, sizeof(SPIDER_MON_TABLE_RESULT),
2014-03-25 04:23:24 +09:00
MYF(MY_WME | MY_ZEROFILL)))
) {
strcpy(message, "spider_ping_table() out of memory");
goto error;
}
mon_table_result->trx = trx;
initid->ptr = (char *) mon_table_result;
DBUG_RETURN(FALSE);
error:
if (mon_table_result)
{
spider_free(spider_current_trx, mon_table_result, MYF(0));
}
DBUG_RETURN(TRUE);
}
void spider_ping_table_deinit_body(
UDF_INIT *initid
) {
SPIDER_MON_TABLE_RESULT *mon_table_result =
(SPIDER_MON_TABLE_RESULT *) initid->ptr;
DBUG_ENTER("spider_ping_table_deinit_body");
if (mon_table_result)
{
spider_free(spider_current_trx, mon_table_result, MYF(0));
}
DBUG_VOID_RETURN;
}
long long spider_flush_table_mon_cache_body()
{
DBUG_ENTER("spider_flush_table_mon_cache_body");
spider_mon_table_cache_version_req++;
DBUG_RETURN(1);
}
void spider_ping_table_free_mon_list(
SPIDER_TABLE_MON_LIST *table_mon_list
) {
DBUG_ENTER("spider_ping_table_free_mon_list");
if (table_mon_list)
{
spider_ping_table_free_mon(table_mon_list->first);
spider_free_tmp_share_alloc(table_mon_list->share);
pthread_mutex_destroy(&table_mon_list->update_status_mutex);
pthread_mutex_destroy(&table_mon_list->monitor_mutex);
pthread_mutex_destroy(&table_mon_list->receptor_mutex);
pthread_mutex_destroy(&table_mon_list->caller_mutex);
spider_free(spider_current_trx, table_mon_list, MYF(0));
}
DBUG_VOID_RETURN;
}
void spider_ping_table_free_mon(
SPIDER_TABLE_MON *table_mon
) {
SPIDER_TABLE_MON *table_mon_next;
DBUG_ENTER("spider_ping_table_free_mon");
while (table_mon)
{
spider_free_tmp_share_alloc(table_mon->share);
table_mon_next = table_mon->next;
spider_free(spider_current_trx, table_mon, MYF(0));
table_mon = table_mon_next;
}
DBUG_VOID_RETURN;
}
int spider_ping_table_mon_from_table(
SPIDER_TRX *trx,
THD *thd,
SPIDER_SHARE *share,
int base_link_idx,
2014-03-25 04:23:24 +09:00
uint32 server_id,
char *conv_name, /* Usually fully qualified table name */
2014-03-25 04:23:24 +09:00
uint conv_name_length,
int link_idx, /* The link id to ping */
2014-03-25 04:23:24 +09:00
char *where_clause,
uint where_clause_length,
long monitoring_kind,
longlong monitoring_limit,
2015-10-29 07:34:53 +09:00
long monitoring_flag,
2014-03-25 04:23:24 +09:00
bool need_lock
) {
int error_num = 0, current_mon_count, flags;
uint32 first_sid;
SPIDER_TABLE_MON_LIST *table_mon_list;
SPIDER_TABLE_MON *table_mon;
SPIDER_MON_TABLE_RESULT mon_table_result;
SPIDER_CONN *mon_conn;
TABLE_SHARE *table_share = share->table_share;
char link_idx_str[SPIDER_CONNECT_INFO_MAX_LEN + 1];
2014-03-25 04:23:24 +09:00
int link_idx_str_length;
char *db_or_server;
2014-03-25 04:23:24 +09:00
uint sql_command = thd_sql_command(thd);
DBUG_ENTER("spider_ping_table_mon_from_table");
if (table_share->tmp_table != NO_TMP_TABLE)
{
my_printf_error(ER_SPIDER_TMP_TABLE_MON_NUM,
ER_SPIDER_TMP_TABLE_MON_STR, MYF(0));
DBUG_RETURN(ER_SPIDER_TMP_TABLE_MON_NUM);
}
if (
sql_command == SQLCOM_DROP_TABLE ||
sql_command == SQLCOM_ALTER_TABLE
) {
my_printf_error(ER_SPIDER_MON_AT_ALTER_TABLE_NUM,
ER_SPIDER_MON_AT_ALTER_TABLE_STR, MYF(0));
DBUG_RETURN(ER_SPIDER_MON_AT_ALTER_TABLE_NUM);
}
2014-06-08 19:52:11 +09:00
DBUG_PRINT("info",("spider thd->killed=%s",
thd ? (thd->killed ? "TRUE" : "FALSE") : "NULL"));
DBUG_PRINT("info",("spider abort_loop=%s",
*spd_abort_loop ? "TRUE" : "FALSE"));
2014-06-08 19:52:11 +09:00
if (
(thd && thd->killed) ||
*spd_abort_loop
2014-06-08 19:52:11 +09:00
) {
DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM);
}
2014-03-25 04:23:24 +09:00
if (share->static_link_ids[link_idx])
{
memcpy(link_idx_str, share->static_link_ids[link_idx],
share->static_link_ids_lengths[link_idx] + 1);
link_idx_str_length = share->static_link_ids_lengths[link_idx];
} else {
link_idx_str_length = my_sprintf(link_idx_str, (link_idx_str, "%010d",
link_idx));
}
char *buf = (char *) my_alloca(conv_name_length + link_idx_str_length + 1);
if (!buf)
{
my_error(HA_ERR_OUT_OF_MEM, MYF(0));
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
2014-03-25 04:23:24 +09:00
buf[conv_name_length + link_idx_str_length] = '\0';
spider_string conv_name_str(buf, conv_name_length + link_idx_str_length + 1,
system_charset_info);
conv_name_str.init_calc_mem(SPD_MID_PING_TABLE_MON_FROM_TABLE_1);
2014-03-25 04:23:24 +09:00
conv_name_str.length(0);
conv_name_str.q_append(conv_name, conv_name_length);
conv_name_str.q_append(link_idx_str, link_idx_str_length + 1);
conv_name_str.length(conv_name_str.length() - 1);
if (monitoring_kind == 1)
flags = SPIDER_UDF_PING_TABLE_PING_ONLY;
else if (monitoring_kind == 3)
flags = SPIDER_UDF_PING_TABLE_USE_WHERE;
else
flags = 0;
2015-10-29 07:34:53 +09:00
if (monitoring_flag & 1)
flags |= SPIDER_UDF_PING_TABLE_USE_ALL_MONITORING_NODES;
/* Get or create `table_mon_list' for `conv_name_str'. */
2014-03-25 04:23:24 +09:00
if (!(table_mon_list = spider_get_ping_table_mon_list(trx, thd,
&conv_name_str, conv_name_length, link_idx,
share->static_link_ids[link_idx],
share->static_link_ids_lengths[link_idx],
server_id, need_lock, &error_num)))
{
my_afree(buf);
2014-03-25 04:23:24 +09:00
goto end;
}
2014-03-25 04:23:24 +09:00
db_or_server= table_mon_list->share->tgt_dbs[0];
if (!db_or_server)
db_or_server= table_mon_list->share->server_names[0];
2014-03-25 04:23:24 +09:00
if (table_mon_list->mon_status == SPIDER_LINK_MON_NG)
{
DBUG_PRINT("info",
("spider share->link_statuses[%d]=SPIDER_LINK_STATUS_NG", link_idx));
2015-10-29 07:34:53 +09:00
pthread_mutex_lock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]);
2014-03-25 04:23:24 +09:00
share->link_statuses[link_idx] = SPIDER_LINK_STATUS_NG;
2015-10-29 07:34:53 +09:00
pthread_mutex_unlock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]);
2014-03-25 04:23:24 +09:00
error_num = ER_SPIDER_LINK_MON_NG_NUM;
my_printf_error(error_num,
ER_SPIDER_LINK_MON_NG_STR, MYF(0), db_or_server,
2014-03-25 04:23:24 +09:00
table_mon_list->share->tgt_table_names[0]);
my_afree(buf);
2014-03-25 04:23:24 +09:00
goto end_with_free_table_mon_list;
}
if (!pthread_mutex_trylock(&table_mon_list->caller_mutex))
{
table_mon = table_mon_list->current;
first_sid = table_mon->server_id;
current_mon_count = 1;
/* Call spider_ping_table on each table_mon of `table_mon_list',
until one succeeds */
2014-03-25 04:23:24 +09:00
while (TRUE)
{
2014-06-08 19:52:11 +09:00
DBUG_PRINT("info",("spider thd->killed=%s",
thd ? (thd->killed ? "TRUE" : "FALSE") : "NULL"));
DBUG_PRINT("info",("spider abort_loop=%s",
*spd_abort_loop ? "TRUE" : "FALSE"));
2014-03-25 04:23:24 +09:00
if (
2014-06-08 19:52:11 +09:00
(thd && thd->killed) ||
*spd_abort_loop
2014-03-25 04:23:24 +09:00
) {
2014-06-08 19:52:11 +09:00
error_num = ER_SPIDER_COND_SKIP_NUM;
2014-03-25 04:23:24 +09:00
break;
2014-06-08 19:52:11 +09:00
} else {
if (!table_mon)
table_mon = table_mon_list->first;
if (
current_mon_count > table_mon_list->list_size ||
(current_mon_count > 1 && table_mon->server_id == first_sid)
) {
table_mon_list->last_caller_result = SPIDER_LINK_MON_DRAW_FEW_MON;
mon_table_result.result_status = SPIDER_LINK_MON_DRAW_FEW_MON;
DBUG_PRINT("info",(
"spider mon_table_result->result_status=SPIDER_LINK_MON_DRAW_FEW_MON 1"));
error_num = ER_SPIDER_LINK_MON_DRAW_FEW_MON_NUM;
my_printf_error(error_num,
ER_SPIDER_LINK_MON_DRAW_FEW_MON_STR, MYF(0), db_or_server,
2014-06-08 19:52:11 +09:00
table_mon_list->share->tgt_table_names[0]);
break;
}
int prev_error = 0;
char prev_error_msg[MYSQL_ERRMSG_SIZE];
if (thd->is_error())
2014-03-25 04:23:24 +09:00
{
2014-06-08 19:52:11 +09:00
prev_error = spider_stmt_da_sql_errno(thd);
strmov(prev_error_msg, spider_stmt_da_message(thd));
thd->clear_error();
}
if ((mon_conn = spider_get_ping_table_tgt_conn(trx,
table_mon->share, &error_num))
) {
if (!spider_db_udf_ping_table_mon_next(
thd, table_mon, mon_conn, &mon_table_result, conv_name,
conv_name_length, link_idx,
where_clause, where_clause_length, /*first_sid=*/-1, table_mon_list->list_size,
2014-06-08 19:52:11 +09:00
0, 0, 0, flags, monitoring_limit))
{
if (
mon_table_result.result_status == SPIDER_LINK_MON_NG &&
table_mon_list->mon_status != SPIDER_LINK_MON_NG
) {
2015-10-29 07:34:53 +09:00
pthread_mutex_lock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]);
2014-06-08 19:52:11 +09:00
if (table_mon_list->mon_status != SPIDER_LINK_MON_NG)
{
table_mon_list->mon_status = SPIDER_LINK_MON_NG;
table_mon_list->share->link_statuses[0] = SPIDER_LINK_STATUS_NG;
DBUG_PRINT("info", (
"spider share->link_statuses[%d]=SPIDER_LINK_STATUS_NG",
link_idx));
share->link_statuses[link_idx] = SPIDER_LINK_STATUS_NG;
spider_sys_update_tables_link_status(thd, conv_name,
conv_name_length, link_idx, SPIDER_LINK_STATUS_NG);
2014-06-08 19:52:11 +09:00
spider_sys_log_tables_link_failed(thd, conv_name,
conv_name_length, link_idx);
2014-06-08 19:52:11 +09:00
}
2015-10-29 07:34:53 +09:00
pthread_mutex_unlock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]);
2014-06-08 19:52:11 +09:00
}
table_mon_list->last_caller_result = mon_table_result.result_status;
if (mon_table_result.result_status == SPIDER_LINK_MON_OK)
2014-03-25 04:23:24 +09:00
{
2014-06-08 19:52:11 +09:00
if (prev_error)
my_message(prev_error, prev_error_msg, MYF(0));
error_num = ER_SPIDER_LINK_MON_OK_NUM;
my_printf_error(error_num,
ER_SPIDER_LINK_MON_OK_STR, MYF(0),
db_or_server,
2014-06-08 19:52:11 +09:00
table_mon_list->share->tgt_table_names[0]);
break;
2014-03-25 04:23:24 +09:00
}
2014-06-08 19:52:11 +09:00
if (mon_table_result.result_status == SPIDER_LINK_MON_NG)
{
error_num = ER_SPIDER_LINK_MON_NG_NUM;
my_printf_error(error_num,
ER_SPIDER_LINK_MON_NG_STR, MYF(0),
db_or_server,
2014-06-08 19:52:11 +09:00
table_mon_list->share->tgt_table_names[0]);
break;
}
if (mon_table_result.result_status ==
SPIDER_LINK_MON_DRAW_FEW_MON)
{
error_num = ER_SPIDER_LINK_MON_DRAW_FEW_MON_NUM;
my_printf_error(error_num,
ER_SPIDER_LINK_MON_DRAW_FEW_MON_STR, MYF(0),
db_or_server,
2014-06-08 19:52:11 +09:00
table_mon_list->share->tgt_table_names[0]);
break;
}
error_num = ER_SPIDER_LINK_MON_DRAW_NUM;
2014-03-25 04:23:24 +09:00
my_printf_error(error_num,
2014-06-08 19:52:11 +09:00
ER_SPIDER_LINK_MON_DRAW_STR, MYF(0),
db_or_server,
2014-03-25 04:23:24 +09:00
table_mon_list->share->tgt_table_names[0]);
break;
}
2014-06-08 19:52:11 +09:00
}
table_mon = table_mon->next;
current_mon_count++;
}
}
pthread_mutex_unlock(&table_mon_list->caller_mutex);
} else {
pthread_mutex_lock(&table_mon_list->caller_mutex);
DBUG_PRINT("info",("spider thd->killed=%s",
thd ? (thd->killed ? "TRUE" : "FALSE") : "NULL"));
DBUG_PRINT("info",("spider abort_loop=%s",
*spd_abort_loop ? "TRUE" : "FALSE"));
2014-06-08 19:52:11 +09:00
if (
(thd && thd->killed) ||
*spd_abort_loop
2014-06-08 19:52:11 +09:00
) {
error_num = ER_SPIDER_COND_SKIP_NUM;
} else {
switch (table_mon_list->last_caller_result)
{
case SPIDER_LINK_MON_OK:
error_num = ER_SPIDER_LINK_MON_OK_NUM;
my_printf_error(error_num,
ER_SPIDER_LINK_MON_OK_STR, MYF(0), db_or_server,
2014-06-08 19:52:11 +09:00
table_mon_list->share->tgt_table_names[0]);
break;
case SPIDER_LINK_MON_NG:
error_num = ER_SPIDER_LINK_MON_NG_NUM;
my_printf_error(error_num,
ER_SPIDER_LINK_MON_NG_STR, MYF(0), db_or_server,
2014-06-08 19:52:11 +09:00
table_mon_list->share->tgt_table_names[0]);
break;
case SPIDER_LINK_MON_DRAW_FEW_MON:
error_num = ER_SPIDER_LINK_MON_DRAW_FEW_MON_NUM;
my_printf_error(error_num,
ER_SPIDER_LINK_MON_DRAW_FEW_MON_STR, MYF(0), db_or_server,
2014-06-08 19:52:11 +09:00
table_mon_list->share->tgt_table_names[0]);
break;
default:
2014-03-25 04:23:24 +09:00
error_num = ER_SPIDER_LINK_MON_DRAW_NUM;
my_printf_error(error_num,
ER_SPIDER_LINK_MON_DRAW_STR, MYF(0), db_or_server,
2014-03-25 04:23:24 +09:00
table_mon_list->share->tgt_table_names[0]);
break;
}
}
pthread_mutex_unlock(&table_mon_list->caller_mutex);
}
my_afree(buf);
2014-03-25 04:23:24 +09:00
end_with_free_table_mon_list:
spider_free_ping_table_mon_list(table_mon_list);
end:
DBUG_RETURN(error_num);
}