mariadb/storage/spider/spd_ping_table.cc
Jacob Mathew 519060da45 MDEV-12900: spider tests failed in buildbot with valgrind
The failures with valgrind occur as a result of Spider sometimes using the
wrong transaction for operations in background threads that send requests to
the data nodes.  The use of the wrong transaction caused the networking to the
data nodes to use the wrong thread in some cases.  Valgrind eventually
detects this when such a thread is destroyed before it is used to disconnect
from the data node by that wrong transaction when it is freed.

I have fixed the problem by correcting the transaction used in each of these
cases.

Author:
  Jacob Mathew.

Reviewer:
  Kentoku Shiba.

Cherry-Picked:
  Commit afe5a51 on branch 10.2
2018-05-21 19:17:03 -07:00

1563 lines
52 KiB
C++

/* Copyright (C) 2009-2015 Kentoku Shiba
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
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#define MYSQL_SERVER 1
#include "mysql_version.h"
#if MYSQL_VERSION_ID < 50500
#include "mysql_priv.h"
#include <mysql/plugin.h>
#else
#include "sql_priv.h"
#include "probes_mysql.h"
#include "sql_class.h"
#include "sql_partition.h"
#include "sql_acl.h"
#endif
#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;
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
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;
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;
volatile ulonglong spider_mon_table_cache_version = 0;
volatile ulonglong spider_mon_table_cache_version_req = 1;
SPIDER_TABLE_MON_LIST *spider_get_ping_table_mon_list(
SPIDER_TRX *trx,
THD *thd,
spider_string *str,
uint conv_name_length,
int link_idx,
uint32 server_id,
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;
#ifdef SPIDER_HAS_HASH_VALUE_TYPE
my_hash_value_type hash_value;
#endif
DBUG_ENTER("spider_get_ping_table_mon_list");
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));
}
mutex_hash = spider_udf_calc_hash(str->c_ptr(),
spider_param_udf_table_mon_mutex_count());
DBUG_PRINT("info",("spider hash key=%s", str->c_ptr()));
DBUG_PRINT("info",("spider hash key length=%u", str->length()));
#ifdef SPIDER_HAS_HASH_VALUE_TYPE
hash_value = my_calc_hash(
&spider_udf_table_mon_list_hash[mutex_hash],
(uchar*) str->c_ptr(), str->length());
#endif
pthread_mutex_lock(&spider_udf_table_mon_mutexes[mutex_hash]);
mon_table_cache_version = (ulonglong) spider_mon_table_cache_version;
#ifdef SPIDER_HAS_HASH_VALUE_TYPE
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
)
#else
if (!(table_mon_list = (SPIDER_TABLE_MON_LIST *) my_hash_search(
&spider_udf_table_mon_list_hash[mutex_hash],
(uchar*) str->c_ptr(), str->length())) ||
table_mon_list->mon_table_cache_version != mon_table_cache_version
)
#endif
{
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);
if (!(table_mon_list = spider_get_ping_table_tgt(thd, str->c_ptr(),
conv_name_length, link_idx, server_id, str, need_lock, error_num)))
{
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;
#ifdef SPIDER_HAS_HASH_VALUE_TYPE
table_mon_list->key_hash_value = hash_value;
#endif
#ifdef HASH_UPDATE_WITH_HASH_VALUE
if (my_hash_insert_with_hash_value(
&spider_udf_table_mon_list_hash[mutex_hash],
hash_value, (uchar*) table_mon_list))
#else
if (my_hash_insert(&spider_udf_table_mon_list_hash[mutex_hash],
(uchar*) table_mon_list))
#endif
{
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");
#ifdef HASH_UPDATE_WITH_HASH_VALUE
my_hash_delete_with_hash_value(&spider_udf_table_mon_list_hash[mutex_hash],
table_mon_list->key_hash_value, (uchar*) table_mon_list);
#else
my_hash_delete(&spider_udf_table_mon_list_hash[mutex_hash],
(uchar*) table_mon_list);
#endif
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;
}
void spider_release_ping_table_mon_list(
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_SQL_INT_LEN];
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));
#if defined(_MSC_VER) || defined(__SUNPRO_CC)
spider_string conv_name_str(conv_name_length + link_idx_str_length + 1);
conv_name_str.set_charset(system_charset_info);
#else
char buf[conv_name_length + link_idx_str_length + 1];
spider_string conv_name_str(buf, conv_name_length + link_idx_str_length + 1,
system_charset_info);
#endif
conv_name_str.init_calc_mem(134);
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_param_udf_table_mon_mutex_count());
#ifdef SPIDER_HAS_HASH_VALUE_TYPE
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());
#endif
pthread_mutex_lock(&spider_udf_table_mon_mutexes[mutex_hash]);
#ifdef SPIDER_HAS_HASH_VALUE_TYPE
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())))
#else
if ((table_mon_list = (SPIDER_TABLE_MON_LIST *) my_hash_search(
&spider_udf_table_mon_list_hash[mutex_hash],
(uchar*) conv_name_str.c_ptr(), conv_name_str.length())))
#endif
spider_release_ping_table_mon_list_loop(mutex_hash, table_mon_list);
pthread_mutex_unlock(&spider_udf_table_mon_mutexes[mutex_hash]);
DBUG_VOID_RETURN;
}
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;
#if MYSQL_VERSION_ID < 50500
Open_tables_state open_tables_backup;
#else
Open_tables_backup open_tables_backup;
#endif
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,
need_lock, &error_num))
) {
my_error(error_num, MYF(0));
goto error;
}
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:
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;
}
do {
if (!(table_mon = (SPIDER_TABLE_MON *)
spider_bulk_malloc(spider_current_trx, 35, MYF(MY_WME | MY_ZEROFILL),
&table_mon, sizeof(SPIDER_TABLE_MON),
&tmp_share, sizeof(SPIDER_SHARE),
&tmp_connect_info, sizeof(char *) * SPIDER_TMP_SHARE_CHAR_PTR_COUNT,
&tmp_connect_info_length, sizeof(uint) * SPIDER_TMP_SHARE_UINT_COUNT,
&tmp_long, sizeof(long) * SPIDER_TMP_SHARE_LONG_COUNT,
&tmp_longlong, sizeof(longlong) * SPIDER_TMP_SHARE_LONGLONG_COUNT,
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;
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, 0, mem_root))
) {
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,
#ifdef WITH_PARTITION_STORAGE_ENGINE
NULL,
NULL,
#endif
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_close_sys_table(thd, table_link_mon,
&open_tables_backup, need_lock);
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_close_sys_table(thd, table_link_mon,
&open_tables_backup, need_lock);
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);
}
SPIDER_TABLE_MON_LIST *spider_get_ping_table_tgt(
THD *thd,
char *name,
uint name_length,
int link_idx,
uint32 server_id,
spider_string *str,
bool need_lock,
int *error_num
) {
TABLE *table_tables = NULL;
#if MYSQL_VERSION_ID < 50500
Open_tables_state open_tables_backup;
#else
Open_tables_backup open_tables_backup;
#endif
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, 36, MYF(MY_WME | MY_ZEROFILL),
&table_mon_list, sizeof(SPIDER_TABLE_MON_LIST),
&tmp_share, sizeof(SPIDER_SHARE),
&tmp_connect_info, sizeof(char *) * SPIDER_TMP_SHARE_CHAR_PTR_COUNT,
&tmp_connect_info_length, sizeof(uint) * SPIDER_TMP_SHARE_UINT_COUNT,
&tmp_long, sizeof(long) * SPIDER_TMP_SHARE_LONG_COUNT,
&tmp_longlong, sizeof(longlong) * SPIDER_TMP_SHARE_LONGLONG_COUNT,
&key_str, str->length() + 1,
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;
if (
!(table_tables = spider_open_sys_table(
thd, SPIDER_SYS_TABLES_TABLE_NAME_STR,
SPIDER_SYS_TABLES_TABLE_NAME_LEN, FALSE, &open_tables_backup, need_lock,
error_num))
) {
my_error(*error_num, MYF(0));
goto error;
}
spider_store_tables_name(table_tables, name, name_length);
spider_store_tables_link_idx(table_tables, link_idx);
if (
(*error_num = spider_check_sys_table(table_tables, table_key)) ||
(*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->file->print_error(*error_num, MYF(0));
goto error;
}
spider_close_sys_table(thd, table_tables,
&open_tables_backup, need_lock);
table_tables = NULL;
if (
(*error_num = spider_set_connect_info_default(
tmp_share,
#ifdef WITH_PARTITION_STORAGE_ENGINE
NULL,
NULL,
#endif
NULL
)) ||
(*error_num = spider_set_connect_info_default_dbtable(
tmp_share, name, name_length
)) ||
(*error_num = spider_create_conn_keys(tmp_share)) ||
/*
(*error_num = spider_db_create_table_names_str(tmp_share)) ||
*/
(*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_VERSION_ID < 50500
if (pthread_mutex_init(&table_mon_list->caller_mutex, MY_MUTEX_INIT_FAST))
#else
if (mysql_mutex_init(spd_key_mutex_mon_list_caller,
&table_mon_list->caller_mutex, MY_MUTEX_INIT_FAST))
#endif
{
*error_num = HA_ERR_OUT_OF_MEM;
goto error_caller_mutex_init;
}
#if MYSQL_VERSION_ID < 50500
if (pthread_mutex_init(&table_mon_list->receptor_mutex, MY_MUTEX_INIT_FAST))
#else
if (mysql_mutex_init(spd_key_mutex_mon_list_receptor,
&table_mon_list->receptor_mutex, MY_MUTEX_INIT_FAST))
#endif
{
*error_num = HA_ERR_OUT_OF_MEM;
goto error_receptor_mutex_init;
}
#if MYSQL_VERSION_ID < 50500
if (pthread_mutex_init(&table_mon_list->monitor_mutex, MY_MUTEX_INIT_FAST))
#else
if (mysql_mutex_init(spd_key_mutex_mon_list_monitor,
&table_mon_list->monitor_mutex, MY_MUTEX_INIT_FAST))
#endif
{
*error_num = HA_ERR_OUT_OF_MEM;
goto error_monitor_mutex_init;
}
#if MYSQL_VERSION_ID < 50500
if (pthread_mutex_init(&table_mon_list->update_status_mutex,
MY_MUTEX_INIT_FAST))
#else
if (mysql_mutex_init(spd_key_mutex_mon_list_update_status,
&table_mon_list->update_status_mutex, MY_MUTEX_INIT_FAST))
#endif
{
*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_close_sys_table(thd, table_tables,
&open_tables_backup, need_lock);
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,
SPIDER_CONN_KIND_MYSQL, error_num))
) {
my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0),
share->server_names[0]);
*error_num = ER_CONNECT_TO_FOREIGN_DATA_SOURCE;
goto error;
}
#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
conn->error_mode = 0;
DBUG_RETURN(conn);
error:
DBUG_RETURN(NULL);
}
int spider_init_ping_table_mon_cache(
THD *thd,
MEM_ROOT *mem_root,
bool need_lock
) {
int error_num, same;
TABLE *table_link_mon = NULL;
#if MYSQL_VERSION_ID < 50500
Open_tables_state open_tables_backup;
#else
Open_tables_backup open_tables_backup;
#endif
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,
need_lock, &error_num))
) {
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;
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 {
if ((error_num = spider_get_sys_link_mon_key(table_link_mon, &mon_key,
mem_root, &same)))
goto error_get_sys_link_mon_key;
if (!same)
{
mon_key.sort = spider_calc_for_sort(3, mon_key.db_name,
mon_key.table_name, mon_key.link_id);
if (push_dynamic(&spider_mon_table_cache, (uchar *) &mon_key))
{
error_num = HA_ERR_OUT_OF_MEM;
goto error_push_dynamic;
}
}
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);
uint old_elements = spider_mon_table_cache.max_element;
freeze_size(&spider_mon_table_cache);
if (spider_mon_table_cache.max_element < old_elements)
{
spider_free_mem_calc(spider_current_trx,
spider_mon_table_cache_id,
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_close_sys_table(thd, table_link_mon, &open_tables_backup, need_lock);
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_close_sys_table(thd, table_link_mon, &open_tables_backup, need_lock);
error_open_sys_table:
DBUG_RETURN(error_num);
}
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])) ||
!(table_name = get_field(mem_root, table->field[1])) ||
!(link_id = get_field(mem_root, table->field[2]))
)
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
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,
char *is_null,
char *error
) {
int error_num = 0, link_idx, flags, full_mon_count, current_mon_count,
success_count, fault_count, tmp_error_num = 0;
uint32 first_sid;
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];
spider_string conv_name(buf, sizeof(buf), system_charset_info);
int conv_name_length;
char link_idx_str[SPIDER_SQL_INT_LEN];
int link_idx_str_length;
bool get_lock = FALSE;
DBUG_ENTER("spider_ping_table_body");
conv_name.init_calc_mem(135);
conv_name.length(0);
if (
thd->open_tables != 0 ||
thd->handler_tables_hash.records != 0 ||
thd->derived_tables != 0 ||
thd->lock != 0 ||
#if MYSQL_VERSION_ID < 50500
thd->locked_tables != 0 ||
thd->prelocked_mode != NON_PRELOCKED
#else
thd->locked_tables_list.locked_tables() ||
thd->locked_tables_mode != LTM_NONE
#endif
) {
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);
#if MYSQL_VERSION_ID < 50500
} else if (thd->locked_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->locked_tables", thd->locked_tables);
} else if (thd->prelocked_mode != NON_PRELOCKED)
{
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->prelocked_mode", (longlong) thd->prelocked_mode);
#else
} 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);
#endif
}
goto error;
}
if (
args->lengths[0] > SPIDER_CONNECT_INFO_MAX_LEN
) {
my_printf_error(ER_SPIDER_UDF_PING_TABLE_PARAM_TOO_LONG_NUM,
ER_SPIDER_UDF_PING_TABLE_PARAM_TOO_LONG_STR, MYF(0));
goto error;
}
if (
args->lengths[0] == 0
) {
my_printf_error(ER_SPIDER_UDF_PING_TABLE_PARAM_REQIRED_NUM,
ER_SPIDER_UDF_PING_TABLE_PARAM_REQIRED_STR, MYF(0));
goto error;
}
link_idx = (int) (args->args[1] ? *((longlong *) args->args[1]) : 0);
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 *) "";
link_idx_str_length = my_sprintf(link_idx_str, (link_idx_str, "%010d",
link_idx));
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 defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100002
if (!(table_mon_list = spider_get_ping_table_mon_list(trx, trx->thd,
&conv_name, conv_name_length, link_idx, global_system_variables.server_id,
TRUE, &error_num)))
#else
if (!(table_mon_list = spider_get_ping_table_mon_list(trx, trx->thd,
&conv_name, conv_name_length, link_idx, thd->server_id, TRUE, &error_num)))
#endif
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 {
#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100002
first_sid = global_system_variables.server_id;
#else
first_sid = thd->server_id;
#endif
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
))
) {
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));
if (tmp_error_num == HA_ERR_OUT_OF_MEM)
goto error_with_free_table_mon_list;
else if(tmp_error_num)
thd->clear_error();
if (tmp_error_num != ER_CON_COUNT_ERROR)
{
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"));
if (table_mon_list->mon_status != SPIDER_LINK_MON_NG)
{
/*
pthread_mutex_lock(&table_mon_list->update_status_mutex);
*/
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, TRUE);
spider_sys_log_tables_link_failed(trx->thd,
conv_name.c_ptr(), conv_name_length, link_idx, TRUE);
}
/*
pthread_mutex_unlock(&table_mon_list->update_status_mutex);
*/
pthread_mutex_unlock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]);
}
goto end;
}
}
} else {
success_count++;
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 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
) {
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(&table_mon_list->update_status_mutex);
*/
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, TRUE);
spider_sys_log_tables_link_failed(trx->thd,
conv_name.c_ptr(), conv_name_length, link_idx, TRUE);
}
/*
pthread_mutex_unlock(&table_mon_list->update_status_mutex);
*/
pthread_mutex_unlock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]);
}
} 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)
{
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
) {
/*
pthread_mutex_lock(&table_mon_list->update_status_mutex);
*/
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, TRUE);
spider_sys_log_tables_link_failed(trx->thd,
conv_name.c_ptr(), conv_name_length, link_idx, TRUE);
}
/*
pthread_mutex_unlock(&table_mon_list->update_status_mutex);
*/
pthread_mutex_unlock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]);
}
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[1] != INT_RESULT ||
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 2nd, 3rd, 4,6,7,8,"
"9th and 10th argument");
goto error;
}
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, 11, sizeof(SPIDER_MON_TABLE_RESULT),
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,
uint32 server_id,
char *conv_name,
uint conv_name_length,
int link_idx,
char *where_clause,
uint where_clause_length,
long monitoring_kind,
longlong monitoring_limit,
long monitoring_flag,
bool need_lock
) {
int error_num = 0, current_mon_count, flags;
uint32 first_sid;
/*
THD *thd = trx->thd;
*/
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_SQL_INT_LEN];
int link_idx_str_length;
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);
}
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"));
if (
(thd && thd->killed) ||
*spd_abort_loop
) {
DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM);
}
link_idx_str_length = my_sprintf(link_idx_str, (link_idx_str, "%010d",
link_idx));
#if defined(_MSC_VER) || defined(__SUNPRO_CC)
spider_string conv_name_str(conv_name_length + link_idx_str_length + 1);
conv_name_str.set_charset(system_charset_info);
*((char *)(conv_name_str.ptr() + conv_name_length + link_idx_str_length)) =
'\0';
#else
char buf[conv_name_length + link_idx_str_length + 1];
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);
#endif
conv_name_str.init_calc_mem(136);
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;
if (monitoring_flag & 1)
flags |= SPIDER_UDF_PING_TABLE_USE_ALL_MONITORING_NODES;
if (!(table_mon_list = spider_get_ping_table_mon_list(trx, thd,
&conv_name_str, conv_name_length, link_idx, server_id, need_lock,
&error_num)))
goto end;
if (table_mon_list->mon_status == SPIDER_LINK_MON_NG)
{
DBUG_PRINT("info",
("spider share->link_statuses[%d]=SPIDER_LINK_STATUS_NG", link_idx));
pthread_mutex_lock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]);
share->link_statuses[link_idx] = SPIDER_LINK_STATUS_NG;
pthread_mutex_unlock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]);
error_num = ER_SPIDER_LINK_MON_NG_NUM;
my_printf_error(error_num,
ER_SPIDER_LINK_MON_NG_STR, MYF(0),
table_mon_list->share->tgt_dbs[0],
table_mon_list->share->tgt_table_names[0]);
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;
while (TRUE)
{
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"));
if (
(thd && thd->killed) ||
*spd_abort_loop
) {
error_num = ER_SPIDER_COND_SKIP_NUM;
break;
} 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),
table_mon_list->share->tgt_dbs[0],
table_mon_list->share->tgt_table_names[0]);
break;
}
int prev_error = 0;
char prev_error_msg[MYSQL_ERRMSG_SIZE];
if (thd->is_error())
{
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, -1, table_mon_list->list_size,
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
) {
/*
pthread_mutex_lock(&table_mon_list->update_status_mutex);
*/
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;
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, need_lock);
spider_sys_log_tables_link_failed(thd, conv_name,
conv_name_length, link_idx, need_lock);
}
/*
pthread_mutex_unlock(&table_mon_list->update_status_mutex);
*/
pthread_mutex_unlock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]);
}
table_mon_list->last_caller_result = mon_table_result.result_status;
if (mon_table_result.result_status == SPIDER_LINK_MON_OK)
{
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),
table_mon_list->share->tgt_dbs[0],
table_mon_list->share->tgt_table_names[0]);
break;
}
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),
table_mon_list->share->tgt_dbs[0],
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),
table_mon_list->share->tgt_dbs[0],
table_mon_list->share->tgt_table_names[0]);
break;
}
error_num = ER_SPIDER_LINK_MON_DRAW_NUM;
my_printf_error(error_num,
ER_SPIDER_LINK_MON_DRAW_STR, MYF(0),
table_mon_list->share->tgt_dbs[0],
table_mon_list->share->tgt_table_names[0]);
break;
}
}
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"));
if (
(thd && thd->killed) ||
*spd_abort_loop
) {
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),
table_mon_list->share->tgt_dbs[0],
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),
table_mon_list->share->tgt_dbs[0],
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),
table_mon_list->share->tgt_dbs[0],
table_mon_list->share->tgt_table_names[0]);
break;
default:
error_num = ER_SPIDER_LINK_MON_DRAW_NUM;
my_printf_error(error_num,
ER_SPIDER_LINK_MON_DRAW_STR, MYF(0),
table_mon_list->share->tgt_dbs[0],
table_mon_list->share->tgt_table_names[0]);
break;
}
}
pthread_mutex_unlock(&table_mon_list->caller_mutex);
}
end_with_free_table_mon_list:
spider_free_ping_table_mon_list(table_mon_list);
end:
DBUG_RETURN(error_num);
}