1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

MDEV-6268 SPIDER table with no COMMENT clause causes queries to wait forever

Add looping check

Conflicts:
	sql/table.h
This commit is contained in:
Kentoku SHIBA
2020-03-03 03:06:33 +09:00
parent 272625d92a
commit 23c8adda74
31 changed files with 1146 additions and 35 deletions

View File

@@ -1977,11 +1977,13 @@ retry_share:
MYF(MY_WME))))
goto err_lock;
table_list->intention_table= table;
error= open_table_from_share(thd, share, &table_list->alias,
HA_OPEN_KEYFILE | HA_TRY_READ_ONLY,
EXTRA_RECORD,
thd->open_options, table, FALSE,
IF_PARTITIONING(table_list->partition_names,0));
IF_PARTITIONING(table_list->partition_names,0),
table_list);
if (unlikely(error))
{

View File

@@ -3868,7 +3868,8 @@ bool copy_keys_from_share(TABLE *outparam, MEM_ROOT *root)
enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
const LEX_CSTRING *alias, uint db_stat, uint prgflag,
uint ha_open_flags, TABLE *outparam,
bool is_create_table, List<String> *partitions_to_open)
bool is_create_table, List<String> *partitions_to_open,
TABLE_LIST *table_list)
{
enum open_frm_error error;
uint records, i, bitmap_size, bitmap_count;
@@ -3890,6 +3891,7 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
outparam->s= share;
outparam->db_stat= db_stat;
outparam->write_row_record= NULL;
outparam->intention_pos_in_table_list= table_list;
if (share->incompatible_version &&
!(ha_open_flags & (HA_OPEN_FOR_ALTER | HA_OPEN_FOR_REPAIR)))

View File

@@ -1289,6 +1289,9 @@ public:
/* Table's triggers, 0 if there are no of them */
Table_triggers_list *triggers;
TABLE_LIST *pos_in_table_list;/* Element referring to this table */
/* This is same as pos_in_table_list, but it is set as soon as possible when
TABLE is allocated */
TABLE_LIST *intention_pos_in_table_list;
/* Position in thd->locked_table_list under LOCK TABLES */
TABLE_LIST *pos_in_locked_tables;
/* Tables used in DEFAULT and CHECK CONSTRAINT (normally sequence tables) */
@@ -2262,6 +2265,9 @@ struct TABLE_LIST
/* Index names in a "... JOIN ... USE/IGNORE INDEX ..." clause. */
List<Index_hint> *index_hints;
TABLE *table; /* opened table */
/* This is same as table, but it is set as soon as possible when
TABLE is allocated */
TABLE *intention_table;
ulonglong table_id; /* table id (from binlog) for opened table */
/*
select_result for derived table to pass it from table creation to table
@@ -3107,7 +3113,8 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
const LEX_CSTRING *alias, uint db_stat, uint prgflag,
uint ha_open_flags, TABLE *outparam,
bool is_create_table,
List<String> *partitions_to_open= NULL);
List<String> *partitions_to_open= NULL,
TABLE_LIST *table_list= NULL);
bool copy_keys_from_share(TABLE *outparam, MEM_ROOT *root);
bool fix_session_vcol_expr(THD *thd, Virtual_column_info *vcol);
bool fix_session_vcol_expr_for_read(THD *thd, Field *field,

View File

@@ -423,6 +423,16 @@ int ha_spider::open(
wide_handler->rnd_read_bitmap = rnd_read_bitmap;
wide_handler->rnd_write_bitmap = rnd_write_bitmap;
wide_handler->owner = owner;
if (table_share->tmp_table == NO_TMP_TABLE)
{
TABLE_LIST *top = spider_get_parent_table_list(this);
if (top->intention_table)
{
wide_handler->top_share = top->intention_table->s;
} else {
wide_handler->top_share = top->table->s;
}
}
owner->wide_handler_owner = TRUE;
memset(wide_handler->ft_discard_bitmap, 0xFF,
no_bytes_in_map(table->read_set));

View File

@@ -0,0 +1,10 @@
--connection master_1
set spider_same_server_link= @old_spider_same_server_link;
--let $MASTER_1_COMMENT_2_1= $MASTER_1_COMMENT_2_1_BACKUP
--disable_warnings
--disable_query_log
--disable_result_log
--source ../t/test_deinit.inc
--enable_result_log
--enable_query_log
--enable_warnings

View File

@@ -0,0 +1,13 @@
--disable_warnings
--disable_query_log
--disable_result_log
--source ../t/test_init.inc
--enable_result_log
--enable_query_log
--enable_warnings
--let $MASTER_1_COMMENT_2_1_BACKUP= $MASTER_1_COMMENT_2_1
let $MASTER_1_COMMENT_2_1=
COMMENT='table "tbl_a", host "127.0.0.1", port "$MASTER_1_MYPORT", user "root"';
--connection master_1
set @old_spider_same_server_link= @@spider_same_server_link;
set spider_same_server_link= ON;

View File

@@ -0,0 +1,36 @@
for master_1
for child2
for child3
connection master_1;
set @old_spider_same_server_link= @@spider_same_server_link;
set spider_same_server_link= ON;
this test is for MDEV-6268
drop and create databases
connection master_1;
CREATE DATABASE auto_test_local;
USE auto_test_local;
create table
connection master_1;
CREATE TABLE tbl_a (
pkey int NOT NULL,
PRIMARY KEY (pkey)
) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_1
select test 1
connection master_1;
SELECT pkey FROM tbl_a;
ERROR HY000: An infinite loop is detected when opening table auto_test_local.tbl_a
deinit
connection master_1;
DROP DATABASE IF EXISTS auto_test_local;
connection master_1;
set spider_same_server_link= @old_spider_same_server_link;
for master_1
for child2
for child3
end of test

View File

@@ -48,7 +48,7 @@ SET SESSION sql_log_bin= 0;
connection child2_1;
SELECT argument FROM mysql.general_log WHERE argument LIKE '%set %';
argument
set session time_zone = '+00:00'
set session time_zone = '+00:00';set @`spider_lc_./auto_test_remote/tbl_a` = '-xxxxxxxxxxxx-xxxxx-./auto_test_local/tbl_a-'
SET NAMES utf8
set session transaction isolation level read committed;set session autocommit = 1;set session wait_timeout = 604800;set session sql_mode = 'strict_trans_tables,error_for_division_by_zero,no_auto_create_user,no_engine_substitution';start transaction
SELECT argument FROM mysql.general_log WHERE argument LIKE '%set %'

View File

@@ -50,7 +50,7 @@ pkey
connection child2_1;
SELECT argument FROM mysql.general_log WHERE argument LIKE '%sql_mode%';
argument
set session transaction isolation level repeatable read;set session autocommit = 1;set session sql_log_off = 0;set session wait_timeout = 604800;set session sql_mode = 'real_as_float,ignore_bad_table_options,no_unsigned_subtraction,no_dir_in_create,no_auto_value_on_zero,strict_trans_tables,strict_all_tables,no_zero_in_date,no_zero_date,allow_invalid_dates,error_for_division_by_zero,no_auto_create_user,high_not_precedence,no_engine_substitution,pad_char_to_full_length,empty_string_is_null,simultaneous_assignment,time_round_fractional';set session time_zone = '+00:00';start transaction
set session transaction isolation level repeatable read;set session autocommit = 1;set session sql_log_off = 0;set session wait_timeout = 604800;set session sql_mode = 'real_as_float,ignore_bad_table_options,no_unsigned_subtraction,no_dir_in_create,no_auto_value_on_zero,strict_trans_tables,strict_all_tables,no_zero_in_date,no_zero_date,allow_invalid_dates,error_for_division_by_zero,no_auto_create_user,high_not_precedence,no_engine_substitution,pad_char_to_full_length,empty_string_is_null,simultaneous_assignment,time_round_fractional';set session time_zone = '+00:00';set @`spider_lc_./auto_test_remote/tbl_a` = '-xxxxxxxxxxxx-xxxxx-./auto_test_local/tbl_a-';start transaction
SELECT argument FROM mysql.general_log WHERE argument LIKE '%sql_mode%'
SELECT pkey FROM tbl_a ORDER BY pkey;
pkey

View File

@@ -50,7 +50,7 @@ pkey
connection child2_1;
SELECT argument FROM mysql.general_log WHERE argument LIKE '%sql_mode%';
argument
set session transaction isolation level repeatable read;set session autocommit = 1;set session sql_log_off = 0;set session wait_timeout = 604800;set session sql_mode = 'real_as_float,ignore_bad_table_options,no_unsigned_subtraction,no_dir_in_create,no_auto_value_on_zero,strict_trans_tables,strict_all_tables,no_zero_in_date,no_zero_date,allow_invalid_dates,error_for_division_by_zero,no_auto_create_user,high_not_precedence,no_engine_substitution,pad_char_to_full_length';set session time_zone = '+00:00';start transaction
set session transaction isolation level repeatable read;set session autocommit = 1;set session sql_log_off = 0;set session wait_timeout = 604800;set session sql_mode = 'real_as_float,ignore_bad_table_options,no_unsigned_subtraction,no_dir_in_create,no_auto_value_on_zero,strict_trans_tables,strict_all_tables,no_zero_in_date,no_zero_date,allow_invalid_dates,error_for_division_by_zero,no_auto_create_user,high_not_precedence,no_engine_substitution,pad_char_to_full_length';set session time_zone = '+00:00';set @`spider_lc_./auto_test_remote/tbl_a` = '-xxxxxxxxxxxx-xxxxx-./auto_test_local/tbl_a-';start transaction
SELECT argument FROM mysql.general_log WHERE argument LIKE '%sql_mode%'
SELECT pkey FROM tbl_a ORDER BY pkey;
pkey

View File

@@ -0,0 +1,2 @@
!include include/default_mysqld.cnf
!include ../my_1_1.cnf

View File

@@ -0,0 +1,45 @@
--source ../include/self_reference_init.inc
--echo
--echo this test is for MDEV-6268
--echo
--echo drop and create databases
--connection master_1
--disable_warnings
CREATE DATABASE auto_test_local;
USE auto_test_local;
--enable_warnings
--echo
--echo create table
--connection master_1
--disable_query_log
echo CREATE TABLE tbl_a (
pkey int NOT NULL,
PRIMARY KEY (pkey)
) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_1;
eval CREATE TABLE tbl_a (
pkey int NOT NULL,
PRIMARY KEY (pkey)
) $MASTER_1_ENGINE $MASTER_1_CHARSET $MASTER_1_COMMENT_2_1;
--enable_query_log
--echo
--echo select test 1
--connection master_1
--error 12719
SELECT pkey FROM tbl_a;
--echo
--echo deinit
--disable_warnings
--connection master_1
DROP DATABASE IF EXISTS auto_test_local;
--enable_warnings
--source ../include/self_reference_deinit.inc
--echo
--echo end of test

View File

@@ -70,6 +70,7 @@ sync_with_master;
SET SESSION sql_log_bin= 0;
--connection child2_1
--replace_regex /-[0-9a-f]{12}-[0-9a-f]+-/-xxxxxxxxxxxx-xxxxx-/
eval $CHILD2_1_SELECT_ARGUMENT1;
eval $CHILD2_1_SELECT_TABLES;

View File

@@ -48,6 +48,7 @@ TRUNCATE TABLE mysql.general_log;
SELECT * FROM tbl_a ORDER BY pkey;
--connection child2_1
--replace_regex /-[0-9a-f]{12}-[0-9a-f]+-/-xxxxxxxxxxxx-xxxxx-/
eval $CHILD2_1_SELECT_ARGUMENT1;
eval $CHILD2_1_SELECT_TABLES;

View File

@@ -46,6 +46,10 @@ DROP TABLE IF EXISTS mysql.spider_table_sts;
DROP TABLE IF EXISTS mysql.spider_table_crd;
if ($VERSION_COMPILE_OS_WIN)
{
if ($MASTER_1_MYPORT)
{
DROP SERVER s_1;
}
if ($CHILD2_1_MYPORT)
{
DROP SERVER s_2_1;
@@ -73,6 +77,10 @@ if ($VERSION_COMPILE_OS_WIN)
}
if (!$VERSION_COMPILE_OS_WIN)
{
if ($MASTER_1_MYSOCK)
{
DROP SERVER s_1;
}
if ($CHILD2_1_MYSOCK)
{
DROP SERVER s_2_1;

View File

@@ -3,6 +3,16 @@ let $VERSION_COMPILE_OS_WIN=
if ($VERSION_COMPILE_OS_WIN)
{
INSTALL PLUGIN spider SONAME 'ha_spider.dll';
if ($MASTER_1_MYPORT)
{
eval CREATE SERVER s_1 FOREIGN DATA WRAPPER mysql OPTIONS (
HOST 'localhost',
DATABASE 'auto_test_local',
USER 'root',
PASSWORD '',
PORT $MASTER_1_MYPORT
);
}
if ($CHILD2_1_MYPORT)
{
eval CREATE SERVER s_2_1 FOREIGN DATA WRAPPER mysql OPTIONS (
@@ -67,6 +77,16 @@ if ($VERSION_COMPILE_OS_WIN)
if (!$VERSION_COMPILE_OS_WIN)
{
INSTALL PLUGIN spider SONAME 'ha_spider.so';
if ($MASTER_1_MYSOCK)
{
eval CREATE SERVER s_1 FOREIGN DATA WRAPPER mysql OPTIONS (
HOST 'localhost',
DATABASE 'auto_test_local',
USER 'root',
PASSWORD '',
SOCKET '$MASTER_1_MYSOCK'
);
}
if ($CHILD2_1_MYSOCK)
{
eval CREATE SERVER s_2_1 FOREIGN DATA WRAPPER mysql OPTIONS (

View File

@@ -51,7 +51,7 @@ SET SESSION sql_log_bin= 0;
connection child2_1;
SELECT argument FROM mysql.general_log WHERE argument LIKE '%set %';
argument
set session time_zone = '+00:00'
set session time_zone = '+00:00';set @`spider_lc_./auto_test_remote/tbl_a` = '-xxxxxxxxxxxx-xxxxx-./auto_test_local/tbl_a-'
SET NAMES utf8
set session transaction isolation level read committed;set session autocommit = 1;set session wait_timeout = 604800;set session sql_mode = 'strict_trans_tables,error_for_division_by_zero,no_auto_create_user,no_engine_substitution';start transaction
SELECT argument FROM mysql.general_log WHERE argument LIKE '%set %'

View File

@@ -108,6 +108,7 @@ if ($USE_CHILD_GROUP2)
--connection child2_1
if ($USE_GENERAL_LOG)
{
--replace_regex /-[0-9a-f]{12}-[0-9a-f]+-/-xxxxxxxxxxxx-xxxxx-/
eval $CHILD2_1_SELECT_ARGUMENT1;
}
eval $CHILD2_1_SELECT_TABLES;

View File

@@ -56,6 +56,8 @@ inline void SPIDER_set_next_thread_id(THD *A)
extern handlerton *spider_hton_ptr;
extern SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE];
extern struct charset_info_st *spd_charset_utf8mb3_bin;
extern LEX_CSTRING spider_unique_id;
pthread_mutex_t spider_conn_id_mutex;
pthread_mutex_t spider_ipport_conn_mutex;
ulonglong spider_conn_id = 1;
@@ -66,6 +68,7 @@ extern pthread_attr_t spider_pt_attr;
#ifdef HAVE_PSI_INTERFACE
extern PSI_mutex_key spd_key_mutex_mta_conn;
extern PSI_mutex_key spd_key_mutex_conn_i;
extern PSI_mutex_key spd_key_mutex_conn_loop_check;
extern PSI_cond_key spd_key_cond_conn_i;
#ifndef WITHOUT_SPIDER_BG_SEARCH
extern PSI_mutex_key spd_key_mutex_bg_conn_chain;
@@ -145,6 +148,102 @@ uchar *spider_ipport_conn_get_key(
DBUG_RETURN((uchar*) ip_port->key);
}
static uchar *spider_loop_check_full_get_key(
SPIDER_CONN_LOOP_CHECK *ptr,
size_t *length,
my_bool not_used __attribute__ ((unused))
) {
DBUG_ENTER("spider_loop_check_full_get_key");
*length = ptr->full_name.length;
DBUG_RETURN((uchar*) ptr->full_name.str);
}
static uchar *spider_loop_check_to_get_key(
SPIDER_CONN_LOOP_CHECK *ptr,
size_t *length,
my_bool not_used __attribute__ ((unused))
) {
DBUG_ENTER("spider_loop_check_to_get_key");
*length = ptr->to_name.length;
DBUG_RETURN((uchar*) ptr->to_name.str);
}
int spider_conn_init(
SPIDER_CONN *conn
) {
int error_num = HA_ERR_OUT_OF_MEM;
DBUG_ENTER("spider_conn_init");
#if MYSQL_VERSION_ID < 50500
if (pthread_mutex_init(&conn->loop_check_mutex, MY_MUTEX_INIT_FAST))
#else
if (mysql_mutex_init(spd_key_mutex_conn_loop_check, &conn->loop_check_mutex,
MY_MUTEX_INIT_FAST))
#endif
{
goto error_loop_check_mutex_init;
}
if (
my_hash_init(PSI_INSTRUMENT_ME, &conn->loop_checked, spd_charset_utf8mb3_bin, 32, 0, 0,
(my_hash_get_key) spider_loop_check_full_get_key, 0, 0)
) {
goto error_loop_checked_hash_init;
}
spider_alloc_calc_mem_init(conn->loop_checked, 268);
spider_alloc_calc_mem(spider_current_trx,
conn->loop_checked,
conn->loop_checked.array.max_element *
conn->loop_checked.array.size_of_element);
if (
my_hash_init(PSI_INSTRUMENT_ME, &conn->loop_check_queue, spd_charset_utf8mb3_bin, 32, 0, 0,
(my_hash_get_key) spider_loop_check_to_get_key, 0, 0)
) {
goto error_loop_check_queue_hash_init;
}
spider_alloc_calc_mem_init(conn->loop_check_queue, 269);
spider_alloc_calc_mem(spider_current_trx,
conn->loop_check_queue,
conn->loop_check_queue.array.max_element *
conn->loop_check_queue.array.size_of_element);
DBUG_RETURN(0);
error_loop_check_queue_hash_init:
spider_free_mem_calc(spider_current_trx,
conn->loop_checked_id,
conn->loop_checked.array.max_element *
conn->loop_checked.array.size_of_element);
my_hash_free(&conn->loop_checked);
error_loop_checked_hash_init:
pthread_mutex_destroy(&conn->loop_check_mutex);
error_loop_check_mutex_init:
DBUG_RETURN(error_num);
}
void spider_conn_done(
SPIDER_CONN *conn
) {
SPIDER_CONN_LOOP_CHECK *lcptr;
DBUG_ENTER("spider_conn_done");
uint l = 0;
while ((lcptr = (SPIDER_CONN_LOOP_CHECK *) my_hash_element(
&conn->loop_checked, l)))
{
spider_free(spider_current_trx, lcptr, MYF(0));
++l;
}
spider_free_mem_calc(spider_current_trx,
conn->loop_check_queue_id,
conn->loop_check_queue.array.max_element *
conn->loop_check_queue.array.size_of_element);
my_hash_free(&conn->loop_check_queue);
spider_free_mem_calc(spider_current_trx,
conn->loop_checked_id,
conn->loop_checked.array.max_element *
conn->loop_checked.array.size_of_element);
my_hash_free(&conn->loop_checked);
pthread_mutex_destroy(&conn->loop_check_mutex);
DBUG_VOID_RETURN;
}
int spider_reset_conn_setted_parameter(
SPIDER_CONN *conn,
THD *thd
@@ -183,7 +282,7 @@ int spider_reset_conn_setted_parameter(
conn->default_database.length(default_database_length);
} else
conn->default_database.length(0);
DBUG_RETURN(0);
DBUG_RETURN(spider_conn_reset_queue_loop_check(conn));
}
int spider_free_conn_alloc(
@@ -199,6 +298,7 @@ int spider_free_conn_alloc(
delete conn->db_conn;
conn->db_conn = NULL;
}
spider_conn_done(conn);
DBUG_ASSERT(!conn->mta_conn_mutex_file_pos.file_name);
pthread_mutex_destroy(&conn->mta_conn_mutex);
conn->default_database.free();
@@ -741,6 +841,11 @@ SPIDER_CONN *spider_create_conn(
goto error_mta_conn_mutex_init;
}
if (unlikely((*error_num = spider_conn_init(conn))))
{
goto error_conn_init;
}
spider_conn_queue_connect(share, conn, link_idx);
conn->ping_time = (time_t) time((time_t*) 0);
conn->connect_error_time = conn->ping_time;
@@ -792,12 +897,10 @@ SPIDER_CONN *spider_create_conn(
DBUG_RETURN(conn);
/*
error_init_lock_table_hash:
DBUG_ASSERT(!conn->mta_conn_mutex_file_pos.file_name);
pthread_mutex_destroy(&conn->mta_conn_mutex);
*/
error_too_many_ipport_count:
spider_conn_done(conn);
error_conn_init:
pthread_mutex_destroy(&conn->mta_conn_mutex);
error_mta_conn_mutex_init:
error_db_conn_init:
delete conn->db_conn;
@@ -1232,6 +1335,20 @@ SPIDER_CONN *spider_get_conn(
conn->queued_ping = FALSE;
}
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
if (conn_kind == SPIDER_CONN_KIND_MYSQL)
{
#endif
if (unlikely(spider && spider->wide_handler->top_share &&
(*error_num = spider_conn_queue_loop_check(
conn, spider, base_link_idx))))
{
goto error;
}
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
}
#endif
DBUG_PRINT("info",("spider conn=%p", conn));
DBUG_RETURN(conn);
@@ -1484,6 +1601,423 @@ void spider_conn_queue_UTC_time_zone(
DBUG_VOID_RETURN;
}
int spider_conn_queue_and_merge_loop_check(
SPIDER_CONN *conn,
SPIDER_CONN_LOOP_CHECK *lcptr
) {
int error_num = HA_ERR_OUT_OF_MEM;
char *tmp_name, *from_name, *cur_name, *to_name, *full_name, *from_value,
*merged_value;
SPIDER_CONN_LOOP_CHECK *lcqptr, *lcrptr;
DBUG_ENTER("spider_conn_queue_and_merge_loop_check");
DBUG_PRINT("info", ("spider conn=%p", conn));
#ifdef SPIDER_HAS_HASH_VALUE_TYPE
if (unlikely(!(lcqptr = (SPIDER_CONN_LOOP_CHECK *)
my_hash_search_using_hash_value(&conn->loop_check_queue,
lcptr->hash_value_to,
(uchar *) lcptr->to_name.str, lcptr->to_name.length))))
#else
if (unlikely(!(lcqptr = (SPIDER_CONN_LOOP_CHECK *) my_hash_search(
&conn->loop_check_queue,
(uchar *) lcptr->to_name.str, lcptr->to_name.length))))
#endif
{
DBUG_PRINT("info", ("spider create merged_value and insert"));
lcptr->merged_value.length = spider_unique_id.length +
lcptr->cur_name.length + lcptr->from_value.length + 1;
tmp_name = (char *) lcptr->merged_value.str;
memcpy(tmp_name, spider_unique_id.str, spider_unique_id.length);
tmp_name += spider_unique_id.length;
memcpy(tmp_name, lcptr->cur_name.str, lcptr->cur_name.length);
tmp_name += lcptr->cur_name.length;
*tmp_name = '-';
++tmp_name;
memcpy(tmp_name, lcptr->from_value.str, lcptr->from_value.length + 1);
#ifdef HASH_UPDATE_WITH_HASH_VALUE
if (unlikely(my_hash_insert_with_hash_value(&conn->loop_check_queue,
lcptr->hash_value_to, (uchar *) lcptr)))
#else
if (unlikely(my_hash_insert(&conn->loop_check_queue, (uchar *) lcptr)))
#endif
{
goto error_hash_insert_queue;
}
lcptr->flag |= SPIDER_LOP_CHK_QUEUED;
} else {
DBUG_PRINT("info", ("spider append merged_value and replace"));
if (unlikely(!spider_bulk_malloc(spider_current_trx, 271, MYF(MY_WME),
&lcrptr, (uint) (sizeof(SPIDER_CONN_LOOP_CHECK)),
&from_name, (uint) (lcqptr->from_name.length + 1),
&cur_name, (uint) (lcqptr->cur_name.length + 1),
&to_name, (uint) (lcqptr->to_name.length + 1),
&full_name, (uint) (lcqptr->full_name.length + 1),
&from_value, (uint) (lcqptr->from_value.length + 1),
&merged_value, (uint) (lcqptr->merged_value.length +
spider_unique_id.length + lcptr->cur_name.length +
lcptr->from_value.length + 2),
NullS)
)) {
goto error_alloc_loop_check_replace;
}
#ifdef SPIDER_HAS_HASH_VALUE_TYPE
lcrptr->hash_value_to = lcqptr->hash_value_to;
lcrptr->hash_value_full = lcqptr->hash_value_full;
#endif
lcrptr->from_name.str = from_name;
lcrptr->from_name.length = lcqptr->from_name.length;
memcpy(from_name, lcqptr->from_name.str, lcqptr->from_name.length + 1);
lcrptr->cur_name.str = cur_name;
lcrptr->cur_name.length = lcqptr->cur_name.length;
memcpy(cur_name, lcqptr->cur_name.str, lcqptr->cur_name.length + 1);
lcrptr->to_name.str = to_name;
lcrptr->to_name.length = lcqptr->to_name.length;
memcpy(to_name, lcqptr->to_name.str, lcqptr->to_name.length + 1);
lcrptr->full_name.str = full_name;
lcrptr->full_name.length = lcqptr->full_name.length;
memcpy(full_name, lcqptr->full_name.str, lcqptr->full_name.length + 1);
lcrptr->from_value.str = from_value;
lcrptr->from_value.length = lcqptr->from_value.length;
memcpy(from_value, lcqptr->from_value.str, lcqptr->from_value.length + 1);
lcrptr->merged_value.str = merged_value;
lcrptr->merged_value.length = lcqptr->merged_value.length;
memcpy(merged_value,
lcqptr->merged_value.str, lcqptr->merged_value.length);
merged_value += lcqptr->merged_value.length;
memcpy(merged_value, spider_unique_id.str, spider_unique_id.length);
merged_value += spider_unique_id.length;
memcpy(merged_value, lcptr->cur_name.str, lcptr->cur_name.length);
merged_value += lcptr->cur_name.length;
*merged_value = '-';
++merged_value;
memcpy(merged_value, lcptr->from_value.str, lcptr->from_value.length + 1);
DBUG_PRINT("info", ("spider free lcqptr"));
#ifdef HASH_UPDATE_WITH_HASH_VALUE
my_hash_delete_with_hash_value(&conn->loop_checked,
lcqptr->hash_value_full, (uchar *) lcqptr);
my_hash_delete_with_hash_value(&conn->loop_check_queue,
lcqptr->hash_value_to, (uchar *) lcqptr);
#else
my_hash_delete(&conn->loop_checked, (uchar*) lcqptr);
my_hash_delete(&conn->loop_check_queue, (uchar*) lcqptr);
#endif
spider_free(spider_current_trx, lcqptr, MYF(0));
lcptr = lcrptr;
#ifdef HASH_UPDATE_WITH_HASH_VALUE
if (unlikely(my_hash_insert_with_hash_value(&conn->loop_checked,
lcptr->hash_value_full, (uchar *) lcptr)))
#else
if (unlikely(my_hash_insert(&conn->loop_checked, (uchar *) lcptr)))
#endif
{
goto error_hash_insert;
}
#ifdef HASH_UPDATE_WITH_HASH_VALUE
if (unlikely(my_hash_insert_with_hash_value(&conn->loop_check_queue,
lcptr->hash_value_to, (uchar *) lcptr)))
#else
if (unlikely(my_hash_insert(&conn->loop_check_queue, (uchar *) lcptr)))
#endif
{
goto error_hash_insert_queue;
}
lcptr->flag = SPIDER_LOP_CHK_MERAGED;
lcptr->next = NULL;
if (!conn->loop_check_meraged_first)
{
conn->loop_check_meraged_first = lcptr;
conn->loop_check_meraged_last = lcptr;
} else {
conn->loop_check_meraged_last->next = lcptr;
conn->loop_check_meraged_last = lcptr;
}
}
DBUG_RETURN(0);
error_alloc_loop_check_replace:
error_hash_insert_queue:
#ifdef HASH_UPDATE_WITH_HASH_VALUE
my_hash_delete_with_hash_value(&conn->loop_checked,
lcptr->hash_value_full, (uchar *) lcptr);
#else
my_hash_delete(&conn->loop_checked, (uchar*) lcptr);
#endif
error_hash_insert:
spider_free(spider_current_trx, lcptr, MYF(0));
pthread_mutex_unlock(&conn->loop_check_mutex);
DBUG_RETURN(error_num);
}
int spider_conn_reset_queue_loop_check(
SPIDER_CONN *conn
) {
int error_num;
SPIDER_CONN_LOOP_CHECK *lcptr;
DBUG_ENTER("spider_conn_reset_queue_loop_check");
uint l = 0;
pthread_mutex_lock(&conn->loop_check_mutex);
while ((lcptr = (SPIDER_CONN_LOOP_CHECK *) my_hash_element(
&conn->loop_checked, l)))
{
if (!lcptr->flag)
{
DBUG_PRINT("info", ("spider free lcptr"));
#ifdef HASH_UPDATE_WITH_HASH_VALUE
my_hash_delete_with_hash_value(&conn->loop_checked,
lcptr->hash_value_full, (uchar *) lcptr);
#else
my_hash_delete(&conn->loop_checked, (uchar*) lcptr);
#endif
spider_free(spider_current_trx, lcptr, MYF(0));
}
++l;
}
lcptr = conn->loop_check_ignored_first;
while (lcptr)
{
lcptr->flag = 0;
if ((error_num = spider_conn_queue_and_merge_loop_check(conn, lcptr)))
{
goto error_queue_and_merge;
}
lcptr = lcptr->next;
}
conn->loop_check_meraged_first = NULL;
pthread_mutex_unlock(&conn->loop_check_mutex);
DBUG_RETURN(0);
error_queue_and_merge:
lcptr = lcptr->next;
while (lcptr)
{
lcptr->flag = 0;
lcptr = lcptr->next;
}
conn->loop_check_meraged_first = NULL;
pthread_mutex_unlock(&conn->loop_check_mutex);
DBUG_RETURN(error_num);
}
int spider_conn_queue_loop_check(
SPIDER_CONN *conn,
ha_spider *spider,
int link_idx
) {
int error_num = HA_ERR_OUT_OF_MEM;
uint conn_link_idx = spider->conn_link_idx[link_idx], buf_sz;
char path[FN_REFLEN + 1];
char *tmp_name, *from_name, *cur_name, *to_name, *full_name, *from_value,
*merged_value;
user_var_entry *loop_check;
char *loop_check_buf;
THD *thd = spider->wide_handler->trx->thd;
TABLE_SHARE *top_share = spider->wide_handler->top_share;
SPIDER_SHARE *share = spider->share;
SPIDER_CONN_LOOP_CHECK *lcptr;
LEX_CSTRING lex_str, from_str, to_str;
DBUG_ENTER("spider_conn_queue_loop_check");
DBUG_PRINT("info", ("spider conn=%p", conn));
lex_str.length = top_share->path.length + SPIDER_SQL_LOP_CHK_PRM_PRF_LEN;
buf_sz = lex_str.length + 2;
loop_check_buf = (char *) my_alloca(buf_sz);
if (unlikely(!loop_check_buf))
{
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
lex_str.str = loop_check_buf;
memcpy(loop_check_buf,
SPIDER_SQL_LOP_CHK_PRM_PRF_STR, SPIDER_SQL_LOP_CHK_PRM_PRF_LEN);
memcpy(loop_check_buf + SPIDER_SQL_LOP_CHK_PRM_PRF_LEN,
top_share->path.str, top_share->path.length);
loop_check_buf[lex_str.length] = '\0';
DBUG_PRINT("info", ("spider param name=%s", lex_str.str));
loop_check = get_variable(&thd->user_vars, &lex_str, FALSE);
if (!loop_check || loop_check->type != STRING_RESULT)
{
DBUG_PRINT("info", ("spider client is not Spider"));
lex_str.str = "";
lex_str.length = 0;
from_str.str = "";
from_str.length = 0;
} else {
lex_str.str = loop_check->value;
lex_str.length = loop_check->length;
DBUG_PRINT("info", ("spider from_str=%s", lex_str.str));
if (unlikely(!(tmp_name = strchr(loop_check->value, '-'))))
{
DBUG_PRINT("info", ("spider invalid value for loop checking 1"));
from_str.str = "";
from_str.length = 0;
}
else if (unlikely(!(tmp_name = strchr(tmp_name + 1, '-'))))
{
DBUG_PRINT("info", ("spider invalid value for loop checking 2"));
from_str.str = "";
from_str.length = 0;
}
else if (unlikely(!(tmp_name = strchr(tmp_name + 1, '-'))))
{
DBUG_PRINT("info", ("spider invalid value for loop checking 3"));
from_str.str = "";
from_str.length = 0;
}
else if (unlikely(!(tmp_name = strchr(tmp_name + 1, '-'))))
{
DBUG_PRINT("info", ("spider invalid value for loop checking 4"));
from_str.str = "";
from_str.length = 0;
}
else
{
from_str.str = lex_str.str;
from_str.length = tmp_name - lex_str.str + 1;
}
}
my_afree(loop_check_buf);
to_str.length = build_table_filename(path, FN_REFLEN,
share->tgt_dbs[conn_link_idx], share->tgt_table_names[conn_link_idx],
"", 0);
to_str.str = path;
DBUG_PRINT("info", ("spider to=%s", to_str.str));
buf_sz = from_str.length + top_share->path.length + to_str.length + 3;
loop_check_buf = (char *) my_alloca(buf_sz);
if (unlikely(!loop_check_buf))
{
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
DBUG_PRINT("info", ("spider top_share->path=%s", top_share->path.str));
memcpy(loop_check_buf, from_str.str, from_str.length);
tmp_name = loop_check_buf + from_str.length;
*tmp_name = '-';
++tmp_name;
memcpy(tmp_name, top_share->path.str, top_share->path.length);
tmp_name += top_share->path.length;
*tmp_name = '-';
++tmp_name;
memcpy(tmp_name, to_str.str, to_str.length);
tmp_name += to_str.length;
*tmp_name = '\0';
#ifdef SPIDER_HAS_HASH_VALUE_TYPE
my_hash_value_type hash_value = my_calc_hash(&conn->loop_checked,
(uchar *) loop_check_buf, buf_sz - 1);
#endif
pthread_mutex_lock(&conn->loop_check_mutex);
if (unlikely(
#ifdef SPIDER_HAS_HASH_VALUE_TYPE
!(lcptr = (SPIDER_CONN_LOOP_CHECK *)
my_hash_search_using_hash_value(&conn->loop_checked, hash_value,
(uchar *) loop_check_buf, buf_sz - 1)) ||
#else
!(lcptr = (SPIDER_CONN_LOOP_CHECK *) my_hash_search(
&conn->loop_checked, (uchar *) loop_check_buf, buf_sz - 1)) ||
#endif
(
!lcptr->flag &&
(
lcptr->from_value.length != lex_str.length ||
memcmp(lcptr->from_value.str, lex_str.str, lex_str.length)
)
)
))
{
if (unlikely(lcptr))
{
DBUG_PRINT("info", ("spider free lcptr"));
#ifdef HASH_UPDATE_WITH_HASH_VALUE
my_hash_delete_with_hash_value(&conn->loop_checked,
lcptr->hash_value_full, (uchar *) lcptr);
#else
my_hash_delete(&conn->loop_checked, (uchar*) lcptr);
#endif
spider_free(spider_current_trx, lcptr, MYF(0));
}
DBUG_PRINT("info", ("spider alloc_lcptr"));
if (unlikely(!spider_bulk_malloc(spider_current_trx, 272, MYF(MY_WME),
&lcptr, (uint) (sizeof(SPIDER_CONN_LOOP_CHECK)),
&from_name, (uint) (from_str.length + 1),
&cur_name, (uint) (top_share->path.length + 1),
&to_name, (uint) (to_str.length + 1),
&full_name, (uint) (buf_sz),
&from_value, (uint) (lex_str.length + 1),
&merged_value, (uint) (spider_unique_id.length + top_share->path.length +
lex_str.length + 2),
NullS)
)) {
my_afree(loop_check_buf);
goto error_alloc_loop_check;
}
lcptr->flag = 0;
lcptr->from_name.str = from_name;
lcptr->from_name.length = from_str.length;
memcpy(from_name, from_str.str, from_str.length + 1);
lcptr->cur_name.str = cur_name;
lcptr->cur_name.length = top_share->path.length;
memcpy(cur_name, top_share->path.str, top_share->path.length + 1);
lcptr->to_name.str = to_name;
lcptr->to_name.length = to_str.length;
memcpy(to_name, to_str.str, to_str.length + 1);
lcptr->full_name.str = full_name;
lcptr->full_name.length = buf_sz - 1;
memcpy(full_name, loop_check_buf, buf_sz);
lcptr->from_value.str = from_value;
lcptr->from_value.length = lex_str.length;
memcpy(from_value, lex_str.str, lex_str.length + 1);
lcptr->merged_value.str = merged_value;
#ifdef SPIDER_HAS_HASH_VALUE_TYPE
lcptr->hash_value_to = my_calc_hash(&conn->loop_checked,
(uchar *) to_str.str, to_str.length);
lcptr->hash_value_full = hash_value;
#endif
#ifdef HASH_UPDATE_WITH_HASH_VALUE
if (unlikely(my_hash_insert_with_hash_value(&conn->loop_checked,
lcptr->hash_value_full, (uchar *) lcptr)))
#else
if (unlikely(my_hash_insert(&conn->loop_checked, (uchar *) lcptr)))
#endif
{
my_afree(loop_check_buf);
goto error_hash_insert;
}
} else {
if (!lcptr->flag)
{
DBUG_PRINT("info", ("spider add to ignored list"));
lcptr->flag |= SPIDER_LOP_CHK_IGNORED;
lcptr->next = NULL;
if (!conn->loop_check_ignored_first)
{
conn->loop_check_ignored_first = lcptr;
conn->loop_check_ignored_last = lcptr;
} else {
conn->loop_check_ignored_last->next = lcptr;
conn->loop_check_ignored_last = lcptr;
}
}
pthread_mutex_unlock(&conn->loop_check_mutex);
my_afree(loop_check_buf);
DBUG_PRINT("info", ("spider be sent or queued already"));
DBUG_RETURN(0);
}
my_afree(loop_check_buf);
if ((error_num = spider_conn_queue_and_merge_loop_check(conn, lcptr)))
{
goto error_queue_and_merge;
}
pthread_mutex_unlock(&conn->loop_check_mutex);
DBUG_RETURN(0);
error_hash_insert:
spider_free(spider_current_trx, lcptr, MYF(0));
error_queue_and_merge:
pthread_mutex_unlock(&conn->loop_check_mutex);
error_alloc_loop_check:
DBUG_RETURN(error_num);
}
void spider_conn_queue_start_transaction(
SPIDER_CONN *conn
) {

View File

@@ -26,6 +26,26 @@
#define SPIDER_SIMPLE_CHECKSUM_TABLE 4
#endif
#define SPIDER_LOP_CHK_QUEUED (1 << 0)
#define SPIDER_LOP_CHK_MERAGED (1 << 1)
#define SPIDER_LOP_CHK_IGNORED (1 << 2)
typedef struct st_spider_conn_loop_check
{
uint flag;
#ifdef SPIDER_HAS_HASH_VALUE_TYPE
my_hash_value_type hash_value_to;
my_hash_value_type hash_value_full;
#endif
LEX_CSTRING from_name;
LEX_CSTRING cur_name;
LEX_CSTRING to_name;
LEX_CSTRING full_name;
LEX_CSTRING from_value;
LEX_CSTRING merged_value;
st_spider_conn_loop_check *next;
} SPIDER_CONN_LOOP_CHECK;
uchar *spider_conn_get_key(
SPIDER_CONN *conn,
size_t *length,
@@ -38,6 +58,14 @@ uchar *spider_ipport_conn_get_key(
my_bool not_used __attribute__ ((unused))
);
int spider_conn_init(
SPIDER_CONN *conn
);
void spider_conn_done(
SPIDER_CONN *conn
);
int spider_reset_conn_setted_parameter(
SPIDER_CONN *conn,
THD *thd
@@ -155,6 +183,21 @@ void spider_conn_queue_UTC_time_zone(
SPIDER_CONN *conn
);
int spider_conn_queue_and_merge_loop_check(
SPIDER_CONN *conn,
SPIDER_CONN_LOOP_CHECK *lcptr
);
int spider_conn_reset_queue_loop_check(
SPIDER_CONN *conn
);
int spider_conn_queue_loop_check(
SPIDER_CONN *conn,
ha_spider *spider,
int link_idx
);
void spider_conn_queue_start_transaction(
SPIDER_CONN *conn
);

View File

@@ -402,6 +402,12 @@ int spider_db_conn_queue_action(
(error_num = spider_dbton[conn->dbton_id].db_util->
append_time_zone(&sql_str, conn->queued_time_zone_val))
) ||
(
conn->loop_check_queue.records &&
conn->db_conn->set_loop_check_in_bulk_sql() &&
(error_num = spider_dbton[conn->dbton_id].db_util->
append_loop_check(&sql_str, conn))
) ||
(
conn->queued_trx_start &&
conn->db_conn->trx_start_in_bulk_sql() &&
@@ -497,6 +503,13 @@ int spider_db_conn_queue_action(
) {
DBUG_RETURN(error_num);
}
if (
conn->loop_check_queue.records &&
!conn->db_conn->set_loop_check_in_bulk_sql() &&
(error_num = conn->db_conn->set_loop_check((int *) conn->need_mon))
) {
DBUG_RETURN(error_num);
}
if (
conn->queued_trx_isolation &&
!conn->queued_semi_trx_isolation &&
@@ -603,6 +616,11 @@ int spider_db_conn_queue_action(
DBUG_PRINT("info", ("spider conn->time_zone=%p",
conn->time_zone));
}
if (conn->loop_check_queue.records)
{
conn->db_conn->fin_loop_check();
}
spider_conn_clear_queue(conn);
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
} else if (conn->server_lost)

View File

@@ -31,6 +31,7 @@
#include "spd_err.h"
#include "spd_db_include.h"
#include "spd_include.h"
#include "spd_conn.h"
spider_db_result::spider_db_result(
SPIDER_DB_CONN *in_db_conn
@@ -60,6 +61,65 @@ spider_db_conn::spider_db_conn(
DBUG_VOID_RETURN;
}
bool spider_db_conn::set_loop_check_in_bulk_sql()
{
DBUG_ENTER("spider_db_conn::set_loop_check_in_bulk_sql");
DBUG_PRINT("info",("spider this=%p", this));
DBUG_RETURN(FALSE);
}
int spider_db_conn::set_loop_check(
int *need_mon
) {
DBUG_ENTER("spider_db_conn::set_loop_check");
DBUG_PRINT("info",("spider this=%p", this));
/* nothing to do */
DBUG_RETURN(0);
}
int spider_db_conn::fin_loop_check()
{
st_spider_conn_loop_check *lcptr;
DBUG_ENTER("spider_db_conn::fin_loop_check");
DBUG_PRINT("info",("spider this=%p", this));
if (conn->loop_check_queue.records)
{
uint l = 0;
while ((lcptr = (SPIDER_CONN_LOOP_CHECK *) my_hash_element(
&conn->loop_check_queue, l)))
{
lcptr->flag = 0;
++l;
}
my_hash_reset(&conn->loop_check_queue);
}
lcptr = conn->loop_check_ignored_first;
while (lcptr)
{
lcptr->flag = 0;
lcptr = lcptr->next;
}
conn->loop_check_ignored_first = NULL;
lcptr = conn->loop_check_meraged_first;
while (lcptr)
{
lcptr->flag = 0;
lcptr = lcptr->next;
}
conn->loop_check_meraged_first = NULL;
DBUG_RETURN(0);
}
int spider_db_util::append_loop_check(
spider_string *str,
SPIDER_CONN *conn
) {
DBUG_ENTER("spider_db_util::append_loop_check");
DBUG_PRINT("info",("spider this=%p", this));
/* nothing to do */
DBUG_RETURN(0);
}
#ifdef HA_HAS_CHECKSUM_EXTENDED
bool spider_db_share::checksum_support()
{

View File

@@ -98,6 +98,8 @@ typedef st_spider_result SPIDER_RESULT;
#define SPIDER_SQL_DOT_STR "."
#define SPIDER_SQL_DOT_LEN (sizeof(SPIDER_SQL_DOT_STR) - 1)
#define SPIDER_SQL_HYPHEN_STR "-"
#define SPIDER_SQL_HYPHEN_LEN (sizeof(SPIDER_SQL_HYPHEN_STR) - 1)
#define SPIDER_SQL_EQUAL_STR " = "
#define SPIDER_SQL_EQUAL_LEN (sizeof(SPIDER_SQL_EQUAL_STR) - 1)
@@ -214,6 +216,9 @@ typedef st_spider_result SPIDER_RESULT;
#define SPIDER_SQL_LCL_NAME_QUOTE_STR "`"
#define SPIDER_SQL_LCL_NAME_QUOTE_LEN (sizeof(SPIDER_SQL_LCL_NAME_QUOTE_STR) - 1)
#define SPIDER_SQL_LOP_CHK_PRM_PRF_STR "spider_lc_"
#define SPIDER_SQL_LOP_CHK_PRM_PRF_LEN (sizeof(SPIDER_SQL_LOP_CHK_PRM_PRF_STR) - 1)
#define SPIDER_CONN_KIND_MYSQL (1 << 0)
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
#define SPIDER_CONN_KIND_HS_READ (1 << 2)
@@ -874,6 +879,10 @@ public:
spider_string *str,
Time_zone *time_zone
) = 0;
virtual int append_loop_check(
spider_string *str,
SPIDER_CONN *conn
);
virtual int append_start_transaction(
spider_string *str
) = 0;
@@ -1186,6 +1195,11 @@ public:
Time_zone *time_zone,
int *need_mon
) = 0;
virtual bool set_loop_check_in_bulk_sql();
virtual int set_loop_check(
int *need_mon
);
virtual int fin_loop_check();
virtual int show_master_status(
SPIDER_TRX *trx,
SPIDER_SHARE *share,

View File

@@ -100,6 +100,9 @@ static const char *name_quote_str = SPIDER_SQL_NAME_QUOTE_STR;
#define SPIDER_SQL_TIME_ZONE_STR "set session time_zone = '"
#define SPIDER_SQL_TIME_ZONE_LEN sizeof(SPIDER_SQL_TIME_ZONE_STR) - 1
#define SPIDER_SQL_SET_USER_VAL_STR "set @`"
#define SPIDER_SQL_SET_USER_VAL_LEN sizeof(SPIDER_SQL_SET_USER_VAL_STR) - 1
#define SPIDER_SQL_COMMIT_STR "commit"
#define SPIDER_SQL_COMMIT_LEN sizeof(SPIDER_SQL_COMMIT_STR) - 1
#define SPIDER_SQL_ROLLBACK_STR "rollback"
@@ -2280,19 +2283,23 @@ bool spider_db_mbase::is_xa_nota_error(
DBUG_RETURN(xa_nota);
}
void spider_db_mbase::print_warnings(
int spider_db_mbase::print_warnings(
struct tm *l_time
) {
int error_num = 0;
DBUG_ENTER("spider_db_mbase::print_warnings");
DBUG_PRINT("info",("spider this=%p", this));
if (db_conn->status == MYSQL_STATUS_READY)
{
if (
#if MYSQL_VERSION_ID < 50500
if (!(db_conn->last_used_con->server_status & SERVER_MORE_RESULTS_EXISTS))
!(db_conn->last_used_con->server_status & SERVER_MORE_RESULTS_EXISTS) &&
db_conn->last_used_con->warning_count
#else
if (!(db_conn->server_status & SERVER_MORE_RESULTS_EXISTS))
!(db_conn->server_status & SERVER_MORE_RESULTS_EXISTS) &&
db_conn->warning_count
#endif
{
) {
/*
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -2318,7 +2325,7 @@ void spider_db_mbase::print_warnings(
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
*/
DBUG_VOID_RETURN;
DBUG_RETURN(0);
}
/* no record is ok */
}
@@ -2330,17 +2337,32 @@ void spider_db_mbase::print_warnings(
if (num_fields != 3)
{
mysql_free_result(res);
DBUG_VOID_RETURN;
DBUG_RETURN(0);
}
while (row)
if (l_time)
{
fprintf(stderr, "%04d%02d%02d %02d:%02d:%02d [WARN SPIDER RESULT] "
"from [%s] %ld to %ld: %s %s %s\n",
l_time->tm_year + 1900, l_time->tm_mon + 1, l_time->tm_mday,
l_time->tm_hour, l_time->tm_min, l_time->tm_sec,
conn->tgt_host, (ulong) db_conn->thread_id,
(ulong) current_thd->thread_id, row[0], row[1], row[2]);
row = mysql_fetch_row(res);
while (row)
{
fprintf(stderr, "%04d%02d%02d %02d:%02d:%02d [WARN SPIDER RESULT] "
"from [%s] %ld to %ld: %s %s %s\n",
l_time->tm_year + 1900, l_time->tm_mon + 1, l_time->tm_mday,
l_time->tm_hour, l_time->tm_min, l_time->tm_sec,
conn->tgt_host, (ulong) db_conn->thread_id,
(ulong) current_thd->thread_id, row[0], row[1], row[2]);
row = mysql_fetch_row(res);
}
} else {
while (row)
{
DBUG_PRINT("info",("spider row[0]=%s", row[0]));
DBUG_PRINT("info",("spider row[1]=%s", row[1]));
DBUG_PRINT("info",("spider row[2]=%s", row[2]));
longlong res_num =
(longlong) my_strtoll10(row[1], (char**) NULL, &error_num);
my_printf_error(res_num, row[2], MYF(0));
error_num = res_num;
row = mysql_fetch_row(res);
}
}
if (res)
mysql_free_result(res);
@@ -2352,7 +2374,7 @@ void spider_db_mbase::print_warnings(
}
}
}
DBUG_VOID_RETURN;
DBUG_RETURN(error_num);
}
spider_db_result *spider_db_mbase::store_result(
@@ -3047,6 +3069,99 @@ int spider_db_mbase::set_time_zone(
DBUG_RETURN(0);
}
bool spider_db_mbase::set_loop_check_in_bulk_sql()
{
DBUG_ENTER("spider_db_mbase::set_loop_check_in_bulk_sql");
DBUG_PRINT("info",("spider this=%p", this));
DBUG_RETURN(TRUE);
}
int spider_db_mbase::set_loop_check(
int *need_mon
) {
SPIDER_CONN_LOOP_CHECK *lcptr;
char sql_buf[MAX_FIELD_WIDTH];
spider_string sql_str(sql_buf, sizeof(sql_buf), &my_charset_bin);
DBUG_ENTER("spider_db_mbase::set_loop_check");
DBUG_PRINT("info",("spider this=%p", this));
sql_str.init_calc_mem(270);
while ((lcptr = (SPIDER_CONN_LOOP_CHECK *) my_hash_element(
&conn->loop_check_queue, 0)))
{
sql_str.length(0);
if (sql_str.reserve(SPIDER_SQL_SET_USER_VAL_LEN +
SPIDER_SQL_LOP_CHK_PRM_PRF_LEN + lcptr->to_name.length +
SPIDER_SQL_NAME_QUOTE_LEN + SPIDER_SQL_EQUAL_LEN +
SPIDER_SQL_VALUE_QUOTE_LEN +
lcptr->merged_value.length + SPIDER_SQL_VALUE_QUOTE_LEN))
{
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
sql_str.q_append(SPIDER_SQL_SET_USER_VAL_STR, SPIDER_SQL_SET_USER_VAL_LEN);
sql_str.q_append(SPIDER_SQL_LOP_CHK_PRM_PRF_STR,
SPIDER_SQL_LOP_CHK_PRM_PRF_LEN);
sql_str.q_append(lcptr->to_name.str, lcptr->to_name.length);
sql_str.q_append(SPIDER_SQL_NAME_QUOTE_STR, SPIDER_SQL_NAME_QUOTE_LEN);
sql_str.q_append(SPIDER_SQL_EQUAL_STR, SPIDER_SQL_EQUAL_LEN);
sql_str.q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
sql_str.q_append(lcptr->merged_value.str, lcptr->merged_value.length);
sql_str.q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
if (spider_db_query(
conn,
sql_str.ptr(),
sql_str.length(),
-1,
need_mon)
) {
DBUG_RETURN(spider_db_errorno(conn));
}
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
#ifdef HASH_UPDATE_WITH_HASH_VALUE
my_hash_delete_with_hash_value(&conn->loop_check_queue,
lcptr->hash_value, (uchar *) lcptr);
#else
my_hash_delete(&conn->loop_check_queue, (uchar*) lcptr);
#endif
}
DBUG_RETURN(0);
}
int spider_db_mbase::fin_loop_check()
{
st_spider_conn_loop_check *lcptr;
DBUG_ENTER("spider_db_mbase::fin_loop_check");
DBUG_PRINT("info",("spider this=%p", this));
if (conn->loop_check_queue.records)
{
uint l = 0;
while ((lcptr = (SPIDER_CONN_LOOP_CHECK *) my_hash_element(
&conn->loop_check_queue, l)))
{
lcptr->flag = 0;
++l;
}
my_hash_reset(&conn->loop_check_queue);
}
lcptr = conn->loop_check_ignored_first;
while (lcptr)
{
lcptr->flag = 0;
lcptr = lcptr->next;
}
conn->loop_check_ignored_first = NULL;
lcptr = conn->loop_check_meraged_first;
while (lcptr)
{
lcptr->flag = 0;
lcptr = lcptr->next;
}
conn->loop_check_meraged_first = NULL;
DBUG_RETURN(0);
}
int spider_db_mbase::exec_simple_sql_with_result(
SPIDER_TRX *trx,
SPIDER_SHARE *share,
@@ -5187,6 +5302,47 @@ int spider_db_mbase_util::append_time_zone(
DBUG_RETURN(0);
}
int spider_db_mbase_util::append_loop_check(
spider_string *str,
SPIDER_CONN *conn
) {
SPIDER_CONN_LOOP_CHECK *lcptr;
DBUG_ENTER("spider_db_mbase_util::append_loop_check");
DBUG_PRINT("info",("spider this=%p", this));
DBUG_PRINT("info",("spider str=%s", str->c_ptr_safe()));
uint l = 0;
while ((lcptr = (SPIDER_CONN_LOOP_CHECK *) my_hash_element(
&conn->loop_check_queue, l)))
{
DBUG_PRINT("info",("spider lcptr=%p", lcptr));
if (str->reserve(SPIDER_SQL_SEMICOLON_LEN + SPIDER_SQL_SET_USER_VAL_LEN +
SPIDER_SQL_LOP_CHK_PRM_PRF_LEN + lcptr->to_name.length +
SPIDER_SQL_NAME_QUOTE_LEN + SPIDER_SQL_EQUAL_LEN +
SPIDER_SQL_VALUE_QUOTE_LEN +
lcptr->merged_value.length + SPIDER_SQL_VALUE_QUOTE_LEN))
{
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
if (str->length())
{
str->q_append(SPIDER_SQL_SEMICOLON_STR, SPIDER_SQL_SEMICOLON_LEN);
}
str->q_append(SPIDER_SQL_SET_USER_VAL_STR, SPIDER_SQL_SET_USER_VAL_LEN);
str->q_append(SPIDER_SQL_LOP_CHK_PRM_PRF_STR,
SPIDER_SQL_LOP_CHK_PRM_PRF_LEN);
str->q_append(lcptr->to_name.str, lcptr->to_name.length);
str->q_append(SPIDER_SQL_NAME_QUOTE_STR, SPIDER_SQL_NAME_QUOTE_LEN);
str->q_append(SPIDER_SQL_EQUAL_STR, SPIDER_SQL_EQUAL_LEN);
str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
str->q_append(lcptr->merged_value.str, lcptr->merged_value.length);
str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
++l;
DBUG_PRINT("info",("spider str=%s", str->c_ptr_safe()));
}
DBUG_RETURN(0);
}
int spider_db_mbase_util::append_start_transaction(
spider_string *str
) {
@@ -13860,6 +14016,10 @@ int spider_mbase_handler::show_table_status(
DBUG_RETURN(error_num);
}
}
if ((error_num = ((spider_db_mbase *) conn->db_conn)->print_warnings(NULL)))
{
DBUG_RETURN(error_num);
}
if (share->static_records_for_status != -1)
{
share->stat.records = (ha_rows) share->static_records_for_status;

View File

@@ -91,6 +91,10 @@ public:
spider_string *str,
Time_zone *time_zone
);
int append_loop_check(
spider_string *str,
SPIDER_CONN *conn
);
int append_start_transaction(
spider_string *str
);
@@ -439,7 +443,7 @@ public:
bool is_xa_nota_error(
int error_num
);
void print_warnings(
int print_warnings(
struct tm *l_time
);
spider_db_result *store_result(
@@ -529,6 +533,11 @@ public:
Time_zone *time_zone,
int *need_mon
);
bool set_loop_check_in_bulk_sql();
int set_loop_check(
int *need_mon
);
int fin_loop_check();
int exec_simple_sql_with_result(
SPIDER_TRX *trx,
SPIDER_SHARE *share,

View File

@@ -595,6 +595,11 @@ SPIDER_CONN *spider_udf_direct_sql_create_conn(
goto error_mta_conn_mutex_init;
}
if (unlikely((*error_num = spider_conn_init(conn))))
{
goto error_conn_init;
}
if ((*error_num = spider_db_udf_direct_sql_connect(direct_sql, conn)))
goto error;
conn->ping_time = (time_t) time((time_t*) 0);
@@ -648,8 +653,10 @@ SPIDER_CONN *spider_udf_direct_sql_create_conn(
error:
DBUG_ASSERT(!conn->mta_conn_mutex_file_pos.file_name);
pthread_mutex_destroy(&conn->mta_conn_mutex);
error_too_many_ipport_count:
spider_conn_done(conn);
error_conn_init:
pthread_mutex_destroy(&conn->mta_conn_mutex);
error_mta_conn_mutex_init:
error_db_conn_init:
delete conn->db_conn;

View File

@@ -1,4 +1,5 @@
/* Copyright (C) 2008-2018 Kentoku Shiba & 2017 MariaDB corp
/* Copyright (C) 2008-2019 Kentoku Shiba
Copyright (C) 2017-2019 MariaDB corp
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

View File

@@ -124,9 +124,13 @@
#define ER_SPIDER_CON_COUNT_ERROR_STR "Too many connections between spider and remote"
#define ER_SPIDER_TABLE_OPEN_TIMEOUT_NUM 12714
#define ER_SPIDER_TABLE_OPEN_TIMEOUT_STR "Table %s.%s open timeout"
#define ER_SPIDER_INFINITE_LOOP_NUM 12719
#define ER_SPIDER_INFINITE_LOOP_STR "An infinite loop is detected when opening table %s.%s"
#define ER_SPIDER_SAME_SERVER_LINK_NUM 12720
#define ER_SPIDER_SAME_SERVER_LINK_STR1 "Host:%s and Socket:%s aim self server. Please change spider_same_server_link parameter if this link is required."
#define ER_SPIDER_SAME_SERVER_LINK_STR2 "Host:%s and Port:%ld aim self server. Please change spider_same_server_link parameter if this link is required."
#define ER_SPIDER_CANT_NUM 12721
#define ER_SPIDER_CANT_STR1 "Can't %s%d"
#define ER_SPIDER_COND_SKIP_NUM 12801
#define ER_SPIDER_UNKNOWN_NUM 12500

View File

@@ -261,7 +261,7 @@ const char SPIDER_empty_string = "";
#define SPIDER_TMP_SHARE_LONG_COUNT 19
#define SPIDER_TMP_SHARE_LONGLONG_COUNT 3
#define SPIDER_MEM_CALC_LIST_NUM 268
#define SPIDER_MEM_CALC_LIST_NUM 273
#define SPIDER_CONN_META_BUF_LEN 64
#define SPIDER_BACKUP_DASTATUS \
@@ -413,6 +413,8 @@ typedef struct st_spider_alter_table
uint tmp_link_statuses_length;
} SPIDER_ALTER_TABLE;
typedef struct st_spider_conn_loop_check SPIDER_CONN_LOOP_CHECK;
/* database connection */
typedef struct st_spider_conn
{
@@ -603,6 +605,22 @@ typedef struct st_spider_conn
SPIDER_LINK_IDX_CHAIN *link_idx_chain;
#endif
SPIDER_IP_PORT_CONN *ip_port_conn;
pthread_mutex_t loop_check_mutex;
HASH loop_checked;
uint loop_checked_id;
const char *loop_checked_func_name;
const char *loop_checked_file_name;
ulong loop_checked_line_no;
HASH loop_check_queue;
uint loop_check_queue_id;
const char *loop_check_queue_func_name;
const char *loop_check_queue_file_name;
ulong loop_check_queue_line_no;
SPIDER_CONN_LOOP_CHECK *loop_check_ignored_first;
SPIDER_CONN_LOOP_CHECK *loop_check_ignored_last;
SPIDER_CONN_LOOP_CHECK *loop_check_meraged_first;
SPIDER_CONN_LOOP_CHECK *loop_check_meraged_last;
} SPIDER_CONN;
typedef struct st_spider_lgtm_tblhnd_share
@@ -702,6 +720,7 @@ typedef struct st_spider_wide_handler
#endif
TABLE *top_table;
Field **top_table_field;
TABLE_SHARE *top_share;
enum thr_lock_type lock_type;
uchar lock_table_type;
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)

View File

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

View File

@@ -196,6 +196,7 @@ PSI_mutex_key spd_key_mutex_conn_i;
PSI_mutex_key spd_key_mutex_bg_stss;
PSI_mutex_key spd_key_mutex_bg_crds;
#endif
PSI_mutex_key spd_key_mutex_conn_loop_check;
static PSI_mutex_info all_spider_mutexes[]=
{
@@ -246,6 +247,7 @@ static PSI_mutex_info all_spider_mutexes[]=
{ &spd_key_mutex_pt_handler, "pt_handler", 0},
#endif
{ &spd_key_mutex_udf_table, "udf_table", 0},
{ &spd_key_mutex_conn_loop_check, "conn_loop_check", 0},
};
#ifndef WITHOUT_SPIDER_BG_SEARCH
@@ -404,6 +406,9 @@ extern ulonglong spider_free_mem_count[SPIDER_MEM_CALC_LIST_NUM];
static char spider_wild_many = '%', spider_wild_one = '_',
spider_wild_prefix='\\';
static char spider_unique_id_buf[1 + 12 + 1 + 16 + 1 + 1];
LEX_CSTRING spider_unique_id;
// for spider_open_tables
uchar *spider_tbl_get_key(
SPIDER_SHARE *share,
@@ -4605,7 +4610,7 @@ SPIDER_SHARE *spider_get_share(
SPIDER_SHARE *share;
TABLE_SHARE *table_share = table->s;
SPIDER_RESULT_LIST *result_list = &spider->result_list;
uint length, tmp_conn_link_idx = 0;
uint length, tmp_conn_link_idx = 0, buf_sz;
char *tmp_name, *tmp_cid;
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
char *tmp_hs_r_name, *tmp_hs_w_name;
@@ -4640,13 +4645,60 @@ SPIDER_SHARE *spider_get_share(
bool same_server_link;
int load_sts_at_startup;
int load_crd_at_startup;
user_var_entry *loop_check;
char *loop_check_buf;
TABLE_SHARE *top_share;
LEX_CSTRING lex_str;
DBUG_ENTER("spider_get_share");
top_share = spider->wide_handler->top_share;
length = (uint) strlen(table_name);
#ifdef SPIDER_HAS_HASH_VALUE_TYPE
my_hash_value_type hash_value = my_calc_hash(&spider_open_tables,
(uchar*) table_name, length);
#endif
if (top_share)
{
lex_str.length = top_share->path.length + SPIDER_SQL_LOP_CHK_PRM_PRF_LEN;
buf_sz = spider_unique_id.length > SPIDER_SQL_LOP_CHK_PRM_PRF_LEN ?
top_share->path.length + spider_unique_id.length + 2 :
lex_str.length + 2;
loop_check_buf = (char *) my_alloca(buf_sz);
if (unlikely(!loop_check_buf))
{
*error_num = HA_ERR_OUT_OF_MEM;
DBUG_RETURN(NULL);
}
lex_str.str = loop_check_buf + buf_sz - lex_str.length - 2;
memcpy((void *) lex_str.str,
SPIDER_SQL_LOP_CHK_PRM_PRF_STR, SPIDER_SQL_LOP_CHK_PRM_PRF_LEN);
memcpy((void *) (lex_str.str + SPIDER_SQL_LOP_CHK_PRM_PRF_LEN),
top_share->path.str, top_share->path.length);
((char *) lex_str.str)[lex_str.length] = '\0';
DBUG_PRINT("info",("spider loop check param name=%s", lex_str.str));
loop_check = get_variable(&thd->user_vars, &lex_str, FALSE);
if (loop_check && loop_check->type == STRING_RESULT)
{
lex_str.length = top_share->path.length + spider_unique_id.length + 1;
lex_str.str = loop_check_buf + buf_sz - top_share->path.length -
spider_unique_id.length - 2;
memcpy((void *) lex_str.str, spider_unique_id.str,
spider_unique_id.length);
((char *) lex_str.str)[lex_str.length - 1] = '-';
((char *) lex_str.str)[lex_str.length] = '\0';
DBUG_PRINT("info",("spider loop check key=%s", lex_str.str));
DBUG_PRINT("info",("spider loop check param value=%s",
loop_check->value));
if (unlikely(strstr(loop_check->value, lex_str.str)))
{
*error_num = ER_SPIDER_INFINITE_LOOP_NUM;
my_printf_error(*error_num, ER_SPIDER_INFINITE_LOOP_STR, MYF(0),
top_share->db.str, top_share->table_name.str);
my_afree(loop_check_buf);
DBUG_RETURN(NULL);
}
}
my_afree(loop_check_buf);
}
pthread_mutex_lock(&spider_tbl_mutex);
#ifdef SPIDER_HAS_HASH_VALUE_TYPE
if (!(share = (SPIDER_SHARE*) my_hash_search_using_hash_value(
@@ -5245,6 +5297,7 @@ SPIDER_SHARE *spider_get_share(
my_printf_error(ER_SPIDER_TABLE_OPEN_TIMEOUT_NUM,
ER_SPIDER_TABLE_OPEN_TIMEOUT_STR, MYF(0),
table_share->db.str, table_share->table_name.str);
spider_free_share(share);
goto error_but_no_delete;
}
my_sleep(10000); // wait 10 ms
@@ -6918,6 +6971,7 @@ int spider_db_init(
) {
int error_num = HA_ERR_OUT_OF_MEM, roop_count;
uint dbton_id = 0;
char addr[6];
handlerton *spider_hton = (handlerton *)p;
DBUG_ENTER("spider_db_init");
spider_hton_ptr = spider_hton;
@@ -6959,6 +7013,16 @@ int spider_db_init(
spider_hton->create_group_by = spider_create_group_by_handler;
#endif
if (my_gethwaddr((uchar *) addr))
{
my_printf_error(ER_SPIDER_CANT_NUM, ER_SPIDER_CANT_STR1, MYF(0),
"get hardware address with error ", errno);
}
spider_unique_id.str = spider_unique_id_buf;
spider_unique_id.length = my_sprintf(spider_unique_id_buf,
(spider_unique_id_buf, "-%02x%02x%02x%02x%02x%02x-%lx-",
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], (ulong) getpid()));
memset(&spider_alloc_func_name, 0, sizeof(spider_alloc_func_name));
memset(&spider_alloc_file_name, 0, sizeof(spider_alloc_file_name));
memset(&spider_alloc_line_no, 0, sizeof(spider_alloc_line_no));
@@ -8402,8 +8466,27 @@ TABLE_LIST *spider_get_parent_table_list(
ha_spider *spider
) {
TABLE *table = spider->get_top_table();
TABLE_LIST *current, *parent;
DBUG_ENTER("spider_get_parent_table_list");
DBUG_RETURN(table->pos_in_table_list);
DBUG_PRINT("info",("spider table=%p", table));
if (table->pos_in_table_list)
{
current = table->pos_in_table_list;
} else {
current = table->intention_pos_in_table_list;
}
#ifdef HANDLER_HAS_TOP_TABLE_FIELDS
if (!spider->set_top_table_fields)
{
#endif
while ((parent = current->parent_l))
{
current = parent;
}
#ifdef HANDLER_HAS_TOP_TABLE_FIELDS
}
#endif
DBUG_RETURN(current);
}
List<Index_hint> *spider_get_index_hints(