mariadb/storage/spider/spd_trx.cc

3922 lines
121 KiB
C++
Raw Normal View History

/* Copyright (C) 2008-2019 Kentoku Shiba
Copyright (C) 2019 MariaDB corp
2013-06-27 13:18:48 +02:00
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
2019-05-11 21:19:05 +02:00
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
2013-06-27 13:18:48 +02:00
#define MYSQL_SERVER 1
#include <my_global.h>
2013-06-27 13:18:48 +02:00
#include "mysql_version.h"
#include "sql_priv.h"
#include "probes_mysql.h"
#include "sql_class.h"
#include "sql_partition.h"
#include "records.h"
#include "spd_err.h"
#include "spd_param.h"
#include "spd_db_include.h"
#include "spd_include.h"
#include "spd_sys_table.h"
#include "ha_spider.h"
#include "spd_trx.h"
#include "spd_db_conn.h"
#include "spd_table.h"
#include "spd_conn.h"
#include "spd_ping_table.h"
#include "spd_malloc.h"
2015-10-28 23:34:53 +01:00
#ifdef SPIDER_XID_USES_xid_cache_iterate
#else
2014-03-24 20:40:46 +01:00
#ifdef XID_CACHE_IS_SPLITTED
extern uint *spd_db_att_xid_cache_split_num;
#endif
2013-06-27 13:18:48 +02:00
extern pthread_mutex_t *spd_db_att_LOCK_xid_cache;
extern HASH *spd_db_att_xid_cache;
2015-10-28 23:34:53 +01:00
#endif
extern struct charset_info_st *spd_charset_utf8mb3_bin;
2013-06-27 13:18:48 +02:00
extern handlerton *spider_hton_ptr;
2014-03-24 21:33:41 +01:00
extern SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE];
2013-06-27 13:18:48 +02:00
pthread_mutex_t spider_thread_id_mutex;
MDEV-33661 MENT-1591 Keep spider in memory until exit in ASAN builds Same as MDEV-29579. For some reason, libodbc does not clean up properly if unloaded too early with the dlclose() of spider. So we add UNIQUE symbols to spider so the spider does not reload in dlclose(). This change, however, uncovers some hidden problems in the spider codebase, for which we move the initialisation of some spider global variables into the initialisation of spider itself. Spider has some global variables. Their initialisation should be done in the initialisation of spider itself, otherwise, if spider were re-initialised without these symbol being unloaded, the values could be inconsistent and causing issues. One such issue is caused by the variables spider_mon_table_cache_version and spider_mon_table_cache_version_req. They are used for resetting the spider monitoring table cache and have initial values of 0 and 1 respectively. We have that always spider_mon_table_cache_version_req >= spider_mon_table_cache_version, and when the relation is strict, the cache is reset, spider_mon_table_cache_version is brought to be equal to spider_mon_table_cache_version_req, and the cache is searched for matching table_name, db_name and link_idx. If the relation is equal, no reset would happen and the cache would be searched directly. When spider is re-inited without resetting the values of spider_mon_table_cache_version and spider_mon_table_cache_version_req that were set to be equal in the previous cache reset action, the cache was emptied in the previous spider deinit, which would result in HA_ERR_KEY_NOT_FOUND unexpectedly. An alternative way to fix this issue would be to call the spider udf spider_flush_mon_cache_table(), which increments spider_mon_table_cache_version_req thus making sure the inequality is strict. However, there's no reason for spider to initialise these global variables on dlopen(), rather than on spider init, which is cleaner and "purer". To reproduce this issue, simply revert the changes involving the two variables and then run: mtr --no-reorder spider.ha{,_part}
2024-03-13 03:11:15 +01:00
ulonglong spider_thread_id;
2013-06-27 13:18:48 +02:00
#ifdef HAVE_PSI_INTERFACE
extern PSI_mutex_key spd_key_mutex_udf_table;
#endif
extern HASH spider_allocated_thds;
extern uint spider_allocated_thds_id;
extern const char *spider_allocated_thds_func_name;
extern const char *spider_allocated_thds_file_name;
extern ulong spider_allocated_thds_line_no;
extern pthread_mutex_t spider_allocated_thds_mutex;
// for spider_alter_tables
const uchar *spider_alter_tbl_get_key(
const void *alter_table_,
2013-06-27 13:18:48 +02:00
size_t *length,
my_bool
2013-06-27 13:18:48 +02:00
) {
auto alter_table= static_cast<const SPIDER_ALTER_TABLE *>(alter_table_);
2013-06-27 13:18:48 +02:00
DBUG_ENTER("spider_alter_tbl_get_key");
*length = alter_table->table_name_length;
DBUG_PRINT("info",("spider table_name_length=%zu", *length));
DBUG_PRINT("info",("spider table_name=%s", alter_table->table_name));
DBUG_RETURN(reinterpret_cast<const uchar *>(alter_table->table_name));
2013-06-27 13:18:48 +02:00
}
// for SPIDER_TRX_HA
const uchar *spider_trx_ha_get_key(
const void *trx_ha_,
2013-06-27 13:18:48 +02:00
size_t *length,
my_bool
2013-06-27 13:18:48 +02:00
) {
auto trx_ha= static_cast<const SPIDER_TRX_HA *>(trx_ha_);
2013-06-27 13:18:48 +02:00
DBUG_ENTER("spider_trx_ha_get_key");
*length = trx_ha->table_name_length;
DBUG_PRINT("info",("spider table_name_length=%zu", *length));
DBUG_PRINT("info",("spider table_name=%s", trx_ha->table_name));
DBUG_RETURN(reinterpret_cast<const uchar *>(trx_ha->table_name));
2013-06-27 13:18:48 +02:00
}
/*
Try to free the connections held by the given transaction.
*/
int spider_free_trx_conn(SPIDER_TRX *trx, bool trx_free)
{
int loop_count= 0;
2013-06-27 13:18:48 +02:00
SPIDER_CONN *conn;
HASH *conn_hash= &trx->trx_conn_hash;
2013-06-27 13:18:48 +02:00
DBUG_ENTER("spider_free_trx_conn");
/* Clear the connection queues in any case. */
while ((conn= (SPIDER_CONN *) my_hash_element(conn_hash, loop_count)))
{
spider_conn_clear_queue_at_commit(conn);
loop_count++;
2013-06-27 13:18:48 +02:00
}
if (trx_free || spider_param_conn_recycle_mode(trx->thd) != 2)
{
loop_count= 0;
while ((conn= (SPIDER_CONN *) my_hash_element(&trx->trx_conn_hash,
loop_count)))
2013-06-27 13:18:48 +02:00
{
if (conn->table_lock)
{
DBUG_ASSERT(!trx_free);
loop_count++;
}
else
2013-06-27 13:18:48 +02:00
{
spider_free_conn_from_trx(trx, conn, FALSE, trx_free, &loop_count);
}
2013-06-27 13:18:48 +02:00
}
trx->trx_conn_adjustment++;
DBUG_RETURN(0);
2013-06-27 13:18:48 +02:00
}
loop_count= 0;
while ((conn= (SPIDER_CONN *) my_hash_element(conn_hash, loop_count)))
2013-06-27 13:18:48 +02:00
{
if (!conn->table_lock)
2013-06-27 13:18:48 +02:00
{
conn->error_mode= 1;
2013-06-27 13:18:48 +02:00
}
loop_count++;
2013-06-27 13:18:48 +02:00
}
2013-06-27 13:18:48 +02:00
DBUG_RETURN(0);
}
int spider_free_trx_another_conn(
SPIDER_TRX *trx,
bool lock
) {
int error_num, tmp_error_num;
2014-03-24 21:33:41 +01:00
int roop_count = 0;
2013-06-27 13:18:48 +02:00
SPIDER_CONN *conn;
DBUG_ENTER("spider_free_trx_another_conn");
2014-03-24 21:33:41 +01:00
trx->tmp_spider->conns = &conn;
2013-06-27 13:18:48 +02:00
error_num = 0;
while ((conn = (SPIDER_CONN*) my_hash_element(&trx->trx_another_conn_hash,
roop_count)))
{
2014-03-24 21:33:41 +01:00
if (lock && (tmp_error_num = spider_db_unlock_tables(trx->tmp_spider, 0)))
2013-06-27 13:18:48 +02:00
error_num = tmp_error_num;
spider_free_conn_from_trx(trx, conn, TRUE, TRUE, &roop_count);
}
DBUG_RETURN(error_num);
}
int spider_trx_another_lock_tables(
SPIDER_TRX *trx
) {
int error_num;
int roop_count = 0, need_mon = 0;
THD *thd = trx->thd;
SPIDER_CONN *conn;
ha_spider tmp_spider;
SPIDER_SHARE tmp_share;
SPIDER_WIDE_HANDLER tmp_wide_handler;
2013-06-27 13:18:48 +02:00
char sql_buf[MAX_FIELD_WIDTH];
spider_string sql_str(sql_buf, sizeof(sql_buf), system_charset_info);
DBUG_ENTER("spider_trx_another_lock_tables");
SPIDER_BACKUP_DASTATUS;
sql_str.init_calc_mem(SPD_MID_TRX_ANOTHER_LOCK_TABLES_1);
2013-06-27 13:18:48 +02:00
sql_str.length(0);
2014-03-24 21:32:12 +01:00
memset((void*)&tmp_spider, 0, sizeof(ha_spider));
2019-03-16 16:03:54 +01:00
memset((void*)&tmp_share, 0, sizeof(SPIDER_SHARE));
memset((void*)&tmp_wide_handler, 0, sizeof(SPIDER_WIDE_HANDLER));
2013-06-27 13:18:48 +02:00
tmp_spider.share = &tmp_share;
tmp_spider.wide_handler = &tmp_wide_handler;
tmp_wide_handler.trx = trx;
2013-06-27 13:18:48 +02:00
tmp_share.access_charset = system_charset_info;
tmp_spider.conns = &conn;
tmp_spider.result_list.sqls = &sql_str;
tmp_spider.need_mons = &need_mon;
while ((conn = (SPIDER_CONN*) my_hash_element(&trx->trx_another_conn_hash,
roop_count)))
{
if ((error_num = spider_db_lock_tables(&tmp_spider, 0)))
{
SPIDER_CONN_RESTORE_DASTATUS_AND_RESET_ERROR_NUM;
if (error_num)
{
DBUG_RETURN(error_num);
}
}
roop_count++;
}
DBUG_RETURN(0);
}
int spider_trx_another_flush_tables(
SPIDER_TRX *trx
) {
int error_num;
int roop_count = 0, need_mon = 0;
THD *thd = trx->thd;
SPIDER_CONN *conn;
ha_spider tmp_spider;
SPIDER_SHARE tmp_share;
long tmp_link_statuses = SPIDER_LINK_STATUS_OK;
DBUG_ENTER("spider_trx_another_flush_tables");
SPIDER_BACKUP_DASTATUS;
2014-03-24 21:32:12 +01:00
memset((void*)&tmp_spider, 0, sizeof(ha_spider));
2013-06-27 13:18:48 +02:00
tmp_share.link_count = 1;
tmp_share.all_link_count = 1;
tmp_share.link_statuses = &tmp_link_statuses;
tmp_share.link_statuses_length = 1;
tmp_spider.share = &tmp_share;
tmp_spider.conns = &conn;
tmp_spider.need_mons = &need_mon;
while ((conn = (SPIDER_CONN*) my_hash_element(&trx->trx_another_conn_hash,
roop_count)))
{
if ((error_num = spider_db_flush_tables(&tmp_spider, FALSE)))
{
SPIDER_CONN_RESTORE_DASTATUS_AND_RESET_ERROR_NUM;
if (error_num)
DBUG_RETURN(error_num);
}
roop_count++;
}
DBUG_RETURN(0);
}
int spider_trx_all_flush_tables(
SPIDER_TRX *trx
) {
int error_num;
int roop_count = 0, need_mon = 0;
THD *thd = trx->thd;
SPIDER_CONN *conn;
ha_spider tmp_spider;
SPIDER_SHARE tmp_share;
long tmp_link_statuses = SPIDER_LINK_STATUS_OK;
DBUG_ENTER("spider_trx_all_flush_tables");
SPIDER_BACKUP_DASTATUS;
2014-03-24 21:32:12 +01:00
memset((void*)&tmp_spider, 0, sizeof(ha_spider));
2013-06-27 13:18:48 +02:00
tmp_share.link_count = 1;
tmp_share.all_link_count = 1;
tmp_share.link_statuses = &tmp_link_statuses;
tmp_share.link_statuses_length = 1;
tmp_spider.share = &tmp_share;
tmp_spider.conns = &conn;
tmp_spider.need_mons = &need_mon;
while ((conn = (SPIDER_CONN*) my_hash_element(&trx->trx_conn_hash,
roop_count)))
{
if ((error_num = spider_db_flush_tables(&tmp_spider, TRUE)))
{
SPIDER_CONN_RESTORE_DASTATUS_AND_RESET_ERROR_NUM;
if (error_num)
DBUG_RETURN(error_num);
}
roop_count++;
}
DBUG_RETURN(0);
}
int spider_trx_all_unlock_tables(
SPIDER_TRX *trx
) {
int error_num;
2014-03-24 21:33:41 +01:00
int roop_count = 0;
2013-06-27 13:18:48 +02:00
THD *thd = trx->thd;
SPIDER_CONN *conn;
DBUG_ENTER("spider_trx_all_unlock_tables");
SPIDER_BACKUP_DASTATUS;
2014-03-24 21:33:41 +01:00
trx->tmp_spider->conns = &conn;
2013-06-27 13:18:48 +02:00
while ((conn = (SPIDER_CONN*) my_hash_element(&trx->trx_conn_hash,
roop_count)))
{
2014-03-24 21:33:41 +01:00
if ((error_num = spider_db_unlock_tables(trx->tmp_spider, 0)))
2013-06-27 13:18:48 +02:00
{
SPIDER_CONN_RESTORE_DASTATUS_AND_RESET_ERROR_NUM;
if (error_num)
DBUG_RETURN(error_num);
}
roop_count++;
}
DBUG_RETURN(0);
}
int spider_trx_all_start_trx(
SPIDER_TRX *trx
) {
int error_num, need_mon = 0;
int roop_count = 0;
THD *thd = trx->thd;
SPIDER_CONN *conn;
ha_spider tmp_spider;
SPIDER_WIDE_HANDLER tmp_wide_handler;
2013-06-27 13:18:48 +02:00
DBUG_ENTER("spider_trx_all_start_trx");
SPIDER_BACKUP_DASTATUS;
2014-03-24 21:32:12 +01:00
memset((void*)&tmp_spider, 0, sizeof(ha_spider));
memset(&tmp_wide_handler, 0, sizeof(SPIDER_WIDE_HANDLER));
tmp_spider.wide_handler = &tmp_wide_handler;
tmp_wide_handler.trx = trx;
2013-06-27 13:18:48 +02:00
tmp_spider.need_mons = &need_mon;
while ((conn = (SPIDER_CONN*) my_hash_element(&trx->trx_conn_hash,
roop_count)))
{
if (
(spider_param_sync_trx_isolation(trx->thd) &&
(error_num = spider_check_and_set_trx_isolation(conn, &need_mon))) ||
(error_num = spider_internal_start_trx_for_connection(&tmp_spider,
conn, 0))
2013-06-27 13:18:48 +02:00
) {
SPIDER_CONN_RESTORE_DASTATUS_AND_RESET_ERROR_NUM;
if (error_num)
DBUG_RETURN(error_num);
}
roop_count++;
}
DBUG_RETURN(0);
}
int spider_trx_all_flush_logs(
SPIDER_TRX *trx
) {
int error_num;
int roop_count = 0, need_mon = 0;
THD *thd = trx->thd;
SPIDER_CONN *conn;
ha_spider tmp_spider;
SPIDER_SHARE tmp_share;
SPIDER_WIDE_HANDLER tmp_wide_handler;
2013-06-27 13:18:48 +02:00
long tmp_link_statuses = SPIDER_LINK_STATUS_OK;
uint conn_link_idx = 0;
long net_read_timeout = 600;
long net_write_timeout = 600;
DBUG_ENTER("spider_trx_all_flush_logs");
SPIDER_BACKUP_DASTATUS;
2014-03-24 21:32:12 +01:00
memset((void*)&tmp_spider, 0, sizeof(ha_spider));
memset(&tmp_wide_handler, 0, sizeof(SPIDER_WIDE_HANDLER));
2013-06-27 13:18:48 +02:00
tmp_share.link_count = 1;
tmp_share.all_link_count = 1;
tmp_share.link_statuses = &tmp_link_statuses;
tmp_share.link_statuses_length = 1;
tmp_share.net_read_timeouts = &net_read_timeout;
tmp_share.net_read_timeouts_length = 1;
tmp_share.net_write_timeouts = &net_write_timeout;
tmp_share.net_write_timeouts_length = 1;
tmp_spider.share = &tmp_share;
tmp_spider.conns = &conn;
tmp_spider.need_mons = &need_mon;
tmp_spider.conn_link_idx = &conn_link_idx;
tmp_spider.wide_handler = &tmp_wide_handler;
tmp_wide_handler.trx = trx;
2013-06-27 13:18:48 +02:00
while ((conn = (SPIDER_CONN*) my_hash_element(&trx->trx_conn_hash,
roop_count)))
{
if ((error_num = spider_db_flush_logs(&tmp_spider)))
{
SPIDER_CONN_RESTORE_DASTATUS_AND_RESET_ERROR_NUM;
if (error_num)
DBUG_RETURN(error_num);
}
roop_count++;
}
DBUG_RETURN(0);
}
void spider_free_trx_alter_table_alloc(
SPIDER_TRX *trx,
SPIDER_ALTER_TABLE *alter_table
) {
DBUG_ENTER("spider_free_trx_alter_table_alloc");
my_hash_delete(&trx->trx_alter_table_hash, (uchar*) alter_table);
if (alter_table->tmp_char)
spider_free(trx, alter_table->tmp_char, MYF(0));
spider_free(trx, alter_table, MYF(0));
DBUG_VOID_RETURN;
}
int spider_free_trx_alter_table(
SPIDER_TRX *trx
) {
SPIDER_ALTER_TABLE *alter_table;
DBUG_ENTER("spider_free_trx_alter_table");
while ((alter_table =
(SPIDER_ALTER_TABLE*) my_hash_element(&trx->trx_alter_table_hash, 0)))
{
spider_free_trx_alter_table_alloc(trx, alter_table);
}
DBUG_RETURN(0);
}
/** Copy a string from one array to another */
static inline void spider_maybe_memcpy_indexed_string(
char **dests,
char **srcs,
const uint* lengths,
const int idx,
char *&ptr)
{
if (size_t len= sizeof(char) * lengths[idx])
{
dests[idx]= ptr;
memcpy(ptr, srcs[idx], len);
ptr+= len + 1;
}
}
2013-06-27 13:18:48 +02:00
int spider_create_trx_alter_table(
SPIDER_TRX *trx,
SPIDER_SHARE *share,
bool now_create
) {
int error_num, link_idx;
2013-06-27 13:18:48 +02:00
SPIDER_ALTER_TABLE *alter_table, *share_alter;
char *tmp_name;
char **tmp_server_names;
char **tmp_tgt_table_names;
char **tmp_tgt_dbs;
char **tmp_tgt_hosts;
char **tmp_tgt_usernames;
char **tmp_tgt_passwords;
char **tmp_tgt_sockets;
char **tmp_tgt_wrappers;
char **tmp_tgt_ssl_cas;
char **tmp_tgt_ssl_capaths;
char **tmp_tgt_ssl_certs;
char **tmp_tgt_ssl_ciphers;
char **tmp_tgt_ssl_keys;
char **tmp_tgt_default_files;
char **tmp_tgt_default_groups;
2020-03-22 01:36:37 +01:00
char **tmp_tgt_dsns;
char **tmp_static_link_ids;
2013-06-27 13:18:48 +02:00
uint *tmp_server_names_lengths;
uint *tmp_tgt_table_names_lengths;
uint *tmp_tgt_dbs_lengths;
uint *tmp_tgt_hosts_lengths;
uint *tmp_tgt_usernames_lengths;
uint *tmp_tgt_passwords_lengths;
uint *tmp_tgt_sockets_lengths;
uint *tmp_tgt_wrappers_lengths;
uint *tmp_tgt_ssl_cas_lengths;
uint *tmp_tgt_ssl_capaths_lengths;
uint *tmp_tgt_ssl_certs_lengths;
uint *tmp_tgt_ssl_ciphers_lengths;
uint *tmp_tgt_ssl_keys_lengths;
uint *tmp_tgt_default_files_lengths;
uint *tmp_tgt_default_groups_lengths;
2020-03-22 01:36:37 +01:00
uint *tmp_tgt_dsns_lengths;
uint *tmp_static_link_ids_lengths;
2013-06-27 13:18:48 +02:00
long *tmp_tgt_ports;
long *tmp_tgt_ssl_vscs;
long *tmp_monitoring_binlog_pos_at_failing;
2013-06-27 13:18:48 +02:00
long *tmp_link_statuses;
char *tmp_server_names_char;
char *tmp_tgt_table_names_char;
char *tmp_tgt_dbs_char;
char *tmp_tgt_hosts_char;
char *tmp_tgt_usernames_char;
char *tmp_tgt_passwords_char;
char *tmp_tgt_sockets_char;
char *tmp_tgt_wrappers_char;
char *tmp_tgt_ssl_cas_char;
char *tmp_tgt_ssl_capaths_char;
char *tmp_tgt_ssl_certs_char;
char *tmp_tgt_ssl_ciphers_char;
char *tmp_tgt_ssl_keys_char;
char *tmp_tgt_default_files_char;
char *tmp_tgt_default_groups_char;
2020-03-22 01:36:37 +01:00
char *tmp_tgt_dsns_char;
char *tmp_static_link_ids_char;
2013-06-27 13:18:48 +02:00
uint old_elements;
DBUG_ENTER("spider_create_trx_alter_table");
share_alter = &share->alter_table;
if (!(alter_table = (SPIDER_ALTER_TABLE *)
spider_bulk_malloc(spider_current_trx, SPD_MID_CREATE_TRX_ALTER_TABLE_1, MYF(MY_WME | MY_ZEROFILL),
&alter_table, (uint) (sizeof(*alter_table)),
&tmp_name, (uint) (sizeof(char) * (share->table_name_length + 1)),
&tmp_server_names, (uint) (sizeof(char *) * share->all_link_count),
&tmp_tgt_table_names, (uint) (sizeof(char *) * share->all_link_count),
&tmp_tgt_dbs, (uint) (sizeof(char *) * share->all_link_count),
&tmp_tgt_hosts, (uint) (sizeof(char *) * share->all_link_count),
&tmp_tgt_usernames, (uint) (sizeof(char *) * share->all_link_count),
&tmp_tgt_passwords, (uint) (sizeof(char *) * share->all_link_count),
&tmp_tgt_sockets, (uint) (sizeof(char *) * share->all_link_count),
&tmp_tgt_wrappers, (uint) (sizeof(char *) * share->all_link_count),
&tmp_tgt_ssl_cas, (uint) (sizeof(char *) * share->all_link_count),
&tmp_tgt_ssl_capaths, (uint) (sizeof(char *) * share->all_link_count),
&tmp_tgt_ssl_certs, (uint) (sizeof(char *) * share->all_link_count),
&tmp_tgt_ssl_ciphers, (uint) (sizeof(char *) * share->all_link_count),
&tmp_tgt_ssl_keys, (uint) (sizeof(char *) * share->all_link_count),
&tmp_tgt_default_files, (uint) (sizeof(char *) * share->all_link_count),
&tmp_tgt_default_groups, (uint) (sizeof(char *) * share->all_link_count),
2020-03-22 01:36:37 +01:00
&tmp_tgt_dsns, (uint) (sizeof(char *) * share->all_link_count),
&tmp_static_link_ids, (uint) (sizeof(char *) * share->all_link_count),
&tmp_server_names_lengths, (uint) (sizeof(uint) * share->all_link_count),
&tmp_tgt_table_names_lengths,
(uint) (sizeof(uint) * share->all_link_count),
&tmp_tgt_dbs_lengths, (uint) (sizeof(uint) * share->all_link_count),
&tmp_tgt_hosts_lengths, (uint) (sizeof(uint) * share->all_link_count),
&tmp_tgt_usernames_lengths,
(uint) (sizeof(uint) * share->all_link_count),
&tmp_tgt_passwords_lengths,
(uint) (sizeof(uint) * share->all_link_count),
&tmp_tgt_sockets_lengths, (uint) (sizeof(uint) * share->all_link_count),
&tmp_tgt_wrappers_lengths, (uint) (sizeof(uint) * share->all_link_count),
&tmp_tgt_ssl_cas_lengths, (uint) (sizeof(uint) * share->all_link_count),
&tmp_tgt_ssl_capaths_lengths,
(uint) (sizeof(uint) * share->all_link_count),
&tmp_tgt_ssl_certs_lengths,
(uint) (sizeof(uint) * share->all_link_count),
&tmp_tgt_ssl_ciphers_lengths,
(uint) (sizeof(uint) * share->all_link_count),
&tmp_tgt_ssl_keys_lengths, (uint) (sizeof(uint) * share->all_link_count),
&tmp_tgt_default_files_lengths,
(uint) (sizeof(uint) * share->all_link_count),
&tmp_tgt_default_groups_lengths,
(uint) (sizeof(uint) * share->all_link_count),
2020-03-22 01:36:37 +01:00
&tmp_tgt_dsns_lengths, (uint) (sizeof(uint) * share->all_link_count),
&tmp_static_link_ids_lengths,
(uint) (sizeof(uint) * share->all_link_count),
&tmp_tgt_ports, (uint) (sizeof(long) * share->all_link_count),
&tmp_tgt_ssl_vscs, (uint) (sizeof(long) * share->all_link_count),
&tmp_monitoring_binlog_pos_at_failing,
(uint) (sizeof(long) * share->all_link_count),
&tmp_link_statuses, (uint) (sizeof(long) * share->all_link_count),
&tmp_server_names_char, (uint) (sizeof(char) *
(share_alter->tmp_server_names_charlen + 1)),
&tmp_tgt_table_names_char, (uint) (sizeof(char) *
(share_alter->tmp_tgt_table_names_charlen + 1)),
&tmp_tgt_dbs_char, (uint) (sizeof(char) *
(share_alter->tmp_tgt_dbs_charlen + 1)),
&tmp_tgt_hosts_char, (uint) (sizeof(char) *
(share_alter->tmp_tgt_hosts_charlen + 1)),
&tmp_tgt_usernames_char, (uint) (sizeof(char) *
(share_alter->tmp_tgt_usernames_charlen + 1)),
&tmp_tgt_passwords_char, (uint) (sizeof(char) *
(share_alter->tmp_tgt_passwords_charlen + 1)),
&tmp_tgt_sockets_char, (uint) (sizeof(char) *
(share_alter->tmp_tgt_sockets_charlen + 1)),
&tmp_tgt_wrappers_char, (uint) (sizeof(char) *
(share_alter->tmp_tgt_wrappers_charlen + 1)),
&tmp_tgt_ssl_cas_char, (uint) (sizeof(char) *
(share_alter->tmp_tgt_ssl_cas_charlen + 1)),
&tmp_tgt_ssl_capaths_char, (uint) (sizeof(char) *
(share_alter->tmp_tgt_ssl_capaths_charlen + 1)),
&tmp_tgt_ssl_certs_char, (uint) (sizeof(char) *
(share_alter->tmp_tgt_ssl_certs_charlen + 1)),
&tmp_tgt_ssl_ciphers_char, (uint) (sizeof(char) *
(share_alter->tmp_tgt_ssl_ciphers_charlen + 1)),
&tmp_tgt_ssl_keys_char, (uint) (sizeof(char) *
(share_alter->tmp_tgt_ssl_keys_charlen + 1)),
&tmp_tgt_default_files_char, (uint) (sizeof(char) *
(share_alter->tmp_tgt_default_files_charlen + 1)),
&tmp_tgt_default_groups_char, (uint) (sizeof(char) *
(share_alter->tmp_tgt_default_groups_charlen + 1)),
2020-03-22 01:36:37 +01:00
&tmp_tgt_dsns_char, (uint) (sizeof(char) *
(share_alter->tmp_tgt_dsns_charlen + 1)),
&tmp_static_link_ids_char, (uint) (sizeof(char) *
(share_alter->tmp_static_link_ids_charlen + 1)),
2013-06-27 13:18:48 +02:00
NullS))
) {
error_num = HA_ERR_OUT_OF_MEM;
goto error_alloc_alter_table;
}
alter_table->now_create = now_create;
alter_table->table_name = tmp_name;
memcpy(alter_table->table_name, share->table_name, share->table_name_length);
alter_table->table_name_length = share->table_name_length;
DBUG_PRINT("info",("spider table_name_hash_value=%u",
share->table_name_hash_value));
alter_table->table_name_hash_value = share->table_name_hash_value;
alter_table->tmp_priority = share->priority;
alter_table->link_count = share->link_count;
alter_table->all_link_count = share->all_link_count;
alter_table->tmp_server_names = tmp_server_names;
alter_table->tmp_tgt_table_names = tmp_tgt_table_names;
alter_table->tmp_tgt_dbs = tmp_tgt_dbs;
alter_table->tmp_tgt_hosts = tmp_tgt_hosts;
alter_table->tmp_tgt_usernames = tmp_tgt_usernames;
alter_table->tmp_tgt_passwords = tmp_tgt_passwords;
alter_table->tmp_tgt_sockets = tmp_tgt_sockets;
alter_table->tmp_tgt_wrappers = tmp_tgt_wrappers;
alter_table->tmp_tgt_ssl_cas = tmp_tgt_ssl_cas;
alter_table->tmp_tgt_ssl_capaths = tmp_tgt_ssl_capaths;
alter_table->tmp_tgt_ssl_certs = tmp_tgt_ssl_certs;
alter_table->tmp_tgt_ssl_ciphers = tmp_tgt_ssl_ciphers;
alter_table->tmp_tgt_ssl_keys = tmp_tgt_ssl_keys;
alter_table->tmp_tgt_default_files = tmp_tgt_default_files;
alter_table->tmp_tgt_default_groups = tmp_tgt_default_groups;
2020-03-22 01:36:37 +01:00
alter_table->tmp_tgt_dsns = tmp_tgt_dsns;
alter_table->tmp_static_link_ids = tmp_static_link_ids;
2013-06-27 13:18:48 +02:00
alter_table->tmp_tgt_ports = tmp_tgt_ports;
alter_table->tmp_tgt_ssl_vscs = tmp_tgt_ssl_vscs;
alter_table->tmp_monitoring_binlog_pos_at_failing =
tmp_monitoring_binlog_pos_at_failing;
2013-06-27 13:18:48 +02:00
alter_table->tmp_link_statuses = tmp_link_statuses;
alter_table->tmp_server_names_lengths = tmp_server_names_lengths;
alter_table->tmp_tgt_table_names_lengths = tmp_tgt_table_names_lengths;
alter_table->tmp_tgt_dbs_lengths = tmp_tgt_dbs_lengths;
alter_table->tmp_tgt_hosts_lengths = tmp_tgt_hosts_lengths;
alter_table->tmp_tgt_usernames_lengths = tmp_tgt_usernames_lengths;
alter_table->tmp_tgt_passwords_lengths = tmp_tgt_passwords_lengths;
alter_table->tmp_tgt_sockets_lengths = tmp_tgt_sockets_lengths;
alter_table->tmp_tgt_wrappers_lengths = tmp_tgt_wrappers_lengths;
alter_table->tmp_tgt_ssl_cas_lengths = tmp_tgt_ssl_cas_lengths;
alter_table->tmp_tgt_ssl_capaths_lengths = tmp_tgt_ssl_capaths_lengths;
alter_table->tmp_tgt_ssl_certs_lengths = tmp_tgt_ssl_certs_lengths;
alter_table->tmp_tgt_ssl_ciphers_lengths = tmp_tgt_ssl_ciphers_lengths;
alter_table->tmp_tgt_ssl_keys_lengths = tmp_tgt_ssl_keys_lengths;
alter_table->tmp_tgt_default_files_lengths = tmp_tgt_default_files_lengths;
alter_table->tmp_tgt_default_groups_lengths = tmp_tgt_default_groups_lengths;
2020-03-22 01:36:37 +01:00
alter_table->tmp_tgt_dsns_lengths = tmp_tgt_dsns_lengths;
alter_table->tmp_static_link_ids_lengths = tmp_static_link_ids_lengths;
2013-06-27 13:18:48 +02:00
for(link_idx = 0; link_idx < (int) share->all_link_count; link_idx++)
2013-06-27 13:18:48 +02:00
{
spider_maybe_memcpy_indexed_string(
tmp_server_names, share_alter->tmp_server_names,
share_alter->tmp_server_names_lengths, link_idx, tmp_server_names_char);
spider_maybe_memcpy_indexed_string(
tmp_tgt_table_names, share_alter->tmp_tgt_table_names,
share_alter->tmp_tgt_table_names_lengths, link_idx, tmp_tgt_table_names_char);
spider_maybe_memcpy_indexed_string(
tmp_tgt_dbs, share_alter->tmp_tgt_dbs,
share_alter->tmp_tgt_dbs_lengths, link_idx, tmp_tgt_dbs_char);
spider_maybe_memcpy_indexed_string(
tmp_tgt_hosts, share_alter->tmp_tgt_hosts,
share_alter->tmp_tgt_hosts_lengths, link_idx, tmp_tgt_hosts_char);
spider_maybe_memcpy_indexed_string(
tmp_tgt_usernames, share_alter->tmp_tgt_usernames,
share_alter->tmp_tgt_usernames_lengths, link_idx, tmp_tgt_usernames_char);
spider_maybe_memcpy_indexed_string(
tmp_tgt_passwords, share_alter->tmp_tgt_passwords,
share_alter->tmp_tgt_passwords_lengths, link_idx, tmp_tgt_passwords_char);
spider_maybe_memcpy_indexed_string(
tmp_tgt_sockets, share_alter->tmp_tgt_sockets,
share_alter->tmp_tgt_sockets_lengths, link_idx, tmp_tgt_sockets_char);
spider_maybe_memcpy_indexed_string(
tmp_tgt_wrappers, share_alter->tmp_tgt_wrappers,
share_alter->tmp_tgt_wrappers_lengths, link_idx, tmp_tgt_wrappers_char);
spider_maybe_memcpy_indexed_string(
tmp_tgt_ssl_cas, share_alter->tmp_tgt_ssl_cas,
share_alter->tmp_tgt_ssl_cas_lengths, link_idx, tmp_tgt_ssl_cas_char);
spider_maybe_memcpy_indexed_string(
tmp_tgt_ssl_capaths, share_alter->tmp_tgt_ssl_capaths,
share_alter->tmp_tgt_ssl_capaths_lengths, link_idx, tmp_tgt_ssl_capaths_char);
spider_maybe_memcpy_indexed_string(
tmp_tgt_ssl_certs, share_alter->tmp_tgt_ssl_certs,
share_alter->tmp_tgt_ssl_certs_lengths, link_idx, tmp_tgt_ssl_certs_char);
spider_maybe_memcpy_indexed_string(
tmp_tgt_ssl_ciphers, share_alter->tmp_tgt_ssl_ciphers,
share_alter->tmp_tgt_ssl_ciphers_lengths, link_idx, tmp_tgt_ssl_ciphers_char);
spider_maybe_memcpy_indexed_string(
tmp_tgt_ssl_keys, share_alter->tmp_tgt_ssl_keys,
share_alter->tmp_tgt_ssl_keys_lengths, link_idx, tmp_tgt_ssl_keys_char);
spider_maybe_memcpy_indexed_string(
tmp_tgt_default_files, share_alter->tmp_tgt_default_files,
share_alter->tmp_tgt_default_files_lengths, link_idx, tmp_tgt_default_files_char);
spider_maybe_memcpy_indexed_string(
tmp_tgt_default_groups, share_alter->tmp_tgt_default_groups,
share_alter->tmp_tgt_default_groups_lengths, link_idx, tmp_tgt_default_groups_char);
/* Notes on merge conflicts (remove this comment after merging):
for 10.6+ see d74103292c7be236f3da71c86249d37295f57bbc */
2023-07-20 11:54:52 +02:00
spider_maybe_memcpy_indexed_string(
tmp_tgt_dsns, share_alter->tmp_tgt_dsns,
share_alter->tmp_tgt_dsns_lengths, link_idx, tmp_tgt_dsns_char);
spider_maybe_memcpy_indexed_string(
tmp_static_link_ids, share_alter->tmp_static_link_ids,
share_alter->tmp_static_link_ids_lengths, link_idx, tmp_static_link_ids_char);
2013-06-27 13:18:48 +02:00
}
memcpy(tmp_tgt_ports, share_alter->tmp_tgt_ports,
sizeof(long) * share->all_link_count);
memcpy(tmp_tgt_ssl_vscs, share_alter->tmp_tgt_ssl_vscs,
sizeof(long) * share->all_link_count);
memcpy(tmp_monitoring_binlog_pos_at_failing,
share_alter->tmp_monitoring_binlog_pos_at_failing,
sizeof(long) * share->all_link_count);
2013-06-27 13:18:48 +02:00
memcpy(tmp_link_statuses, share_alter->tmp_link_statuses,
sizeof(long) * share->all_link_count);
memcpy(tmp_server_names_lengths, share_alter->tmp_server_names_lengths,
sizeof(uint) * share->all_link_count);
memcpy(tmp_tgt_table_names_lengths, share_alter->tmp_tgt_table_names_lengths,
sizeof(uint) * share->all_link_count);
memcpy(tmp_tgt_dbs_lengths, share_alter->tmp_tgt_dbs_lengths,
sizeof(uint) * share->all_link_count);
memcpy(tmp_tgt_hosts_lengths, share_alter->tmp_tgt_hosts_lengths,
sizeof(uint) * share->all_link_count);
memcpy(tmp_tgt_usernames_lengths, share_alter->tmp_tgt_usernames_lengths,
sizeof(uint) * share->all_link_count);
memcpy(tmp_tgt_passwords_lengths, share_alter->tmp_tgt_passwords_lengths,
sizeof(uint) * share->all_link_count);
memcpy(tmp_tgt_sockets_lengths, share_alter->tmp_tgt_sockets_lengths,
sizeof(uint) * share->all_link_count);
memcpy(tmp_tgt_wrappers_lengths, share_alter->tmp_tgt_wrappers_lengths,
sizeof(uint) * share->all_link_count);
memcpy(tmp_tgt_ssl_cas_lengths, share_alter->tmp_tgt_ssl_cas_lengths,
sizeof(uint) * share->all_link_count);
memcpy(tmp_tgt_ssl_capaths_lengths, share_alter->tmp_tgt_ssl_capaths_lengths,
sizeof(uint) * share->all_link_count);
memcpy(tmp_tgt_ssl_certs_lengths, share_alter->tmp_tgt_ssl_certs_lengths,
sizeof(uint) * share->all_link_count);
memcpy(tmp_tgt_ssl_ciphers_lengths, share_alter->tmp_tgt_ssl_ciphers_lengths,
sizeof(uint) * share->all_link_count);
memcpy(tmp_tgt_ssl_keys_lengths, share_alter->tmp_tgt_ssl_keys_lengths,
sizeof(uint) * share->all_link_count);
memcpy(tmp_tgt_default_files_lengths,
share_alter->tmp_tgt_default_files_lengths,
sizeof(uint) * share->all_link_count);
memcpy(tmp_tgt_default_groups_lengths,
share_alter->tmp_tgt_default_groups_lengths,
sizeof(uint) * share->all_link_count);
2020-03-22 01:36:37 +01:00
memcpy(tmp_tgt_dsns_lengths, share_alter->tmp_tgt_dsns_lengths,
sizeof(uint) * share->all_link_count);
memcpy(tmp_static_link_ids_lengths,
share_alter->tmp_static_link_ids_lengths,
sizeof(uint) * share->all_link_count);
2013-06-27 13:18:48 +02:00
alter_table->tmp_server_names_length =
share_alter->tmp_server_names_length;
alter_table->tmp_tgt_table_names_length =
share_alter->tmp_tgt_table_names_length;
alter_table->tmp_tgt_dbs_length =
share_alter->tmp_tgt_dbs_length;
alter_table->tmp_tgt_hosts_length =
share_alter->tmp_tgt_hosts_length;
alter_table->tmp_tgt_usernames_length =
share_alter->tmp_tgt_usernames_length;
alter_table->tmp_tgt_passwords_length =
share_alter->tmp_tgt_passwords_length;
alter_table->tmp_tgt_sockets_length =
share_alter->tmp_tgt_sockets_length;
alter_table->tmp_tgt_wrappers_length =
share_alter->tmp_tgt_wrappers_length;
alter_table->tmp_tgt_ssl_cas_length =
share_alter->tmp_tgt_ssl_cas_length;
alter_table->tmp_tgt_ssl_capaths_length =
share_alter->tmp_tgt_ssl_capaths_length;
alter_table->tmp_tgt_ssl_certs_length =
share_alter->tmp_tgt_ssl_certs_length;
alter_table->tmp_tgt_ssl_ciphers_length =
share_alter->tmp_tgt_ssl_ciphers_length;
alter_table->tmp_tgt_ssl_keys_length =
share_alter->tmp_tgt_ssl_keys_length;
alter_table->tmp_tgt_default_files_length =
share_alter->tmp_tgt_default_files_length;
alter_table->tmp_tgt_default_groups_length =
share_alter->tmp_tgt_default_groups_length;
2020-03-22 01:36:37 +01:00
alter_table->tmp_tgt_dsns_length =
share_alter->tmp_tgt_dsns_length;
alter_table->tmp_static_link_ids_length =
share_alter->tmp_static_link_ids_length;
2013-06-27 13:18:48 +02:00
alter_table->tmp_tgt_ports_length =
share_alter->tmp_tgt_ports_length;
alter_table->tmp_tgt_ssl_vscs_length =
share_alter->tmp_tgt_ssl_vscs_length;
alter_table->tmp_monitoring_binlog_pos_at_failing_length =
share_alter->tmp_monitoring_binlog_pos_at_failing_length;
2013-06-27 13:18:48 +02:00
alter_table->tmp_link_statuses_length =
share_alter->tmp_link_statuses_length;
old_elements = trx->trx_alter_table_hash.array.max_element;
if (my_hash_insert(&trx->trx_alter_table_hash, (uchar*) alter_table))
{
error_num = HA_ERR_OUT_OF_MEM;
goto error;
}
if (trx->trx_alter_table_hash.array.max_element > old_elements)
{
spider_alloc_calc_mem(spider_current_trx,
trx->trx_alter_table_hash,
(trx->trx_alter_table_hash.array.max_element - old_elements) *
trx->trx_alter_table_hash.array.size_of_element);
}
DBUG_RETURN(0);
error:
spider_free(trx, alter_table, MYF(0));
error_alloc_alter_table:
DBUG_RETURN(error_num);
}
bool spider_cmp_trx_alter_table(
SPIDER_ALTER_TABLE *cmp1,
SPIDER_ALTER_TABLE *cmp2
) {
int roop_count;
DBUG_ENTER("spider_cmp_trx_alter_table");
if (
cmp1->tmp_priority != cmp2->tmp_priority ||
cmp1->link_count != cmp2->link_count ||
cmp1->all_link_count != cmp2->all_link_count
)
DBUG_RETURN(TRUE);
for (roop_count = 0; roop_count < (int) cmp1->all_link_count; roop_count++)
{
if (
(
cmp1->tmp_server_names[roop_count] !=
cmp2->tmp_server_names[roop_count] &&
(
!cmp1->tmp_server_names[roop_count] ||
!cmp2->tmp_server_names[roop_count] ||
strcmp(cmp1->tmp_server_names[roop_count],
cmp2->tmp_server_names[roop_count])
)
) ||
(
cmp1->tmp_tgt_table_names[roop_count] !=
cmp2->tmp_tgt_table_names[roop_count] &&
(
!cmp1->tmp_tgt_table_names[roop_count] ||
!cmp2->tmp_tgt_table_names[roop_count] ||
strcmp(cmp1->tmp_tgt_table_names[roop_count],
cmp2->tmp_tgt_table_names[roop_count])
)
) ||
(
cmp1->tmp_tgt_dbs[roop_count] !=
cmp2->tmp_tgt_dbs[roop_count] &&
(
!cmp1->tmp_tgt_dbs[roop_count] ||
!cmp2->tmp_tgt_dbs[roop_count] ||
strcmp(cmp1->tmp_tgt_dbs[roop_count],
cmp2->tmp_tgt_dbs[roop_count])
)
) ||
(
cmp1->tmp_tgt_hosts[roop_count] !=
cmp2->tmp_tgt_hosts[roop_count] &&
(
!cmp1->tmp_tgt_hosts[roop_count] ||
!cmp2->tmp_tgt_hosts[roop_count] ||
strcmp(cmp1->tmp_tgt_hosts[roop_count],
cmp2->tmp_tgt_hosts[roop_count])
)
) ||
(
cmp1->tmp_tgt_usernames[roop_count] !=
cmp2->tmp_tgt_usernames[roop_count] &&
(
!cmp1->tmp_tgt_usernames[roop_count] ||
!cmp2->tmp_tgt_usernames[roop_count] ||
strcmp(cmp1->tmp_tgt_usernames[roop_count],
cmp2->tmp_tgt_usernames[roop_count])
)
) ||
(
cmp1->tmp_tgt_passwords[roop_count] !=
cmp2->tmp_tgt_passwords[roop_count] &&
(
!cmp1->tmp_tgt_passwords[roop_count] ||
!cmp2->tmp_tgt_passwords[roop_count] ||
strcmp(cmp1->tmp_tgt_passwords[roop_count],
cmp2->tmp_tgt_passwords[roop_count])
)
) ||
(
cmp1->tmp_tgt_sockets[roop_count] !=
cmp2->tmp_tgt_sockets[roop_count] &&
(
!cmp1->tmp_tgt_sockets[roop_count] ||
!cmp2->tmp_tgt_sockets[roop_count] ||
strcmp(cmp1->tmp_tgt_sockets[roop_count],
cmp2->tmp_tgt_sockets[roop_count])
)
) ||
(
cmp1->tmp_tgt_wrappers[roop_count] !=
cmp2->tmp_tgt_wrappers[roop_count] &&
(
!cmp1->tmp_tgt_wrappers[roop_count] ||
!cmp2->tmp_tgt_wrappers[roop_count] ||
strcmp(cmp1->tmp_tgt_wrappers[roop_count],
cmp2->tmp_tgt_wrappers[roop_count])
)
) ||
(
cmp1->tmp_tgt_ssl_cas[roop_count] !=
cmp2->tmp_tgt_ssl_cas[roop_count] &&
(
!cmp1->tmp_tgt_ssl_cas[roop_count] ||
!cmp2->tmp_tgt_ssl_cas[roop_count] ||
strcmp(cmp1->tmp_tgt_ssl_cas[roop_count],
cmp2->tmp_tgt_ssl_cas[roop_count])
)
) ||
(
cmp1->tmp_tgt_ssl_capaths[roop_count] !=
cmp2->tmp_tgt_ssl_capaths[roop_count] &&
(
!cmp1->tmp_tgt_ssl_capaths[roop_count] ||
!cmp2->tmp_tgt_ssl_capaths[roop_count] ||
strcmp(cmp1->tmp_tgt_ssl_capaths[roop_count],
cmp2->tmp_tgt_ssl_capaths[roop_count])
)
) ||
(
cmp1->tmp_tgt_ssl_certs[roop_count] !=
cmp2->tmp_tgt_ssl_certs[roop_count] &&
(
!cmp1->tmp_tgt_ssl_certs[roop_count] ||
!cmp2->tmp_tgt_ssl_certs[roop_count] ||
strcmp(cmp1->tmp_tgt_ssl_certs[roop_count],
cmp2->tmp_tgt_ssl_certs[roop_count])
)
) ||
(
cmp1->tmp_tgt_ssl_ciphers[roop_count] !=
cmp2->tmp_tgt_ssl_ciphers[roop_count] &&
(
!cmp1->tmp_tgt_ssl_ciphers[roop_count] ||
!cmp2->tmp_tgt_ssl_ciphers[roop_count] ||
strcmp(cmp1->tmp_tgt_ssl_ciphers[roop_count],
cmp2->tmp_tgt_ssl_ciphers[roop_count])
)
) ||
(
cmp1->tmp_tgt_ssl_keys[roop_count] !=
cmp2->tmp_tgt_ssl_keys[roop_count] &&
(
!cmp1->tmp_tgt_ssl_keys[roop_count] ||
!cmp2->tmp_tgt_ssl_keys[roop_count] ||
strcmp(cmp1->tmp_tgt_ssl_keys[roop_count],
cmp2->tmp_tgt_ssl_keys[roop_count])
)
) ||
(
cmp1->tmp_tgt_default_files[roop_count] !=
cmp2->tmp_tgt_default_files[roop_count] &&
(
!cmp1->tmp_tgt_default_files[roop_count] ||
!cmp2->tmp_tgt_default_files[roop_count] ||
strcmp(cmp1->tmp_tgt_default_files[roop_count],
cmp2->tmp_tgt_default_files[roop_count])
)
) ||
(
cmp1->tmp_tgt_default_groups[roop_count] !=
cmp2->tmp_tgt_default_groups[roop_count] &&
(
!cmp1->tmp_tgt_default_groups[roop_count] ||
!cmp2->tmp_tgt_default_groups[roop_count] ||
strcmp(cmp1->tmp_tgt_default_groups[roop_count],
cmp2->tmp_tgt_default_groups[roop_count])
)
) ||
2020-03-22 01:36:37 +01:00
(
cmp1->tmp_tgt_dsns[roop_count] !=
cmp2->tmp_tgt_dsns[roop_count] &&
(
!cmp1->tmp_tgt_dsns[roop_count] ||
!cmp2->tmp_tgt_dsns[roop_count] ||
strcmp(cmp1->tmp_tgt_dsns[roop_count],
cmp2->tmp_tgt_dsns[roop_count])
)
) ||
(
cmp1->tmp_static_link_ids[roop_count] !=
cmp2->tmp_static_link_ids[roop_count] &&
(
!cmp1->tmp_static_link_ids[roop_count] ||
!cmp2->tmp_static_link_ids[roop_count] ||
strcmp(cmp1->tmp_static_link_ids[roop_count],
cmp2->tmp_static_link_ids[roop_count])
)
) ||
2013-06-27 13:18:48 +02:00
cmp1->tmp_tgt_ports[roop_count] != cmp2->tmp_tgt_ports[roop_count] ||
cmp1->tmp_tgt_ssl_vscs[roop_count] !=
cmp2->tmp_tgt_ssl_vscs[roop_count] ||
cmp1->tmp_monitoring_binlog_pos_at_failing[roop_count] !=
cmp2->tmp_monitoring_binlog_pos_at_failing[roop_count] ||
2013-06-27 13:18:48 +02:00
cmp1->tmp_link_statuses[roop_count] !=
cmp2->tmp_link_statuses[roop_count]
)
DBUG_RETURN(TRUE);
}
DBUG_RETURN(FALSE);
}
int spider_free_trx_alloc(
SPIDER_TRX *trx
) {
int roop_count;
DBUG_ENTER("spider_free_trx_alloc");
2014-03-24 21:33:41 +01:00
if (trx->tmp_spider)
{
for (roop_count = 0; roop_count < SPIDER_DBTON_SIZE; ++roop_count)
{
if (trx->tmp_spider->dbton_handler[roop_count])
{
delete trx->tmp_spider->dbton_handler[roop_count];
trx->tmp_spider->dbton_handler[roop_count] = NULL;
}
}
if (trx->tmp_spider->result_list.sqls)
{
delete [] trx->tmp_spider->result_list.sqls;
trx->tmp_spider->result_list.sqls = NULL;
}
delete trx->tmp_spider;
trx->tmp_spider = NULL;
}
if (trx->tmp_share)
{
for (roop_count = 0; roop_count < SPIDER_DBTON_SIZE; ++roop_count)
{
if (trx->tmp_share->dbton_share[roop_count])
{
delete trx->tmp_share->dbton_share[roop_count];
trx->tmp_share->dbton_share[roop_count] = NULL;
}
}
spider_free_tmp_share_alloc(trx->tmp_share);
}
2013-06-27 13:18:48 +02:00
spider_db_udf_free_set_names(trx);
for (roop_count = spider_param_udf_table_lock_mutex_count() - 1;
roop_count >= 0; roop_count--)
pthread_mutex_destroy(&trx->udf_table_mutexes[roop_count]);
spider_free_trx_ha(trx);
spider_free_trx_conn(trx, TRUE);
spider_free_trx_alter_table(trx);
spider_free_mem_calc(spider_current_trx,
trx->trx_conn_hash_id,
trx->trx_conn_hash.array.max_element *
trx->trx_conn_hash.array.size_of_element);
my_hash_free(&trx->trx_conn_hash);
spider_free_mem_calc(spider_current_trx,
trx->trx_another_conn_hash_id,
trx->trx_another_conn_hash.array.max_element *
trx->trx_another_conn_hash.array.size_of_element);
my_hash_free(&trx->trx_another_conn_hash);
spider_free_mem_calc(spider_current_trx,
trx->trx_ha_hash_id,
trx->trx_ha_hash.array.max_element *
trx->trx_ha_hash.array.size_of_element);
my_hash_free(&trx->trx_ha_hash);
spider_free_mem_calc(spider_current_trx,
trx->trx_alter_table_hash_id,
trx->trx_alter_table_hash.array.max_element *
trx->trx_alter_table_hash.array.size_of_element);
my_hash_free(&trx->trx_alter_table_hash);
2014-03-24 21:33:41 +01:00
free_root(&trx->mem_root, MYF(0));
2013-06-27 13:18:48 +02:00
DBUG_RETURN(0);
}
/* Get or create a trx associated with the given THD. */
2013-06-27 13:18:48 +02:00
SPIDER_TRX *spider_get_trx(
THD *thd,
bool regist_allocated_thds,
int *error_num
) {
2014-03-24 21:33:41 +01:00
int roop_count = 0, roop_count2;
2013-06-27 13:18:48 +02:00
SPIDER_TRX *trx;
2014-03-24 21:33:41 +01:00
SPIDER_SHARE *tmp_share;
SPIDER_WIDE_HANDLER *tmp_wide_handler;
2013-06-27 13:18:48 +02:00
pthread_mutex_t *udf_table_mutexes;
DBUG_ENTER("spider_get_trx");
if (
!thd ||
!(trx = (SPIDER_TRX*) thd_get_ha_data(thd, spider_hton_ptr))
2013-06-27 13:18:48 +02:00
) {
DBUG_PRINT("info",("spider create new trx"));
if (!(trx = (SPIDER_TRX *)
spider_bulk_malloc(NULL, SPD_MID_GET_TRX_1, MYF(MY_WME | MY_ZEROFILL),
&trx, (uint) (sizeof(*trx)),
&tmp_share, (uint) (sizeof(SPIDER_SHARE)),
&tmp_wide_handler, (uint) sizeof(SPIDER_WIDE_HANDLER),
&udf_table_mutexes, (uint) (sizeof(pthread_mutex_t) *
spider_param_udf_table_lock_mutex_count()),
2013-06-27 13:18:48 +02:00
NullS))
)
goto error_alloc_trx;
2014-03-24 21:33:41 +01:00
SPD_INIT_ALLOC_ROOT(&trx->mem_root, 4096, 0, MYF(MY_WME));
trx->tmp_share = tmp_share;
2013-06-27 13:18:48 +02:00
trx->udf_table_mutexes = udf_table_mutexes;
for (roop_count = 0;
roop_count < (int) spider_param_udf_table_lock_mutex_count();
roop_count++)
{
if (mysql_mutex_init(spd_key_mutex_udf_table,
&trx->udf_table_mutexes[roop_count], MY_MUTEX_INIT_FAST))
goto error_init_udf_table_mutex;
}
if (my_hash_init(PSI_INSTRUMENT_ME, &trx->trx_conn_hash,
spd_charset_utf8mb3_bin, 32, 0, 0, spider_conn_get_key, 0,
0))
2013-06-27 13:18:48 +02:00
goto error_init_hash;
spider_alloc_calc_mem_init(trx->trx_conn_hash, SPD_MID_GET_TRX_2);
2013-06-27 13:18:48 +02:00
spider_alloc_calc_mem(
thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL,
2013-06-27 13:18:48 +02:00
trx->trx_conn_hash,
trx->trx_conn_hash.array.max_element *
trx->trx_conn_hash.array.size_of_element);
if (my_hash_init(PSI_INSTRUMENT_ME, &trx->trx_another_conn_hash,
spd_charset_utf8mb3_bin, 32, 0, 0, spider_conn_get_key, 0,
0))
2013-06-27 13:18:48 +02:00
goto error_init_another_hash;
spider_alloc_calc_mem_init(trx->trx_another_conn_hash, SPD_MID_GET_TRX_3);
2013-06-27 13:18:48 +02:00
spider_alloc_calc_mem(
thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL,
2013-06-27 13:18:48 +02:00
trx->trx_another_conn_hash,
trx->trx_another_conn_hash.array.max_element *
trx->trx_another_conn_hash.array.size_of_element);
if (my_hash_init(PSI_INSTRUMENT_ME, &trx->trx_alter_table_hash,
spd_charset_utf8mb3_bin, 32, 0, 0,
spider_alter_tbl_get_key, 0, 0))
2013-06-27 13:18:48 +02:00
goto error_init_alter_hash;
spider_alloc_calc_mem_init(trx->trx_alter_table_hash, SPD_MID_GET_TRX_8);
2013-06-27 13:18:48 +02:00
spider_alloc_calc_mem(
thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL,
2013-06-27 13:18:48 +02:00
trx->trx_alter_table_hash,
trx->trx_alter_table_hash.array.max_element *
trx->trx_alter_table_hash.array.size_of_element);
if (my_hash_init(PSI_INSTRUMENT_ME, &trx->trx_ha_hash,
spd_charset_utf8mb3_bin, 32, 0, 0, spider_trx_ha_get_key,
0, 0))
2013-06-27 13:18:48 +02:00
goto error_init_trx_ha_hash;
spider_alloc_calc_mem_init(trx->trx_ha_hash, SPD_MID_GET_TRX_9);
2013-06-27 13:18:48 +02:00
spider_alloc_calc_mem(
thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL,
2013-06-27 13:18:48 +02:00
trx->trx_ha_hash,
trx->trx_ha_hash.array.max_element *
trx->trx_ha_hash.array.size_of_element);
trx->thd = (THD*) thd;
if (thd)
trx->thd_hash_value = my_calc_hash(&spider_allocated_thds,
(uchar*) thd, sizeof(THD *));
else
trx->thd_hash_value = 0;
pthread_mutex_lock(&spider_thread_id_mutex);
trx->spider_thread_id = spider_thread_id;
++spider_thread_id;
pthread_mutex_unlock(&spider_thread_id_mutex);
trx->trx_conn_adjustment = 1;
if (thd)
{
2014-03-24 21:33:41 +01:00
spider_set_tmp_share_pointer(trx->tmp_share, trx->tmp_connect_info,
trx->tmp_connect_info_length, trx->tmp_long, trx->tmp_longlong);
if (
spider_set_connect_info_default(
trx->tmp_share,
#ifdef WITH_PARTITION_STORAGE_ENGINE
NULL,
NULL,
#endif
NULL
) ||
spider_set_connect_info_default_db_table(
trx->tmp_share,
"", 0,
"", 0
) ||
spider_create_conn_keys(trx->tmp_share)
) {
goto error_set_connect_info_default;
}
if (!(trx->tmp_spider = new (&trx->mem_root) ha_spider()))
{
goto error_alloc_spider;
}
trx->tmp_spider->need_mons = &trx->tmp_need_mon;
trx->tmp_spider->share = trx->tmp_share;
trx->tmp_spider->wide_handler = tmp_wide_handler;
tmp_wide_handler->trx = trx;
2014-03-24 21:33:41 +01:00
trx->tmp_spider->dbton_handler = trx->tmp_dbton_handler;
if (!(trx->tmp_spider->result_list.sqls =
new spider_string[trx->tmp_share->link_count]))
{
goto error_init_result_list_sql;
}
for (roop_count2 = 0; roop_count2 < (int) trx->tmp_share->link_count;
++roop_count2)
{
trx->tmp_spider->result_list.sqls[roop_count2].init_calc_mem(SPD_MID_GET_TRX_10);
2014-03-24 21:33:41 +01:00
trx->tmp_spider->result_list.sqls[roop_count2].set_charset(
trx->tmp_share->access_charset);
}
for (roop_count2 = 0; roop_count2 < SPIDER_DBTON_SIZE; ++roop_count2)
{
if (!spider_dbton[roop_count2].init)
continue;
if (!(trx->tmp_share->dbton_share[roop_count2] =
spider_dbton[roop_count2].create_db_share(trx->tmp_share)))
{
goto error_create_db_share;
}
if (trx->tmp_share->dbton_share[roop_count2]->init())
{
delete trx->tmp_share->dbton_share[roop_count2];
trx->tmp_share->dbton_share[roop_count2] = NULL;
goto error_create_db_share;
}
if (!(trx->tmp_spider->dbton_handler[roop_count2] =
spider_dbton[roop_count2].create_db_handler(trx->tmp_spider,
trx->tmp_share->dbton_share[roop_count2])))
{
goto error_create_db_share;
}
if (trx->tmp_spider->dbton_handler[roop_count2]->init())
{
delete trx->tmp_spider->dbton_handler[roop_count2];
trx->tmp_spider->dbton_handler[roop_count2] = NULL;
goto error_create_db_share;
}
}
2013-06-27 13:18:48 +02:00
if (regist_allocated_thds)
{
pthread_mutex_lock(&spider_allocated_thds_mutex);
uint old_elements = spider_allocated_thds.array.max_element;
if (my_hash_insert(&spider_allocated_thds, (uchar*) thd))
{
pthread_mutex_unlock(&spider_allocated_thds_mutex);
goto error_allocated_thds_insert;
}
if (spider_allocated_thds.array.max_element > old_elements)
{
spider_alloc_calc_mem(trx,
spider_allocated_thds,
(spider_allocated_thds.array.max_element - old_elements) *
spider_allocated_thds.array.size_of_element);
}
pthread_mutex_unlock(&spider_allocated_thds_mutex);
trx->registed_allocated_thds = TRUE;
}
thd_set_ha_data(thd, spider_hton_ptr, trx);
2013-06-27 13:18:48 +02:00
}
}
DBUG_PRINT("info",("spider trx=%p", trx));
DBUG_RETURN(trx);
error_allocated_thds_insert:
2014-03-24 21:33:41 +01:00
error_alloc_spider:
error_create_db_share:
if (thd)
{
delete [] trx->tmp_spider->result_list.sqls;
trx->tmp_spider->result_list.sqls = NULL;
}
error_init_result_list_sql:
if (thd)
{
delete trx->tmp_spider;
trx->tmp_spider = NULL;
for (roop_count2 = 0; roop_count2 < SPIDER_DBTON_SIZE; ++roop_count2)
{
if (trx->tmp_spider->dbton_handler[roop_count2])
{
delete trx->tmp_spider->dbton_handler[roop_count2];
trx->tmp_spider->dbton_handler[roop_count2] = NULL;
}
if (trx->tmp_share->dbton_share[roop_count2])
{
delete trx->tmp_share->dbton_share[roop_count2];
trx->tmp_share->dbton_share[roop_count2] = NULL;
}
}
}
error_set_connect_info_default:
if (thd)
{
spider_free_tmp_share_alloc(trx->tmp_share);
}
2013-06-27 13:18:48 +02:00
spider_free_mem_calc(trx,
trx->trx_ha_hash_id,
trx->trx_ha_hash.array.max_element *
trx->trx_ha_hash.array.size_of_element);
my_hash_free(&trx->trx_ha_hash);
error_init_trx_ha_hash:
spider_free_mem_calc(
thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL,
2013-06-27 13:18:48 +02:00
trx->trx_alter_table_hash_id,
trx->trx_alter_table_hash.array.max_element *
trx->trx_alter_table_hash.array.size_of_element);
my_hash_free(&trx->trx_alter_table_hash);
error_init_alter_hash:
spider_free_mem_calc(
thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL,
2013-06-27 13:18:48 +02:00
trx->trx_another_conn_hash_id,
trx->trx_another_conn_hash.array.max_element *
trx->trx_another_conn_hash.array.size_of_element);
my_hash_free(&trx->trx_another_conn_hash);
error_init_another_hash:
spider_free_mem_calc(
thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL,
2013-06-27 13:18:48 +02:00
trx->trx_conn_hash_id,
trx->trx_conn_hash.array.max_element *
trx->trx_conn_hash.array.size_of_element);
my_hash_free(&trx->trx_conn_hash);
error_init_hash:
if (roop_count > 0)
{
for (roop_count--; roop_count >= 0; roop_count--)
pthread_mutex_destroy(&trx->udf_table_mutexes[roop_count]);
}
error_init_udf_table_mutex:
2014-03-24 21:33:41 +01:00
free_root(&trx->mem_root, MYF(0));
2013-06-27 13:18:48 +02:00
spider_free(NULL, trx, MYF(0));
error_alloc_trx:
*error_num = HA_ERR_OUT_OF_MEM;
DBUG_RETURN(NULL);
}
int spider_free_trx(
SPIDER_TRX *trx,
bool need_lock,
bool reset_ha_data
2013-06-27 13:18:48 +02:00
) {
DBUG_ENTER("spider_free_trx");
if (trx->thd)
{
if (trx->registed_allocated_thds)
{
if (need_lock)
pthread_mutex_lock(&spider_allocated_thds_mutex);
my_hash_delete(&spider_allocated_thds, (uchar*) trx->thd);
if (need_lock)
pthread_mutex_unlock(&spider_allocated_thds_mutex);
}
if (reset_ha_data)
thd_set_ha_data(trx->thd, spider_hton_ptr, NULL);
2013-06-27 13:18:48 +02:00
}
spider_free_trx_alloc(trx);
spider_merge_mem_calc(trx, TRUE);
spider_free(NULL, trx, MYF(0));
DBUG_RETURN(0);
}
int spider_check_and_set_trx_isolation(
SPIDER_CONN *conn,
int *need_mon
) {
THD *thd = conn->thd;
2013-06-27 13:18:48 +02:00
int trx_isolation;
DBUG_ENTER("spider_check_and_set_trx_isolation");
if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL)
2013-06-27 13:18:48 +02:00
{
if ((trx_isolation = spider_param_slave_trx_isolation()) == -1)
{
trx_isolation = thd_tx_isolation(thd);
DBUG_PRINT("info",("spider local trx_isolation=%d", trx_isolation));
} else {
DBUG_PRINT("info",("spider slave trx_isolation=%d", trx_isolation));
}
} else {
trx_isolation = thd_tx_isolation(thd);
DBUG_PRINT("info",("spider local trx_isolation=%d", trx_isolation));
2013-06-27 13:18:48 +02:00
}
spider_conn_queue_trx_isolation(conn, trx_isolation);
2013-06-27 13:18:48 +02:00
DBUG_RETURN(0);
}
int spider_check_and_set_autocommit(
THD *thd,
SPIDER_CONN *conn,
int *need_mon
) {
DBUG_ENTER("spider_check_and_set_autocommit");
spider_conn_queue_autocommit(
conn, !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT));
2013-06-27 13:18:48 +02:00
DBUG_RETURN(0);
}
int spider_check_and_set_sql_log_off(
THD *thd,
SPIDER_CONN *conn,
int *need_mon
) {
int internal_sql_log_off;
2013-06-27 13:18:48 +02:00
DBUG_ENTER("spider_check_and_set_sql_log_off");
internal_sql_log_off = spider_param_internal_sql_log_off(thd);
if (internal_sql_log_off != -1)
2013-06-27 13:18:48 +02:00
{
if (internal_sql_log_off)
{
spider_conn_queue_sql_log_off(conn, TRUE);
} else {
spider_conn_queue_sql_log_off(conn, FALSE);
}
2013-06-27 13:18:48 +02:00
}
DBUG_RETURN(0);
}
int spider_check_and_set_wait_timeout(
THD *thd,
SPIDER_CONN *conn,
int *need_mon
) {
int wait_timeout;
DBUG_ENTER("spider_check_and_set_wait_timeout");
wait_timeout = spider_param_wait_timeout(thd);
if (wait_timeout > 0)
{
spider_conn_queue_wait_timeout(conn, wait_timeout);
}
DBUG_RETURN(0);
}
int spider_check_and_set_sql_mode(
THD *thd,
SPIDER_CONN *conn,
int *need_mon
) {
DBUG_ENTER("spider_check_and_set_sql_mode");
spider_conn_queue_sql_mode(conn, thd->variables.sql_mode);
DBUG_RETURN(0);
}
2013-06-27 13:18:48 +02:00
int spider_check_and_set_time_zone(
THD *thd,
SPIDER_CONN *conn,
int *need_mon
) {
Time_zone *time_zone;
DBUG_ENTER("spider_check_and_set_time_zone");
time_zone = thd->variables.time_zone;
DBUG_PRINT("info",("spider local time_zone=%p", time_zone));
/*
DBUG_PRINT("info",("spider conn->time_zone=%p", conn->time_zone));
if (time_zone != conn->time_zone)
{
*/
spider_conn_queue_time_zone(conn, time_zone);
/*
conn->time_zone = time_zone;
}
*/
DBUG_RETURN(0);
}
static int spider_xa_lock(
XID_STATE *xid_state,
XID *xid
2013-06-27 13:18:48 +02:00
) {
2014-03-24 20:40:46 +01:00
THD *thd = current_thd;
2013-06-27 13:18:48 +02:00
int error_num;
2014-03-24 20:40:46 +01:00
const char *old_proc_info;
2013-06-27 13:18:48 +02:00
DBUG_ENTER("spider_xa_lock");
2015-10-28 23:34:53 +01:00
#ifdef SPIDER_XID_USES_xid_cache_iterate
#else
2013-06-27 13:18:48 +02:00
my_hash_value_type hash_value = my_calc_hash(spd_db_att_xid_cache,
(uchar*) xid_state->xid.key(), xid_state->xid.key_length());
2014-03-24 20:40:46 +01:00
#ifdef XID_CACHE_IS_SPLITTED
uint idx = hash_value % *spd_db_att_xid_cache_split_num;
#endif
2013-06-27 13:18:48 +02:00
#endif
2014-03-24 20:40:46 +01:00
old_proc_info = thd_proc_info(thd, "Locking xid by Spider");
2015-10-28 23:34:53 +01:00
#ifdef SPIDER_XID_USES_xid_cache_iterate
if (xid_cache_insert(thd, xid_state, xid))
2015-10-28 23:34:53 +01:00
{
error_num = (spider_stmt_da_sql_errno(thd) == ER_XAER_DUPID ?
ER_SPIDER_XA_LOCKED_NUM : HA_ERR_OUT_OF_MEM);
2015-10-28 23:34:53 +01:00
goto error;
}
#else
2014-03-24 20:40:46 +01:00
#ifdef XID_CACHE_IS_SPLITTED
pthread_mutex_lock(&spd_db_att_LOCK_xid_cache[idx]);
#else
2013-06-27 13:18:48 +02:00
pthread_mutex_lock(spd_db_att_LOCK_xid_cache);
2014-03-24 20:40:46 +01:00
#endif
#ifdef XID_CACHE_IS_SPLITTED
if (my_hash_search_using_hash_value(&spd_db_att_xid_cache[idx], hash_value,
xid_state->xid.key(), xid_state->xid.key_length()))
#else
2013-06-27 13:18:48 +02:00
if (my_hash_search_using_hash_value(spd_db_att_xid_cache, hash_value,
xid_state->xid.key(), xid_state->xid.key_length()))
#endif
{
error_num = ER_SPIDER_XA_LOCKED_NUM;
goto error;
}
if (my_hash_insert(spd_db_att_xid_cache, (uchar*)xid_state))
{
error_num = HA_ERR_OUT_OF_MEM;
goto error;
}
2014-03-24 20:40:46 +01:00
#ifdef XID_CACHE_IS_SPLITTED
pthread_mutex_unlock(&spd_db_att_LOCK_xid_cache[idx]);
#else
2013-06-27 13:18:48 +02:00
pthread_mutex_unlock(spd_db_att_LOCK_xid_cache);
2015-10-28 23:34:53 +01:00
#endif
2014-03-24 20:40:46 +01:00
#endif
thd_proc_info(thd, old_proc_info);
2013-06-27 13:18:48 +02:00
DBUG_RETURN(0);
error:
2015-10-28 23:34:53 +01:00
#ifdef SPIDER_XID_USES_xid_cache_iterate
#else
2014-03-24 20:40:46 +01:00
#ifdef XID_CACHE_IS_SPLITTED
pthread_mutex_unlock(&spd_db_att_LOCK_xid_cache[idx]);
#else
2013-06-27 13:18:48 +02:00
pthread_mutex_unlock(spd_db_att_LOCK_xid_cache);
2015-10-28 23:34:53 +01:00
#endif
2014-03-24 20:40:46 +01:00
#endif
thd_proc_info(thd, old_proc_info);
2013-06-27 13:18:48 +02:00
DBUG_RETURN(error_num);
}
static int spider_xa_unlock(
2013-06-27 13:18:48 +02:00
XID_STATE *xid_state
) {
2014-03-24 20:40:46 +01:00
THD *thd = current_thd;
const char *old_proc_info;
2013-06-27 13:18:48 +02:00
DBUG_ENTER("spider_xa_unlock");
2015-10-28 23:34:53 +01:00
#ifdef SPIDER_XID_USES_xid_cache_iterate
#else
2014-03-24 20:40:46 +01:00
#endif
old_proc_info = thd_proc_info(thd, "Unlocking xid by Spider");
2015-10-28 23:34:53 +01:00
#ifdef SPIDER_XID_USES_xid_cache_iterate
xid_cache_delete(thd, xid_state);
#else
2014-03-24 20:40:46 +01:00
#ifdef XID_CACHE_IS_SPLITTED
pthread_mutex_lock(&spd_db_att_LOCK_xid_cache[idx]);
#else
2013-06-27 13:18:48 +02:00
pthread_mutex_lock(spd_db_att_LOCK_xid_cache);
2014-03-24 20:40:46 +01:00
#endif
2013-06-27 13:18:48 +02:00
my_hash_delete(spd_db_att_xid_cache, (uchar *)xid_state);
2014-03-24 20:40:46 +01:00
#ifdef XID_CACHE_IS_SPLITTED
pthread_mutex_unlock(&spd_db_att_LOCK_xid_cache[idx]);
#else
2013-06-27 13:18:48 +02:00
pthread_mutex_unlock(spd_db_att_LOCK_xid_cache);
2015-10-28 23:34:53 +01:00
#endif
2014-03-24 20:40:46 +01:00
#endif
thd_proc_info(thd, old_proc_info);
2013-06-27 13:18:48 +02:00
DBUG_RETURN(0);
}
int spider_start_internal_consistent_snapshot(
SPIDER_TRX *trx,
SPIDER_CONN *conn,
int *need_mon
) {
DBUG_ENTER("spider_start_internal_consistent_snapshot");
if (trx->trx_consistent_snapshot)
DBUG_RETURN(spider_db_consistent_snapshot(conn, need_mon));
DBUG_RETURN(0);
}
int spider_internal_start_trx(
ha_spider *spider
2013-06-27 13:18:48 +02:00
) {
int error_num;
SPIDER_TRX *trx = spider->wide_handler->trx;
2014-03-24 20:45:34 +01:00
THD *thd = trx->thd;
2013-06-27 13:18:48 +02:00
bool xa_lock = FALSE;
DBUG_ENTER("spider_internal_start_trx");
if (!trx->trx_start)
{
if (!trx->trx_consistent_snapshot)
{
trx->use_consistent_snapshot =
2014-03-24 20:45:34 +01:00
spider_param_use_consistent_snapshot(thd);
trx->internal_xa = spider_param_internal_xa(thd);
trx->internal_xa_snapshot = spider_param_internal_xa_snapshot(thd);
2013-06-27 13:18:48 +02:00
}
}
spider->wide_handler->consistent_snapshot = FALSE;
2013-06-27 13:18:48 +02:00
if (trx->trx_consistent_snapshot)
{
if (trx->internal_xa && trx->internal_xa_snapshot < 2)
{
error_num = ER_SPIDER_CANT_USE_BOTH_INNER_XA_AND_SNAPSHOT_NUM;
my_message(error_num, ER_SPIDER_CANT_USE_BOTH_INNER_XA_AND_SNAPSHOT_STR,
MYF(0));
goto error;
} else if (!trx->internal_xa || trx->internal_xa_snapshot == 2)
{
spider->wide_handler->consistent_snapshot = TRUE;
2013-06-27 13:18:48 +02:00
}
}
DBUG_PRINT("info",("spider trx->trx_start= %s",
trx->trx_start ? "TRUE" : "FALSE"));
2013-06-27 13:18:48 +02:00
if (!trx->trx_start)
{
if (
thd->transaction->xid_state.is_explicit_XA() &&
2013-06-27 13:18:48 +02:00
spider_param_support_xa()
) {
trx->trx_xa = TRUE;
2014-03-24 20:45:34 +01:00
thd_get_xid(thd, (MYSQL_XID*) &trx->xid);
2013-06-27 13:18:48 +02:00
}
2014-03-24 20:17:18 +01:00
if (
!trx->trx_xa &&
trx->internal_xa &&
2014-03-24 20:42:40 +01:00
(!trx->trx_consistent_snapshot || trx->internal_xa_snapshot == 3) &&
spider->wide_handler->sql_command != SQLCOM_LOCK_TABLES
2014-03-24 20:17:18 +01:00
) {
trx->trx_xa = TRUE;
trx->xid.formatID = 1;
2014-03-24 20:45:34 +01:00
if (spider_param_internal_xa_id_type(thd) == 0)
{
trx->xid.gtrid_length
= my_sprintf(trx->xid.data,
(trx->xid.data, "%lx", thd_get_thread_id(thd)));
} else {
trx->xid.gtrid_length
= my_sprintf(trx->xid.data,
(trx->xid.data, "%lx%016llx", thd_get_thread_id(thd),
thd->query_id));
}
2014-03-24 20:17:18 +01:00
trx->xid.bqual_length
= my_sprintf(trx->xid.data + trx->xid.gtrid_length,
(trx->xid.data + trx->xid.gtrid_length, "%lx",
2014-03-24 20:45:34 +01:00
thd->variables.server_id));
2013-06-27 13:18:48 +02:00
2015-10-28 23:34:53 +01:00
#ifdef SPIDER_XID_STATE_HAS_in_thd
2014-03-24 20:17:18 +01:00
trx->internal_xid_state.in_thd = 1;
2015-10-28 23:34:53 +01:00
#endif
if ((error_num = spider_xa_lock(&trx->internal_xid_state, &trx->xid)))
2014-03-24 20:17:18 +01:00
{
2014-03-24 20:42:40 +01:00
if (error_num == ER_SPIDER_XA_LOCKED_NUM)
2014-03-24 20:17:18 +01:00
my_message(error_num, ER_SPIDER_XA_LOCKED_STR, MYF(0));
2014-03-24 20:42:40 +01:00
goto error;
2013-06-27 13:18:48 +02:00
}
2014-03-24 20:17:18 +01:00
xa_lock = TRUE;
} else
trx->internal_xa = FALSE;
2013-06-27 13:18:48 +02:00
DBUG_PRINT("info",("spider trx->trx_consistent_snapshot= %s",
trx->trx_consistent_snapshot ? "TRUE" : "FALSE"));
2013-06-27 13:18:48 +02:00
if (!trx->trx_consistent_snapshot)
{
2020-02-27 16:00:43 +01:00
trans_register_ha(thd, FALSE, spider_hton_ptr, 0);
2014-03-24 20:45:34 +01:00
if (thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
2020-02-27 16:00:43 +01:00
trans_register_ha(thd, TRUE, spider_hton_ptr, 0);
2013-06-27 13:18:48 +02:00
}
trx->trx_start = TRUE;
2014-03-24 20:42:40 +01:00
trx->trx_xa_prepared = FALSE;
trx->updated_in_this_trx = FALSE;
DBUG_PRINT("info",("spider trx->updated_in_this_trx=FALSE"));
2013-06-27 13:18:48 +02:00
}
DBUG_RETURN(0);
error:
if (xa_lock)
spider_xa_unlock(&trx->internal_xid_state);
DBUG_RETURN(error_num);
}
int spider_internal_start_trx_for_connection(
ha_spider *spider,
SPIDER_CONN *conn,
int link_idx
) {
int error_num;
SPIDER_TRX *trx = spider->wide_handler->trx;
THD *thd = trx->thd;
bool sync_autocommit = spider_param_sync_autocommit(thd);
double ping_interval_at_trx_start =
spider_param_ping_interval_at_trx_start(thd);
time_t tmp_time = (time_t) time((time_t*) 0);
DBUG_ENTER("spider_internal_start_trx_for_connection");
if (
conn->server_lost ||
difftime(tmp_time, conn->ping_time) >= ping_interval_at_trx_start
) {
spider_conn_queue_ping(spider, conn, link_idx);
}
conn->disable_reconnect = TRUE;
if (
(error_num = spider_check_and_set_sql_log_off(thd, conn,
&spider->need_mons[link_idx])) ||
(error_num = spider_check_and_set_wait_timeout(thd, conn,
&spider->need_mons[link_idx])) ||
(spider_param_sync_sql_mode(thd) &&
(error_num = spider_check_and_set_sql_mode(thd, conn,
&spider->need_mons[link_idx]))) ||
(sync_autocommit &&
(error_num = spider_check_and_set_autocommit(thd, conn,
&spider->need_mons[link_idx])))
)
goto error;
if (spider->wide_handler->consistent_snapshot)
{
if ((error_num = spider_start_internal_consistent_snapshot(trx, conn,
&spider->need_mons[link_idx])))
goto error;
}
2013-06-27 13:18:48 +02:00
DBUG_PRINT("info",("spider sync_autocommit = %d", sync_autocommit));
DBUG_PRINT("info",("spider conn->semi_trx_chk = %d", conn->semi_trx_chk));
DBUG_PRINT("info",("spider conn->table_lock = %d", conn->table_lock));
DBUG_PRINT("info",("spider conn->autocommit = %d", conn->autocommit));
2014-03-24 20:45:34 +01:00
DBUG_PRINT("info",("spider semi_trx = %d", spider_param_semi_trx(thd)));
2013-06-27 13:18:48 +02:00
conn->semi_trx = FALSE;
if (conn->table_lock == 3)
{
DBUG_PRINT("info",("spider conn->table_lock == 3"));
conn->disable_xa = TRUE;
} else if (trx->trx_xa)
{
DBUG_PRINT("info",("spider trx->trx_xa"));
if (
sync_autocommit &&
conn->semi_trx_chk &&
!conn->table_lock &&
(
(!conn->queued_autocommit && conn->autocommit == 1) ||
(conn->queued_autocommit && conn->queued_autocommit_val == TRUE)
) &&
2014-03-24 20:45:34 +01:00
spider_param_semi_trx(thd)
2013-06-27 13:18:48 +02:00
) {
DBUG_PRINT("info",("spider semi_trx is set"));
conn->semi_trx = TRUE;
}
spider_conn_queue_xa_start(conn, &trx->xid);
conn->disable_xa = FALSE;
} else if (
!trx->trx_consistent_snapshot &&
2014-03-24 20:45:34 +01:00
!thd_test_options(thd, OPTION_BEGIN) &&
2013-06-27 13:18:48 +02:00
sync_autocommit &&
conn->semi_trx_chk &&
!conn->table_lock &&
(
(!conn->queued_autocommit && conn->autocommit == 1) ||
(conn->queued_autocommit && conn->queued_autocommit_val == TRUE)
) &&
2014-03-24 20:45:34 +01:00
spider_param_semi_trx(thd)
2013-06-27 13:18:48 +02:00
) {
DBUG_PRINT("info",("spider semi_trx is set"));
spider_conn_queue_start_transaction(conn);
conn->semi_trx = TRUE;
} else if (
!trx->trx_consistent_snapshot &&
2014-03-24 20:45:34 +01:00
thd_test_options(thd, OPTION_BEGIN)
2013-06-27 13:18:48 +02:00
) {
DBUG_PRINT("info",("spider start transaction"));
spider_conn_queue_start_transaction(conn);
}
conn->join_trx = 1;
if (trx->join_trx_top)
spider_tree_insert(trx->join_trx_top, conn);
else {
conn->p_small = NULL;
conn->p_big = NULL;
conn->c_small = NULL;
conn->c_big = NULL;
trx->join_trx_top = conn;
}
DBUG_RETURN(0);
error:
DBUG_RETURN(error_num);
}
int spider_internal_xa_commit(
THD* thd,
SPIDER_TRX *trx,
XID* xid,
TABLE *table_xa,
TABLE *table_xa_member
) {
int error_num = 0, tmp_error_num;
2013-06-27 13:18:48 +02:00
char xa_key[MAX_KEY_LENGTH];
SPIDER_CONN *conn;
uint force_commit = spider_param_force_commit(thd);
MEM_ROOT mem_root;
SPIDER_Open_tables_backup open_tables_backup;
2013-06-27 13:18:48 +02:00
bool table_xa_opened = FALSE;
bool table_xa_member_opened = FALSE;
DBUG_ENTER("spider_internal_xa_commit");
if (trx->updated_in_this_trx || spider_param_xa_register_mode(thd) == 0)
{
/*
select
status
from
mysql.spider_xa
where
format_id = xid->format_id and
gtrid_length = xid->gtrid_length and
data = xid->data
*/
if (
!(table_xa = spider_open_sys_table(
thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
TRUE, &open_tables_backup, TRUE, &error_num))
)
goto error_open_table;
table_xa_opened = TRUE;
spider_store_xa_pk(table_xa, &trx->xid);
if (
(error_num = spider_check_sys_table(table_xa, xa_key))
) {
if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE)
{
table_xa->file->print_error(error_num, MYF(0));
goto error;
}
my_message(ER_SPIDER_XA_NOT_EXISTS_NUM, ER_SPIDER_XA_NOT_EXISTS_STR,
MYF(0));
error_num = ER_SPIDER_XA_NOT_EXISTS_NUM;
goto error;
}
SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME));
if (
force_commit != 2 &&
(error_num = spider_check_sys_xa_status(
table_xa,
SPIDER_SYS_XA_PREPARED_STR,
SPIDER_SYS_XA_COMMIT_STR,
NULL,
ER_SPIDER_XA_NOT_PREPARED_NUM,
&mem_root))
) {
free_root(&mem_root, MYF(0));
if (error_num == ER_SPIDER_XA_NOT_PREPARED_NUM)
my_message(error_num, ER_SPIDER_XA_NOT_PREPARED_STR, MYF(0));
2013-06-27 13:18:48 +02:00
goto error;
}
free_root(&mem_root, MYF(0));
/*
update
mysql.spider_xa
set
status = 'COMMIT'
where
format_id = trx->xid.format_id and
gtrid_length = trx->xid.gtrid_length and
data = trx->xid.data
*/
if (
(error_num = spider_update_xa(
table_xa, &trx->xid, SPIDER_SYS_XA_COMMIT_STR))
)
goto error;
spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
table_xa_opened = FALSE;
}
2013-06-27 13:18:48 +02:00
SPIDER_BACKUP_DASTATUS;
if ((conn = spider_tree_first(trx->join_trx_top)))
{
do {
2014-03-24 20:46:43 +01:00
if (conn->bg_search)
spider_bg_conn_break(conn, NULL);
DBUG_PRINT("info",("spider conn=%p", conn));
DBUG_PRINT("info",("spider conn->join_trx=%u", conn->join_trx));
2013-06-27 13:18:48 +02:00
if (conn->join_trx)
{
if ((tmp_error_num = spider_db_xa_commit(conn, &trx->xid)))
{
if (force_commit == 0 ||
(force_commit == 1 && tmp_error_num != ER_XAER_NOTA))
{
SPIDER_CONN_RESTORE_DASTATUS_AND_RESET_TMP_ERROR_NUM;
if (!error_num && tmp_error_num)
error_num = tmp_error_num;
}
2013-08-24 08:20:44 +02:00
spider_sys_log_xa_failed(thd, &trx->xid, conn,
SPIDER_SYS_XA_COMMIT_STR, TRUE);
2013-06-27 13:18:48 +02:00
}
if ((tmp_error_num = spider_end_trx(trx, conn)))
{
SPIDER_CONN_RESTORE_DASTATUS_AND_RESET_TMP_ERROR_NUM;
if (!error_num && tmp_error_num)
error_num = tmp_error_num;
}
conn->join_trx = 0;
}
} while ((conn = spider_tree_next(conn)));
trx->join_trx_top = NULL;
}
if (error_num)
goto error_in_commit;
if (trx->updated_in_this_trx || spider_param_xa_register_mode(thd) == 0)
{
/*
delete from
mysql.spider_xa_member
where
format_id = xid->format_id and
gtrid_length = xid->gtrid_length and
data = xid->data
*/
if (
!(table_xa_member = spider_open_sys_table(
thd, SPIDER_SYS_XA_MEMBER_TABLE_NAME_STR,
SPIDER_SYS_XA_MEMBER_TABLE_NAME_LEN, TRUE, &open_tables_backup, TRUE,
&error_num))
)
goto error_open_table;
table_xa_member_opened = TRUE;
if ((error_num = spider_delete_xa_member(table_xa_member, &trx->xid)))
goto error;
spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE);
table_xa_member_opened = FALSE;
2013-06-27 13:18:48 +02:00
/*
delete from
mysql.spider_xa
where
format_id = xid->format_id and
gtrid_length = xid->gtrid_length and
data = xid->data
*/
if (
!(table_xa = spider_open_sys_table(
thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
TRUE, &open_tables_backup, TRUE, &error_num))
)
goto error_open_table;
table_xa_opened = TRUE;
if ((error_num = spider_delete_xa(table_xa, &trx->xid)))
goto error;
spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
table_xa_opened = FALSE;
}
2020-08-12 22:36:23 +02:00
if (trx->internal_xa)
{
spider_xa_unlock(&trx->internal_xid_state);
}
2013-06-27 13:18:48 +02:00
DBUG_RETURN(0);
error:
if (table_xa_opened)
spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
if (table_xa_member_opened)
spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE);
error_in_commit:
error_open_table:
2020-08-12 22:36:23 +02:00
if (trx->internal_xa)
{
spider_xa_unlock(&trx->internal_xid_state);
}
2013-06-27 13:18:48 +02:00
DBUG_RETURN(error_num);
}
int spider_internal_xa_rollback(
THD* thd,
SPIDER_TRX *trx
) {
int error_num = 0, tmp_error_num;
TABLE *table_xa, *table_xa_member;
char xa_key[MAX_KEY_LENGTH];
SPIDER_CONN *conn;
uint force_commit = spider_param_force_commit(thd);
MEM_ROOT mem_root;
SPIDER_Open_tables_backup open_tables_backup;
2013-06-27 13:18:48 +02:00
bool server_lost = FALSE;
bool table_xa_opened = FALSE;
bool table_xa_member_opened = FALSE;
DBUG_ENTER("spider_internal_xa_rollback");
if (
trx->trx_xa_prepared &&
(
trx->updated_in_this_trx ||
spider_param_xa_register_mode(thd) == 0
)
) {
2013-06-27 13:18:48 +02:00
/*
select
status
from
mysql.spider_xa
where
format_id = xid->format_id and
gtrid_length = xid->gtrid_length and
data = xid->data
*/
if (
!(table_xa = spider_open_sys_table(
thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
TRUE, &open_tables_backup, TRUE, &error_num))
)
goto error_open_table;
table_xa_opened = TRUE;
spider_store_xa_pk(table_xa, &trx->xid);
if (
(error_num = spider_check_sys_table(table_xa, xa_key))
) {
if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE)
{
table_xa->file->print_error(error_num, MYF(0));
goto error;
}
my_message(ER_SPIDER_XA_NOT_EXISTS_NUM, ER_SPIDER_XA_NOT_EXISTS_STR,
MYF(0));
error_num = ER_SPIDER_XA_NOT_EXISTS_NUM;
goto error;
}
SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME));
if (
force_commit != 2 &&
(error_num = spider_check_sys_xa_status(
table_xa,
SPIDER_SYS_XA_PREPARED_STR,
SPIDER_SYS_XA_ROLLBACK_STR,
NULL,
ER_SPIDER_XA_NOT_PREPARED_NUM,
&mem_root))
) {
free_root(&mem_root, MYF(0));
if (error_num == ER_SPIDER_XA_NOT_PREPARED_NUM)
my_message(error_num, ER_SPIDER_XA_NOT_PREPARED_STR, MYF(0));
goto error;
}
free_root(&mem_root, MYF(0));
/*
update
mysql.spider_xa
set
status = 'COMMIT'
where
format_id = trx->xid.format_id and
gtrid_length = trx->xid.gtrid_length and
data = trx->xid.data
*/
if (
(error_num = spider_update_xa(
table_xa, &trx->xid, SPIDER_SYS_XA_ROLLBACK_STR))
)
goto error;
spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
table_xa_opened = FALSE;
}
SPIDER_BACKUP_DASTATUS;
if ((conn = spider_tree_first(trx->join_trx_top)))
{
do {
2014-03-24 20:46:43 +01:00
if (conn->bg_search)
spider_bg_conn_break(conn, NULL);
2013-06-27 13:18:48 +02:00
if (conn->join_trx)
{
if (conn->disable_xa)
{
2014-03-24 20:42:40 +01:00
if (conn->table_lock != 3 && !trx->trx_xa_prepared)
2013-06-27 13:18:48 +02:00
{
if (
!conn->server_lost &&
(tmp_error_num = spider_db_rollback(conn))
) {
SPIDER_CONN_RESTORE_DASTATUS_AND_RESET_TMP_ERROR_NUM;
if (!error_num && tmp_error_num)
error_num = tmp_error_num;
}
}
} else {
if (!conn->server_lost)
{
if (
2014-03-24 20:42:40 +01:00
!trx->trx_xa_prepared &&
2013-06-27 13:18:48 +02:00
(tmp_error_num = spider_db_xa_end(conn, &trx->xid))
) {
if (
force_commit == 0 ||
(force_commit == 1 &&
(
tmp_error_num != ER_XAER_NOTA &&
tmp_error_num != ER_XA_RBTIMEOUT &&
tmp_error_num != ER_XA_RBDEADLOCK
)
)
) {
SPIDER_CONN_RESTORE_DASTATUS_AND_RESET_TMP_ERROR_NUM;
if (!error_num && tmp_error_num)
error_num = tmp_error_num;
}
}
if ((tmp_error_num = spider_db_xa_rollback(conn, &trx->xid)))
{
if (
force_commit == 0 ||
(force_commit == 1 &&
(
tmp_error_num != ER_XAER_NOTA &&
tmp_error_num != ER_XA_RBTIMEOUT &&
tmp_error_num != ER_XA_RBDEADLOCK
)
)
) {
SPIDER_CONN_RESTORE_DASTATUS_AND_RESET_TMP_ERROR_NUM;
if (!error_num && tmp_error_num)
error_num = tmp_error_num;
}
}
}
}
if ((tmp_error_num = spider_end_trx(trx, conn)))
{
SPIDER_CONN_RESTORE_DASTATUS_AND_RESET_TMP_ERROR_NUM;
if (!error_num && tmp_error_num)
error_num = tmp_error_num;
}
conn->join_trx = 0;
if (conn->server_lost)
server_lost = TRUE;
}
} while ((conn = spider_tree_next(conn)));
trx->join_trx_top = NULL;
}
if (error_num)
goto error_in_rollback;
if (
2014-03-24 20:42:40 +01:00
trx->trx_xa_prepared &&
!server_lost &&
(
trx->updated_in_this_trx ||
spider_param_xa_register_mode(thd) == 0
)
2013-06-27 13:18:48 +02:00
) {
/*
delete from
mysql.spider_xa_member
where
format_id = xid->format_id and
gtrid_length = xid->gtrid_length and
data = xid->data
*/
if (
!(table_xa_member = spider_open_sys_table(
thd, SPIDER_SYS_XA_MEMBER_TABLE_NAME_STR,
SPIDER_SYS_XA_MEMBER_TABLE_NAME_LEN, TRUE, &open_tables_backup, TRUE,
&error_num))
)
goto error_open_table;
table_xa_member_opened = TRUE;
if ((error_num = spider_delete_xa_member(table_xa_member, &trx->xid)))
goto error;
spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE);
table_xa_member_opened = FALSE;
/*
delete from
mysql.spider_xa
where
format_id = xid->format_id and
gtrid_length = xid->gtrid_length and
data = xid->data
*/
if (
!(table_xa = spider_open_sys_table(
thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
TRUE, &open_tables_backup, TRUE, &error_num))
)
goto error_open_table;
table_xa_opened = TRUE;
if ((error_num = spider_delete_xa(table_xa, &trx->xid)))
goto error;
spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
table_xa_opened = FALSE;
}
2020-08-12 22:36:23 +02:00
if (trx->internal_xa)
{
spider_xa_unlock(&trx->internal_xid_state);
}
2013-06-27 13:18:48 +02:00
DBUG_RETURN(0);
error:
if (table_xa_opened)
spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
if (table_xa_member_opened)
spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE);
error_in_rollback:
error_open_table:
2020-08-12 22:36:23 +02:00
if (trx->internal_xa)
{
spider_xa_unlock(&trx->internal_xid_state);
}
2013-06-27 13:18:48 +02:00
DBUG_RETURN(error_num);
}
int spider_internal_xa_prepare(
THD* thd,
SPIDER_TRX *trx,
TABLE *table_xa,
TABLE *table_xa_member,
bool internal_xa
) {
int error_num;
SPIDER_CONN *conn;
uint force_commit = spider_param_force_commit(thd);
SPIDER_Open_tables_backup open_tables_backup;
2013-06-27 13:18:48 +02:00
bool table_xa_opened = FALSE;
bool table_xa_member_opened = FALSE;
DBUG_ENTER("spider_internal_xa_prepare");
if (trx->updated_in_this_trx || spider_param_xa_register_mode(thd) == 0)
{
/*
insert into mysql.spider_xa
(format_id, gtrid_length, bqual_length, data, status) values
(trx->xid.format_id, trx->xid.gtrid_length, trx->xid.bqual_length,
trx->xid.data, 'NOT YET')
*/
if (
!(table_xa = spider_open_sys_table(
thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
TRUE, &open_tables_backup, TRUE, &error_num))
)
goto error_open_table;
table_xa_opened = TRUE;
if (
(error_num = spider_insert_xa(
table_xa, &trx->xid, SPIDER_SYS_XA_NOT_YET_STR))
)
goto error;
spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
table_xa_opened = FALSE;
2013-06-27 13:18:48 +02:00
if (
!(table_xa_member = spider_open_sys_table(
thd, SPIDER_SYS_XA_MEMBER_TABLE_NAME_STR,
SPIDER_SYS_XA_MEMBER_TABLE_NAME_LEN, TRUE, &open_tables_backup, TRUE,
&error_num))
)
goto error_open_table;
table_xa_member_opened = TRUE;
}
2013-06-27 13:18:48 +02:00
SPIDER_BACKUP_DASTATUS;
if ((conn = spider_tree_first(trx->join_trx_top)))
{
do {
2014-03-24 20:46:43 +01:00
if (conn->bg_search)
spider_bg_conn_break(conn, NULL);
2013-06-27 13:18:48 +02:00
if (conn->disable_xa)
{
if (conn->table_lock != 3)
{
if ((error_num = spider_db_rollback(conn)))
{
SPIDER_CONN_RESTORE_DASTATUS_AND_RESET_ERROR_NUM;
if (error_num)
goto error;
}
}
if ((error_num = spider_end_trx(trx, conn)))
{
SPIDER_CONN_RESTORE_DASTATUS_AND_RESET_ERROR_NUM;
if (error_num)
goto error;
}
conn->join_trx = 0;
} else {
if (trx->updated_in_this_trx || spider_param_xa_register_mode(thd) == 0)
{
/*
insert into mysql.spider_xa_member
(format_id, gtrid_length, bqual_length, data,
scheme, host, port, socket, username, password) values
(trx->xid.format_id, trx->xid.gtrid_length,
trx->xid.bqual_length, trx->xid.data,
conn->tgt_wrapper,
conn->tgt_host,
conn->tgt_port,
conn->tgt_socket,
conn->tgt_username,
conn->tgt_password)
*/
if (
(error_num = spider_insert_xa_member(
table_xa_member, &trx->xid, conn))
) {
SPIDER_CONN_RESTORE_DASTATUS_AND_RESET_ERROR_NUM;
if (error_num)
goto error;
}
2013-06-27 13:18:48 +02:00
}
if ((error_num = spider_db_xa_end(conn, &trx->xid)))
{
if (force_commit == 0 ||
(force_commit == 1 && error_num != ER_XAER_NOTA))
{
SPIDER_CONN_RESTORE_DASTATUS_AND_RESET_ERROR_NUM;
if (error_num)
goto error;
}
}
if ((error_num = spider_db_xa_prepare(conn, &trx->xid)))
{
if (force_commit == 0 ||
(force_commit == 1 && error_num != ER_XAER_NOTA))
{
SPIDER_CONN_RESTORE_DASTATUS_AND_RESET_ERROR_NUM;
if (error_num)
goto error;
}
}
/*
if (!internal_xa)
{
if ((error_num = spider_end_trx(trx, conn)))
DBUG_RETURN(error_num);
conn->join_trx = 0;
}
*/
}
} while ((conn = spider_tree_next(conn)));
/*
if (!internal_xa)
trx->join_trx_top = NULL;
*/
}
if (trx->updated_in_this_trx || spider_param_xa_register_mode(thd) == 0)
{
spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE);
table_xa_member_opened = FALSE;
2013-06-27 13:18:48 +02:00
/*
update
mysql.spider_xa
set
status = 'PREPARED'
where
format_id = trx->xid.format_id and
gtrid_length = trx->xid.gtrid_length and
data = trx->xid.data
*/
if (
!(table_xa = spider_open_sys_table(
thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
TRUE, &open_tables_backup, TRUE, &error_num))
)
goto error_open_table;
table_xa_opened = TRUE;
if (
(error_num = spider_update_xa(
table_xa, &trx->xid, SPIDER_SYS_XA_PREPARED_STR))
)
goto error;
spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
table_xa_opened = FALSE;
}
2013-06-27 13:18:48 +02:00
DBUG_RETURN(0);
error:
if (table_xa_opened)
spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
if (table_xa_member_opened)
spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE);
error_open_table:
DBUG_RETURN(error_num);
}
int spider_internal_xa_recover(
THD* thd,
XID* xid_list,
uint len
) {
TABLE *table_xa;
int cnt = 0;
char xa_key[MAX_KEY_LENGTH];
MEM_ROOT mem_root;
SPIDER_Open_tables_backup open_tables_backup;
2013-06-27 13:18:48 +02:00
DBUG_ENTER("spider_internal_xa_recover");
/*
select
format_id,
gtrid_length,
bqual_length,
data
from
mysql.spider_xa
where
status = 'PREPARED'
*/
if (
!(table_xa = spider_open_sys_table(
thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
FALSE, &open_tables_backup, TRUE, &my_errno))
)
goto error_open_table;
spider_store_xa_status(table_xa, SPIDER_SYS_XA_PREPARED_STR);
if (
(my_errno = spider_get_sys_table_by_idx(table_xa, xa_key, 1,
SPIDER_SYS_XA_IDX1_COL_CNT))
) {
spider_sys_index_end(table_xa);
if (my_errno != HA_ERR_KEY_NOT_FOUND && my_errno != HA_ERR_END_OF_FILE)
{
table_xa->file->print_error(my_errno, MYF(0));
goto error;
}
goto error;
}
SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME));
do {
spider_get_sys_xid(table_xa, &xid_list[cnt], &mem_root);
cnt++;
my_errno = spider_sys_index_next_same(table_xa, xa_key);
} while (my_errno == 0 && cnt < (int) len);
free_root(&mem_root, MYF(0));
spider_sys_index_end(table_xa);
spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
DBUG_RETURN(cnt);
error:
spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
error_open_table:
DBUG_RETURN(0);
}
int spider_initinal_xa_recover(
XID* xid_list,
uint len
) {
int error_num;
THD *thd;
TABLE *table_xa;
READ_RECORD *read_record;
SPIDER_Open_tables_backup open_tables_backup;
2013-06-27 13:18:48 +02:00
int cnt = 0;
MEM_ROOT mem_root;
DBUG_ENTER("spider_initinal_xa_recover");
if (!(read_record = new READ_RECORD))
2013-06-27 13:18:48 +02:00
{
error_num = HA_ERR_OUT_OF_MEM;
goto error_create_read_record;
2013-06-27 13:18:48 +02:00
}
if (!(thd = spider_create_tmp_thd()))
2013-06-27 13:18:48 +02:00
{
error_num = HA_ERR_OUT_OF_MEM;
goto error_create_thd;
2013-06-27 13:18:48 +02:00
}
/*
select
format_id,
gtrid_length,
bqual_length,
data
from
mysql.spider_xa
*/
if (
!(table_xa = spider_open_sys_table(
thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
FALSE, &open_tables_backup, TRUE, &error_num))
)
goto error_open_table;
SPIDER_init_read_record(read_record, thd, table_xa, NULL, NULL, TRUE,
FALSE, FALSE);
2013-06-27 13:18:48 +02:00
SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME));
while ((!(read_record->SPIDER_read_record_read_record(read_record))) &&
cnt < (int) len)
2013-06-27 13:18:48 +02:00
{
spider_get_sys_xid(table_xa, &xid_list[cnt], &mem_root);
cnt++;
}
free_root(&mem_root, MYF(0));
end_read_record(read_record);
2013-06-27 13:18:48 +02:00
spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
table_xa = NULL;
spider_free_tmp_thd(thd);
thd = NULL;
delete read_record;
read_record = NULL;
DBUG_RETURN(cnt);
2013-06-27 13:18:48 +02:00
error_open_table:
spider_free_tmp_thd(thd);
thd = NULL;
error_create_thd:
delete read_record;
read_record = NULL;
error_create_read_record:
DBUG_RETURN(0);
}
int spider_internal_xa_commit_by_xid(
THD* thd,
SPIDER_TRX *trx,
XID* xid
) {
TABLE *table_xa, *table_xa_member = 0;
2013-06-27 13:18:48 +02:00
int error_num;
char xa_key[MAX_KEY_LENGTH];
char xa_member_key[MAX_KEY_LENGTH];
SPIDER_SHARE tmp_share;
char *tmp_connect_info[SPIDER_TMP_SHARE_CHAR_PTR_COUNT];
uint tmp_connect_info_length[SPIDER_TMP_SHARE_UINT_COUNT];
long tmp_long[SPIDER_TMP_SHARE_LONG_COUNT];
longlong tmp_longlong[SPIDER_TMP_SHARE_LONGLONG_COUNT];
2013-06-27 13:18:48 +02:00
SPIDER_CONN *conn;
uint force_commit = spider_param_force_commit(thd);
MEM_ROOT mem_root;
SPIDER_Open_tables_backup open_tables_backup;
2013-06-27 13:18:48 +02:00
bool table_xa_opened = FALSE;
bool table_xa_member_opened = FALSE;
DBUG_ENTER("spider_internal_xa_commit_by_xid");
/*
select
status
from
mysql.spider_xa
where
format_id = xid->format_id and
gtrid_length = xid->gtrid_length and
data = xid->data
*/
if (
!(table_xa = spider_open_sys_table(
thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
TRUE, &open_tables_backup, TRUE, &error_num))
)
goto error_open_table;
table_xa_opened = TRUE;
spider_store_xa_pk(table_xa, xid);
if (
(error_num = spider_check_sys_table(table_xa, xa_key))
) {
if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE)
{
table_xa->file->print_error(error_num, MYF(0));
goto error;
}
my_message(ER_SPIDER_XA_NOT_EXISTS_NUM, ER_SPIDER_XA_NOT_EXISTS_STR,
MYF(0));
error_num = ER_SPIDER_XA_NOT_EXISTS_NUM;
goto error;
}
SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME));
if (
force_commit != 2 &&
(error_num = spider_check_sys_xa_status(
table_xa,
SPIDER_SYS_XA_PREPARED_STR,
SPIDER_SYS_XA_COMMIT_STR,
NULL,
ER_SPIDER_XA_NOT_PREPARED_NUM,
&mem_root))
) {
free_root(&mem_root, MYF(0));
if (error_num == ER_SPIDER_XA_NOT_PREPARED_NUM)
my_message(error_num, ER_SPIDER_XA_NOT_PREPARED_STR, MYF(0));
goto error;
}
/*
update
mysql.spider_xa
set
status = 'COMMIT'
where
format_id = trx->xid.format_id and
gtrid_length = trx->xid.gtrid_length and
data = trx->xid.data
*/
if (
(error_num = spider_update_xa(
table_xa, xid, SPIDER_SYS_XA_COMMIT_STR))
) {
free_root(&mem_root, MYF(0));
goto error;
}
spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
table_xa_opened = FALSE;
/*
select
scheme tmp_share.tgt_wrappers,
host tmp_share.tgt_hosts,
port tmp_share.tgt_ports,
socket tmp_share.tgt_sockets,
username tmp_share.tgt_usernames,
password tmp_share.tgt_passwords
from
mysql.spider_xa_member
where
format_id = xid->format_id and
gtrid_length = xid->gtrid_length and
data = xid->data
*/
if (
!(table_xa_member = spider_open_sys_table(
thd, SPIDER_SYS_XA_MEMBER_TABLE_NAME_STR,
SPIDER_SYS_XA_MEMBER_TABLE_NAME_LEN, TRUE, &open_tables_backup, TRUE,
&error_num))
) {
free_root(&mem_root, MYF(0));
goto error_open_table;
}
table_xa_member_opened = TRUE;
spider_store_xa_pk(table_xa_member, xid);
if (
(error_num = spider_get_sys_table_by_idx(table_xa_member, xa_member_key, 0,
SPIDER_SYS_XA_PK_COL_CNT))
) {
if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE)
{
free_root(&mem_root, MYF(0));
table_xa_member->file->print_error(error_num, MYF(0));
goto error;
} else {
free_root(&mem_root, MYF(0));
spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE);
table_xa_member_opened = FALSE;
goto xa_delete;
}
}
2019-03-16 16:03:54 +01:00
memset((void*)&tmp_share, 0, sizeof(SPIDER_SHARE));
memset(&tmp_connect_info, 0,
sizeof(char *) * SPIDER_TMP_SHARE_CHAR_PTR_COUNT);
spider_set_tmp_share_pointer(&tmp_share, tmp_connect_info,
tmp_connect_info_length, tmp_long, tmp_longlong);
2013-06-27 13:18:48 +02:00
do {
SPIDER_BACKUP_DASTATUS;
spider_get_sys_server_info(table_xa_member, &tmp_share, 0, &mem_root);
if ((error_num = spider_create_conn_keys(&tmp_share)))
{
spider_sys_index_end(table_xa_member);
free_root(&mem_root, MYF(0));
goto error;
}
if (
!(conn = spider_get_conn(
&tmp_share, 0, tmp_share.conn_keys[0], trx, NULL, FALSE, FALSE,
SPIDER_CONN_KIND_MYSQL, &error_num)) &&
(force_commit == 0 ||
(force_commit == 1 && error_num != ER_XAER_NOTA))
) {
spider_sys_index_end(table_xa_member);
spider_free_tmp_share_alloc(&tmp_share);
free_root(&mem_root, MYF(0));
goto error;
}
conn->error_mode &= spider_param_error_read_mode(thd, 0);
conn->error_mode &= spider_param_error_write_mode(thd, 0);
if (
(error_num = spider_db_xa_commit(conn, xid)) &&
(force_commit == 0 ||
(force_commit == 1 && error_num != ER_XAER_NOTA))
) {
SPIDER_CONN_RESTORE_DASTATUS_AND_RESET_ERROR_NUM;
if (error_num)
{
spider_sys_index_end(table_xa_member);
spider_free_tmp_share_alloc(&tmp_share);
free_root(&mem_root, MYF(0));
goto error;
}
}
spider_free_tmp_share_alloc(&tmp_share);
error_num = spider_sys_index_next_same(table_xa_member, xa_member_key);
} while (error_num == 0);
if ((error_num = spider_sys_index_end(table_xa_member)))
{
free_root(&mem_root, MYF(0));
goto error;
}
free_root(&mem_root, MYF(0));
spider_reuse_trx_ha(trx);
spider_free_trx_conn(trx, FALSE);
/*
delete from
mysql.spider_xa_member
where
format_id = xid->format_id and
gtrid_length = xid->gtrid_length and
data = xid->data
*/
if ((error_num = spider_delete_xa_member(table_xa_member, xid)))
goto error;
spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE);
table_xa_member_opened = FALSE;
xa_delete:
/*
delete from
mysql.spider_xa
where
format_id = xid->format_id and
gtrid_length = xid->gtrid_length and
data = xid->data
*/
if (
!(table_xa = spider_open_sys_table(
thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
TRUE, &open_tables_backup, TRUE, &error_num))
)
goto error_open_table;
table_xa_opened = TRUE;
if ((error_num = spider_delete_xa(table_xa, xid)))
goto error;
spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
table_xa_opened = FALSE;
DBUG_RETURN(0);
error:
if (table_xa_opened)
spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
if (table_xa_member_opened)
spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE);
error_open_table:
DBUG_RETURN(error_num);
}
int spider_internal_xa_rollback_by_xid(
THD* thd,
SPIDER_TRX *trx,
XID* xid
) {
TABLE *table_xa, *table_xa_member = 0;
2013-06-27 13:18:48 +02:00
int error_num;
char xa_key[MAX_KEY_LENGTH];
char xa_member_key[MAX_KEY_LENGTH];
/* This share has only one link */
2013-06-27 13:18:48 +02:00
SPIDER_SHARE tmp_share;
char *tmp_connect_info[SPIDER_TMP_SHARE_CHAR_PTR_COUNT];
uint tmp_connect_info_length[SPIDER_TMP_SHARE_UINT_COUNT];
long tmp_long[SPIDER_TMP_SHARE_LONG_COUNT];
longlong tmp_longlong[SPIDER_TMP_SHARE_LONGLONG_COUNT];
2013-06-27 13:18:48 +02:00
SPIDER_CONN *conn;
uint force_commit = spider_param_force_commit(thd);
MEM_ROOT mem_root;
SPIDER_Open_tables_backup open_tables_backup;
2013-06-27 13:18:48 +02:00
bool table_xa_opened = FALSE;
bool table_xa_member_opened = FALSE;
DBUG_ENTER("spider_internal_xa_rollback_by_xid");
/*
select
status
from
mysql.spider_xa
where
format_id = xid->format_id and
gtrid_length = xid->gtrid_length and
data = xid->data
*/
if (
!(table_xa = spider_open_sys_table(
thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
TRUE, &open_tables_backup, TRUE, &error_num))
)
goto error_open_table;
table_xa_opened = TRUE;
spider_store_xa_pk(table_xa, xid);
if (
(error_num = spider_check_sys_table(table_xa, xa_key))
) {
if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE)
{
table_xa->file->print_error(error_num, MYF(0));
goto error;
}
error_num = ER_SPIDER_XA_NOT_EXISTS_NUM;
goto error;
}
SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME));
if (
force_commit != 2 &&
(error_num = spider_check_sys_xa_status(
table_xa,
SPIDER_SYS_XA_NOT_YET_STR,
SPIDER_SYS_XA_PREPARED_STR,
SPIDER_SYS_XA_ROLLBACK_STR,
ER_SPIDER_XA_PREPARED_NUM,
&mem_root))
) {
free_root(&mem_root, MYF(0));
if (error_num == ER_SPIDER_XA_PREPARED_NUM)
my_message(error_num, ER_SPIDER_XA_PREPARED_STR, MYF(0));
goto error;
}
/*
update
mysql.spider_xa
set
status = 'ROLLBACK'
where
format_id = trx->xid.format_id and
gtrid_length = trx->xid.gtrid_length and
data = trx->xid.data
*/
if (
(error_num = spider_update_xa(
table_xa, xid, SPIDER_SYS_XA_ROLLBACK_STR))
) {
free_root(&mem_root, MYF(0));
goto error;
}
spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
table_xa_opened = FALSE;
/*
select
scheme tmp_share.tgt_wrappers,
host tmp_share.tgt_hosts,
port tmp_share.tgt_ports,
socket tmp_share.tgt_sockets,
username tmp_share.tgt_usernames,
password tmp_share.tgt_passwords
from
mysql.spider_xa_member
where
format_id = xid->format_id and
gtrid_length = xid->gtrid_length and
data = xid->data
*/
if (
!(table_xa_member = spider_open_sys_table(
thd, SPIDER_SYS_XA_MEMBER_TABLE_NAME_STR,
SPIDER_SYS_XA_MEMBER_TABLE_NAME_LEN, TRUE, &open_tables_backup, TRUE,
&error_num))
) {
free_root(&mem_root, MYF(0));
goto error_open_table;
}
table_xa_member_opened = TRUE;
spider_store_xa_pk(table_xa_member, xid);
if (
(error_num = spider_get_sys_table_by_idx(table_xa_member, xa_member_key, 0,
SPIDER_SYS_XA_PK_COL_CNT))
) {
if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE)
{
free_root(&mem_root, MYF(0));
table_xa_member->file->print_error(error_num, MYF(0));
goto error;
} else {
free_root(&mem_root, MYF(0));
spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE);
table_xa_member_opened = FALSE;
goto xa_delete;
}
}
2019-03-16 16:03:54 +01:00
memset((void*)&tmp_share, 0, sizeof(SPIDER_SHARE));
memset(&tmp_connect_info, 0,
sizeof(char *) * SPIDER_TMP_SHARE_CHAR_PTR_COUNT);
spider_set_tmp_share_pointer(&tmp_share, tmp_connect_info,
tmp_connect_info_length, tmp_long, tmp_longlong);
2013-06-27 13:18:48 +02:00
do {
SPIDER_BACKUP_DASTATUS;
spider_get_sys_server_info(table_xa_member, &tmp_share, 0, &mem_root);
if ((error_num = spider_create_conn_keys(&tmp_share)))
{
spider_sys_index_end(table_xa_member);
free_root(&mem_root, MYF(0));
goto error;
}
if (
!(conn = spider_get_conn(
&tmp_share, 0, tmp_share.conn_keys[0], trx, NULL, FALSE, FALSE,
SPIDER_CONN_KIND_MYSQL, &error_num)) &&
(force_commit == 0 ||
(force_commit == 1 && error_num != ER_XAER_NOTA))
) {
spider_sys_index_end(table_xa_member);
spider_free_tmp_share_alloc(&tmp_share);
free_root(&mem_root, MYF(0));
goto error;
}
conn->error_mode &= spider_param_error_read_mode(thd, 0);
conn->error_mode &= spider_param_error_write_mode(thd, 0);
if (
(error_num = spider_db_xa_rollback(conn, xid)) &&
(force_commit == 0 ||
(force_commit == 1 && error_num != ER_XAER_NOTA))
) {
SPIDER_CONN_RESTORE_DASTATUS_AND_RESET_ERROR_NUM;
if (error_num)
{
spider_sys_index_end(table_xa_member);
spider_free_tmp_share_alloc(&tmp_share);
free_root(&mem_root, MYF(0));
goto error;
}
}
spider_free_tmp_share_alloc(&tmp_share);
error_num = spider_sys_index_next_same(table_xa_member, xa_member_key);
} while (error_num == 0);
if ((error_num = spider_sys_index_end(table_xa_member)))
{
free_root(&mem_root, MYF(0));
goto error;
}
free_root(&mem_root, MYF(0));
spider_reuse_trx_ha(trx);
spider_free_trx_conn(trx, FALSE);
/*
delete from
mysql.spider_xa_member
where
format_id = xid->format_id and
gtrid_length = xid->gtrid_length and
data = xid->data
*/
if ((error_num = spider_delete_xa_member(table_xa_member, xid)))
goto error;
spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE);
table_xa_member_opened = FALSE;
xa_delete:
/*
delete from
mysql.spider_xa
where
format_id = xid->format_id and
gtrid_length = xid->gtrid_length and
data = xid->data
*/
if (
!(table_xa = spider_open_sys_table(
thd, SPIDER_SYS_XA_TABLE_NAME_STR, SPIDER_SYS_XA_TABLE_NAME_LEN,
TRUE, &open_tables_backup, TRUE, &error_num))
)
goto error_open_table;
table_xa_opened = TRUE;
if ((error_num = spider_delete_xa(table_xa, xid)))
goto error;
spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
table_xa_opened = FALSE;
DBUG_RETURN(0);
error:
if (table_xa_opened)
spider_close_sys_table(thd, table_xa, &open_tables_backup, TRUE);
if (table_xa_member_opened)
spider_close_sys_table(thd, table_xa_member, &open_tables_backup, TRUE);
error_open_table:
DBUG_RETURN(error_num);
}
int spider_start_consistent_snapshot(
handlerton *hton,
THD* thd
) {
int error_num;
SPIDER_TRX *trx;
DBUG_ENTER("spider_start_consistent_snapshot");
if (!(trx = spider_get_trx(thd, TRUE, &error_num)))
DBUG_RETURN(error_num);
if (spider_param_use_consistent_snapshot(trx->thd))
{
if (spider_param_internal_xa(trx->thd) &&
spider_param_internal_xa_snapshot(trx->thd) == 1)
{
error_num = ER_SPIDER_CANT_USE_BOTH_INNER_XA_AND_SNAPSHOT_NUM;
my_message(error_num, ER_SPIDER_CANT_USE_BOTH_INNER_XA_AND_SNAPSHOT_STR,
MYF(0));
goto error;
} else {
trx->trx_consistent_snapshot = TRUE;
trx->use_consistent_snapshot = TRUE;
trx->internal_xa_snapshot = spider_param_internal_xa_snapshot(trx->thd);
2020-02-27 16:00:43 +01:00
trans_register_ha(trx->thd, FALSE, spider_hton_ptr, 0);
trans_register_ha(trx->thd, TRUE, spider_hton_ptr, 0);
2013-06-27 13:18:48 +02:00
if (spider_param_use_all_conns_snapshot(trx->thd))
{
trx->internal_xa = FALSE;
if ((error_num = spider_open_all_tables(trx, TRUE)))
goto error_open_all_tables;
if (
spider_param_use_snapshot_with_flush_tables(trx->thd) == 1 &&
(error_num = spider_trx_all_flush_tables(trx))
)
goto error_trx_all_flush_tables;
if (spider_param_use_snapshot_with_flush_tables(trx->thd) == 2)
{
if ((error_num = spider_trx_another_lock_tables(trx)))
goto error_trx_another_lock_tables;
if ((error_num = spider_trx_another_flush_tables(trx)))
goto error_trx_another_flush_tables;
}
if ((error_num = spider_trx_all_start_trx(trx)))
goto error_trx_all_start_trx;
if (spider_param_use_snapshot_with_flush_tables(trx->thd) == 1)
{
if (
spider_param_use_flash_logs(trx->thd) &&
(error_num = spider_trx_all_flush_logs(trx))
)
goto error_trx_all_flush_logs;
if ((error_num = spider_trx_all_unlock_tables(trx)))
goto error_trx_all_unlock_tables;
}
if (spider_param_use_snapshot_with_flush_tables(trx->thd) == 2)
{
if (
spider_param_use_flash_logs(trx->thd) &&
(error_num = spider_trx_all_flush_logs(trx))
)
goto error_trx_all_flush_logs2;
if ((error_num = spider_free_trx_another_conn(trx, TRUE)))
goto error_free_trx_another_conn;
}
} else
trx->internal_xa = spider_param_internal_xa(trx->thd);
}
}
DBUG_RETURN(0);
error_trx_all_flush_logs:
error_trx_all_start_trx:
error_trx_another_flush_tables:
error_trx_another_lock_tables:
error_trx_all_flush_tables:
if (spider_param_use_snapshot_with_flush_tables(trx->thd) == 1)
spider_trx_all_unlock_tables(trx);
error_trx_all_flush_logs2:
error_trx_all_unlock_tables:
error_open_all_tables:
if (spider_param_use_snapshot_with_flush_tables(trx->thd) == 2)
spider_free_trx_another_conn(trx, TRUE);
error_free_trx_another_conn:
error:
DBUG_RETURN(error_num);
}
int spider_commit(
handlerton *hton,
THD *thd,
bool all
) {
SPIDER_TRX *trx;
TABLE *table_xa = NULL;
TABLE *table_xa_member = NULL;
int error_num = 0;
SPIDER_CONN *conn;
DBUG_ENTER("spider_commit");
if (!(trx = (SPIDER_TRX*) thd_get_ha_data(thd, spider_hton_ptr)))
2013-06-27 13:18:48 +02:00
DBUG_RETURN(0); /* transaction is not started */
/*
We do (almost) nothing if the following two conditions are both met:
* This is just the end of a statement, not an explicit commit.
* The autocommit is OFF or we are in an explicit transaction.
*/
2013-06-27 13:18:48 +02:00
if (all || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
{
if (trx->trx_start)
{
if (trx->trx_xa)
{
2014-03-24 20:42:40 +01:00
if (trx->internal_xa && !trx->trx_xa_prepared)
{
if (
(error_num = spider_internal_xa_prepare(
thd, trx, table_xa, table_xa_member, TRUE))
) {
2013-06-27 13:18:48 +02:00
/*
2014-03-24 20:42:40 +01:00
if (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
{
2013-06-27 13:18:48 +02:00
*/
2014-03-24 20:42:40 +01:00
/* rollback for semi_trx */
spider_rollback(hton, thd, all);
2013-06-27 13:18:48 +02:00
/*
2014-03-24 20:42:40 +01:00
}
2013-06-27 13:18:48 +02:00
*/
2014-03-24 20:42:40 +01:00
DBUG_RETURN(error_num);
}
trx->trx_xa_prepared = TRUE;
2013-06-27 13:18:48 +02:00
}
int tmp_error_num;
2013-06-27 13:18:48 +02:00
if (
(tmp_error_num = spider_internal_xa_commit(
2013-06-27 13:18:48 +02:00
thd, trx, &trx->xid, table_xa, table_xa_member))
) {
if (tmp_error_num)
error_num = tmp_error_num;
2013-06-27 13:18:48 +02:00
}
trx->trx_xa = FALSE;
2014-03-24 20:14:30 +01:00
trx->join_trx_top = NULL;
2013-06-27 13:18:48 +02:00
} else {
if ((conn = spider_tree_first(trx->join_trx_top)))
{
SPIDER_BACKUP_DASTATUS;
int tmp_error_num;
do {
if (
(conn->autocommit != 1 || conn->trx_start) &&
(tmp_error_num = spider_db_commit(conn))
) {
SPIDER_CONN_RESTORE_DASTATUS_AND_RESET_TMP_ERROR_NUM;
if (tmp_error_num)
error_num = tmp_error_num;
}
if ((tmp_error_num = spider_end_trx(trx, conn)))
{
SPIDER_CONN_RESTORE_DASTATUS_AND_RESET_TMP_ERROR_NUM;
if (tmp_error_num)
error_num = tmp_error_num;
}
conn->join_trx = 0;
} while ((conn = spider_tree_next(conn)));
trx->join_trx_top = NULL;
}
}
trx->trx_start = FALSE;
trx->updated_in_this_trx = FALSE;
DBUG_PRINT("info",("spider trx->trx_start=FALSE"));
DBUG_PRINT("info",("spider trx->updated_in_this_trx=FALSE"));
2013-06-27 13:18:48 +02:00
}
spider_reuse_trx_ha(trx);
spider_free_trx_conn(trx, FALSE);
trx->trx_consistent_snapshot = FALSE;
}
spider_merge_mem_calc(trx, FALSE);
DBUG_RETURN(error_num);
}
int spider_rollback(
handlerton *hton,
THD *thd,
bool all
) {
SPIDER_TRX *trx;
int error_num = 0;
SPIDER_CONN *conn;
DBUG_ENTER("spider_rollback");
if (!(trx = (SPIDER_TRX*) thd_get_ha_data(thd, spider_hton_ptr)))
2013-06-27 13:18:48 +02:00
DBUG_RETURN(0); /* transaction is not started */
/* In case the rollback happens due to failure of LOCK TABLE, we
need to clear the list of tables to lock. */
for (uint i= 0; i < trx->trx_conn_hash.records; i++)
{
conn= (SPIDER_CONN *) my_hash_element(&trx->trx_conn_hash, i);
conn->db_conn->reset_lock_table_hash();
}
2013-06-27 13:18:48 +02:00
if (all || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
{
if (trx->trx_start)
{
if (trx->trx_xa)
{
int tmp_error_num;
2013-06-27 13:18:48 +02:00
if (
(tmp_error_num = spider_internal_xa_rollback(thd, trx))
) {
if (tmp_error_num)
error_num = tmp_error_num;
}
2013-06-27 13:18:48 +02:00
trx->trx_xa = FALSE;
2014-03-24 20:14:30 +01:00
trx->join_trx_top = NULL;
2013-06-27 13:18:48 +02:00
} else {
if ((conn = spider_tree_first(trx->join_trx_top)))
{
SPIDER_BACKUP_DASTATUS;
int tmp_error_num;
do {
if (
!conn->server_lost &&
(conn->autocommit != 1 || conn->trx_start) &&
(tmp_error_num = spider_db_rollback(conn))
) {
SPIDER_CONN_RESTORE_DASTATUS_AND_RESET_TMP_ERROR_NUM;
if (tmp_error_num)
error_num = tmp_error_num;
}
if ((tmp_error_num = spider_end_trx(trx, conn)))
{
SPIDER_CONN_RESTORE_DASTATUS_AND_RESET_TMP_ERROR_NUM;
if (tmp_error_num)
error_num = tmp_error_num;
}
conn->join_trx = 0;
} while ((conn = spider_tree_next(conn)));
trx->join_trx_top = NULL;
}
}
trx->trx_start = FALSE;
trx->updated_in_this_trx = FALSE;
DBUG_PRINT("info",("spider trx->trx_start=FALSE"));
DBUG_PRINT("info",("spider trx->updated_in_this_trx=FALSE"));
2013-06-27 13:18:48 +02:00
}
spider_reuse_trx_ha(trx);
spider_free_trx_conn(trx, FALSE);
trx->trx_consistent_snapshot = FALSE;
}
spider_merge_mem_calc(trx, FALSE);
DBUG_RETURN(error_num);
}
int spider_xa_prepare(
handlerton *hton,
THD* thd,
bool all
) {
int error_num;
SPIDER_TRX *trx;
TABLE *table_xa = NULL;
TABLE *table_xa_member = NULL;
DBUG_ENTER("spider_xa_prepare");
if (all || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
{
if (!(trx = (SPIDER_TRX*) thd_get_ha_data(thd, spider_hton_ptr)))
2013-06-27 13:18:48 +02:00
DBUG_RETURN(0); /* transaction is not started */
DBUG_PRINT("info",("spider trx_start=%s",
trx->trx_start ? "TRUE" : "FALSE"));
DBUG_PRINT("info",("spider trx_xa=%s",
trx->trx_xa ? "TRUE" : "FALSE"));
if (trx->trx_start && trx->trx_xa)
{
if ((error_num = spider_internal_xa_prepare(
thd, trx, table_xa, table_xa_member, FALSE)))
goto error;
2014-03-24 20:42:40 +01:00
trx->trx_xa_prepared = TRUE;
2013-06-27 13:18:48 +02:00
}
}
DBUG_RETURN(0);
error:
DBUG_RETURN(error_num);
}
int spider_xa_recover(
handlerton *hton,
XID* xid_list,
uint len
) {
THD* thd = current_thd;
DBUG_ENTER("spider_xa_recover");
if (len == 0 || xid_list == NULL)
DBUG_RETURN(0);
if (thd)
DBUG_RETURN(spider_internal_xa_recover(thd, xid_list, len));
else
DBUG_RETURN(spider_initinal_xa_recover(xid_list, len));
}
int spider_xa_commit_by_xid(
handlerton *hton,
XID* xid
) {
SPIDER_TRX *trx;
int error_num;
THD* thd = current_thd;
DBUG_ENTER("spider_xa_commit_by_xid");
if (!(trx = spider_get_trx(thd, TRUE, &error_num)))
goto error_get_trx;
if ((error_num = spider_internal_xa_commit_by_xid(thd, trx, xid)))
goto error;
DBUG_RETURN(0);
error:
error_get_trx:
DBUG_RETURN(error_num);
}
int spider_xa_rollback_by_xid(
handlerton *hton,
XID* xid
) {
SPIDER_TRX *trx;
int error_num;
THD* thd = current_thd;
DBUG_ENTER("spider_xa_rollback_by_xid");
if (!(trx = spider_get_trx(thd, TRUE, &error_num)))
goto error_get_trx;
if ((error_num = spider_internal_xa_rollback_by_xid(thd, trx, xid)))
goto error;
DBUG_RETURN(0);
error:
error_get_trx:
DBUG_RETURN(error_num);
}
2014-03-24 20:42:40 +01:00
void spider_copy_table_free_trx_conn(
SPIDER_TRX *trx
) {
SPIDER_CONN *conn;
DBUG_ENTER("spider_copy_table_free_trx_conn");
if ((conn = spider_tree_first(trx->join_trx_top)))
{
do {
spider_end_trx(trx, conn);
conn->join_trx = 0;
} while ((conn = spider_tree_next(conn)));
trx->join_trx_top = NULL;
}
spider_reuse_trx_ha(trx);
spider_free_trx_conn(trx, FALSE);
trx->trx_consistent_snapshot = FALSE;
spider_merge_mem_calc(trx, FALSE);
DBUG_VOID_RETURN;
}
2013-06-27 13:18:48 +02:00
int spider_end_trx(
SPIDER_TRX *trx,
SPIDER_CONN *conn
) {
int error_num = 0, need_mon = 0;
DBUG_ENTER("spider_end_trx");
if (conn->table_lock == 3)
{
2014-03-24 21:33:41 +01:00
trx->tmp_spider->conns = &conn;
2013-06-27 13:18:48 +02:00
conn->table_lock = 0;
conn->disable_reconnect = FALSE;
if (
!conn->server_lost &&
2014-03-24 21:33:41 +01:00
(error_num = spider_db_unlock_tables(trx->tmp_spider, 0))
2013-06-27 13:18:48 +02:00
) {
if (error_num == ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM)
error_num = 0;
}
} else if (!conn->table_lock)
conn->disable_reconnect = FALSE;
if (
conn->semi_trx_isolation >= 0 &&
conn->trx_isolation != conn->semi_trx_isolation
) {
DBUG_PRINT("info",("spider conn=%p", conn));
DBUG_PRINT("info",("spider conn->trx_isolation=%d", conn->trx_isolation));
if (
!conn->server_lost &&
!conn->queued_semi_trx_isolation &&
(error_num = spider_db_set_trx_isolation(
conn, conn->trx_isolation, &need_mon))
) {
if (
!conn->disable_reconnect &&
error_num == ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM
)
error_num = 0;
}
}
conn->semi_trx_isolation = -2;
conn->semi_trx_isolation_chk = FALSE;
conn->semi_trx_chk = FALSE;
DBUG_RETURN(error_num);
}
int spider_check_trx_and_get_conn(
THD *thd,
ha_spider *spider,
bool use_conn_kind
) {
int error_num, roop_count, search_link_idx;
SPIDER_TRX *trx;
SPIDER_SHARE *share = spider->share;
SPIDER_CONN *conn;
char first_byte, first_byte_bak;
int semi_table_lock_conn = spider_param_semi_table_lock_connection(thd,
share->semi_table_lock_conn);
DBUG_ENTER("spider_check_trx_and_get_conn");
if (!(trx = spider_get_trx(thd, TRUE, &error_num)))
{
DBUG_PRINT("info",("spider get trx error"));
DBUG_RETURN(error_num);
}
spider->wide_handler->trx = trx;
2013-06-27 13:18:48 +02:00
spider->set_error_mode();
if (spider->wide_handler->sql_command != SQLCOM_DROP_TABLE)
{
2013-06-27 13:18:48 +02:00
SPIDER_TRX_HA *trx_ha = spider_check_trx_ha(trx, spider);
if (!trx_ha || trx_ha->wait_for_reusing)
spider_trx_set_link_idx_for_all(spider);
if (semi_table_lock_conn)
first_byte = '0' +
spider_param_semi_table_lock(thd, share->semi_table_lock);
else
first_byte = '0';
DBUG_PRINT("info",("spider semi_table_lock_conn = %d",
semi_table_lock_conn));
DBUG_PRINT("info",("spider semi_table_lock = %d",
spider_param_semi_table_lock(thd, share->semi_table_lock)));
DBUG_PRINT("info",("spider first_byte = %d", first_byte));
if (
!trx_ha ||
trx_ha->wait_for_reusing ||
trx->spider_thread_id != spider->spider_thread_id ||
trx->trx_conn_adjustment != spider->trx_conn_adjustment ||
first_byte != *spider->conn_keys[0] ||
share->link_statuses[spider->conn_link_idx[spider->search_link_idx]] ==
SPIDER_LINK_STATUS_NG
) {
DBUG_PRINT("info",(first_byte != *spider->conn_keys[0] ?
"spider change conn type" : trx != spider->wide_handler->trx ?
"spider change thd" : "spider next trx"));
spider->wide_handler->trx = trx;
2013-06-27 13:18:48 +02:00
spider->trx_conn_adjustment = trx->trx_conn_adjustment;
if (
spider->spider_thread_id != trx->spider_thread_id ||
spider->search_link_query_id != thd->query_id
) {
search_link_idx = spider_conn_first_link_idx(thd,
share->link_statuses, share->access_balances, spider->conn_link_idx,
share->link_count, SPIDER_LINK_STATUS_OK);
if (search_link_idx == -1)
{
TABLE *table = spider->get_table();
TABLE_SHARE *table_share = table->s;
char *db = (char *) my_alloca(
table_share->db.length + 1 + table_share->table_name.length + 1);
if (!db)
{
my_error(HA_ERR_OUT_OF_MEM, MYF(0));
2013-06-27 13:18:48 +02:00
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
char *table_name = db + table_share->db.length + 1;
2013-06-27 13:18:48 +02:00
memcpy(db, table_share->db.str, table_share->db.length);
db[table_share->db.length] = '\0';
memcpy(table_name, table_share->table_name.str,
table_share->table_name.length);
table_name[table_share->table_name.length] = '\0';
my_printf_error(ER_SPIDER_ALL_LINKS_FAILED_NUM,
ER_SPIDER_ALL_LINKS_FAILED_STR, MYF(0), db, table_name);
my_afree(db);
2013-06-27 13:18:48 +02:00
DBUG_RETURN(ER_SPIDER_ALL_LINKS_FAILED_NUM);
} else if (search_link_idx == -2)
{
my_error(HA_ERR_OUT_OF_MEM, MYF(0));
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
2013-06-27 13:18:48 +02:00
}
spider->search_link_idx = search_link_idx;
spider->search_link_query_id = thd->query_id;
}
spider->spider_thread_id = trx->spider_thread_id;
first_byte_bak = *spider->conn_keys[0];
*spider->conn_keys[0] = first_byte;
for (roop_count = 0; roop_count < (int) share->link_count; roop_count++)
{
if (!spider->handler_opened(roop_count, SPIDER_CONN_KIND_MYSQL))
spider->conns[roop_count] = NULL;
}
2015-10-28 23:34:53 +01:00
bool search_link_idx_is_checked = FALSE;
2013-06-27 13:18:48 +02:00
for (
roop_count = spider_conn_link_idx_next(share->link_statuses,
spider->conn_link_idx, -1, share->link_count,
SPIDER_LINK_STATUS_RECOVERY);
roop_count < (int) share->link_count;
roop_count = spider_conn_link_idx_next(share->link_statuses,
spider->conn_link_idx, roop_count, share->link_count,
SPIDER_LINK_STATUS_RECOVERY)
) {
uint tgt_conn_kind = (use_conn_kind ? spider->conn_kind[roop_count] :
SPIDER_CONN_KIND_MYSQL);
2015-10-28 23:34:53 +01:00
if (roop_count == spider->search_link_idx)
search_link_idx_is_checked = TRUE;
2013-06-27 13:18:48 +02:00
if (
tgt_conn_kind == SPIDER_CONN_KIND_MYSQL &&
!spider->conns[roop_count]
) {
*spider->conn_keys[roop_count] = first_byte;
if (
!(conn =
spider_get_conn(share, roop_count,
spider->conn_keys[roop_count], trx,
spider, FALSE, TRUE,
use_conn_kind ? spider->conn_kind[roop_count] :
SPIDER_CONN_KIND_MYSQL,
&error_num))
) {
if (
share->monitoring_kind[roop_count] &&
spider->need_mons[roop_count]
) {
error_num = spider_ping_table_mon_from_table(
trx,
trx->thd,
share,
roop_count,
2013-06-27 13:18:48 +02:00
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
spider->conn_link_idx[roop_count],
NULL,
0,
share->monitoring_kind[roop_count],
share->monitoring_limit[roop_count],
2015-10-28 23:34:53 +01:00
share->monitoring_flag[roop_count],
2013-06-27 13:18:48 +02:00
TRUE
);
}
DBUG_PRINT("info",("spider get conn error"));
*spider->conn_keys[0] = first_byte_bak;
spider->spider_thread_id = 0;
DBUG_RETURN(error_num);
}
conn->error_mode &= spider->error_mode;
}
}
2015-10-28 23:34:53 +01:00
if (!search_link_idx_is_checked)
{
TABLE *table = spider->get_table();
TABLE_SHARE *table_share = table->s;
char *db = (char *) my_alloca(
table_share->db.length + 1 + table_share->table_name.length + 1);
if (!db)
{
my_error(HA_ERR_OUT_OF_MEM, MYF(0));
2015-10-28 23:34:53 +01:00
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
char *table_name = db + table_share->db.length + 1;
2015-10-28 23:34:53 +01:00
memcpy(db, table_share->db.str, table_share->db.length);
db[table_share->db.length] = '\0';
memcpy(table_name, table_share->table_name.str,
table_share->table_name.length);
table_name[table_share->table_name.length] = '\0';
my_printf_error(ER_SPIDER_LINK_MON_JUST_NG_NUM,
ER_SPIDER_LINK_MON_JUST_NG_STR, MYF(0), db, table_name);
my_afree(db);
2015-10-28 23:34:53 +01:00
DBUG_RETURN(ER_SPIDER_LINK_MON_JUST_NG_NUM);
}
2013-06-27 13:18:48 +02:00
} else {
2014-03-24 20:39:17 +01:00
DBUG_PRINT("info",("spider link_status = %ld",
share->link_statuses[spider->conn_link_idx[spider->search_link_idx]]));
2015-10-28 23:34:53 +01:00
bool search_link_idx_is_checked = FALSE;
2013-06-27 13:18:48 +02:00
for (
roop_count = spider_conn_link_idx_next(share->link_statuses,
spider->conn_link_idx, -1, share->link_count,
SPIDER_LINK_STATUS_RECOVERY);
roop_count < (int) share->link_count;
roop_count = spider_conn_link_idx_next(share->link_statuses,
spider->conn_link_idx, roop_count, share->link_count,
SPIDER_LINK_STATUS_RECOVERY)
) {
2015-10-28 23:34:53 +01:00
if (roop_count == spider->search_link_idx)
search_link_idx_is_checked = TRUE;
conn = spider->conns[roop_count];
2013-06-27 13:18:48 +02:00
if (!conn)
{
DBUG_PRINT("info",("spider get conn %d", roop_count));
if (
!(conn =
spider_get_conn(share, roop_count,
spider->conn_keys[roop_count], trx,
spider, FALSE, TRUE,
use_conn_kind ? spider->conn_kind[roop_count] :
SPIDER_CONN_KIND_MYSQL,
&error_num))
) {
if (
share->monitoring_kind[roop_count] &&
spider->need_mons[roop_count]
) {
error_num = spider_ping_table_mon_from_table(
trx,
trx->thd,
share,
roop_count,
2013-06-27 13:18:48 +02:00
(uint32) share->monitoring_sid[roop_count],
share->table_name,
share->table_name_length,
spider->conn_link_idx[roop_count],
NULL,
0,
share->monitoring_kind[roop_count],
share->monitoring_limit[roop_count],
2015-10-28 23:34:53 +01:00
share->monitoring_flag[roop_count],
2013-06-27 13:18:48 +02:00
TRUE
);
}
DBUG_PRINT("info",("spider get conn error"));
DBUG_RETURN(error_num);
}
}
conn->error_mode &= spider->error_mode;
}
2015-10-28 23:34:53 +01:00
if (!search_link_idx_is_checked)
{
TABLE *table = spider->get_table();
TABLE_SHARE *table_share = table->s;
char *db = (char *) my_alloca(
table_share->db.length + 1 + table_share->table_name.length + 1);
if (!db)
{
my_error(HA_ERR_OUT_OF_MEM, MYF(0));
2015-10-28 23:34:53 +01:00
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
char *table_name = db + table_share->db.length + 1;
2015-10-28 23:34:53 +01:00
memcpy(db, table_share->db.str, table_share->db.length);
db[table_share->db.length] = '\0';
memcpy(table_name, table_share->table_name.str,
table_share->table_name.length);
table_name[table_share->table_name.length] = '\0';
my_printf_error(ER_SPIDER_LINK_MON_JUST_NG_NUM,
ER_SPIDER_LINK_MON_JUST_NG_STR, MYF(0), db, table_name);
my_afree(db);
2015-10-28 23:34:53 +01:00
DBUG_RETURN(ER_SPIDER_LINK_MON_JUST_NG_NUM);
}
2013-06-27 13:18:48 +02:00
}
spider->set_first_link_idx();
DBUG_RETURN(spider_create_trx_ha(trx, spider, trx_ha));
}
spider->spider_thread_id = trx->spider_thread_id;
DBUG_RETURN(0);
}
THD *spider_create_tmp_thd()
{
THD *thd;
DBUG_ENTER("spider_create_tmp_thd");
if (!(thd = SPIDER_new_THD((my_thread_id) 0)))
2013-06-27 13:18:48 +02:00
DBUG_RETURN(NULL);
thd->killed = NOT_KILLED;
thd->proc_info = "";
thd->thread_stack = (char*) &thd;
thd->store_globals();
2013-06-27 13:18:48 +02:00
lex_start(thd);
DBUG_RETURN(thd);
}
void spider_free_tmp_thd(
THD *thd
) {
DBUG_ENTER("spider_free_tmp_thd");
2014-03-24 20:51:28 +01:00
thd->cleanup();
2013-09-24 19:42:49 +02:00
thd->reset_globals();
2013-06-27 13:18:48 +02:00
delete thd;
DBUG_VOID_RETURN;
}
/*
Check the info of a given SPIDER_TRX_HA with spider->share. If it
does not match or if the given SPIDER_TRX_HA is NULL, then create a
new one from spider and spider->share, and add the new SPIDER_TRX_HA
to trx->trx_ha_hash. On mismatch and non-NULL trx_ha, then it will
be removed from the hash and freed before the creation of a new one.
*/
2013-06-27 13:18:48 +02:00
int spider_create_trx_ha(
SPIDER_TRX *trx,
ha_spider *spider,
SPIDER_TRX_HA *trx_ha
) {
bool need_create;
char *tmp_name;
uint *conn_link_idx;
uchar *conn_can_fo;
SPIDER_SHARE *share = spider->share;
DBUG_ENTER("spider_create_trx_ha");
if (!trx_ha)
{
DBUG_PRINT("info",("spider need create"));
need_create = TRUE;
} else if (
trx_ha->share != share ||
trx_ha->link_count != share->link_count ||
trx_ha->link_bitmap_size != share->link_bitmap_size
) {
DBUG_PRINT("info",("spider need recreate"));
need_create = TRUE;
my_hash_delete(&trx->trx_ha_hash, (uchar*) trx_ha);
spider_free(trx, trx_ha, MYF(0));
} else {
DBUG_PRINT("info",("spider use this"));
trx_ha->wait_for_reusing = FALSE;
need_create = FALSE;
}
if (need_create)
{
if (!(trx_ha = (SPIDER_TRX_HA *)
spider_bulk_malloc(spider_current_trx, SPD_MID_CREATE_TRX_HA_1, MYF(MY_WME),
&trx_ha, (uint) (sizeof(SPIDER_TRX_HA)),
&tmp_name, (uint) (sizeof(char *) * (share->table_name_length + 1)),
&conn_link_idx, (uint) (sizeof(uint) * share->link_count),
&conn_can_fo, (uint) (sizeof(uchar) * share->link_bitmap_size),
2013-06-27 13:18:48 +02:00
NullS))
) {
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
trx_ha->table_name = tmp_name;
memcpy(trx_ha->table_name, share->table_name, share->table_name_length);
trx_ha->table_name[share->table_name_length] = '\0';
trx_ha->table_name_length = share->table_name_length;
trx_ha->share = share;
trx_ha->link_count = share->link_count;
trx_ha->link_bitmap_size = share->link_bitmap_size;
trx_ha->conn_link_idx = conn_link_idx;
trx_ha->conn_can_fo = conn_can_fo;
trx_ha->wait_for_reusing = FALSE;
uint old_elements = trx->trx_ha_hash.array.max_element;
if (my_hash_insert(&trx->trx_ha_hash, (uchar*) trx_ha))
{
spider_free(trx, trx_ha, MYF(0));
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
if (trx->trx_ha_hash.array.max_element > old_elements)
{
spider_alloc_calc_mem(spider_current_trx,
trx->trx_ha_hash,
(trx->trx_ha_hash.array.max_element - old_elements) *
trx->trx_ha_hash.array.size_of_element);
}
}
memcpy(trx_ha->conn_link_idx, spider->conn_link_idx,
sizeof(uint) * share->link_count);
memcpy(trx_ha->conn_can_fo, spider->conn_can_fo,
sizeof(uint) * share->link_bitmap_size);
DBUG_RETURN(0);
}
SPIDER_TRX_HA *spider_check_trx_ha(
SPIDER_TRX *trx,
ha_spider *spider
) {
SPIDER_TRX_HA *trx_ha;
SPIDER_SHARE *share = spider->share;
DBUG_ENTER("spider_check_trx_ha");
/*
Check for mismatch in trx_ha->share, link_count and
link_bitmap_size, which is an indication of a share that has been
freed. Delete the trx_ha and return NULL on mismatch.
*/
2013-06-27 13:18:48 +02:00
if ((trx_ha = (SPIDER_TRX_HA *) my_hash_search_using_hash_value(
&trx->trx_ha_hash, share->table_name_hash_value,
(uchar*) share->table_name, share->table_name_length)))
{
if (trx_ha->share == share && trx_ha->link_count == share->link_count &&
trx_ha->link_bitmap_size == share->link_bitmap_size)
{
memcpy(spider->conn_link_idx, trx_ha->conn_link_idx,
sizeof(uint) * share->link_count);
memcpy(spider->conn_can_fo, trx_ha->conn_can_fo,
sizeof(uint) * share->link_bitmap_size);
DBUG_RETURN(trx_ha);
}
else
{
my_hash_delete(&trx->trx_ha_hash, (uchar*) trx_ha);
spider_free(trx, trx_ha, MYF(0));
}
2013-06-27 13:18:48 +02:00
}
DBUG_RETURN(NULL);
}
void spider_free_trx_ha(
SPIDER_TRX *trx
) {
ulong roop_count;
SPIDER_TRX_HA *trx_ha;
DBUG_ENTER("spider_free_trx_ha");
for (roop_count = 0; roop_count < trx->trx_ha_hash.records; roop_count++)
{
trx_ha = (SPIDER_TRX_HA *) my_hash_element(&trx->trx_ha_hash, roop_count);
spider_free(spider_current_trx, trx_ha, MYF(0));
}
my_hash_reset(&trx->trx_ha_hash);
DBUG_VOID_RETURN;
}
void spider_reuse_trx_ha(
SPIDER_TRX *trx
) {
ulong roop_count;
SPIDER_TRX_HA *trx_ha;
DBUG_ENTER("spider_reuse_trx_ha");
if (trx->trx_ha_reuse_count < 10000)
{
trx->trx_ha_reuse_count++;
for (roop_count = 0; roop_count < trx->trx_ha_hash.records; roop_count++)
{
trx_ha = (SPIDER_TRX_HA *) my_hash_element(&trx->trx_ha_hash,
roop_count);
trx_ha->wait_for_reusing = TRUE;
}
} else {
trx->trx_ha_reuse_count = 0;
spider_free_trx_ha(trx);
}
DBUG_VOID_RETURN;
}
/**
Sets link indices for load balancing read connections
Assuming `spider->share->link_count` is the number of active servers
to use, this function updates `spider->conn_link_idx` with the first
server in the same "modulus group" whose link status is not
`SPIDER_LINK_STATUS_NG`, or if one cannot be found, use the
`link_idx`th server
*/
2013-06-27 13:18:48 +02:00
void spider_trx_set_link_idx_for_all(
ha_spider *spider
) {
int roop_count, roop_count2;
SPIDER_SHARE *share = spider->share;
long *link_statuses = share->link_statuses;
uint *conn_link_idx = spider->conn_link_idx;
int link_count = share->link_count;
int all_link_count = share->all_link_count;
uchar *conn_can_fo = spider->conn_can_fo;
DBUG_ENTER("spider_trx_set_link_idx_for_all");
DBUG_PRINT("info",("spider set link_count=%d", link_count));
DBUG_PRINT("info",("spider set all_link_count=%d", all_link_count));
memset(conn_can_fo, 0, sizeof(uchar) * share->link_bitmap_size);
for (roop_count = 0; roop_count < link_count; roop_count++)
{
for (roop_count2 = roop_count; roop_count2 < all_link_count;
roop_count2 += link_count)
{
if (link_statuses[roop_count2] <= SPIDER_LINK_STATUS_RECOVERY)
break;
}
if (roop_count2 < all_link_count)
{
conn_link_idx[roop_count] = roop_count2;
if (roop_count2 + link_count < all_link_count)
spider_set_bit(conn_can_fo, roop_count);
DBUG_PRINT("info",("spider set conn_link_idx[%d]=%d",
roop_count, roop_count2));
} else {
conn_link_idx[roop_count] = roop_count;
DBUG_PRINT("info",("spider set2 conn_link_idx[%d]=%d",
roop_count, roop_count));
}
spider->conn_keys[roop_count] =
ADD_TO_PTR(spider->conn_keys_first_ptr,
PTR_BYTE_DIFF(share->conn_keys[conn_link_idx[roop_count]],
share->conn_keys[0]), char*);
DBUG_PRINT("info",("spider conn_keys[%d]=%s",
roop_count, spider->conn_keys[roop_count]));
}
DBUG_VOID_RETURN;
}
int spider_trx_check_link_idx_failed(
ha_spider *spider
) {
int roop_count;
SPIDER_SHARE *share = spider->share;
long *link_statuses = share->link_statuses;
uint *conn_link_idx = spider->conn_link_idx;
int link_count = share->link_count;
uchar *conn_can_fo = spider->conn_can_fo;
DBUG_ENTER("spider_trx_check_link_idx_failed");
2013-06-27 13:18:48 +02:00
for (roop_count = 0; roop_count < link_count; roop_count++)
{
if (
link_statuses[conn_link_idx[roop_count]] == SPIDER_LINK_STATUS_NG &&
spider_bit_is_set(conn_can_fo, roop_count)
) {
my_message(ER_SPIDER_LINK_IS_FAILOVER_NUM,
ER_SPIDER_LINK_IS_FAILOVER_STR, MYF(0));
DBUG_RETURN(ER_SPIDER_LINK_IS_FAILOVER_NUM);
}
}
DBUG_RETURN(0);
}