summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKentoku <kentokushiba@gmail.com>2019-05-28 16:40:59 +0900
committerKentoku <kentokushiba@gmail.com>2019-09-02 07:06:05 +0900
commit4a8dafe26ec1aa97c153f7dedc7a487b6cedffd9 (patch)
tree101a557ddf6adbc4d76deac240d6a1dcf52f06c9
parent24773bf38024d32c9af4e6bc09e67043318bba6e (diff)
downloadmariadb-git-bb-10.4-MDEV-6268.tar.gz
MDEV-6268 SPIDER table with no COMMENT clause causes queries to wait foreverbb-10.4-MDEV-6268
Add loop checks by using user variables
-rw-r--r--sql/sql_base.cc4
-rw-r--r--sql/sql_select.cc2
-rw-r--r--sql/table.cc4
-rw-r--r--sql/table.h9
-rw-r--r--storage/spider/ha_spider.cc15
-rw-r--r--storage/spider/ha_spider.h4
-rw-r--r--storage/spider/mysql-test/spider/bugfix/include/ping_table_deinit.inc11
-rw-r--r--storage/spider/mysql-test/spider/bugfix/include/ping_table_init.inc60
-rw-r--r--storage/spider/mysql-test/spider/bugfix/include/self_reference_deinit.inc10
-rw-r--r--storage/spider/mysql-test/spider/bugfix/include/self_reference_init.inc13
-rw-r--r--storage/spider/mysql-test/spider/bugfix/r/self_reference.result36
-rw-r--r--storage/spider/mysql-test/spider/bugfix/r/slave_trx_isolation.result2
-rw-r--r--storage/spider/mysql-test/spider/bugfix/t/ping_table.cnf3
-rw-r--r--storage/spider/mysql-test/spider/bugfix/t/ping_table.test66
-rw-r--r--storage/spider/mysql-test/spider/bugfix/t/self_reference.cnf2
-rw-r--r--storage/spider/mysql-test/spider/bugfix/t/self_reference.test45
-rw-r--r--storage/spider/mysql-test/spider/bugfix/t/slave_trx_isolation.test1
-rw-r--r--storage/spider/mysql-test/spider/include/deinit_spider.inc69
-rw-r--r--storage/spider/mysql-test/spider/include/init_spider.inc226
-rw-r--r--storage/spider/mysql-test/spider/r/slave_trx_isolation.result2
-rw-r--r--storage/spider/mysql-test/spider/t/slave_trx_isolation.test1
-rw-r--r--storage/spider/spd_conn.cc546
-rw-r--r--storage/spider/spd_conn.h43
-rw-r--r--storage/spider/spd_db_conn.cc18
-rw-r--r--storage/spider/spd_db_include.cc61
-rw-r--r--storage/spider/spd_db_include.h14
-rw-r--r--storage/spider/spd_db_mysql.cc192
-rw-r--r--storage/spider/spd_db_mysql.h11
-rw-r--r--storage/spider/spd_direct_sql.cc9
-rw-r--r--storage/spider/spd_environ.h4
-rw-r--r--storage/spider/spd_err.h18
-rw-r--r--storage/spider/spd_include.h22
-rw-r--r--storage/spider/spd_table.cc96
33 files changed, 1488 insertions, 131 deletions
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 60371813280..54bf3bf29f2 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -2040,11 +2040,13 @@ retry_share:
if (!(table=(TABLE*) my_malloc(sizeof(*table),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))
{
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 598f46594e5..f85e598b776 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -3123,7 +3123,7 @@ bool JOIN::make_aggr_tables_info()
distinct in the engine, so we do this for all queries, not only
GROUP BY queries.
*/
- if (tables_list && !procedure)
+ if (tables_list && !procedure && join_tab)
{
/*
At the moment we only support push down for queries where
diff --git a/sql/table.cc b/sql/table.cc
index 699102885c2..ffc00158956 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -3543,7 +3543,8 @@ static void print_long_unique_table(TABLE *table)
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;
@@ -3565,6 +3566,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)))
diff --git a/sql/table.h b/sql/table.h
index 42c017d63af..da7e0b4a99e 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -1167,6 +1167,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) */
@@ -2144,6 +2147,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
@@ -2982,7 +2988,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 fix_session_vcol_expr(THD *thd, Virtual_column_info *vcol);
bool fix_session_vcol_expr_for_read(THD *thd, Field *field,
Virtual_column_info *vcol);
diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc
index fb947ef643f..f279561f4b2 100644
--- a/storage/spider/ha_spider.cc
+++ b/storage/spider/ha_spider.cc
@@ -1,4 +1,5 @@
-/* Copyright (C) 2008-2018 Kentoku Shiba
+/* Copyright (C) 2008-2019 Kentoku Shiba
+ Copyright (C) 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
@@ -356,6 +357,18 @@ int ha_spider::open(
dup_key_idx = (uint) -1;
conn_kinds = SPIDER_CONN_KIND_MYSQL;
+ if (table_share->tmp_table == NO_TMP_TABLE)
+ {
+ TABLE_LIST *top = spider_get_parent_table_list(this);
+ if (top->intention_table)
+ {
+ top_share = top->intention_table->s;
+ } else {
+ top_share = top->table->s;
+ }
+ } else {
+ top_share = NULL;
+ }
if (!spider_get_share(name, table, thd, this, &error_num))
goto error_get_share;
thr_lock_data_init(&share->lock,&lock,NULL);
diff --git a/storage/spider/ha_spider.h b/storage/spider/ha_spider.h
index 9ffe49754e8..e6674bc7a50 100644
--- a/storage/spider/ha_spider.h
+++ b/storage/spider/ha_spider.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 2008-2018 Kentoku Shiba
+/* Copyright (C) 2008-2019 Kentoku Shiba
+ Copyright (C) 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
@@ -54,6 +55,7 @@ public:
THR_LOCK_DATA lock;
SPIDER_SHARE *share;
SPIDER_TRX *trx;
+ TABLE_SHARE *top_share;
ulonglong spider_thread_id;
ulonglong trx_conn_adjustment;
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
diff --git a/storage/spider/mysql-test/spider/bugfix/include/ping_table_deinit.inc b/storage/spider/mysql-test/spider/bugfix/include/ping_table_deinit.inc
new file mode 100644
index 00000000000..76b7582abfe
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/include/ping_table_deinit.inc
@@ -0,0 +1,11 @@
+--let $MASTER_1_COMMENT_2_1= $MASTER_1_COMMENT_2_1_BACKUP
+--let $CHILD2_1_DROP_TABLES= $CHILD2_1_DROP_TABLES_BACKUP
+--let $CHILD2_1_CREATE_TABLES= $CHILD2_1_CREATE_TABLES_BACKUP
+--let $CHILD2_1_SELECT_TABLES= $CHILD2_1_SELECT_TABLES_BACKUP
+--disable_warnings
+--disable_query_log
+--disable_result_log
+--source ../t/test_deinit.inc
+--enable_result_log
+--enable_query_log
+--enable_warnings
diff --git a/storage/spider/mysql-test/spider/bugfix/include/ping_table_init.inc b/storage/spider/mysql-test/spider/bugfix/include/ping_table_init.inc
new file mode 100644
index 00000000000..d4757840f0d
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/include/ping_table_init.inc
@@ -0,0 +1,60 @@
+--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", srv "s_2_1"';
+--let $CHILD2_1_DROP_TABLES_BACKUP= $CHILD2_1_DROP_TABLES
+let $CHILD2_1_DROP_TABLES=
+ DROP TABLE IF EXISTS tbl_a;
+--let $CHILD2_1_CREATE_TABLES_BACKUP= $CHILD2_1_CREATE_TABLES
+let $CHILD2_1_CREATE_TABLES=
+ CREATE TABLE tbl_a (
+ pkey int NOT NULL,
+ PRIMARY KEY (pkey)
+ ) $CHILD2_1_ENGINE $CHILD2_1_CHARSET;
+--let $CHILD2_1_SELECT_TABLES_BACKUP= $CHILD2_1_SELECT_TABLES
+let $CHILD2_1_SELECT_TABLES=
+ SELECT pkey FROM tbl_a ORDER BY pkey;
+let $CHILD2_1_SELECT_ARGUMENT1=
+ SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
+--connection master_1
+if ($VERSION_COMPILE_OS_WIN)
+{
+ let $PING_COMMAND=
+ SELECT spider_ping_table('.\\auto_test_local\\tbl_a', 0, 2, 1,
+ ' where pkey = 1', @@server_id, 1, 0, 0, 0);
+}
+if (!$VERSION_COMPILE_OS_WIN)
+{
+ let $PING_COMMAND=
+ SELECT spider_ping_table('./auto_test_local/tbl_a', 0, 2, 1,
+ ' where pkey = 1', @@server_id, 1, 0, 0, 0);
+}
+--disable_query_log
+INSERT INTO mysql.spider_link_mon_servers SET
+ db_name = '%',
+ table_name = '%',
+ link_id = '%',
+ sid = @@server_id,
+ server = 's_1',
+ scheme = null,
+ host = null,
+ port = null,
+ socket = null,
+ username = null,
+ password = null,
+ ssl_ca = null,
+ ssl_capath = null,
+ ssl_cert = null,
+ ssl_cipher = null,
+ ssl_key = null,
+ ssl_verify_server_cert = 0,
+ default_file = null,
+ default_group = null
+;
+--enable_query_log
diff --git a/storage/spider/mysql-test/spider/bugfix/include/self_reference_deinit.inc b/storage/spider/mysql-test/spider/bugfix/include/self_reference_deinit.inc
new file mode 100644
index 00000000000..34376d50584
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/include/self_reference_deinit.inc
@@ -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
diff --git a/storage/spider/mysql-test/spider/bugfix/include/self_reference_init.inc b/storage/spider/mysql-test/spider/bugfix/include/self_reference_init.inc
new file mode 100644
index 00000000000..b7e2c4d02ca
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/include/self_reference_init.inc
@@ -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;
diff --git a/storage/spider/mysql-test/spider/bugfix/r/self_reference.result b/storage/spider/mysql-test/spider/bugfix/r/self_reference.result
new file mode 100644
index 00000000000..1ce9c60a93f
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/r/self_reference.result
@@ -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
diff --git a/storage/spider/mysql-test/spider/bugfix/r/slave_trx_isolation.result b/storage/spider/mysql-test/spider/bugfix/r/slave_trx_isolation.result
index e93eb78417f..dd492bad006 100644
--- a/storage/spider/mysql-test/spider/bugfix/r/slave_trx_isolation.result
+++ b/storage/spider/mysql-test/spider/bugfix/r/slave_trx_isolation.result
@@ -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;start transaction
SELECT argument FROM mysql.general_log WHERE argument LIKE '%set %'
diff --git a/storage/spider/mysql-test/spider/bugfix/t/ping_table.cnf b/storage/spider/mysql-test/spider/bugfix/t/ping_table.cnf
new file mode 100644
index 00000000000..05dfd8a0bce
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/t/ping_table.cnf
@@ -0,0 +1,3 @@
+!include include/default_mysqld.cnf
+!include ../my_1_1.cnf
+!include ../my_2_1.cnf
diff --git a/storage/spider/mysql-test/spider/bugfix/t/ping_table.test b/storage/spider/mysql-test/spider/bugfix/t/ping_table.test
new file mode 100644
index 00000000000..5f33dc2952b
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/t/ping_table.test
@@ -0,0 +1,66 @@
+--source ../include/ping_table_init.inc
+--echo
+--echo drop and create databases
+
+--connection master_1
+--disable_warnings
+CREATE DATABASE auto_test_local;
+USE auto_test_local;
+--enable_warnings
+
+--connection child2_1
+SET @old_log_output = @@global.log_output;
+SET GLOBAL log_output = 'TABLE,FILE';
+CREATE DATABASE auto_test_remote;
+USE auto_test_remote;
+--enable_warnings
+
+--echo
+--echo create table and insert
+
+--connection child2_1
+--disable_query_log
+echo CHILD2_1_CREATE_TABLES;
+eval $CHILD2_1_CREATE_TABLES;
+--enable_query_log
+TRUNCATE TABLE mysql.general_log;
+
+--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
+INSERT INTO tbl_a VALUES (1),(2);
+
+--connection child2_1
+TRUNCATE TABLE mysql.general_log;
+
+--connection master_1
+eval $PING_COMMAND;
+SELECT pkey FROM tbl_a WHERE NULL;
+
+--connection child2_1
+eval $CHILD2_1_SELECT_ARGUMENT1;
+eval $CHILD2_1_SELECT_TABLES;
+
+--echo
+--echo deinit
+--disable_warnings
+
+--connection master_1
+DROP DATABASE IF EXISTS auto_test_local;
+
+--connection child2_1
+DROP DATABASE IF EXISTS auto_test_remote;
+SET GLOBAL log_output = @old_log_output;
+
+--enable_warnings
+--source ../include/ping_table_deinit.inc
+--echo
+--echo end of test
diff --git a/storage/spider/mysql-test/spider/bugfix/t/self_reference.cnf b/storage/spider/mysql-test/spider/bugfix/t/self_reference.cnf
new file mode 100644
index 00000000000..b0853e32654
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/t/self_reference.cnf
@@ -0,0 +1,2 @@
+!include include/default_mysqld.cnf
+!include ../my_1_1.cnf
diff --git a/storage/spider/mysql-test/spider/bugfix/t/self_reference.test b/storage/spider/mysql-test/spider/bugfix/t/self_reference.test
new file mode 100644
index 00000000000..b93cf8ef715
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/t/self_reference.test
@@ -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
diff --git a/storage/spider/mysql-test/spider/bugfix/t/slave_trx_isolation.test b/storage/spider/mysql-test/spider/bugfix/t/slave_trx_isolation.test
index 652fbb1c11c..c608ae018ea 100644
--- a/storage/spider/mysql-test/spider/bugfix/t/slave_trx_isolation.test
+++ b/storage/spider/mysql-test/spider/bugfix/t/slave_trx_isolation.test
@@ -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;
diff --git a/storage/spider/mysql-test/spider/include/deinit_spider.inc b/storage/spider/mysql-test/spider/include/deinit_spider.inc
index 3609551e169..523bb31661a 100644
--- a/storage/spider/mysql-test/spider/include/deinit_spider.inc
+++ b/storage/spider/mysql-test/spider/include/deinit_spider.inc
@@ -3,6 +3,7 @@ DROP FUNCTION spider_bg_direct_sql;
DROP FUNCTION spider_ping_table;
DROP FUNCTION spider_copy_tables;
DROP FUNCTION spider_flush_table_mon_cache;
+UNINSTALL PLUGIN spider_alloc_mem;
UNINSTALL PLUGIN spider;
DROP TABLE IF EXISTS mysql.spider_xa;
DROP TABLE IF EXISTS mysql.spider_xa_member;
@@ -13,9 +14,65 @@ DROP TABLE IF EXISTS mysql.spider_link_failed_log;
DROP TABLE IF EXISTS mysql.spider_table_position_for_recovery;
DROP TABLE IF EXISTS mysql.spider_table_sts;
DROP TABLE IF EXISTS mysql.spider_table_crd;
-DROP SERVER s_2_1;
-DROP SERVER s_2_2;
-DROP SERVER s_2_3;
-DROP SERVER s_3_1;
-DROP SERVER s_3_2;
-DROP SERVER s_3_3;
+if ($VERSION_COMPILE_OS_WIN)
+{
+ if ($MASTER_1_MYPORT)
+ {
+ DROP SERVER s_1;
+ }
+ if ($CHILD2_1_MYPORT)
+ {
+ DROP SERVER s_2_1;
+ }
+ if ($CHILD2_2_MYPORT)
+ {
+ DROP SERVER s_2_2;
+ }
+ if ($CHILD2_3_MYPORT)
+ {
+ DROP SERVER s_2_3;
+ }
+ if ($CHILD3_1_MYPORT)
+ {
+ DROP SERVER s_3_1;
+ }
+ if ($CHILD3_2_MYPORT)
+ {
+ DROP SERVER s_3_2;
+ }
+ if ($CHILD2_3_MYPORT)
+ {
+ DROP SERVER s_3_3;
+ }
+}
+if (!$VERSION_COMPILE_OS_WIN)
+{
+ if ($MASTER_1_MYSOCK)
+ {
+ DROP SERVER s_1;
+ }
+ if ($CHILD2_1_MYSOCK)
+ {
+ DROP SERVER s_2_1;
+ }
+ if ($CHILD2_2_MYSOCK)
+ {
+ DROP SERVER s_2_2;
+ }
+ if ($CHILD2_3_MYSOCK)
+ {
+ DROP SERVER s_2_3;
+ }
+ if ($CHILD3_1_MYSOCK)
+ {
+ DROP SERVER s_3_1;
+ }
+ if ($CHILD3_2_MYSOCK)
+ {
+ DROP SERVER s_3_2;
+ }
+ if ($CHILD3_3_MYSOCK)
+ {
+ DROP SERVER s_3_3;
+ }
+}
diff --git a/storage/spider/mysql-test/spider/include/init_spider.inc b/storage/spider/mysql-test/spider/include/init_spider.inc
index 1da1ec970b5..2ca26f8edd3 100644
--- a/storage/spider/mysql-test/spider/include/init_spider.inc
+++ b/storage/spider/mysql-test/spider/include/init_spider.inc
@@ -3,104 +3,162 @@ let $VERSION_COMPILE_OS_WIN=
if ($VERSION_COMPILE_OS_WIN)
{
INSTALL PLUGIN spider SONAME 'ha_spider.dll';
+ INSTALL PLUGIN spider_alloc_mem SONAME 'ha_spider.dll';
CREATE FUNCTION spider_direct_sql RETURNS INT SONAME 'ha_spider.dll';
CREATE AGGREGATE FUNCTION spider_bg_direct_sql RETURNS INT SONAME 'ha_spider.dll';
CREATE FUNCTION spider_ping_table RETURNS INT SONAME 'ha_spider.dll';
CREATE FUNCTION spider_copy_tables RETURNS INT SONAME 'ha_spider.dll';
CREATE FUNCTION spider_flush_table_mon_cache RETURNS INT SONAME 'ha_spider.dll';
- eval CREATE SERVER s_2_1 FOREIGN DATA WRAPPER mysql OPTIONS (
- HOST 'localhost',
- DATABASE 'auto_test_remote',
- USER 'root',
- PASSWORD '',
- PORT $CHILD2_1_MYPORT
- );
- eval CREATE SERVER s_2_2 FOREIGN DATA WRAPPER mysql OPTIONS (
- HOST 'localhost',
- DATABASE 'auto_test_remote2',
- USER 'root',
- PASSWORD '',
- PORT $CHILD2_2_MYPORT
- );
- eval CREATE SERVER s_2_3 FOREIGN DATA WRAPPER mysql OPTIONS (
- HOST 'localhost',
- DATABASE 'auto_test_remote3',
- USER 'root',
- PASSWORD '',
- PORT $CHILD2_3_MYPORT
- );
- eval CREATE SERVER s_3_1 FOREIGN DATA WRAPPER mysql OPTIONS (
- HOST 'localhost',
- DATABASE 'auto_test_local',
- USER 'root',
- PASSWORD '',
- PORT $CHILD3_1_MYPORT
- );
- eval CREATE SERVER s_3_2 FOREIGN DATA WRAPPER mysql OPTIONS (
- HOST 'localhost',
- DATABASE 'auto_test_local',
- USER 'root',
- PASSWORD '',
- PORT $CHILD3_2_MYPORT
- );
- eval CREATE SERVER s_3_3 FOREIGN DATA WRAPPER mysql OPTIONS (
- HOST 'localhost',
- DATABASE 'auto_test_local',
- USER 'root',
- PASSWORD '',
- PORT $CHILD2_3_MYPORT
- );
+ 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 (
+ HOST 'localhost',
+ DATABASE 'auto_test_remote',
+ USER 'root',
+ PASSWORD '',
+ PORT $CHILD2_1_MYPORT
+ );
+ }
+ if ($CHILD2_2_MYPORT)
+ {
+ eval CREATE SERVER s_2_2 FOREIGN DATA WRAPPER mysql OPTIONS (
+ HOST 'localhost',
+ DATABASE 'auto_test_remote2',
+ USER 'root',
+ PASSWORD '',
+ PORT $CHILD2_2_MYPORT
+ );
+ }
+ if ($CHILD2_3_MYPORT)
+ {
+ eval CREATE SERVER s_2_3 FOREIGN DATA WRAPPER mysql OPTIONS (
+ HOST 'localhost',
+ DATABASE 'auto_test_remote3',
+ USER 'root',
+ PASSWORD '',
+ PORT $CHILD2_3_MYPORT
+ );
+ }
+ if ($CHILD3_1_MYPORT)
+ {
+ eval CREATE SERVER s_3_1 FOREIGN DATA WRAPPER mysql OPTIONS (
+ HOST 'localhost',
+ DATABASE 'auto_test_local',
+ USER 'root',
+ PASSWORD '',
+ PORT $CHILD3_1_MYPORT
+ );
+ }
+ if ($CHILD3_2_MYPORT)
+ {
+ eval CREATE SERVER s_3_2 FOREIGN DATA WRAPPER mysql OPTIONS (
+ HOST 'localhost',
+ DATABASE 'auto_test_local',
+ USER 'root',
+ PASSWORD '',
+ PORT $CHILD3_2_MYPORT
+ );
+ }
+ if ($CHILD2_3_MYPORT)
+ {
+ eval CREATE SERVER s_3_3 FOREIGN DATA WRAPPER mysql OPTIONS (
+ HOST 'localhost',
+ DATABASE 'auto_test_local',
+ USER 'root',
+ PASSWORD '',
+ PORT $CHILD2_3_MYPORT
+ );
+ }
}
if (!$VERSION_COMPILE_OS_WIN)
{
INSTALL PLUGIN spider SONAME 'ha_spider.so';
+ INSTALL PLUGIN spider_alloc_mem SONAME 'ha_spider.so';
CREATE FUNCTION spider_direct_sql RETURNS INT SONAME 'ha_spider.so';
CREATE AGGREGATE FUNCTION spider_bg_direct_sql RETURNS INT SONAME 'ha_spider.so';
CREATE FUNCTION spider_ping_table RETURNS INT SONAME 'ha_spider.so';
CREATE FUNCTION spider_copy_tables RETURNS INT SONAME 'ha_spider.so';
CREATE FUNCTION spider_flush_table_mon_cache RETURNS INT SONAME 'ha_spider.so';
- eval CREATE SERVER s_2_1 FOREIGN DATA WRAPPER mysql OPTIONS (
- HOST 'localhost',
- DATABASE 'auto_test_remote',
- USER 'root',
- PASSWORD '',
- SOCKET '$CHILD2_1_MYSOCK'
- );
- eval CREATE SERVER s_2_2 FOREIGN DATA WRAPPER mysql OPTIONS (
- HOST 'localhost',
- DATABASE 'auto_test_remote2',
- USER 'root',
- PASSWORD '',
- SOCKET '$CHILD2_2_MYSOCK'
- );
- eval CREATE SERVER s_2_3 FOREIGN DATA WRAPPER mysql OPTIONS (
- HOST 'localhost',
- DATABASE 'auto_test_remote3',
- USER 'root',
- PASSWORD '',
- SOCKET '$CHILD2_3_MYSOCK'
- );
- eval CREATE SERVER s_3_1 FOREIGN DATA WRAPPER mysql OPTIONS (
- HOST 'localhost',
- DATABASE 'auto_test_local',
- USER 'root',
- PASSWORD '',
- SOCKET '$CHILD3_1_MYSOCK'
- );
- eval CREATE SERVER s_3_2 FOREIGN DATA WRAPPER mysql OPTIONS (
- HOST 'localhost',
- DATABASE 'auto_test_local',
- USER 'root',
- PASSWORD '',
- SOCKET '$CHILD3_2_MYSOCK'
- );
- eval CREATE SERVER s_3_3 FOREIGN DATA WRAPPER mysql OPTIONS (
- HOST 'localhost',
- DATABASE 'auto_test_local',
- USER 'root',
- PASSWORD '',
- SOCKET '$CHILD3_3_MYSOCK'
- );
+ 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 (
+ HOST 'localhost',
+ DATABASE 'auto_test_remote',
+ USER 'root',
+ PASSWORD '',
+ SOCKET '$CHILD2_1_MYSOCK'
+ );
+ }
+ if ($CHILD2_2_MYSOCK)
+ {
+ eval CREATE SERVER s_2_2 FOREIGN DATA WRAPPER mysql OPTIONS (
+ HOST 'localhost',
+ DATABASE 'auto_test_remote2',
+ USER 'root',
+ PASSWORD '',
+ SOCKET '$CHILD2_2_MYSOCK'
+ );
+ }
+ if ($CHILD2_3_MYSOCK)
+ {
+ eval CREATE SERVER s_2_3 FOREIGN DATA WRAPPER mysql OPTIONS (
+ HOST 'localhost',
+ DATABASE 'auto_test_remote3',
+ USER 'root',
+ PASSWORD '',
+ SOCKET '$CHILD2_3_MYSOCK'
+ );
+ }
+ if ($CHILD3_1_MYSOCK)
+ {
+ eval CREATE SERVER s_3_1 FOREIGN DATA WRAPPER mysql OPTIONS (
+ HOST 'localhost',
+ DATABASE 'auto_test_local',
+ USER 'root',
+ PASSWORD '',
+ SOCKET '$CHILD3_1_MYSOCK'
+ );
+ }
+ if ($CHILD3_2_MYSOCK)
+ {
+ eval CREATE SERVER s_3_2 FOREIGN DATA WRAPPER mysql OPTIONS (
+ HOST 'localhost',
+ DATABASE 'auto_test_local',
+ USER 'root',
+ PASSWORD '',
+ SOCKET '$CHILD3_2_MYSOCK'
+ );
+ }
+ if ($CHILD3_3_MYSOCK)
+ {
+ eval CREATE SERVER s_3_3 FOREIGN DATA WRAPPER mysql OPTIONS (
+ HOST 'localhost',
+ DATABASE 'auto_test_local',
+ USER 'root',
+ PASSWORD '',
+ SOCKET '$CHILD3_3_MYSOCK'
+ );
+ }
}
let $SERVER_NAME=
diff --git a/storage/spider/mysql-test/spider/r/slave_trx_isolation.result b/storage/spider/mysql-test/spider/r/slave_trx_isolation.result
index 4fd2e71d3f2..6ea4e91f631 100644
--- a/storage/spider/mysql-test/spider/r/slave_trx_isolation.result
+++ b/storage/spider/mysql-test/spider/r/slave_trx_isolation.result
@@ -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;start transaction
SELECT argument FROM mysql.general_log WHERE argument LIKE '%set %'
diff --git a/storage/spider/mysql-test/spider/t/slave_trx_isolation.test b/storage/spider/mysql-test/spider/t/slave_trx_isolation.test
index 507e5340779..f7f41358f51 100644
--- a/storage/spider/mysql-test/spider/t/slave_trx_isolation.test
+++ b/storage/spider/mysql-test/spider/t/slave_trx_isolation.test
@@ -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;
diff --git a/storage/spider/spd_conn.cc b/storage/spider/spd_conn.cc
index 9e1dbaf7f28..ac4ab9e8366 100644
--- a/storage/spider/spd_conn.cc
+++ b/storage/spider/spd_conn.cc
@@ -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_utf8_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;
@@ -142,6 +145,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(&conn->loop_checked, spd_charset_utf8_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(&conn->loop_check_queue, spd_charset_utf8_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
@@ -179,7 +278,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(
@@ -195,6 +294,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();
@@ -733,6 +833,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;
@@ -784,12 +889,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;
@@ -1224,6 +1327,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->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);
@@ -1464,6 +1581,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->trx->thd;
+ TABLE_SHARE *top_share = spider->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
) {
diff --git a/storage/spider/spd_conn.h b/storage/spider/spd_conn.h
index ba4db883378..17f1118900a 100644
--- a/storage/spider/spd_conn.h
+++ b/storage/spider/spd_conn.h
@@ -22,6 +22,26 @@
#define SPIDER_BG_SIMPLE_DISCONNECT 2
#define SPIDER_BG_SIMPLE_RECORDS 3
+#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,
@@ -34,6 +54,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
@@ -146,6 +174,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
);
diff --git a/storage/spider/spd_db_conn.cc b/storage/spider/spd_db_conn.cc
index 97a4d362944..18a85172052 100644
--- a/storage/spider/spd_db_conn.cc
+++ b/storage/spider/spd_db_conn.cc
@@ -396,6 +396,12 @@ int spider_db_conn_queue_action(
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() &&
(error_num = spider_dbton[conn->dbton_id].db_util->
@@ -479,6 +485,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 &&
conn->queued_trx_isolation_val != conn->trx_isolation &&
@@ -577,6 +590,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)
diff --git a/storage/spider/spd_db_include.cc b/storage/spider/spd_db_include.cc
index 2910aa97690..032d2ea067d 100644
--- a/storage/spider/spd_db_include.cc
+++ b/storage/spider/spd_db_include.cc
@@ -1,4 +1,5 @@
/* Copyright (C) 2018-2019 Kentoku Shiba
+ Copyright (C) 2018-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
@@ -31,6 +32,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
@@ -49,3 +51,62 @@ spider_db_conn::spider_db_conn(
DBUG_PRINT("info",("spider this=%p", this));
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);
+}
diff --git a/storage/spider/spd_db_include.h b/storage/spider/spd_db_include.h
index 325bf80a1e3..ce95c4132ee 100644
--- a/storage/spider/spd_db_include.h
+++ b/storage/spider/spd_db_include.h
@@ -94,6 +94,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)
@@ -206,6 +208,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)
@@ -850,6 +855,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;
@@ -1155,6 +1164,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,
diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc
index 6a0aef4bafb..b3e223fc981 100644
--- a/storage/spider/spd_db_mysql.cc
+++ b/storage/spider/spd_db_mysql.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2012-2018 Kentoku Shiba
+/* Copyright (C) 2012-2019 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
@@ -94,6 +94,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"
@@ -2175,19 +2178,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);
@@ -2213,7 +2220,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 */
}
@@ -2225,17 +2232,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]));
+ int res_num =
+ (int) 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);
@@ -2247,7 +2269,7 @@ void spider_db_mbase::print_warnings(
}
}
}
- DBUG_VOID_RETURN;
+ DBUG_RETURN(error_num);
}
spider_db_result *spider_db_mbase::store_result(
@@ -2819,6 +2841,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,
@@ -3802,6 +3917,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
) {
@@ -12430,6 +12586,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->records = (ha_rows) share->static_records_for_status;
diff --git a/storage/spider/spd_db_mysql.h b/storage/spider/spd_db_mysql.h
index ff7ebc32bd9..ccbb51e2163 100644
--- a/storage/spider/spd_db_mysql.h
+++ b/storage/spider/spd_db_mysql.h
@@ -72,6 +72,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
);
@@ -400,7 +404,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(
@@ -480,6 +484,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,
diff --git a/storage/spider/spd_direct_sql.cc b/storage/spider/spd_direct_sql.cc
index 7237d0877a7..66367effe18 100644
--- a/storage/spider/spd_direct_sql.cc
+++ b/storage/spider/spd_direct_sql.cc
@@ -593,6 +593,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);
@@ -646,8 +651,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;
diff --git a/storage/spider/spd_environ.h b/storage/spider/spd_environ.h
index 42cbf812bbb..5e7687074b7 100644
--- a/storage/spider/spd_environ.h
+++ b/storage/spider/spd_environ.h
@@ -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
@@ -51,5 +52,6 @@
#define SPIDER_USE_CONST_ITEM_FOR_STRING_INT_REAL_DECIMAL_DATE_ITEM
#define SPIDER_SQL_CACHE_IS_IN_LEX
#define SPIDER_LIKE_FUNC_HAS_GET_NEGATED
+#define HA_HAS_CHECKSUM_EXTENDED
#endif
#endif /* SPD_ENVIRON_INCLUDED */
diff --git a/storage/spider/spd_err.h b/storage/spider/spd_err.h
index a80d903bd6e..bc13e03649b 100644
--- a/storage/spider/spd_err.h
+++ b/storage/spider/spd_err.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 2008-2017 Kentoku Shiba
+/* Copyright (C) 2008-2019 Kentoku Shiba
+ Copyright (C) 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
@@ -124,6 +125,21 @@
#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_NOT_SUPPORTED_NUM 12715
+#define ER_SPIDER_NOT_SUPPORTED_STR "%s is not supported by %s"
+#define ER_SPIDER_INVALID_VALUE_NUM 12716
+#define ER_SPIDER_INVALID_VALUE_STR "Invalid value %s in %s.%s"
+#define ER_SPIDER_SYNTAX_NUM 12717
+#define ER_SPIDER_SYNTAX_STR "%s detected a syntax error near '%-.80s' at line %d"
+#define ER_SPIDER_TOO_LONG_NUM 12718
+#define ER_SPIDER_TOO_LONG_STR "%s is too long"
+#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
diff --git a/storage/spider/spd_include.h b/storage/spider/spd_include.h
index 2886ea02ba4..6b0bb8ef161 100644
--- a/storage/spider/spd_include.h
+++ b/storage/spider/spd_include.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008-2018 Kentoku Shiba
+/* Copyright (C) 2008-2019 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
@@ -260,7 +260,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 265
+#define SPIDER_MEM_CALC_LIST_NUM 273
#define SPIDER_CONN_META_BUF_LEN 64
#define SPIDER_BACKUP_DASTATUS \
@@ -410,6 +410,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
{
@@ -597,6 +599,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
diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc
index 97c42189736..178ef33df3e 100644
--- a/storage/spider/spd_table.cc
+++ b/storage/spider/spd_table.cc
@@ -1,4 +1,5 @@
-/* Copyright (C) 2008-2018 Kentoku Shiba
+/* Copyright (C) 2008-2019 Kentoku Shiba
+ Copyright (C) 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
@@ -188,6 +189,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[]=
{
@@ -238,6 +240,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
@@ -396,6 +399,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,
@@ -4583,7 +4589,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;
@@ -4618,13 +4624,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->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(
@@ -5207,6 +5260,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
@@ -5520,6 +5574,7 @@ SPIDER_SHARE *spider_get_share(
spider->dbton_handler[dbton_id] = NULL;
}
}
+ spider_free_share(share);
goto error_but_no_delete;
}
@@ -6864,8 +6919,9 @@ int spider_panic(
int spider_db_init(
void *p
) {
- int error_num, roop_count;
+ 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;
@@ -6908,6 +6964,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));
@@ -8474,8 +8540,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(
@@ -9761,6 +9846,7 @@ int spider_create_spider_object_for_share(
#endif
(*spider)->dbton_handler = dbton_hdl;
(*spider)->search_link_idx = -1;
+ (*spider)->top_share = NULL;
for (roop_count = 0; roop_count < SPIDER_DBTON_SIZE; roop_count++)
{
if (