mariadb/storage/spider/spd_trx.cc
Nayuta Yanagisawa a26700cca5 MDEV-28352 Spider: heap-use-after-free in ha_spider::lock_tables(), heap freed by spider_commit()
The heap-use-after-free is caused by the following mechanism:

  * In the execution of FLUSH TABLE WITH READ LOCK, the function
    spider_free_trx_conn() is called and the connections held by
    SPIDER_TRX::trx_conn_hash are freed.

  * Then, an instance of ha_spider maintains the freed connections
    because they are also referenced from ha_spider::conns.
    The ha_spider instance is kept in a lock structure until the
    corresponding table is unlocked.

  * Spider accesses ha_spider::conns on the implicit UNLOCK TABLE
    issued by BEGIN.

In the first place, when the connections have been freed, it means
that there are really no remote table locked by Spider.
Thus, there is no need for Spider to access ha_spider::cons on the
implicit UNLOCK TABLE.

We can fix the bug by removing the above mentioned access to
ha_spider::conns. We also modified spider_free_trx_conn() so that it
frees the connections only when no table is locked to reduce the
chance of another heap-use-after-free on ha_spider::conns.
2022-06-28 01:03:33 +09:00

4371 lines
137 KiB
C++

/* Copyright (C) 2008-2019 Kentoku Shiba
Copyright (C) 2019 MariaDB corp
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
#define MYSQL_SERVER 1
#include <my_global.h>
#include "mysql_version.h"
#include "spd_environ.h"
#if MYSQL_VERSION_ID < 50500
#include "mysql_priv.h"
#include <mysql/plugin.h>
#else
#include "sql_priv.h"
#include "probes_mysql.h"
#include "sql_class.h"
#include "sql_partition.h"
#include "records.h"
#endif
#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"
#ifdef SPIDER_XID_USES_xid_cache_iterate
#else
#ifdef XID_CACHE_IS_SPLITTED
extern uint *spd_db_att_xid_cache_split_num;
#endif
extern pthread_mutex_t *spd_db_att_LOCK_xid_cache;
extern HASH *spd_db_att_xid_cache;
#endif
extern struct charset_info_st *spd_charset_utf8mb3_bin;
extern handlerton *spider_hton_ptr;
extern SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE];
pthread_mutex_t spider_thread_id_mutex;
ulonglong spider_thread_id = 1;
#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
uchar *spider_alter_tbl_get_key(
SPIDER_ALTER_TABLE *alter_table,
size_t *length,
my_bool not_used __attribute__ ((unused))
) {
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((uchar*) alter_table->table_name);
}
// for SPIDER_TRX_HA
uchar *spider_trx_ha_get_key(
SPIDER_TRX_HA *trx_ha,
size_t *length,
my_bool not_used __attribute__ ((unused))
) {
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((uchar*) trx_ha->table_name);
}
/*
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;
SPIDER_CONN *conn;
HASH *conn_hash= &trx->trx_conn_hash;
DBUG_ENTER("spider_free_trx_conn");
DBUG_ASSERT(!trx_free || !trx->locked_connections);
/* 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++;
}
if (trx_free || spider_param_conn_recycle_mode(trx->thd) != 2)
{
/* Free connections only when no connection is locked. */
if (!trx->locked_connections)
{
loop_count= 0;
while ((conn= (SPIDER_CONN *) my_hash_element(conn_hash, loop_count)))
{
spider_free_conn_from_trx(trx, conn, FALSE, trx_free, &loop_count);
}
}
trx->trx_conn_adjustment++;
DBUG_RETURN(0);
}
loop_count= 0;
while ((conn= (SPIDER_CONN *) my_hash_element(conn_hash, loop_count)))
{
if (!conn->table_lock)
{
conn->error_mode= 1;
}
loop_count++;
}
DBUG_RETURN(0);
}
int spider_free_trx_another_conn(
SPIDER_TRX *trx,
bool lock
) {
int error_num, tmp_error_num;
int roop_count = 0;
SPIDER_CONN *conn;
DBUG_ENTER("spider_free_trx_another_conn");
trx->tmp_spider->conns = &conn;
error_num = 0;
while ((conn = (SPIDER_CONN*) my_hash_element(&trx->trx_another_conn_hash,
roop_count)))
{
if (lock && (tmp_error_num = spider_db_unlock_tables(trx->tmp_spider, 0)))
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;
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(188);
sql_str.length(0);
memset((void*)&tmp_spider, 0, sizeof(ha_spider));
memset((void*)&tmp_share, 0, sizeof(SPIDER_SHARE));
memset((void*)&tmp_wide_handler, 0, sizeof(SPIDER_WIDE_HANDLER));
tmp_spider.share = &tmp_share;
tmp_spider.wide_handler = &tmp_wide_handler;
tmp_wide_handler.trx = trx;
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;
memset((void*)&tmp_spider, 0, sizeof(ha_spider));
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;
memset((void*)&tmp_spider, 0, sizeof(ha_spider));
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;
int roop_count = 0;
THD *thd = trx->thd;
SPIDER_CONN *conn;
DBUG_ENTER("spider_trx_all_unlock_tables");
SPIDER_BACKUP_DASTATUS;
trx->tmp_spider->conns = &conn;
while ((conn = (SPIDER_CONN*) my_hash_element(&trx->trx_conn_hash,
roop_count)))
{
if ((error_num = spider_db_unlock_tables(trx->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_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;
DBUG_ENTER("spider_trx_all_start_trx");
SPIDER_BACKUP_DASTATUS;
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;
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))
) {
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;
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;
memset((void*)&tmp_spider, 0, sizeof(ha_spider));
memset(&tmp_wide_handler, 0, sizeof(SPIDER_WIDE_HANDLER));
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;
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");
#ifdef HASH_UPDATE_WITH_HASH_VALUE
my_hash_delete_with_hash_value(&trx->trx_alter_table_hash,
alter_table->table_name_hash_value, (uchar*) alter_table);
#else
my_hash_delete(&trx->trx_alter_table_hash, (uchar*) alter_table);
#endif
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);
}
int spider_create_trx_alter_table(
SPIDER_TRX *trx,
SPIDER_SHARE *share,
bool now_create
) {
int error_num, roop_count;
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;
char **tmp_tgt_dsns;
char **tmp_static_link_ids;
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;
uint *tmp_tgt_dsns_lengths;
uint *tmp_static_link_ids_lengths;
long *tmp_tgt_ports;
long *tmp_tgt_ssl_vscs;
long *tmp_monitoring_binlog_pos_at_failing;
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;
char *tmp_tgt_dsns_char;
char *tmp_static_link_ids_char;
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, 55, 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),
&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),
&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)),
&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)),
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;
#ifdef SPIDER_HAS_HASH_VALUE_TYPE
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;
#endif
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;
alter_table->tmp_tgt_dsns = tmp_tgt_dsns;
alter_table->tmp_static_link_ids = tmp_static_link_ids;
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;
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;
alter_table->tmp_tgt_dsns_lengths = tmp_tgt_dsns_lengths;
alter_table->tmp_static_link_ids_lengths = tmp_static_link_ids_lengths;
for(roop_count = 0; roop_count < (int) share->all_link_count; roop_count++)
{
tmp_server_names[roop_count] = tmp_server_names_char;
memcpy(tmp_server_names_char,
share_alter->tmp_server_names[roop_count],
sizeof(char) * share_alter->tmp_server_names_lengths[roop_count]);
tmp_server_names_char +=
share_alter->tmp_server_names_lengths[roop_count] + 1;
tmp_tgt_table_names[roop_count] = tmp_tgt_table_names_char;
memcpy(tmp_tgt_table_names_char,
share_alter->tmp_tgt_table_names[roop_count],
sizeof(char) * share_alter->tmp_tgt_table_names_lengths[roop_count]);
tmp_tgt_table_names_char +=
share_alter->tmp_tgt_table_names_lengths[roop_count] + 1;
tmp_tgt_dbs[roop_count] = tmp_tgt_dbs_char;
memcpy(tmp_tgt_dbs_char, share_alter->tmp_tgt_dbs[roop_count],
sizeof(char) * share_alter->tmp_tgt_dbs_lengths[roop_count]);
tmp_tgt_dbs_char +=
share_alter->tmp_tgt_dbs_lengths[roop_count] + 1;
tmp_tgt_hosts[roop_count] = tmp_tgt_hosts_char;
memcpy(tmp_tgt_hosts_char, share_alter->tmp_tgt_hosts[roop_count],
sizeof(char) * share_alter->tmp_tgt_hosts_lengths[roop_count]);
tmp_tgt_hosts_char +=
share_alter->tmp_tgt_hosts_lengths[roop_count] + 1;
tmp_tgt_usernames[roop_count] = tmp_tgt_usernames_char;
memcpy(tmp_tgt_usernames_char, share_alter->tmp_tgt_usernames[roop_count],
sizeof(char) * share_alter->tmp_tgt_usernames_lengths[roop_count]);
tmp_tgt_usernames_char +=
share_alter->tmp_tgt_usernames_lengths[roop_count] + 1;
tmp_tgt_passwords[roop_count] = tmp_tgt_passwords_char;
memcpy(tmp_tgt_passwords_char, share_alter->tmp_tgt_passwords[roop_count],
sizeof(char) * share_alter->tmp_tgt_passwords_lengths[roop_count]);
tmp_tgt_passwords_char +=
share_alter->tmp_tgt_passwords_lengths[roop_count] + 1;
tmp_tgt_sockets[roop_count] = tmp_tgt_sockets_char;
memcpy(tmp_tgt_sockets_char, share_alter->tmp_tgt_sockets[roop_count],
sizeof(char) * share_alter->tmp_tgt_sockets_lengths[roop_count]);
tmp_tgt_sockets_char +=
share_alter->tmp_tgt_sockets_lengths[roop_count] + 1;
tmp_tgt_wrappers[roop_count] = tmp_tgt_wrappers_char;
memcpy(tmp_tgt_wrappers_char, share_alter->tmp_tgt_wrappers[roop_count],
sizeof(char) * share_alter->tmp_tgt_wrappers_lengths[roop_count]);
tmp_tgt_wrappers_char +=
share_alter->tmp_tgt_wrappers_lengths[roop_count] + 1;
tmp_tgt_ssl_cas[roop_count] = tmp_tgt_ssl_cas_char;
memcpy(tmp_tgt_ssl_cas_char, share_alter->tmp_tgt_ssl_cas[roop_count],
sizeof(char) * share_alter->tmp_tgt_ssl_cas_lengths[roop_count]);
tmp_tgt_ssl_cas_char +=
share_alter->tmp_tgt_ssl_cas_lengths[roop_count] + 1;
tmp_tgt_ssl_capaths[roop_count] = tmp_tgt_ssl_capaths_char;
memcpy(tmp_tgt_ssl_capaths_char,
share_alter->tmp_tgt_ssl_capaths[roop_count],
sizeof(char) * share_alter->tmp_tgt_ssl_capaths_lengths[roop_count]);
tmp_tgt_ssl_capaths_char +=
share_alter->tmp_tgt_ssl_capaths_lengths[roop_count] + 1;
tmp_tgt_ssl_certs[roop_count] = tmp_tgt_ssl_certs_char;
memcpy(tmp_tgt_ssl_certs_char, share_alter->tmp_tgt_ssl_certs[roop_count],
sizeof(char) * share_alter->tmp_tgt_ssl_certs_lengths[roop_count]);
tmp_tgt_ssl_certs_char +=
share_alter->tmp_tgt_ssl_certs_lengths[roop_count] + 1;
tmp_tgt_ssl_ciphers[roop_count] = tmp_tgt_ssl_ciphers_char;
memcpy(tmp_tgt_ssl_ciphers_char,
share_alter->tmp_tgt_ssl_ciphers[roop_count],
sizeof(char) * share_alter->tmp_tgt_ssl_ciphers_lengths[roop_count]);
tmp_tgt_ssl_ciphers_char +=
share_alter->tmp_tgt_ssl_ciphers_lengths[roop_count] + 1;
tmp_tgt_ssl_keys[roop_count] = tmp_tgt_ssl_keys_char;
memcpy(tmp_tgt_ssl_keys_char, share_alter->tmp_tgt_ssl_keys[roop_count],
sizeof(char) * share_alter->tmp_tgt_ssl_keys_lengths[roop_count]);
tmp_tgt_ssl_keys_char +=
share_alter->tmp_tgt_ssl_keys_lengths[roop_count] + 1;
tmp_tgt_default_files[roop_count] = tmp_tgt_default_files_char;
memcpy(tmp_tgt_default_files_char,
share_alter->tmp_tgt_default_files[roop_count],
sizeof(char) * share_alter->tmp_tgt_default_files_lengths[roop_count]);
tmp_tgt_default_files_char +=
share_alter->tmp_tgt_default_files_lengths[roop_count] + 1;
tmp_tgt_default_groups[roop_count] = tmp_tgt_default_groups_char;
memcpy(tmp_tgt_default_groups_char,
share_alter->tmp_tgt_default_groups[roop_count],
sizeof(char) * share_alter->tmp_tgt_default_groups_lengths[roop_count]);
tmp_tgt_default_groups_char +=
share_alter->tmp_tgt_default_groups_lengths[roop_count] + 1;
tmp_tgt_dsns[roop_count] = tmp_tgt_dsns_char;
memcpy(tmp_tgt_dsns_char, share_alter->tmp_tgt_dsns[roop_count],
sizeof(char) * share_alter->tmp_tgt_dsns_lengths[roop_count]);
tmp_tgt_dsns_char +=
share_alter->tmp_tgt_dsns_lengths[roop_count] + 1;
if (share_alter->tmp_static_link_ids[roop_count])
{
tmp_static_link_ids[roop_count] = tmp_static_link_ids_char;
memcpy(tmp_static_link_ids_char,
share_alter->tmp_static_link_ids[roop_count],
sizeof(char) * share_alter->tmp_static_link_ids_lengths[roop_count]);
tmp_static_link_ids_char +=
share_alter->tmp_static_link_ids_lengths[roop_count] + 1;
}
}
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);
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);
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);
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;
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;
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;
alter_table->tmp_link_statuses_length =
share_alter->tmp_link_statuses_length;
old_elements = trx->trx_alter_table_hash.array.max_element;
#ifdef HASH_UPDATE_WITH_HASH_VALUE
if (my_hash_insert_with_hash_value(&trx->trx_alter_table_hash,
alter_table->table_name_hash_value, (uchar*) alter_table))
#else
if (my_hash_insert(&trx->trx_alter_table_hash, (uchar*) alter_table))
#endif
{
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])
)
) ||
(
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])
)
) ||
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] ||
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");
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);
}
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);
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
spider_free_mem_calc(spider_current_trx,
trx->trx_direct_hs_r_conn_hash_id,
trx->trx_direct_hs_r_conn_hash.array.max_element *
trx->trx_direct_hs_r_conn_hash.array.size_of_element);
my_hash_free(&trx->trx_direct_hs_r_conn_hash);
spider_free_mem_calc(spider_current_trx,
trx->trx_direct_hs_w_conn_hash_id,
trx->trx_direct_hs_w_conn_hash.array.max_element *
trx->trx_direct_hs_w_conn_hash.array.size_of_element);
my_hash_free(&trx->trx_direct_hs_w_conn_hash);
#endif
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
spider_free_mem_calc(spider_current_trx,
trx->trx_hs_r_conn_hash_id,
trx->trx_hs_r_conn_hash.array.max_element *
trx->trx_hs_r_conn_hash.array.size_of_element);
my_hash_free(&trx->trx_hs_r_conn_hash);
spider_free_mem_calc(spider_current_trx,
trx->trx_hs_w_conn_hash_id,
trx->trx_hs_w_conn_hash.array.max_element *
trx->trx_hs_w_conn_hash.array.size_of_element);
my_hash_free(&trx->trx_hs_w_conn_hash);
#endif
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);
free_root(&trx->mem_root, MYF(0));
DBUG_RETURN(0);
}
SPIDER_TRX *spider_get_trx(
THD *thd,
bool regist_allocated_thds,
int *error_num
) {
int roop_count = 0, roop_count2;
SPIDER_TRX *trx;
SPIDER_SHARE *tmp_share;
SPIDER_WIDE_HANDLER *tmp_wide_handler;
pthread_mutex_t *udf_table_mutexes;
DBUG_ENTER("spider_get_trx");
if (
!thd ||
!(trx = (SPIDER_TRX*) thd_get_ha_data(thd, spider_hton_ptr))
) {
DBUG_PRINT("info",("spider create new trx"));
if (!(trx = (SPIDER_TRX *)
spider_bulk_malloc(NULL, 56, 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()),
NullS))
)
goto error_alloc_trx;
SPD_INIT_ALLOC_ROOT(&trx->mem_root, 4096, 0, MYF(MY_WME));
trx->tmp_share = tmp_share;
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_VERSION_ID < 50500
if (pthread_mutex_init(&trx->udf_table_mutexes[roop_count],
MY_MUTEX_INIT_FAST))
#else
if (mysql_mutex_init(spd_key_mutex_udf_table,
&trx->udf_table_mutexes[roop_count], MY_MUTEX_INIT_FAST))
#endif
goto error_init_udf_table_mutex;
}
if (
my_hash_init(PSI_INSTRUMENT_ME, &trx->trx_conn_hash,
spd_charset_utf8mb3_bin, 32, 0, 0, (my_hash_get_key)
spider_conn_get_key, 0, 0)
)
goto error_init_hash;
spider_alloc_calc_mem_init(trx->trx_conn_hash, 151);
spider_alloc_calc_mem(
thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL,
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, (my_hash_get_key)
spider_conn_get_key, 0, 0)
)
goto error_init_another_hash;
spider_alloc_calc_mem_init(trx->trx_another_conn_hash, 152);
spider_alloc_calc_mem(
thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL,
trx->trx_another_conn_hash,
trx->trx_another_conn_hash.array.max_element *
trx->trx_another_conn_hash.array.size_of_element);
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
if (
my_hash_init(&trx->trx_hs_r_conn_hash, spd_charset_utf8mb3_bin, 32, 0, 0,
(my_hash_get_key) spider_conn_get_key, 0, 0)
)
goto error_hs_r_init_hash;
spider_alloc_calc_mem_init(trx->trx_hs_r_conn_hash, 153);
spider_alloc_calc_mem(
thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL,
trx->trx_hs_r_conn_hash,
trx->trx_hs_r_conn_hash.array.max_element *
trx->trx_hs_r_conn_hash.array.size_of_element);
if (
my_hash_init(&trx->trx_hs_w_conn_hash, spd_charset_utf8mb3_bin, 32, 0, 0,
(my_hash_get_key) spider_conn_get_key, 0, 0)
)
goto error_hs_w_init_hash;
spider_alloc_calc_mem_init(trx->trx_hs_w_conn_hash, 154);
spider_alloc_calc_mem(
thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL,
trx->trx_hs_w_conn_hash,
trx->trx_hs_w_conn_hash.array.max_element *
trx->trx_hs_w_conn_hash.array.size_of_element);
#endif
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
if (
my_hash_init(&trx->trx_direct_hs_r_conn_hash, spd_charset_utf8mb3_bin, 32,
0, 0, (my_hash_get_key) spider_conn_get_key, 0, 0)
)
goto error_direct_hs_r_init_hash;
spider_alloc_calc_mem_init(trx->trx_direct_hs_r_conn_hash, 155);
spider_alloc_calc_mem(
thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL,
trx->trx_direct_hs_r_conn_hash,
trx->trx_direct_hs_r_conn_hash.array.max_element *
trx->trx_direct_hs_r_conn_hash.array.size_of_element);
if (
my_hash_init(&trx->trx_direct_hs_w_conn_hash, spd_charset_utf8mb3_bin, 32,
0, 0, (my_hash_get_key) spider_conn_get_key, 0, 0)
)
goto error_direct_hs_w_init_hash;
spider_alloc_calc_mem_init(trx->trx_direct_hs_w_conn_hash, 156);
spider_alloc_calc_mem(
thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL,
trx->trx_direct_hs_w_conn_hash,
trx->trx_direct_hs_w_conn_hash.array.max_element *
trx->trx_direct_hs_w_conn_hash.array.size_of_element);
#endif
if (
my_hash_init(PSI_INSTRUMENT_ME, &trx->trx_alter_table_hash,
spd_charset_utf8mb3_bin, 32, 0, 0, (my_hash_get_key)
spider_alter_tbl_get_key, 0, 0)
)
goto error_init_alter_hash;
spider_alloc_calc_mem_init(trx->trx_alter_table_hash, 157);
spider_alloc_calc_mem(
thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL,
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, (my_hash_get_key)
spider_trx_ha_get_key, 0, 0)
)
goto error_init_trx_ha_hash;
spider_alloc_calc_mem_init(trx->trx_ha_hash, 158);
spider_alloc_calc_mem(
thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL,
trx->trx_ha_hash,
trx->trx_ha_hash.array.max_element *
trx->trx_ha_hash.array.size_of_element);
trx->thd = (THD*) thd;
#ifdef SPIDER_HAS_HASH_VALUE_TYPE
if (thd)
trx->thd_hash_value = my_calc_hash(&spider_allocated_thds,
(uchar*) thd, sizeof(THD *));
else
trx->thd_hash_value = 0;
#endif
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 defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
trx->trx_hs_r_conn_adjustment = 1;
trx->trx_hs_w_conn_adjustment = 1;
#endif
if (thd)
{
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;
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(121);
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;
}
}
if (regist_allocated_thds)
{
pthread_mutex_lock(&spider_allocated_thds_mutex);
uint old_elements = spider_allocated_thds.array.max_element;
#ifdef HASH_UPDATE_WITH_HASH_VALUE
if (my_hash_insert_with_hash_value(&spider_allocated_thds,
trx->thd_hash_value, (uchar*) thd))
#else
if (my_hash_insert(&spider_allocated_thds, (uchar*) thd))
#endif
{
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);
}
}
DBUG_PRINT("info",("spider trx=%p", trx));
DBUG_RETURN(trx);
error_allocated_thds_insert:
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);
}
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,
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:
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
spider_free_mem_calc(
thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL,
trx->trx_direct_hs_w_conn_hash_id,
trx->trx_direct_hs_w_conn_hash.array.max_element *
trx->trx_direct_hs_w_conn_hash.array.size_of_element);
my_hash_free(&trx->trx_direct_hs_w_conn_hash);
error_direct_hs_w_init_hash:
spider_free_mem_calc(
thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL,
trx->trx_direct_hs_r_conn_hash_id,
trx->trx_direct_hs_r_conn_hash.array.max_element *
trx->trx_direct_hs_r_conn_hash.array.size_of_element);
my_hash_free(&trx->trx_direct_hs_r_conn_hash);
error_direct_hs_r_init_hash:
#endif
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
spider_free_mem_calc(
thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL,
trx->trx_hs_w_conn_hash_id,
trx->trx_hs_w_conn_hash.array.max_element *
trx->trx_hs_w_conn_hash.array.size_of_element);
my_hash_free(&trx->trx_hs_w_conn_hash);
error_hs_w_init_hash:
spider_free_mem_calc(
thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL,
trx->trx_hs_r_conn_hash_id,
trx->trx_hs_r_conn_hash.array.max_element *
trx->trx_hs_r_conn_hash.array.size_of_element);
my_hash_free(&trx->trx_hs_r_conn_hash);
error_hs_r_init_hash:
#endif
spider_free_mem_calc(
thd ? ((SPIDER_TRX *) thd_get_ha_data(thd, spider_hton_ptr)) : NULL,
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,
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:
free_root(&trx->mem_root, MYF(0));
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
) {
DBUG_ENTER("spider_free_trx");
if (trx->thd)
{
if (trx->registed_allocated_thds)
{
if (need_lock)
pthread_mutex_lock(&spider_allocated_thds_mutex);
#ifdef HASH_UPDATE_WITH_HASH_VALUE
my_hash_delete_with_hash_value(&spider_allocated_thds,
trx->thd_hash_value, (uchar*) trx->thd);
#else
my_hash_delete(&spider_allocated_thds, (uchar*) trx->thd);
#endif
if (need_lock)
pthread_mutex_unlock(&spider_allocated_thds_mutex);
}
if (reset_ha_data)
thd_set_ha_data(trx->thd, spider_hton_ptr, NULL);
}
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;
int trx_isolation;
DBUG_ENTER("spider_check_and_set_trx_isolation");
if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL)
{
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));
}
spider_conn_queue_trx_isolation(conn, trx_isolation);
DBUG_RETURN(0);
}
int spider_check_and_set_autocommit(
THD *thd,
SPIDER_CONN *conn,
int *need_mon
) {
bool autocommit;
DBUG_ENTER("spider_check_and_set_autocommit");
autocommit = !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT);
if (autocommit)
{
spider_conn_queue_autocommit(conn, TRUE);
} else {
spider_conn_queue_autocommit(conn, FALSE);
}
/*
if (autocommit && conn->autocommit != 1)
{
spider_conn_queue_autocommit(conn, TRUE);
conn->autocommit = 1;
} else if (!autocommit && conn->autocommit != 0)
{
spider_conn_queue_autocommit(conn, FALSE);
conn->autocommit = 0;
}
*/
DBUG_RETURN(0);
}
int spider_check_and_set_sql_log_off(
THD *thd,
SPIDER_CONN *conn,
int *need_mon
) {
int internal_sql_log_off;
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)
{
if (internal_sql_log_off)
{
spider_conn_queue_sql_log_off(conn, TRUE);
} else {
spider_conn_queue_sql_log_off(conn, FALSE);
}
}
/*
if (internal_sql_log_off && conn->sql_log_off != 1)
{
spider_conn_queue_sql_log_off(conn, TRUE);
conn->sql_log_off = 1;
} else if (!internal_sql_log_off && conn->sql_log_off != 0)
{
spider_conn_queue_sql_log_off(conn, FALSE);
conn->sql_log_off = 0;
}
*/
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);
}
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
) {
THD *thd = current_thd;
int error_num;
const char *old_proc_info;
DBUG_ENTER("spider_xa_lock");
#ifdef SPIDER_XID_USES_xid_cache_iterate
#else
#ifdef SPIDER_HAS_HASH_VALUE_TYPE
my_hash_value_type hash_value = my_calc_hash(spd_db_att_xid_cache,
(uchar*) xid_state->xid.key(), xid_state->xid.key_length());
#ifdef XID_CACHE_IS_SPLITTED
uint idx = hash_value % *spd_db_att_xid_cache_split_num;
#endif
#endif
#endif
old_proc_info = thd_proc_info(thd, "Locking xid by Spider");
#ifdef SPIDER_XID_USES_xid_cache_iterate
if (xid_cache_insert(thd, xid_state, xid))
{
error_num = (spider_stmt_da_sql_errno(thd) == ER_XAER_DUPID ?
ER_SPIDER_XA_LOCKED_NUM : HA_ERR_OUT_OF_MEM);
goto error;
}
#else
#ifdef XID_CACHE_IS_SPLITTED
pthread_mutex_lock(&spd_db_att_LOCK_xid_cache[idx]);
#else
pthread_mutex_lock(spd_db_att_LOCK_xid_cache);
#endif
#ifdef SPIDER_HAS_HASH_VALUE_TYPE
#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
if (my_hash_search_using_hash_value(spd_db_att_xid_cache, hash_value,
xid_state->xid.key(), xid_state->xid.key_length()))
#endif
#else
if (my_hash_search(spd_db_att_xid_cache,
xid_state->xid.key(), xid_state->xid.key_length()))
#endif
{
error_num = ER_SPIDER_XA_LOCKED_NUM;
goto error;
}
#ifdef HASH_UPDATE_WITH_HASH_VALUE
#ifdef XID_CACHE_IS_SPLITTED
if (my_hash_insert_with_hash_value(&spd_db_att_xid_cache[idx], hash_value,
(uchar*)xid_state))
#else
if (my_hash_insert_with_hash_value(spd_db_att_xid_cache, hash_value,
(uchar*)xid_state))
#endif
#else
if (my_hash_insert(spd_db_att_xid_cache, (uchar*)xid_state))
#endif
{
error_num = HA_ERR_OUT_OF_MEM;
goto error;
}
#ifdef XID_CACHE_IS_SPLITTED
pthread_mutex_unlock(&spd_db_att_LOCK_xid_cache[idx]);
#else
pthread_mutex_unlock(spd_db_att_LOCK_xid_cache);
#endif
#endif
thd_proc_info(thd, old_proc_info);
DBUG_RETURN(0);
error:
#ifdef SPIDER_XID_USES_xid_cache_iterate
#else
#ifdef XID_CACHE_IS_SPLITTED
pthread_mutex_unlock(&spd_db_att_LOCK_xid_cache[idx]);
#else
pthread_mutex_unlock(spd_db_att_LOCK_xid_cache);
#endif
#endif
thd_proc_info(thd, old_proc_info);
DBUG_RETURN(error_num);
}
static int spider_xa_unlock(
XID_STATE *xid_state
) {
THD *thd = current_thd;
const char *old_proc_info;
DBUG_ENTER("spider_xa_unlock");
#ifdef SPIDER_XID_USES_xid_cache_iterate
#else
#if defined(SPIDER_HAS_HASH_VALUE_TYPE) && defined(HASH_UPDATE_WITH_HASH_VALUE)
my_hash_value_type hash_value = my_calc_hash(spd_db_att_xid_cache,
(uchar*) xid_state->xid.key(), xid_state->xid.key_length());
#ifdef XID_CACHE_IS_SPLITTED
uint idx = hash_value % *spd_db_att_xid_cache_split_num;
#endif
#endif
#endif
old_proc_info = thd_proc_info(thd, "Unlocking xid by Spider");
#ifdef SPIDER_XID_USES_xid_cache_iterate
xid_cache_delete(thd, xid_state);
#else
#ifdef XID_CACHE_IS_SPLITTED
pthread_mutex_lock(&spd_db_att_LOCK_xid_cache[idx]);
#else
pthread_mutex_lock(spd_db_att_LOCK_xid_cache);
#endif
#if defined(SPIDER_HAS_HASH_VALUE_TYPE) && defined(HASH_UPDATE_WITH_HASH_VALUE)
#ifdef XID_CACHE_IS_SPLITTED
my_hash_delete_with_hash_value(&spd_db_att_xid_cache[idx],
hash_value, (uchar *)xid_state);
#else
my_hash_delete_with_hash_value(spd_db_att_xid_cache,
hash_value, (uchar *)xid_state);
#endif
#else
my_hash_delete(spd_db_att_xid_cache, (uchar *)xid_state);
#endif
#ifdef XID_CACHE_IS_SPLITTED
pthread_mutex_unlock(&spd_db_att_LOCK_xid_cache[idx]);
#else
pthread_mutex_unlock(spd_db_att_LOCK_xid_cache);
#endif
#endif
thd_proc_info(thd, old_proc_info);
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
) {
int error_num;
SPIDER_TRX *trx = spider->wide_handler->trx;
THD *thd = trx->thd;
bool xa_lock = FALSE;
DBUG_ENTER("spider_internal_start_trx");
if (!trx->trx_start)
{
if (!trx->trx_consistent_snapshot)
{
trx->use_consistent_snapshot =
spider_param_use_consistent_snapshot(thd);
trx->internal_xa = spider_param_internal_xa(thd);
trx->internal_xa_snapshot = spider_param_internal_xa_snapshot(thd);
}
}
spider->wide_handler->consistent_snapshot = FALSE;
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;
}
}
DBUG_PRINT("info",("spider trx->trx_start= %s",
trx->trx_start ? "TRUE" : "FALSE"));
if (!trx->trx_start)
{
if (
thd->transaction->xid_state.is_explicit_XA() &&
spider_param_support_xa()
) {
trx->trx_xa = TRUE;
thd_get_xid(thd, (MYSQL_XID*) &trx->xid);
}
if (
!trx->trx_xa &&
trx->internal_xa &&
(!trx->trx_consistent_snapshot || trx->internal_xa_snapshot == 3) &&
spider->wide_handler->sql_command != SQLCOM_LOCK_TABLES
) {
trx->trx_xa = TRUE;
trx->xid.formatID = 1;
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));
}
#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100002
trx->xid.bqual_length
= my_sprintf(trx->xid.data + trx->xid.gtrid_length,
(trx->xid.data + trx->xid.gtrid_length, "%lx",
thd->variables.server_id));
#else
trx->xid.bqual_length
= my_sprintf(trx->xid.data + trx->xid.gtrid_length,
(trx->xid.data + trx->xid.gtrid_length, "%x",
thd->server_id));
#endif
#ifdef SPIDER_XID_STATE_HAS_in_thd
trx->internal_xid_state.in_thd = 1;
#endif
if ((error_num = spider_xa_lock(&trx->internal_xid_state, &trx->xid)))
{
if (error_num == ER_SPIDER_XA_LOCKED_NUM)
my_message(error_num, ER_SPIDER_XA_LOCKED_STR, MYF(0));
goto error;
}
xa_lock = TRUE;
} else
trx->internal_xa = FALSE;
DBUG_PRINT("info",("spider trx->trx_consistent_snapshot= %s",
trx->trx_consistent_snapshot ? "TRUE" : "FALSE"));
if (!trx->trx_consistent_snapshot)
{
trans_register_ha(thd, FALSE, spider_hton_ptr, 0);
if (thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
trans_register_ha(thd, TRUE, spider_hton_ptr, 0);
}
trx->trx_start = TRUE;
trx->trx_xa_prepared = FALSE;
trx->updated_in_this_trx = FALSE;
DBUG_PRINT("info",("spider trx->updated_in_this_trx=FALSE"));
}
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;
}
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));
DBUG_PRINT("info",("spider semi_trx = %d", spider_param_semi_trx(thd)));
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)
) &&
spider_param_semi_trx(thd)
) {
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 &&
!thd_test_options(thd, OPTION_BEGIN) &&
sync_autocommit &&
conn->semi_trx_chk &&
!conn->table_lock &&
(
(!conn->queued_autocommit && conn->autocommit == 1) ||
(conn->queued_autocommit && conn->queued_autocommit_val == TRUE)
) &&
spider_param_semi_trx(thd)
) {
DBUG_PRINT("info",("spider semi_trx is set"));
spider_conn_queue_start_transaction(conn);
conn->semi_trx = TRUE;
} else if (
!trx->trx_consistent_snapshot &&
thd_test_options(thd, OPTION_BEGIN)
) {
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;
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;
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));
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;
}
SPIDER_BACKUP_DASTATUS;
if ((conn = spider_tree_first(trx->join_trx_top)))
{
do {
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));
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;
}
spider_sys_log_xa_failed(thd, &trx->xid, conn,
SPIDER_SYS_XA_COMMIT_STR, TRUE);
}
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;
/*
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;
}
if (trx->internal_xa)
{
spider_xa_unlock(&trx->internal_xid_state);
}
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:
if (trx->internal_xa)
{
spider_xa_unlock(&trx->internal_xid_state);
}
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;
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
)
) {
/*
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 {
if (conn->bg_search)
spider_bg_conn_break(conn, NULL);
if (conn->join_trx)
{
if (conn->disable_xa)
{
if (conn->table_lock != 3 && !trx->trx_xa_prepared)
{
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 (
!trx->trx_xa_prepared &&
(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 (
trx->trx_xa_prepared &&
!server_lost &&
(
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;
/*
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;
}
if (trx->internal_xa)
{
spider_xa_unlock(&trx->internal_xid_state);
}
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:
if (trx->internal_xa)
{
spider_xa_unlock(&trx->internal_xid_state);
}
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;
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;
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;
}
SPIDER_BACKUP_DASTATUS;
if ((conn = spider_tree_first(trx->join_trx_top)))
{
do {
if (conn->bg_search)
spider_bg_conn_break(conn, NULL);
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;
}
}
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;
/*
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;
}
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;
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;
int cnt = 0;
MEM_ROOT mem_root;
DBUG_ENTER("spider_initinal_xa_recover");
if (!(read_record = new READ_RECORD))
{
error_num = HA_ERR_OUT_OF_MEM;
goto error_create_read_record;
}
if (!(thd = spider_create_tmp_thd()))
{
error_num = HA_ERR_OUT_OF_MEM;
goto error_create_thd;
}
/*
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);
SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME));
while ((!(read_record->SPIDER_read_record_read_record(read_record))) &&
cnt < (int) len)
{
spider_get_sys_xid(table_xa, &xid_list[cnt], &mem_root);
cnt++;
}
free_root(&mem_root, MYF(0));
end_read_record(read_record);
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);
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;
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];
SPIDER_CONN *conn;
uint force_commit = spider_param_force_commit(thd);
MEM_ROOT mem_root;
SPIDER_Open_tables_backup open_tables_backup;
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;
}
}
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);
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;
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];
SPIDER_CONN *conn;
uint force_commit = spider_param_force_commit(thd);
MEM_ROOT mem_root;
SPIDER_Open_tables_backup open_tables_backup;
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;
}
}
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);
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);
trans_register_ha(trx->thd, FALSE, spider_hton_ptr, 0);
trans_register_ha(trx->thd, TRUE, spider_hton_ptr, 0);
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)))
DBUG_RETURN(0); /* transaction is not started */
#ifdef HA_CAN_BULK_ACCESS
DBUG_PRINT("info",("spider trx->bulk_access_conn_first=%p",
trx->bulk_access_conn_first));
trx->bulk_access_conn_first = NULL;
#endif
/*
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.
*/
if (all || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
{
if (trx->trx_start)
{
if (trx->trx_xa)
{
if (trx->internal_xa && !trx->trx_xa_prepared)
{
if (
(error_num = spider_internal_xa_prepare(
thd, trx, table_xa, table_xa_member, TRUE))
) {
/*
if (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
{
*/
/* rollback for semi_trx */
spider_rollback(hton, thd, all);
/*
}
*/
DBUG_RETURN(error_num);
}
trx->trx_xa_prepared = TRUE;
}
int tmp_error_num;
if (
(tmp_error_num = spider_internal_xa_commit(
thd, trx, &trx->xid, table_xa, table_xa_member))
) {
if (tmp_error_num)
error_num = tmp_error_num;
}
trx->trx_xa = FALSE;
trx->join_trx_top = NULL;
} 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"));
}
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)))
DBUG_RETURN(0); /* transaction is not started */
#ifdef HA_CAN_BULK_ACCESS
DBUG_PRINT("info",("spider trx->bulk_access_conn_first=%p",
trx->bulk_access_conn_first));
trx->bulk_access_conn_first = NULL;
#endif
if (all || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
{
if (trx->trx_start)
{
if (trx->trx_xa)
{
int tmp_error_num;
if (
(tmp_error_num = spider_internal_xa_rollback(thd, trx))
) {
if (tmp_error_num)
error_num = tmp_error_num;
}
trx->trx_xa = FALSE;
trx->join_trx_top = NULL;
} 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"));
}
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)))
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;
trx->trx_xa_prepared = TRUE;
}
}
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);
}
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;
}
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)
{
trx->tmp_spider->conns = &conn;
conn->table_lock = 0;
conn->disable_reconnect = FALSE;
if (
!conn->server_lost &&
(error_num = spider_db_unlock_tables(trx->tmp_spider, 0))
) {
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;
spider->set_error_mode();
if (spider->wide_handler->sql_command != SQLCOM_DROP_TABLE)
{
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 defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS
if (use_conn_kind)
{
for (roop_count = 0; roop_count < (int) share->link_count; roop_count++)
{
if (
/*
spider->conn_kind[roop_count] != SPIDER_CONN_KIND_MYSQL &&
*/
share->hs_dbton_ids[spider->conn_link_idx[roop_count]] ==
SPIDER_DBTON_SIZE
) {
/* can't use hs interface */
spider->conn_kind[roop_count] = SPIDER_CONN_KIND_MYSQL;
spider_clear_bit(spider->do_hs_direct_update, roop_count);
}
}
}
#endif
#endif
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 ||
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
(use_conn_kind &&
(
trx->trx_hs_r_conn_adjustment != spider->trx_hs_r_conn_adjustment ||
trx->trx_hs_w_conn_adjustment != spider->trx_hs_w_conn_adjustment
)
) ||
#endif
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;
spider->trx_conn_adjustment = trx->trx_conn_adjustment;
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
if (use_conn_kind)
{
spider->trx_hs_r_conn_adjustment = trx->trx_hs_r_conn_adjustment;
spider->trx_hs_w_conn_adjustment = trx->trx_hs_w_conn_adjustment;
}
#endif
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));
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
char *table_name = db + table_share->db.length + 1;
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);
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);
}
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;
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
if (!spider->handler_opened(roop_count, SPIDER_CONN_KIND_HS_READ))
spider->hs_r_conns[roop_count] = NULL;
if (!spider->handler_opened(roop_count, SPIDER_CONN_KIND_HS_WRITE))
spider->hs_w_conns[roop_count] = NULL;
#endif
}
bool search_link_idx_is_checked = FALSE;
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);
if (roop_count == spider->search_link_idx)
search_link_idx_is_checked = TRUE;
if (
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
(
#endif
tgt_conn_kind == SPIDER_CONN_KIND_MYSQL &&
!spider->conns[roop_count]
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
) ||
(tgt_conn_kind == SPIDER_CONN_KIND_HS_READ &&
!spider->hs_r_conns[roop_count]) ||
(tgt_conn_kind == SPIDER_CONN_KIND_HS_WRITE &&
!spider->hs_w_conns[roop_count])
#endif
) {
*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,
(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],
share->monitoring_flag[roop_count],
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;
}
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS
if (
spider->do_direct_update &&
spider_bit_is_set(spider->do_hs_direct_update, roop_count) &&
!spider->hs_w_conns[roop_count]
) {
if (
!(conn =
spider_get_conn(share, roop_count,
spider->conn_keys[roop_count], trx,
spider, FALSE, TRUE,
SPIDER_CONN_KIND_HS_WRITE,
&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,
(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],
share->monitoring_flag[roop_count],
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;
}
#endif
#endif
}
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));
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
char *table_name = db + table_share->db.length + 1;
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);
DBUG_RETURN(ER_SPIDER_LINK_MON_JUST_NG_NUM);
}
} else {
DBUG_PRINT("info",("spider link_status = %ld",
share->link_statuses[spider->conn_link_idx[spider->search_link_idx]]));
bool search_link_idx_is_checked = FALSE;
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)
) {
if (roop_count == spider->search_link_idx)
search_link_idx_is_checked = TRUE;
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
if (
!use_conn_kind ||
spider->conn_kind[roop_count] == SPIDER_CONN_KIND_MYSQL
) {
#endif
conn = spider->conns[roop_count];
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
} else if (spider->conn_kind[roop_count] == SPIDER_CONN_KIND_HS_READ)
{
conn = spider->hs_r_conns[roop_count];
} else {
conn = spider->hs_w_conns[roop_count];
}
#endif
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,
(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],
share->monitoring_flag[roop_count],
TRUE
);
}
DBUG_PRINT("info",("spider get conn error"));
DBUG_RETURN(error_num);
}
}
conn->error_mode &= spider->error_mode;
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS
if (
spider->do_direct_update &&
spider_bit_is_set(spider->do_hs_direct_update, roop_count)
) {
conn = spider->hs_w_conns[roop_count];
if (!conn)
{
DBUG_PRINT("info",("spider get hs_w_conn %d", roop_count));
if (
!(conn =
spider_get_conn(share, roop_count,
spider->conn_keys[roop_count], trx,
spider, FALSE, TRUE,
SPIDER_CONN_KIND_HS_WRITE,
&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,
(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],
share->monitoring_flag[roop_count],
TRUE
);
}
DBUG_PRINT("info",("spider get conn error"));
DBUG_RETURN(error_num);
}
}
}
conn->error_mode &= spider->error_mode;
#endif
#endif
}
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));
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
char *table_name = db + table_share->db.length + 1;
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);
DBUG_RETURN(ER_SPIDER_LINK_MON_JUST_NG_NUM);
}
}
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)))
DBUG_RETURN(NULL);
#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000
thd->killed = NOT_KILLED;
#else
thd->killed = THD::NOT_KILLED;
#endif
#if MYSQL_VERSION_ID < 50500
thd->locked_tables = FALSE;
#endif
thd->proc_info = "";
#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100200
#else
thd->thread_id = thd->variables.pseudo_thread_id = 0;
#endif
thd->thread_stack = (char*) &thd;
thd->store_globals();
lex_start(thd);
DBUG_RETURN(thd);
}
void spider_free_tmp_thd(
THD *thd
) {
DBUG_ENTER("spider_free_tmp_thd");
thd->cleanup();
#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000
thd->reset_globals();
#else
thd->restore_globals();
#endif
delete thd;
DBUG_VOID_RETURN;
}
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;
#ifdef HASH_UPDATE_WITH_HASH_VALUE
my_hash_delete_with_hash_value(&trx->trx_ha_hash,
share->table_name_hash_value, (uchar*) trx_ha);
#else
my_hash_delete(&trx->trx_ha_hash, (uchar*) trx_ha);
#endif
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, 58, 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),
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->trx = trx;
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;
#ifdef HASH_UPDATE_WITH_HASH_VALUE
if (my_hash_insert_with_hash_value(&trx->trx_ha_hash,
share->table_name_hash_value, (uchar*) trx_ha))
#else
if (my_hash_insert(&trx->trx_ha_hash, (uchar*) trx_ha))
#endif
{
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");
#ifdef SPIDER_HAS_HASH_VALUE_TYPE
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)))
#else
if ((trx_ha = (SPIDER_TRX_HA *) my_hash_search(&trx->trx_ha_hash,
(uchar*) share->table_name, share->table_name_length)))
#endif
{
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);
}
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;
}
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]));
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
spider->hs_r_conn_keys[roop_count] =
ADD_TO_PTR(spider->conn_keys_first_ptr,
PTR_BYTE_DIFF(share->hs_read_conn_keys[conn_link_idx[roop_count]],
share->conn_keys[0]), char*);
DBUG_PRINT("info",("spider hs_r_conn_keys[%d]=%s",
roop_count, spider->hs_r_conn_keys[roop_count]));
spider->hs_w_conn_keys[roop_count] =
ADD_TO_PTR(spider->conn_keys_first_ptr,
PTR_BYTE_DIFF(share->hs_write_conn_keys[conn_link_idx[roop_count]],
share->conn_keys[0]), char*);
DBUG_PRINT("info",("spider hs_w_conn_keys[%d]=%s",
roop_count, spider->hs_w_conn_keys[roop_count]));
#endif
}
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");
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);
}
#ifdef HA_CAN_BULK_ACCESS
void spider_trx_add_bulk_access_conn(
SPIDER_TRX *trx,
SPIDER_CONN *conn
) {
DBUG_ENTER("spider_trx_add_bulk_access_conn");
DBUG_PRINT("info",("spider trx=%p", trx));
DBUG_PRINT("info",("spider conn=%p", conn));
DBUG_PRINT("info",("spider conn->bulk_access_requests=%u",
conn->bulk_access_requests));
DBUG_PRINT("info",("spider conn->bulk_access_sended=%u",
conn->bulk_access_sended));
DBUG_PRINT("info",("spider trx->bulk_access_conn_first=%p",
trx->bulk_access_conn_first));
if (!conn->bulk_access_requests && !conn->bulk_access_sended)
{
if (!trx->bulk_access_conn_first)
{
trx->bulk_access_conn_first = conn;
} else {
trx->bulk_access_conn_last->bulk_access_next = conn;
}
trx->bulk_access_conn_last = conn;
conn->bulk_access_next = NULL;
}
conn->bulk_access_requests++;
DBUG_PRINT("info",("spider conn->bulk_access_requests=%u",
conn->bulk_access_requests));
DBUG_VOID_RETURN;
}
#endif