mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
Merge siva.hindu.god:/home/tsmith/m/bk/51
into siva.hindu.god:/home/tsmith/m/bk/maint/51 sql/mysqld.cc: Auto merged sql/slave.cc: Auto merged sql/sql_select.cc: Auto merged
This commit is contained in:
commit
c4fdf11e58
57 changed files with 1600 additions and 870 deletions
|
@ -690,15 +690,6 @@ extern uint my_thread_end_wait_time;
|
|||
Keep track of shutdown,signal, and main threads so that my_end() will not
|
||||
report errors with them
|
||||
*/
|
||||
|
||||
/* Which kind of thread library is in use */
|
||||
|
||||
#define THD_LIB_OTHER 1
|
||||
#define THD_LIB_NPTL 2
|
||||
#define THD_LIB_LT 4
|
||||
|
||||
extern uint thd_lib_detected;
|
||||
|
||||
/* statistics_xxx functions are for not essential statistic */
|
||||
|
||||
#ifndef thread_safe_increment
|
||||
|
|
|
@ -24,6 +24,11 @@ extern "C" {
|
|||
#ifndef USE_ALARM_THREAD
|
||||
#define USE_ONE_SIGNAL_HAND /* One must call process_alarm */
|
||||
#endif
|
||||
#ifdef HAVE_LINUXTHREADS
|
||||
#define THR_CLIENT_ALARM SIGALRM
|
||||
#else
|
||||
#define THR_CLIENT_ALARM SIGUSR1
|
||||
#endif
|
||||
#ifdef HAVE_rts_threads
|
||||
#undef USE_ONE_SIGNAL_HAND
|
||||
#define USE_ALARM_THREAD
|
||||
|
@ -84,9 +89,6 @@ typedef struct st_alarm {
|
|||
my_bool malloced;
|
||||
} ALARM;
|
||||
|
||||
extern uint thr_client_alarm;
|
||||
extern pthread_t alarm_thread;
|
||||
|
||||
#define thr_alarm_init(A) (*(A))=0
|
||||
#define thr_alarm_in_use(A) (*(A)!= 0)
|
||||
void init_thr_alarm(uint max_alarm);
|
||||
|
|
|
@ -442,3 +442,34 @@ SELECT id, tag, doc, type FROM t1 WHERE id IN ('flipper','sakila');
|
|||
id tag doc type
|
||||
sakila 1 Some text goes here text
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (
|
||||
var1 int(2) NOT NULL,
|
||||
var2 int(2) NOT NULL,
|
||||
PRIMARY KEY (var1)
|
||||
) ENGINE=ndbcluster DEFAULT CHARSET=ascii CHECKSUM=1;
|
||||
CREATE TABLE t2 (
|
||||
var1 int(2) NOT NULL,
|
||||
var2 int(2) NOT NULL,
|
||||
PRIMARY KEY (var1)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=ascii CHECKSUM=1;
|
||||
CREATE TRIGGER testtrigger
|
||||
AFTER UPDATE ON t1 FOR EACH ROW BEGIN
|
||||
REPLACE INTO t2 SELECT * FROM t1 WHERE t1.var1 = NEW.var1;END|
|
||||
INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
|
||||
UPDATE t1 SET var2 = 9 WHERE var1 IN(1,2,3);
|
||||
DROP TRIGGER testtrigger;
|
||||
DROP TABLE t1, t2;
|
||||
create table t1 (a int, b int, primary key (a), key ab (a,b)) engine=ndbcluster;
|
||||
insert into t1 values (1,1), (10,10);
|
||||
select * from t1 use index (ab) where a in(1,10) order by a;
|
||||
a b
|
||||
1 1
|
||||
10 10
|
||||
create table t2 (a int, b int, primary key (a,b)) engine=ndbcluster
|
||||
partition by key(a);
|
||||
insert into t2 values (1,1), (10,10);
|
||||
select * from t2 where a in (1,10) order by a;
|
||||
a b
|
||||
1 1
|
||||
10 10
|
||||
drop table t1, t2;
|
||||
|
|
|
@ -272,3 +272,48 @@ SELECT id, tag, doc, type FROM t1 WHERE id IN ('flipper','orka');
|
|||
SELECT id, tag, doc, type FROM t1 WHERE id IN ('flipper','sakila');
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
#bug#25522
|
||||
CREATE TABLE t1 (
|
||||
var1 int(2) NOT NULL,
|
||||
var2 int(2) NOT NULL,
|
||||
PRIMARY KEY (var1)
|
||||
) ENGINE=ndbcluster DEFAULT CHARSET=ascii CHECKSUM=1;
|
||||
|
||||
|
||||
CREATE TABLE t2 (
|
||||
var1 int(2) NOT NULL,
|
||||
var2 int(2) NOT NULL,
|
||||
PRIMARY KEY (var1)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=ascii CHECKSUM=1;
|
||||
|
||||
|
||||
DELIMITER |;
|
||||
CREATE TRIGGER testtrigger
|
||||
AFTER UPDATE ON t1 FOR EACH ROW BEGIN
|
||||
REPLACE INTO t2 SELECT * FROM t1 WHERE t1.var1 = NEW.var1;END|
|
||||
DELIMITER ;|
|
||||
|
||||
INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
|
||||
|
||||
UPDATE t1 SET var2 = 9 WHERE var1 IN(1,2,3);
|
||||
|
||||
DROP TRIGGER testtrigger;
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
#bug#25821
|
||||
create table t1 (a int, b int, primary key (a), key ab (a,b)) engine=ndbcluster;
|
||||
|
||||
insert into t1 values (1,1), (10,10);
|
||||
|
||||
select * from t1 use index (ab) where a in(1,10) order by a;
|
||||
|
||||
create table t2 (a int, b int, primary key (a,b)) engine=ndbcluster
|
||||
partition by key(a);
|
||||
|
||||
insert into t2 values (1,1), (10,10);
|
||||
|
||||
select * from t2 where a in (1,10) order by a;
|
||||
|
||||
drop table t1, t2;
|
||||
|
|
|
@ -29,8 +29,6 @@
|
|||
#define SCHED_POLICY SCHED_OTHER
|
||||
#endif
|
||||
|
||||
uint thd_lib_detected;
|
||||
|
||||
#ifndef my_pthread_setprio
|
||||
void my_pthread_setprio(pthread_t thread_id,int prior)
|
||||
{
|
||||
|
@ -314,6 +312,8 @@ void sigwait_handle_sig(int sig)
|
|||
pthread_mutex_unlock(&LOCK_sigwait);
|
||||
}
|
||||
|
||||
extern pthread_t alarm_thread;
|
||||
|
||||
void *sigwait_thread(void *set_arg)
|
||||
{
|
||||
sigset_t *set=(sigset_t*) set_arg;
|
||||
|
@ -332,9 +332,7 @@ void *sigwait_thread(void *set_arg)
|
|||
sigaction(i, &sact, (struct sigaction*) 0);
|
||||
}
|
||||
}
|
||||
/* Ensure that init_thr_alarm() is called */
|
||||
DBUG_ASSERT(thr_client_alarm);
|
||||
sigaddset(set, thr_client_alarm);
|
||||
sigaddset(set,THR_CLIENT_ALARM);
|
||||
pthread_sigmask(SIG_UNBLOCK,(sigset_t*) set,(sigset_t*) 0);
|
||||
alarm_thread=pthread_self(); /* For thr_alarm */
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
|
||||
#include "mysys_priv.h"
|
||||
#include <m_string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#ifdef THREAD
|
||||
#ifdef USE_TLS
|
||||
|
@ -64,8 +63,6 @@ pthread_handler_t nptl_pthread_exit_hack_handler(void *arg)
|
|||
|
||||
#endif
|
||||
|
||||
static uint get_thread_lib(void);
|
||||
|
||||
/*
|
||||
initialize thread environment
|
||||
|
||||
|
@ -79,8 +76,6 @@ static uint get_thread_lib(void);
|
|||
|
||||
my_bool my_thread_global_init(void)
|
||||
{
|
||||
thd_lib_detected= get_thread_lib();
|
||||
|
||||
if (pthread_key_create(&THR_KEY_mysys,0))
|
||||
{
|
||||
fprintf(stderr,"Can't initialize threads: error %d\n",errno);
|
||||
|
@ -397,20 +392,4 @@ const char *my_thread_name(void)
|
|||
}
|
||||
#endif /* DBUG_OFF */
|
||||
|
||||
|
||||
static uint get_thread_lib(void)
|
||||
{
|
||||
char buff[64];
|
||||
|
||||
#ifdef _CS_GNU_LIBPTHREAD_VERSION
|
||||
confstr(_CS_GNU_LIBPTHREAD_VERSION, buff, sizeof(buff));
|
||||
|
||||
if (!strncasecmp(buff, "NPTL", 4))
|
||||
return THD_LIB_NPTL;
|
||||
if (!strncasecmp(buff, "linuxthreads", 12))
|
||||
return THD_LIB_LT;
|
||||
#endif
|
||||
return THD_LIB_OTHER;
|
||||
}
|
||||
|
||||
#endif /* THREAD */
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
#define ETIME ETIMEDOUT
|
||||
#endif
|
||||
|
||||
uint thr_client_alarm;
|
||||
static int alarm_aborted=1; /* No alarm thread */
|
||||
my_bool thr_alarm_inited= 0;
|
||||
volatile my_bool alarm_thread_running= 0;
|
||||
|
@ -57,7 +56,9 @@ static void *alarm_handler(void *arg);
|
|||
#define reschedule_alarms() pthread_kill(alarm_thread,THR_SERVER_ALARM)
|
||||
#endif
|
||||
|
||||
#if THR_CLIENT_ALARM != SIGALRM || defined(USE_ALARM_THREAD)
|
||||
static sig_handler thread_alarm(int sig __attribute__((unused)));
|
||||
#endif
|
||||
|
||||
static int compare_ulong(void *not_used __attribute__((unused)),
|
||||
byte *a_ptr,byte* b_ptr)
|
||||
|
@ -76,16 +77,9 @@ void init_thr_alarm(uint max_alarms)
|
|||
sigfillset(&full_signal_set); /* Neaded to block signals */
|
||||
pthread_mutex_init(&LOCK_alarm,MY_MUTEX_INIT_FAST);
|
||||
pthread_cond_init(&COND_alarm,NULL);
|
||||
if (thd_lib_detected == THD_LIB_LT)
|
||||
thr_client_alarm= SIGALRM;
|
||||
else
|
||||
thr_client_alarm= SIGUSR1;
|
||||
#ifndef USE_ALARM_THREAD
|
||||
if (thd_lib_detected != THD_LIB_LT)
|
||||
#if THR_CLIENT_ALARM != SIGALRM || defined(USE_ALARM_THREAD)
|
||||
my_sigset(THR_CLIENT_ALARM,thread_alarm);
|
||||
#endif
|
||||
{
|
||||
my_sigset(thr_client_alarm, thread_alarm);
|
||||
}
|
||||
sigemptyset(&s);
|
||||
sigaddset(&s, THR_SERVER_ALARM);
|
||||
alarm_thread=pthread_self();
|
||||
|
@ -103,11 +97,10 @@ void init_thr_alarm(uint max_alarms)
|
|||
}
|
||||
#elif defined(USE_ONE_SIGNAL_HAND)
|
||||
pthread_sigmask(SIG_BLOCK, &s, NULL); /* used with sigwait() */
|
||||
if (thd_lib_detected == THD_LIB_LT)
|
||||
{
|
||||
my_sigset(thr_client_alarm, process_alarm); /* Linuxthreads */
|
||||
pthread_sigmask(SIG_UNBLOCK, &s, NULL);
|
||||
}
|
||||
#if THR_SERVER_ALARM == THR_CLIENT_ALARM
|
||||
my_sigset(THR_CLIENT_ALARM,process_alarm); /* Linuxthreads */
|
||||
pthread_sigmask(SIG_UNBLOCK, &s, NULL);
|
||||
#endif
|
||||
#else
|
||||
my_sigset(THR_SERVER_ALARM, process_alarm);
|
||||
pthread_sigmask(SIG_UNBLOCK, &s, NULL);
|
||||
|
@ -158,7 +151,7 @@ my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data)
|
|||
|
||||
now=(ulong) time((time_t*) 0);
|
||||
pthread_sigmask(SIG_BLOCK,&full_signal_set,&old_mask);
|
||||
pthread_mutex_lock(&LOCK_alarm); /* Lock from threads & alarms */
|
||||
pthread_mutex_lock(&LOCK_alarm); /* Lock from threads & alarms */
|
||||
if (alarm_aborted > 0)
|
||||
{ /* No signal thread */
|
||||
DBUG_PRINT("info", ("alarm aborted"));
|
||||
|
@ -278,17 +271,18 @@ sig_handler process_alarm(int sig __attribute__((unused)))
|
|||
This must be first as we can't call DBUG inside an alarm for a normal thread
|
||||
*/
|
||||
|
||||
if (thd_lib_detected == THD_LIB_LT &&
|
||||
!pthread_equal(pthread_self(),alarm_thread))
|
||||
#if THR_SERVER_ALARM == THR_CLIENT_ALARM
|
||||
if (!pthread_equal(pthread_self(),alarm_thread))
|
||||
{
|
||||
#if defined(MAIN) && !defined(__bsdi__)
|
||||
printf("thread_alarm in process_alarm\n"); fflush(stdout);
|
||||
#endif
|
||||
#ifdef DONT_REMEMBER_SIGNAL
|
||||
my_sigset(thr_client_alarm, process_alarm); /* int. thread system calls */
|
||||
my_sigset(THR_CLIENT_ALARM,process_alarm); /* int. thread system calls */
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
We have to do do the handling of the alarm in a sub function,
|
||||
|
@ -332,7 +326,7 @@ static sig_handler process_alarm_part2(int sig __attribute__((unused)))
|
|||
alarm_data=(ALARM*) queue_element(&alarm_queue,i);
|
||||
alarm_data->alarmed=1; /* Info to thread */
|
||||
if (pthread_equal(alarm_data->thread,alarm_thread) ||
|
||||
pthread_kill(alarm_data->thread, thr_client_alarm))
|
||||
pthread_kill(alarm_data->thread, THR_CLIENT_ALARM))
|
||||
{
|
||||
#ifdef MAIN
|
||||
printf("Warning: pthread_kill couldn't find thread!!!\n");
|
||||
|
@ -356,7 +350,7 @@ static sig_handler process_alarm_part2(int sig __attribute__((unused)))
|
|||
alarm_data->alarmed=1; /* Info to thread */
|
||||
DBUG_PRINT("info",("sending signal to waiting thread"));
|
||||
if (pthread_equal(alarm_data->thread,alarm_thread) ||
|
||||
pthread_kill(alarm_data->thread, thr_client_alarm))
|
||||
pthread_kill(alarm_data->thread, THR_CLIENT_ALARM))
|
||||
{
|
||||
#ifdef MAIN
|
||||
printf("Warning: pthread_kill couldn't find thread!!!\n");
|
||||
|
@ -493,7 +487,7 @@ void thr_alarm_info(ALARM_INFO *info)
|
|||
ARGSUSED
|
||||
*/
|
||||
|
||||
|
||||
#if THR_CLIENT_ALARM != SIGALRM || defined(USE_ALARM_THREAD)
|
||||
static sig_handler thread_alarm(int sig)
|
||||
{
|
||||
#ifdef MAIN
|
||||
|
@ -503,6 +497,7 @@ static sig_handler thread_alarm(int sig)
|
|||
my_sigset(sig,thread_alarm); /* int. thread system calls */
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_TIMESPEC_TS_SEC
|
||||
|
@ -788,7 +783,9 @@ static void *signal_hand(void *arg __attribute__((unused)))
|
|||
sigaddset(&set,SIGINT);
|
||||
sigaddset(&set,SIGQUIT);
|
||||
sigaddset(&set,SIGTERM);
|
||||
#if THR_CLIENT_ALARM != SIGHUP
|
||||
sigaddset(&set,SIGHUP);
|
||||
#endif
|
||||
#ifdef SIGTSTP
|
||||
sigaddset(&set,SIGTSTP);
|
||||
#endif
|
||||
|
@ -799,7 +796,7 @@ static void *signal_hand(void *arg __attribute__((unused)))
|
|||
puts("Starting signal handling thread");
|
||||
#endif
|
||||
printf("server alarm: %d thread alarm: %d\n",
|
||||
THR_SERVER_ALARM, thr_client_alarm);
|
||||
THR_SERVER_ALARM,THR_CLIENT_ALARM);
|
||||
DBUG_PRINT("info",("Starting signal and alarm handling thread"));
|
||||
for(;;)
|
||||
{
|
||||
|
@ -867,11 +864,11 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
|
|||
sigaddset(&set,SIGTSTP);
|
||||
#endif
|
||||
sigaddset(&set,THR_SERVER_ALARM);
|
||||
sigdelset(&set, thr_client_alarm);
|
||||
sigdelset(&set,THR_CLIENT_ALARM);
|
||||
(void) pthread_sigmask(SIG_SETMASK,&set,NULL);
|
||||
#ifdef NOT_USED
|
||||
sigemptyset(&set);
|
||||
sigaddset(&set, thr_client_alarm);
|
||||
sigaddset(&set,THR_CLIENT_ALARM);
|
||||
VOID(pthread_sigmask(SIG_UNBLOCK, &set, (sigset_t*) 0));
|
||||
#endif
|
||||
|
||||
|
|
|
@ -260,13 +260,14 @@ static int ndb_to_mysql_error(const NdbError *ndberr)
|
|||
int execute_no_commit_ignore_no_key(ha_ndbcluster *h, NdbTransaction *trans)
|
||||
{
|
||||
int res= trans->execute(NdbTransaction::NoCommit,
|
||||
NdbTransaction::AO_IgnoreError,
|
||||
NdbOperation::AO_IgnoreError,
|
||||
h->m_force_send);
|
||||
if (res == 0)
|
||||
return 0;
|
||||
if (res == -1)
|
||||
return -1;
|
||||
|
||||
const NdbError &err= trans->getNdbError();
|
||||
if (err.classification != NdbError::ConstraintViolation &&
|
||||
if (err.classification != NdbError::NoError &&
|
||||
err.classification != NdbError::ConstraintViolation &&
|
||||
err.classification != NdbError::NoDataFound)
|
||||
return res;
|
||||
|
||||
|
@ -286,7 +287,7 @@ int execute_no_commit(ha_ndbcluster *h, NdbTransaction *trans,
|
|||
return h->m_ignore_no_key ?
|
||||
execute_no_commit_ignore_no_key(h,trans) :
|
||||
trans->execute(NdbTransaction::NoCommit,
|
||||
NdbTransaction::AbortOnError,
|
||||
NdbOperation::AbortOnError,
|
||||
h->m_force_send);
|
||||
}
|
||||
|
||||
|
@ -299,7 +300,7 @@ int execute_commit(ha_ndbcluster *h, NdbTransaction *trans)
|
|||
return 0;
|
||||
#endif
|
||||
return trans->execute(NdbTransaction::Commit,
|
||||
NdbTransaction::AbortOnError,
|
||||
NdbOperation::AbortOnError,
|
||||
h->m_force_send);
|
||||
}
|
||||
|
||||
|
@ -312,7 +313,7 @@ int execute_commit(THD *thd, NdbTransaction *trans)
|
|||
return 0;
|
||||
#endif
|
||||
return trans->execute(NdbTransaction::Commit,
|
||||
NdbTransaction::AbortOnError,
|
||||
NdbOperation::AbortOnError,
|
||||
thd->variables.ndb_force_send);
|
||||
}
|
||||
|
||||
|
@ -327,7 +328,7 @@ int execute_no_commit_ie(ha_ndbcluster *h, NdbTransaction *trans,
|
|||
#endif
|
||||
h->release_completed_operations(trans, force_release);
|
||||
return trans->execute(NdbTransaction::NoCommit,
|
||||
NdbTransaction::AO_IgnoreError,
|
||||
NdbOperation::AO_IgnoreError,
|
||||
h->m_force_send);
|
||||
}
|
||||
|
||||
|
@ -1726,7 +1727,8 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf,
|
|||
ERR_RETURN(trans->getNdbError());
|
||||
}
|
||||
|
||||
if (execute_no_commit_ie(this,trans,FALSE) != 0)
|
||||
if ((res = execute_no_commit_ie(this,trans,FALSE)) != 0 ||
|
||||
op->getNdbError().code)
|
||||
{
|
||||
table->status= STATUS_NOT_FOUND;
|
||||
DBUG_RETURN(ndb_err(trans));
|
||||
|
@ -1998,7 +2000,8 @@ int ha_ndbcluster::unique_index_read(const byte *key,
|
|||
if ((res= define_read_attrs(buf, op)))
|
||||
DBUG_RETURN(res);
|
||||
|
||||
if (execute_no_commit_ie(this,trans,FALSE) != 0)
|
||||
if (execute_no_commit_ie(this,trans,FALSE) != 0 ||
|
||||
op->getNdbError().code)
|
||||
{
|
||||
table->status= STATUS_NOT_FOUND;
|
||||
DBUG_RETURN(ndb_err(trans));
|
||||
|
@ -2278,8 +2281,7 @@ int ha_ndbcluster::set_bounds(NdbIndexScanOperation *op,
|
|||
DBUG_PRINT("error", ("key %d unknown flag %d", j, p.key->flag));
|
||||
DBUG_ASSERT(FALSE);
|
||||
// Stop setting bounds but continue with what we have
|
||||
op->end_of_bound(range_no);
|
||||
DBUG_RETURN(0);
|
||||
DBUG_RETURN(op->end_of_bound(range_no));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2326,8 +2328,7 @@ int ha_ndbcluster::set_bounds(NdbIndexScanOperation *op,
|
|||
|
||||
tot_len+= part_store_len;
|
||||
}
|
||||
op->end_of_bound(range_no);
|
||||
DBUG_RETURN(0);
|
||||
DBUG_RETURN(op->end_of_bound(range_no));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -4337,11 +4338,10 @@ int ha_ndbcluster::start_stmt(THD *thd, thr_lock_type lock_type)
|
|||
ERR_RETURN(ndb->getNdbError());
|
||||
no_uncommitted_rows_reset(thd);
|
||||
thd_ndb->stmt= trans;
|
||||
thd_ndb->query_state&= NDB_QUERY_NORMAL;
|
||||
trans_register_ha(thd, FALSE, ndbcluster_hton);
|
||||
}
|
||||
thd_ndb->query_state&= NDB_QUERY_NORMAL;
|
||||
m_active_trans= trans;
|
||||
|
||||
// Start of statement
|
||||
m_ops_pending= 0;
|
||||
thd->set_current_stmt_binlog_row_based_if_mixed();
|
||||
|
@ -5002,11 +5002,17 @@ int ha_ndbcluster::create(const char *name,
|
|||
get a new share
|
||||
*/
|
||||
|
||||
/* ndb_share reference create */
|
||||
if (!(share= get_share(name, form, TRUE, TRUE)))
|
||||
{
|
||||
sql_print_error("NDB: allocating table share for %s failed", name);
|
||||
/* my_errno is set */
|
||||
}
|
||||
else
|
||||
{
|
||||
DBUG_PRINT("NDB_SHARE", ("%s binlog create use_count: %u",
|
||||
share->key, share->use_count));
|
||||
}
|
||||
pthread_mutex_unlock(&ndbcluster_mutex);
|
||||
|
||||
while (!IS_TMP_PREFIX(m_tabname))
|
||||
|
@ -5030,7 +5036,7 @@ int ha_ndbcluster::create(const char *name,
|
|||
if (ndb_extra_logging)
|
||||
sql_print_information("NDB Binlog: CREATE TABLE Event: %s",
|
||||
event_name.c_ptr());
|
||||
if (share && do_event_op &&
|
||||
if (share &&
|
||||
ndbcluster_create_event_ops(share, m_table, event_name.c_ptr()))
|
||||
{
|
||||
sql_print_error("NDB Binlog: FAILED CREATE TABLE event operations."
|
||||
|
@ -5120,6 +5126,9 @@ int ha_ndbcluster::create_handler_files(const char *file,
|
|||
}
|
||||
|
||||
set_ndb_share_state(m_share, NSS_INITIAL);
|
||||
/* ndb_share reference schema(?) free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s binlog schema(?) free use_count: %u",
|
||||
m_share->key, m_share->use_count));
|
||||
free_share(&m_share); // Decrease ref_count
|
||||
|
||||
DBUG_RETURN(error);
|
||||
|
@ -5246,7 +5255,10 @@ int ha_ndbcluster::create_ndb_index(const char *name,
|
|||
*/
|
||||
void ha_ndbcluster::prepare_for_alter()
|
||||
{
|
||||
/* ndb_share reference schema */
|
||||
ndbcluster_get_share(m_share); // Increase ref_count
|
||||
DBUG_PRINT("NDB_SHARE", ("%s binlog schema use_count: %u",
|
||||
m_share->key, m_share->use_count));
|
||||
set_ndb_share_state(m_share, NSS_ALTERED);
|
||||
}
|
||||
|
||||
|
@ -5280,6 +5292,9 @@ int ha_ndbcluster::add_index(TABLE *table_arg,
|
|||
if (error)
|
||||
{
|
||||
set_ndb_share_state(m_share, NSS_INITIAL);
|
||||
/* ndb_share reference schema free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s binlog schema free use_count: %u",
|
||||
m_share->key, m_share->use_count));
|
||||
free_share(&m_share); // Decrease ref_count
|
||||
}
|
||||
DBUG_RETURN(error);
|
||||
|
@ -5324,6 +5339,9 @@ int ha_ndbcluster::final_drop_index(TABLE *table_arg)
|
|||
if((error= drop_indexes(ndb, table_arg)))
|
||||
{
|
||||
m_share->state= NSS_INITIAL;
|
||||
/* ndb_share reference schema free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s binlog schema free use_count: %u",
|
||||
m_share->key, m_share->use_count));
|
||||
free_share(&m_share); // Decrease ref_count
|
||||
}
|
||||
DBUG_RETURN(error);
|
||||
|
@ -5365,9 +5383,12 @@ int ha_ndbcluster::rename_table(const char *from, const char *to)
|
|||
int ndb_table_id= orig_tab->getObjectId();
|
||||
int ndb_table_version= orig_tab->getObjectVersion();
|
||||
|
||||
/* ndb_share reference temporary */
|
||||
NDB_SHARE *share= get_share(from, 0, FALSE);
|
||||
if (share)
|
||||
{
|
||||
DBUG_PRINT("NDB_SHARE", ("%s temporary use_count: %u",
|
||||
share->key, share->use_count));
|
||||
int r= rename_share(share, to);
|
||||
DBUG_ASSERT(r == 0);
|
||||
}
|
||||
|
@ -5391,6 +5412,9 @@ int ha_ndbcluster::rename_table(const char *from, const char *to)
|
|||
{
|
||||
int r= rename_share(share, from);
|
||||
DBUG_ASSERT(r == 0);
|
||||
/* ndb_share reference temporary free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s temporary free use_count: %u",
|
||||
share->key, share->use_count));
|
||||
free_share(&share);
|
||||
}
|
||||
#endif
|
||||
|
@ -5403,7 +5427,12 @@ int ha_ndbcluster::rename_table(const char *from, const char *to)
|
|||
// ToDo in 4.1 should rollback alter table...
|
||||
#ifdef HAVE_NDB_BINLOG
|
||||
if (share)
|
||||
{
|
||||
/* ndb_share reference temporary free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s temporary use_count: %u",
|
||||
share->key, share->use_count));
|
||||
free_share(&share);
|
||||
}
|
||||
#endif
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
|
@ -5437,7 +5466,7 @@ int ha_ndbcluster::rename_table(const char *from, const char *to)
|
|||
if (ndb_extra_logging)
|
||||
sql_print_information("NDB Binlog: RENAME Event: %s",
|
||||
event_name.c_ptr());
|
||||
if (share && ndb_binlog_running &&
|
||||
if (share &&
|
||||
ndbcluster_create_event_ops(share, ndbtab, event_name.c_ptr()))
|
||||
{
|
||||
sql_print_error("NDB Binlog: FAILED create event operations "
|
||||
|
@ -5484,7 +5513,12 @@ int ha_ndbcluster::rename_table(const char *from, const char *to)
|
|||
}
|
||||
}
|
||||
if (share)
|
||||
{
|
||||
/* ndb_share reference temporary free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s temporary free use_count: %u",
|
||||
share->key, share->use_count));
|
||||
free_share(&share);
|
||||
}
|
||||
#endif
|
||||
|
||||
DBUG_RETURN(result);
|
||||
|
@ -5519,7 +5553,13 @@ ha_ndbcluster::delete_table(ha_ndbcluster *h, Ndb *ndb,
|
|||
DBUG_PRINT("info", ("Schema distribution table not setup"));
|
||||
DBUG_RETURN(HA_ERR_NO_CONNECTION);
|
||||
}
|
||||
/* ndb_share reference temporary */
|
||||
NDB_SHARE *share= get_share(path, 0, FALSE);
|
||||
if (share)
|
||||
{
|
||||
DBUG_PRINT("NDB_SHARE", ("%s temporary use_count: %u",
|
||||
share->key, share->use_count));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Drop the table from NDB */
|
||||
|
@ -5599,9 +5639,14 @@ retry_temporary_error1:
|
|||
The share kept by the server has not been freed, free it
|
||||
*/
|
||||
share->state= NSS_DROPPED;
|
||||
/* ndb_share reference create free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s create free use_count: %u",
|
||||
share->key, share->use_count));
|
||||
free_share(&share, TRUE);
|
||||
}
|
||||
/* free the share taken above */
|
||||
/* ndb_share reference temporary free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s temporary free use_count: %u",
|
||||
share->key, share->use_count));
|
||||
free_share(&share, TRUE);
|
||||
pthread_mutex_unlock(&ndbcluster_mutex);
|
||||
}
|
||||
|
@ -5651,9 +5696,14 @@ retry_temporary_error1:
|
|||
The share kept by the server has not been freed, free it
|
||||
*/
|
||||
share->state= NSS_DROPPED;
|
||||
/* ndb_share reference create free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s create free use_count: %u",
|
||||
share->key, share->use_count));
|
||||
free_share(&share, TRUE);
|
||||
}
|
||||
/* free the share taken above */
|
||||
/* ndb_share reference temporary free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s temporary free use_count: %u",
|
||||
share->key, share->use_count));
|
||||
free_share(&share, TRUE);
|
||||
pthread_mutex_unlock(&ndbcluster_mutex);
|
||||
}
|
||||
|
@ -5829,6 +5879,9 @@ ha_ndbcluster::~ha_ndbcluster()
|
|||
|
||||
if (m_share)
|
||||
{
|
||||
/* ndb_share reference handler free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s handler free use_count: %u",
|
||||
m_share->key, m_share->use_count));
|
||||
free_share(&m_share);
|
||||
}
|
||||
release_metadata(thd, ndb);
|
||||
|
@ -5891,14 +5944,21 @@ int ha_ndbcluster::open(const char *name, int mode, uint test_if_locked)
|
|||
DBUG_PRINT("info", ("ref_length: %d", ref_length));
|
||||
|
||||
// Init table lock structure
|
||||
/* ndb_share reference handler */
|
||||
if (!(m_share=get_share(name, table)))
|
||||
DBUG_RETURN(1);
|
||||
DBUG_PRINT("NDB_SHARE", ("%s handler use_count: %u",
|
||||
m_share->key, m_share->use_count));
|
||||
thr_lock_data_init(&m_share->lock,&m_lock,(void*) 0);
|
||||
|
||||
set_dbname(name);
|
||||
set_tabname(name);
|
||||
|
||||
if (check_ndb_connection()) {
|
||||
if (check_ndb_connection())
|
||||
{
|
||||
/* ndb_share reference handler free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s handler free use_count: %u",
|
||||
m_share->key, m_share->use_count));
|
||||
free_share(&m_share);
|
||||
m_share= 0;
|
||||
DBUG_RETURN(HA_ERR_NO_CONNECTION);
|
||||
|
@ -5959,6 +6019,9 @@ int ha_ndbcluster::close(void)
|
|||
DBUG_ENTER("close");
|
||||
THD *thd= current_thd;
|
||||
Ndb *ndb= thd ? check_ndb_in_thd(thd) : g_ndb;
|
||||
/* ndb_share reference handler free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s handler free use_count: %u",
|
||||
m_share->key, m_share->use_count));
|
||||
free_share(&m_share);
|
||||
m_share= 0;
|
||||
release_metadata(thd, ndb);
|
||||
|
@ -6065,7 +6128,13 @@ int ndbcluster_discover(handlerton *hton, THD* thd, const char *db,
|
|||
ndb->setDatabaseName(db);
|
||||
NDBDICT* dict= ndb->getDictionary();
|
||||
build_table_filename(key, sizeof(key), db, name, "", 0);
|
||||
/* ndb_share reference temporary */
|
||||
NDB_SHARE *share= get_share(key, 0, FALSE);
|
||||
if (share)
|
||||
{
|
||||
DBUG_PRINT("NDB_SHARE", ("%s temporary use_count: %u",
|
||||
share->key, share->use_count));
|
||||
}
|
||||
if (share && get_ndb_share_state(share) == NSS_ALTERED)
|
||||
{
|
||||
// Frm has been altered on disk, but not yet written to ndb
|
||||
|
@ -6111,12 +6180,22 @@ int ndbcluster_discover(handlerton *hton, THD* thd, const char *db,
|
|||
*frmblob= data;
|
||||
|
||||
if (share)
|
||||
{
|
||||
/* ndb_share reference temporary free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s temporary free use_count: %u",
|
||||
share->key, share->use_count));
|
||||
free_share(&share);
|
||||
}
|
||||
|
||||
DBUG_RETURN(0);
|
||||
err:
|
||||
if (share)
|
||||
{
|
||||
/* ndb_share reference temporary free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s temporary free use_count: %u",
|
||||
share->key, share->use_count));
|
||||
free_share(&share);
|
||||
}
|
||||
if (ndb_error.code)
|
||||
{
|
||||
ERR_RETURN(ndb_error);
|
||||
|
@ -6354,7 +6433,13 @@ int ndbcluster_find_all_files(THD *thd)
|
|||
}
|
||||
else if (cmp_frm(ndbtab, pack_data, pack_length))
|
||||
{
|
||||
/* ndb_share reference temporary */
|
||||
NDB_SHARE *share= get_share(key, 0, FALSE);
|
||||
if (share)
|
||||
{
|
||||
DBUG_PRINT("NDB_SHARE", ("%s temporary use_count: %u",
|
||||
share->key, share->use_count));
|
||||
}
|
||||
if (!share || get_ndb_share_state(share) != NSS_ALTERED)
|
||||
{
|
||||
discover= 1;
|
||||
|
@ -6362,7 +6447,12 @@ int ndbcluster_find_all_files(THD *thd)
|
|||
elmt.database, elmt.name);
|
||||
}
|
||||
if (share)
|
||||
{
|
||||
/* ndb_share reference temporary free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s temporary free use_count: %u",
|
||||
share->key, share->use_count));
|
||||
free_share(&share);
|
||||
}
|
||||
}
|
||||
my_free((char*) data, MYF(MY_ALLOW_ZERO_PTR));
|
||||
my_free((char*) pack_data, MYF(MY_ALLOW_ZERO_PTR));
|
||||
|
@ -6829,7 +6919,7 @@ static int ndbcluster_end(handlerton *hton, ha_panic_function type)
|
|||
fprintf(stderr, "NDB: table share %s with use_count %d not freed\n",
|
||||
share->key, share->use_count);
|
||||
#endif
|
||||
real_free_share(&share);
|
||||
ndbcluster_real_free_share(&share);
|
||||
}
|
||||
pthread_mutex_unlock(&ndbcluster_mutex);
|
||||
}
|
||||
|
@ -7167,7 +7257,10 @@ uint ndb_get_commitcount(THD *thd, char *dbname, char *tabname,
|
|||
DBUG_PRINT("info", ("Table %s not found in ndbcluster_open_tables", name));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
/* ndb_share reference temporary, free below */
|
||||
share->use_count++;
|
||||
DBUG_PRINT("NDB_SHARE", ("%s temporary use_count: %u",
|
||||
share->key, share->use_count));
|
||||
pthread_mutex_unlock(&ndbcluster_mutex);
|
||||
|
||||
pthread_mutex_lock(&share->mutex);
|
||||
|
@ -7180,6 +7273,9 @@ uint ndb_get_commitcount(THD *thd, char *dbname, char *tabname,
|
|||
DBUG_PRINT("info", ("Getting commit_count: %s from share",
|
||||
llstr(share->commit_count, buff)));
|
||||
pthread_mutex_unlock(&share->mutex);
|
||||
/* ndb_share reference temporary free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s temporary free use_count: %u",
|
||||
share->key, share->use_count));
|
||||
free_share(&share);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
@ -7198,6 +7294,9 @@ uint ndb_get_commitcount(THD *thd, char *dbname, char *tabname,
|
|||
if (ndbtab_g.get_table() == 0
|
||||
|| ndb_get_table_statistics(NULL, FALSE, ndb, ndbtab_g.get_table(), &stat))
|
||||
{
|
||||
/* ndb_share reference temporary free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s temporary free use_count: %u",
|
||||
share->key, share->use_count));
|
||||
free_share(&share);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
@ -7218,6 +7317,9 @@ uint ndb_get_commitcount(THD *thd, char *dbname, char *tabname,
|
|||
*commit_count= 0;
|
||||
}
|
||||
pthread_mutex_unlock(&share->mutex);
|
||||
/* ndb_share reference temporary free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s temporary free use_count: %u",
|
||||
share->key, share->use_count));
|
||||
free_share(&share);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
@ -7434,21 +7536,34 @@ int handle_trailing_share(NDB_SHARE *share)
|
|||
static ulong trailing_share_id= 0;
|
||||
DBUG_ENTER("handle_trailing_share");
|
||||
|
||||
/* ndb_share reference temporary, free below */
|
||||
++share->use_count;
|
||||
DBUG_PRINT("NDB_SHARE", ("%s temporary use_count: %u",
|
||||
share->key, share->use_count));
|
||||
pthread_mutex_unlock(&ndbcluster_mutex);
|
||||
|
||||
TABLE_LIST table_list;
|
||||
bzero((char*) &table_list,sizeof(table_list));
|
||||
table_list.db= share->db;
|
||||
table_list.alias= table_list.table_name= share->table_name;
|
||||
safe_mutex_assert_owner(&LOCK_open);
|
||||
close_cached_tables(thd, 0, &table_list, TRUE);
|
||||
|
||||
pthread_mutex_lock(&ndbcluster_mutex);
|
||||
/* ndb_share reference temporary free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s temporary free use_count: %u",
|
||||
share->key, share->use_count));
|
||||
if (!--share->use_count)
|
||||
{
|
||||
DBUG_PRINT("info", ("NDB_SHARE: close_cashed_tables %s freed share.",
|
||||
share->key));
|
||||
real_free_share(&share);
|
||||
if (ndb_extra_logging)
|
||||
sql_print_information("NDB_SHARE: trailing share "
|
||||
"%s(connect_count: %u) "
|
||||
"released by close_cached_tables at "
|
||||
"connect_count: %u",
|
||||
share->key,
|
||||
share->connect_count,
|
||||
g_ndb_cluster_connection->get_connect_count());
|
||||
ndbcluster_real_free_share(&share);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
@ -7456,16 +7571,28 @@ int handle_trailing_share(NDB_SHARE *share)
|
|||
share still exists, if share has not been dropped by server
|
||||
release that share
|
||||
*/
|
||||
if (share->state != NSS_DROPPED && !--share->use_count)
|
||||
if (share->state != NSS_DROPPED)
|
||||
{
|
||||
DBUG_PRINT("info", ("NDB_SHARE: %s already exists, "
|
||||
"use_count=%d state != NSS_DROPPED.",
|
||||
share->key, share->use_count));
|
||||
real_free_share(&share);
|
||||
DBUG_RETURN(0);
|
||||
share->state= NSS_DROPPED;
|
||||
/* ndb_share reference create free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s create free use_count: %u",
|
||||
share->key, share->use_count));
|
||||
--share->use_count;
|
||||
|
||||
if (share->use_count == 0)
|
||||
{
|
||||
if (ndb_extra_logging)
|
||||
sql_print_information("NDB_SHARE: trailing share "
|
||||
"%s(connect_count: %u) "
|
||||
"released after NSS_DROPPED check "
|
||||
"at connect_count: %u",
|
||||
share->key,
|
||||
share->connect_count,
|
||||
g_ndb_cluster_connection->get_connect_count());
|
||||
ndbcluster_real_free_share(&share);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
}
|
||||
DBUG_PRINT("error", ("NDB_SHARE: %s already exists use_count=%d.",
|
||||
share->key, share->use_count));
|
||||
|
||||
sql_print_error("NDB_SHARE: %s already exists use_count=%d."
|
||||
" Moving away for safety, but possible memleak.",
|
||||
|
@ -7727,7 +7854,7 @@ void ndbcluster_free_share(NDB_SHARE **share, bool have_lock)
|
|||
(*share)->util_lock= 0;
|
||||
if (!--(*share)->use_count)
|
||||
{
|
||||
real_free_share(share);
|
||||
ndbcluster_real_free_share(share);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -7800,7 +7927,7 @@ ndb_get_table_statistics(ha_ndbcluster* file, bool report_error, Ndb* ndb, const
|
|||
(char*)&var_mem);
|
||||
|
||||
if (pTrans->execute(NdbTransaction::NoCommit,
|
||||
NdbTransaction::AbortOnError,
|
||||
NdbOperation::AbortOnError,
|
||||
TRUE) == -1)
|
||||
{
|
||||
error= pTrans->getNdbError();
|
||||
|
@ -8057,7 +8184,6 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
|
|||
!op->readTuple(lm) &&
|
||||
!set_primary_key(op, multi_range_curr->start_key.key) &&
|
||||
!define_read_attrs(curr, op) &&
|
||||
(op->setAbortOption(AO_IgnoreError), TRUE) &&
|
||||
(!m_use_partition_function ||
|
||||
(op->setPartitionId(part_spec.start_part), TRUE)))
|
||||
curr += reclength;
|
||||
|
@ -8079,8 +8205,7 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
|
|||
if ((op= m_active_trans->getNdbIndexOperation(unique_idx, tab)) &&
|
||||
!op->readTuple(lm) &&
|
||||
!set_index_key(op, key_info, multi_range_curr->start_key.key) &&
|
||||
!define_read_attrs(curr, op) &&
|
||||
(op->setAbortOption(AO_IgnoreError), TRUE))
|
||||
!define_read_attrs(curr, op))
|
||||
curr += reclength;
|
||||
else
|
||||
ERR_RETURN(op ? op->getNdbError() : m_active_trans->getNdbError());
|
||||
|
@ -8104,7 +8229,7 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
|
|||
}
|
||||
else if ((scanOp= m_active_trans->getNdbIndexScanOperation(idx, tab))
|
||||
&&!scanOp->readTuples(lm, 0, parallelism, sorted,
|
||||
FALSE, TRUE, need_pk)
|
||||
FALSE, TRUE, need_pk, TRUE)
|
||||
&&!generate_scan_filter(m_cond_stack, scanOp)
|
||||
&&!define_read_attrs(end_of_buffer-reclength, scanOp))
|
||||
{
|
||||
|
@ -8280,6 +8405,8 @@ close_scan:
|
|||
if (multi_range_curr == multi_range_end)
|
||||
{
|
||||
DBUG_MULTI_RANGE(16);
|
||||
Thd_ndb *thd_ndb= get_thd_ndb(current_thd);
|
||||
thd_ndb->query_state&= NDB_QUERY_NORMAL;
|
||||
DBUG_RETURN(HA_ERR_END_OF_FILE);
|
||||
}
|
||||
|
||||
|
@ -8518,7 +8645,10 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused)))
|
|||
continue; // injector thread is the only user, skip statistics
|
||||
share->util_lock= current_thd; // Mark that util thread has lock
|
||||
#endif /* HAVE_NDB_BINLOG */
|
||||
/* ndb_share reference temporary, free below */
|
||||
share->use_count++; /* Make sure the table can't be closed */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s temporary use_count: %u",
|
||||
share->key, share->use_count));
|
||||
DBUG_PRINT("ndb_util_thread",
|
||||
("Found open table[%d]: %s, use_count: %d",
|
||||
i, share->table_name, share->use_count));
|
||||
|
@ -8539,6 +8669,9 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused)))
|
|||
/*
|
||||
Util thread and injector thread is the only user, skip statistics
|
||||
*/
|
||||
/* ndb_share reference temporary free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s temporary free use_count: %u",
|
||||
share->key, share->use_count));
|
||||
free_share(&share);
|
||||
continue;
|
||||
}
|
||||
|
@ -8582,7 +8715,9 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused)))
|
|||
share->commit_count= stat.commit_count;
|
||||
pthread_mutex_unlock(&share->mutex);
|
||||
|
||||
/* Decrease the use count and possibly free share */
|
||||
/* ndb_share reference temporary free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s temporary free use_count: %u",
|
||||
share->key, share->use_count));
|
||||
free_share(&share);
|
||||
}
|
||||
|
||||
|
|
|
@ -108,6 +108,7 @@ typedef struct st_ndbcluster_share {
|
|||
char *table_name;
|
||||
Ndb::TupleIdRange tuple_id_range;
|
||||
#ifdef HAVE_NDB_BINLOG
|
||||
uint32 connect_count;
|
||||
uint32 flags;
|
||||
NdbEventOperation *op;
|
||||
NdbEventOperation *op_old; // for rename table
|
||||
|
|
|
@ -81,6 +81,7 @@ static Ndb *injector_ndb= 0;
|
|||
static Ndb *schema_ndb= 0;
|
||||
|
||||
static int ndbcluster_binlog_inited= 0;
|
||||
static int ndbcluster_binlog_terminating= 0;
|
||||
|
||||
/*
|
||||
Mutex and condition used for interacting between client sql thread
|
||||
|
@ -97,6 +98,7 @@ static ulonglong ndb_latest_received_binlog_epoch= 0;
|
|||
|
||||
NDB_SHARE *ndb_apply_status_share= 0;
|
||||
NDB_SHARE *ndb_schema_share= 0;
|
||||
pthread_mutex_t ndb_schema_share_mutex;
|
||||
|
||||
/* Schema object distribution handling */
|
||||
HASH ndb_schema_objects;
|
||||
|
@ -361,6 +363,8 @@ void ndbcluster_binlog_init_share(NDB_SHARE *share, TABLE *_table)
|
|||
int do_event_op= ndb_binlog_running;
|
||||
DBUG_ENTER("ndbcluster_binlog_init_share");
|
||||
|
||||
share->connect_count= g_ndb_cluster_connection->get_connect_count();
|
||||
|
||||
share->op= 0;
|
||||
share->table= 0;
|
||||
|
||||
|
@ -368,6 +372,10 @@ void ndbcluster_binlog_init_share(NDB_SHARE *share, TABLE *_table)
|
|||
strcmp(share->db, NDB_REP_DB) == 0 &&
|
||||
strcmp(share->table_name, NDB_SCHEMA_TABLE) == 0)
|
||||
do_event_op= 1;
|
||||
else if (!ndb_apply_status_share &&
|
||||
strcmp(share->db, NDB_REP_DB) == 0 &&
|
||||
strcmp(share->table_name, NDB_APPLY_TABLE) == 0)
|
||||
do_event_op= 1;
|
||||
|
||||
{
|
||||
int i, no_nodes= g_ndb_cluster_connection->no_db_nodes();
|
||||
|
@ -575,53 +583,18 @@ static int ndbcluster_binlog_end(THD *thd)
|
|||
|
||||
#ifdef HAVE_NDB_BINLOG
|
||||
/* wait for injector thread to finish */
|
||||
ndbcluster_binlog_terminating= 1;
|
||||
pthread_cond_signal(&injector_cond);
|
||||
pthread_mutex_lock(&injector_mutex);
|
||||
if (ndb_binlog_thread_running > 0)
|
||||
{
|
||||
pthread_cond_signal(&injector_cond);
|
||||
pthread_mutex_unlock(&injector_mutex);
|
||||
|
||||
pthread_mutex_lock(&injector_mutex);
|
||||
while (ndb_binlog_thread_running > 0)
|
||||
{
|
||||
struct timespec abstime;
|
||||
set_timespec(abstime, 1);
|
||||
pthread_cond_timedwait(&injector_cond, &injector_mutex, &abstime);
|
||||
}
|
||||
}
|
||||
while (ndb_binlog_thread_running > 0)
|
||||
pthread_cond_wait(&injector_cond, &injector_mutex);
|
||||
pthread_mutex_unlock(&injector_mutex);
|
||||
|
||||
|
||||
/* remove all shares */
|
||||
{
|
||||
pthread_mutex_lock(&ndbcluster_mutex);
|
||||
for (uint i= 0; i < ndbcluster_open_tables.records; i++)
|
||||
{
|
||||
NDB_SHARE *share=
|
||||
(NDB_SHARE*) hash_element(&ndbcluster_open_tables, i);
|
||||
if (share->table)
|
||||
DBUG_PRINT("share",
|
||||
("table->s->db.table_name: %s.%s",
|
||||
share->table->s->db.str, share->table->s->table_name.str));
|
||||
if (share->state != NSS_DROPPED && !--share->use_count)
|
||||
real_free_share(&share);
|
||||
else
|
||||
{
|
||||
DBUG_PRINT("share",
|
||||
("[%d] 0x%lx key: %s key_length: %d",
|
||||
i, (long) share, share->key, share->key_length));
|
||||
DBUG_PRINT("share",
|
||||
("db.tablename: %s.%s use_count: %d commit_count: %lu",
|
||||
share->db, share->table_name,
|
||||
share->use_count, (long) share->commit_count));
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&ndbcluster_mutex);
|
||||
}
|
||||
|
||||
pthread_mutex_destroy(&injector_mutex);
|
||||
pthread_cond_destroy(&injector_cond);
|
||||
pthread_mutex_destroy(&ndb_schema_share_mutex);
|
||||
#endif
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
@ -1271,6 +1244,16 @@ int ndbcluster_log_schema_op(THD *thd, NDB_SHARE *share,
|
|||
int no_storage_nodes= g_ndb_cluster_connection->no_db_nodes();
|
||||
bitmap_init(&schema_subscribers, bitbuf, sizeof(bitbuf)*8, FALSE);
|
||||
bitmap_set_all(&schema_subscribers);
|
||||
|
||||
/* begin protect ndb_schema_share */
|
||||
pthread_mutex_lock(&ndb_schema_share_mutex);
|
||||
if (ndb_schema_share == 0)
|
||||
{
|
||||
pthread_mutex_unlock(&ndb_schema_share_mutex);
|
||||
if (ndb_schema_object)
|
||||
ndb_free_schema_object(&ndb_schema_object, FALSE);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
(void) pthread_mutex_lock(&ndb_schema_share->mutex);
|
||||
for (i= 0; i < no_storage_nodes; i++)
|
||||
{
|
||||
|
@ -1283,6 +1266,9 @@ int ndbcluster_log_schema_op(THD *thd, NDB_SHARE *share,
|
|||
}
|
||||
}
|
||||
(void) pthread_mutex_unlock(&ndb_schema_share->mutex);
|
||||
pthread_mutex_unlock(&ndb_schema_share_mutex);
|
||||
/* end protect ndb_schema_share */
|
||||
|
||||
if (updated)
|
||||
{
|
||||
bitmap_clear_bit(&schema_subscribers, node_id);
|
||||
|
@ -1478,6 +1464,14 @@ end:
|
|||
&abstime);
|
||||
if (thd->killed)
|
||||
break;
|
||||
|
||||
/* begin protect ndb_schema_share */
|
||||
pthread_mutex_lock(&ndb_schema_share_mutex);
|
||||
if (ndb_schema_share == 0)
|
||||
{
|
||||
pthread_mutex_unlock(&ndb_schema_share_mutex);
|
||||
break;
|
||||
}
|
||||
(void) pthread_mutex_lock(&ndb_schema_share->mutex);
|
||||
for (i= 0; i < no_storage_nodes; i++)
|
||||
{
|
||||
|
@ -1487,6 +1481,8 @@ end:
|
|||
bitmap_intersect(&schema_subscribers, tmp);
|
||||
}
|
||||
(void) pthread_mutex_unlock(&ndb_schema_share->mutex);
|
||||
pthread_mutex_unlock(&ndb_schema_share_mutex);
|
||||
/* end protect ndb_schema_share */
|
||||
|
||||
/* remove any unsubscribed from ndb_schema_object->slock */
|
||||
bitmap_intersect(&ndb_schema_object->slock_bitmap, &schema_subscribers);
|
||||
|
@ -1689,15 +1685,25 @@ ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp,
|
|||
(void) pthread_cond_signal(&injector_cond);
|
||||
|
||||
pthread_mutex_lock(&ndbcluster_mutex);
|
||||
/* ndb_share reference binlog free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s binlog free use_count: %u",
|
||||
share->key, share->use_count));
|
||||
free_share(&share, TRUE);
|
||||
if (is_remote_change && share && share->state != NSS_DROPPED)
|
||||
{
|
||||
DBUG_PRINT("info", ("remote change"));
|
||||
share->state= NSS_DROPPED;
|
||||
if (share->use_count != 1)
|
||||
{
|
||||
/* open handler holding reference */
|
||||
/* wait with freeing create ndb_share to below */
|
||||
do_close_cached_tables= TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ndb_share reference create free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s create free use_count: %u",
|
||||
share->key, share->use_count));
|
||||
free_share(&share, TRUE);
|
||||
share= 0;
|
||||
}
|
||||
|
@ -1720,6 +1726,9 @@ ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp,
|
|||
table_list.db= (char *)dbname;
|
||||
table_list.alias= table_list.table_name= (char *)tabname;
|
||||
close_cached_tables(thd, 0, &table_list);
|
||||
/* ndb_share reference create free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s create free use_count: %u",
|
||||
share->key, share->use_count));
|
||||
free_share(&share);
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
|
@ -1787,7 +1796,13 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb,
|
|||
char key[FN_REFLEN];
|
||||
build_table_filename(key, sizeof(key),
|
||||
schema->db, schema->name, "", 0);
|
||||
/* ndb_share reference temporary, free below */
|
||||
NDB_SHARE *share= get_share(key, 0, FALSE, FALSE);
|
||||
if (share)
|
||||
{
|
||||
DBUG_PRINT("NDB_SHARE", ("%s temporary use_count: %u",
|
||||
share->key, share->use_count));
|
||||
}
|
||||
// invalidation already handled by binlog thread
|
||||
if (!share || !share->op)
|
||||
{
|
||||
|
@ -1803,8 +1818,13 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb,
|
|||
table_list.alias= table_list.table_name= schema->name;
|
||||
close_cached_tables(thd, 0, &table_list, FALSE);
|
||||
}
|
||||
/* ndb_share reference temporary free */
|
||||
if (share)
|
||||
{
|
||||
DBUG_PRINT("NDB_SHARE", ("%s temporary free use_count: %u",
|
||||
share->key, share->use_count));
|
||||
free_share(&share);
|
||||
}
|
||||
}
|
||||
// fall through
|
||||
case SOT_CREATE_TABLE:
|
||||
|
@ -1910,8 +1930,18 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb,
|
|||
ndb_binlog_tables_inited && ndb_binlog_running)
|
||||
sql_print_information("NDB Binlog: ndb tables initially "
|
||||
"read only on reconnect.");
|
||||
|
||||
/* begin protect ndb_schema_share */
|
||||
pthread_mutex_lock(&ndb_schema_share_mutex);
|
||||
/* ndb_share reference binlog extra free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s binlog extra free use_count: %u",
|
||||
ndb_schema_share->key,
|
||||
ndb_schema_share->use_count));
|
||||
free_share(&ndb_schema_share);
|
||||
ndb_schema_share= 0;
|
||||
pthread_mutex_unlock(&ndb_schema_share_mutex);
|
||||
/* end protect ndb_schema_share */
|
||||
|
||||
close_cached_tables((THD*) 0, 0, (TABLE_LIST*) 0, FALSE);
|
||||
// fall through
|
||||
case NDBEVENT::TE_ALTER:
|
||||
|
@ -2033,7 +2063,13 @@ ndb_binlog_thread_handle_schema_event_post_epoch(THD *thd,
|
|||
pthread_mutex_unlock(&ndbcluster_mutex);
|
||||
continue;
|
||||
}
|
||||
/* ndb_share reference temporary, free below */
|
||||
NDB_SHARE *share= get_share(key, 0, FALSE, FALSE);
|
||||
if (share)
|
||||
{
|
||||
DBUG_PRINT("NDB_SHARE", ("%s temporary use_count: %u",
|
||||
share->key, share->use_count));
|
||||
}
|
||||
switch (schema_type)
|
||||
{
|
||||
case SOT_DROP_DB:
|
||||
|
@ -2078,6 +2114,9 @@ ndb_binlog_thread_handle_schema_event_post_epoch(THD *thd,
|
|||
*/
|
||||
if (share)
|
||||
{
|
||||
/* ndb_share reference temporary free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s temporary free use_count: %u",
|
||||
share->key, share->use_count));
|
||||
free_share(&share);
|
||||
share= 0;
|
||||
}
|
||||
|
@ -2110,6 +2149,9 @@ ndb_binlog_thread_handle_schema_event_post_epoch(THD *thd,
|
|||
}
|
||||
if (share)
|
||||
{
|
||||
/* ndb_share reference temporary free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s temporary free use_count: %u",
|
||||
share->key, share->use_count));
|
||||
free_share(&share);
|
||||
share= 0;
|
||||
}
|
||||
|
@ -2278,6 +2320,7 @@ int ndbcluster_binlog_start()
|
|||
|
||||
pthread_mutex_init(&injector_mutex, MY_MUTEX_INIT_FAST);
|
||||
pthread_cond_init(&injector_cond, NULL);
|
||||
pthread_mutex_init(&ndb_schema_share_mutex, MY_MUTEX_INIT_FAST);
|
||||
|
||||
/* Create injector thread */
|
||||
if (pthread_create(&ndb_binlog_thread, &connection_attrib,
|
||||
|
@ -2300,7 +2343,6 @@ int ndbcluster_binlog_start()
|
|||
if (ndb_binlog_thread_running < 0)
|
||||
DBUG_RETURN(-1);
|
||||
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
@ -2411,20 +2453,42 @@ int ndbcluster_create_binlog_setup(Ndb *ndb, const char *key,
|
|||
pthread_mutex_unlock(&ndbcluster_mutex);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
handle_trailing_share(share);
|
||||
if (!share_may_exist || share->connect_count !=
|
||||
g_ndb_cluster_connection->get_connect_count())
|
||||
{
|
||||
handle_trailing_share(share);
|
||||
share= NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create share which is needed to hold replication information */
|
||||
if (!(share= get_share(key, 0, TRUE, TRUE)))
|
||||
if (share)
|
||||
{
|
||||
/* ndb_share reference create */
|
||||
++share->use_count;
|
||||
DBUG_PRINT("NDB_SHARE", ("%s create use_count: %u",
|
||||
share->key, share->use_count));
|
||||
}
|
||||
/* ndb_share reference create */
|
||||
else if (!(share= get_share(key, 0, TRUE, TRUE)))
|
||||
{
|
||||
sql_print_error("NDB Binlog: "
|
||||
"allocating table share for %s failed", key);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBUG_PRINT("NDB_SHARE", ("%s create use_count: %u",
|
||||
share->key, share->use_count));
|
||||
}
|
||||
|
||||
if (!ndb_schema_share &&
|
||||
strcmp(share->db, NDB_REP_DB) == 0 &&
|
||||
strcmp(share->table_name, NDB_SCHEMA_TABLE) == 0)
|
||||
do_event_op= 1;
|
||||
else if (!ndb_apply_status_share &&
|
||||
strcmp(share->db, NDB_REP_DB) == 0 &&
|
||||
strcmp(share->table_name, NDB_APPLY_TABLE) == 0)
|
||||
do_event_op= 1;
|
||||
|
||||
if (!do_event_op)
|
||||
{
|
||||
|
@ -2696,7 +2760,7 @@ ndbcluster_create_event_ops(NDB_SHARE *share, const NDBTAB *ndbtab,
|
|||
else if (!ndb_apply_status_share && strcmp(share->db, NDB_REP_DB) == 0 &&
|
||||
strcmp(share->table_name, NDB_APPLY_TABLE) == 0)
|
||||
do_ndb_apply_status_share= 1;
|
||||
else if (!binlog_filter->db_ok(share->db))
|
||||
else if (!binlog_filter->db_ok(share->db) || !ndb_binlog_running)
|
||||
{
|
||||
share->flags|= NSF_NO_BINLOG;
|
||||
DBUG_RETURN(0);
|
||||
|
@ -2708,6 +2772,9 @@ ndbcluster_create_event_ops(NDB_SHARE *share, const NDBTAB *ndbtab,
|
|||
|
||||
DBUG_ASSERT(share->use_count > 1);
|
||||
sql_print_error("NDB Binlog: discover reusing old ev op");
|
||||
/* ndb_share reference ToDo free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s ToDo free use_count: %u",
|
||||
share->key, share->use_count));
|
||||
free_share(&share); // old event op already has reference
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
@ -2850,15 +2917,24 @@ ndbcluster_create_event_ops(NDB_SHARE *share, const NDBTAB *ndbtab,
|
|||
break;
|
||||
}
|
||||
|
||||
/* ndb_share reference binlog */
|
||||
get_share(share);
|
||||
DBUG_PRINT("NDB_SHARE", ("%s binlog use_count: %u",
|
||||
share->key, share->use_count));
|
||||
if (do_ndb_apply_status_share)
|
||||
{
|
||||
/* ndb_share reference binlog extra */
|
||||
ndb_apply_status_share= get_share(share);
|
||||
DBUG_PRINT("NDB_SHARE", ("%s binlog extra use_count: %u",
|
||||
share->key, share->use_count));
|
||||
(void) pthread_cond_signal(&injector_cond);
|
||||
}
|
||||
else if (do_ndb_schema_share)
|
||||
{
|
||||
/* ndb_share reference binlog extra */
|
||||
ndb_schema_share= get_share(share);
|
||||
DBUG_PRINT("NDB_SHARE", ("%s binlog extra use_count: %u",
|
||||
share->key, share->use_count));
|
||||
(void) pthread_cond_signal(&injector_cond);
|
||||
}
|
||||
|
||||
|
@ -3045,6 +3121,9 @@ ndb_binlog_thread_handle_non_data_event(THD *thd, Ndb *ndb,
|
|||
ndb_binlog_tables_inited && ndb_binlog_running)
|
||||
sql_print_information("NDB Binlog: ndb tables initially "
|
||||
"read only on reconnect.");
|
||||
/* ndb_share reference binlog extra free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s binlog extra free use_count: %u",
|
||||
share->key, share->use_count));
|
||||
free_share(&ndb_apply_status_share);
|
||||
ndb_apply_status_share= 0;
|
||||
}
|
||||
|
@ -3061,6 +3140,9 @@ ndb_binlog_thread_handle_non_data_event(THD *thd, Ndb *ndb,
|
|||
ndb_binlog_tables_inited && ndb_binlog_running)
|
||||
sql_print_information("NDB Binlog: ndb tables initially "
|
||||
"read only on reconnect.");
|
||||
/* ndb_share reference binlog extra free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s binlog extra free use_count: %u",
|
||||
share->key, share->use_count));
|
||||
free_share(&ndb_apply_status_share);
|
||||
ndb_apply_status_share= 0;
|
||||
}
|
||||
|
@ -3437,6 +3519,9 @@ pthread_handler_t ndb_binlog_thread_func(void *arg)
|
|||
s_ndb->init())
|
||||
{
|
||||
sql_print_error("NDB Binlog: Getting Schema Ndb object failed");
|
||||
ndb_binlog_thread_running= -1;
|
||||
pthread_mutex_unlock(&injector_mutex);
|
||||
pthread_cond_signal(&injector_cond);
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
@ -3467,7 +3552,7 @@ pthread_handler_t ndb_binlog_thread_func(void *arg)
|
|||
p_latest_trans_gci=
|
||||
injector_ndb->get_ndb_cluster_connection().get_latest_trans_gci();
|
||||
schema_ndb= s_ndb;
|
||||
ndb_binlog_thread_running= 1;
|
||||
|
||||
if (opt_bin_log)
|
||||
{
|
||||
if (global_system_variables.binlog_format == BINLOG_FORMAT_ROW ||
|
||||
|
@ -3480,10 +3565,9 @@ pthread_handler_t ndb_binlog_thread_func(void *arg)
|
|||
sql_print_error("NDB: only row based binary logging is supported");
|
||||
}
|
||||
}
|
||||
/*
|
||||
We signal the thread that started us that we've finished
|
||||
starting up.
|
||||
*/
|
||||
|
||||
/* Thread start up completed */
|
||||
ndb_binlog_thread_running= 1;
|
||||
pthread_mutex_unlock(&injector_mutex);
|
||||
pthread_cond_signal(&injector_cond);
|
||||
|
||||
|
@ -3502,7 +3586,7 @@ restart:
|
|||
struct timespec abstime;
|
||||
set_timespec(abstime, 1);
|
||||
pthread_cond_timedwait(&injector_cond, &injector_mutex, &abstime);
|
||||
if (abort_loop)
|
||||
if (ndbcluster_binlog_terminating)
|
||||
{
|
||||
pthread_mutex_unlock(&injector_mutex);
|
||||
goto err;
|
||||
|
@ -3527,13 +3611,15 @@ restart:
|
|||
{
|
||||
// wait for the first event
|
||||
thd->proc_info= "Waiting for first event from ndbcluster";
|
||||
DBUG_PRINT("info", ("Waiting for the first event"));
|
||||
int schema_res, res;
|
||||
Uint64 schema_gci;
|
||||
do
|
||||
{
|
||||
if (abort_loop)
|
||||
DBUG_PRINT("info", ("Waiting for the first event"));
|
||||
|
||||
if (ndbcluster_binlog_terminating)
|
||||
goto err;
|
||||
|
||||
schema_res= s_ndb->pollEvents(100, &schema_gci);
|
||||
} while (schema_gci == 0 || ndb_latest_received_binlog_epoch == schema_gci);
|
||||
if (ndb_binlog_running)
|
||||
|
@ -3541,7 +3627,7 @@ restart:
|
|||
Uint64 gci= i_ndb->getLatestGCI();
|
||||
while (gci < schema_gci || gci == ndb_latest_received_binlog_epoch)
|
||||
{
|
||||
if (abort_loop)
|
||||
if (ndbcluster_binlog_terminating)
|
||||
goto err;
|
||||
res= i_ndb->pollEvents(10, &gci);
|
||||
}
|
||||
|
@ -3588,7 +3674,8 @@ restart:
|
|||
thd->db= db;
|
||||
}
|
||||
do_ndbcluster_binlog_close_connection= BCCC_running;
|
||||
for ( ; !((abort_loop || do_ndbcluster_binlog_close_connection) &&
|
||||
for ( ; !((ndbcluster_binlog_terminating ||
|
||||
do_ndbcluster_binlog_close_connection) &&
|
||||
ndb_latest_handled_binlog_epoch >= *p_latest_trans_gci) &&
|
||||
do_ndbcluster_binlog_close_connection != BCCC_restart; )
|
||||
{
|
||||
|
@ -3635,7 +3722,8 @@ restart:
|
|||
schema_res= s_ndb->pollEvents(10, &schema_gci);
|
||||
}
|
||||
|
||||
if ((abort_loop || do_ndbcluster_binlog_close_connection) &&
|
||||
if ((ndbcluster_binlog_terminating ||
|
||||
do_ndbcluster_binlog_close_connection) &&
|
||||
(ndb_latest_handled_binlog_epoch >= *p_latest_trans_gci ||
|
||||
!ndb_binlog_running))
|
||||
break; /* Shutting down server */
|
||||
|
@ -3924,9 +4012,9 @@ restart:
|
|||
"%ld(%d e/s), total time %ld(%d e/s)",
|
||||
(ulong)gci, event_count,
|
||||
write_timer.elapsed_ms(),
|
||||
event_count / write_timer.elapsed_ms(),
|
||||
(1000*event_count) / write_timer.elapsed_ms(),
|
||||
gci_timer.elapsed_ms(),
|
||||
event_count / gci_timer.elapsed_ms());
|
||||
(1000*event_count) / gci_timer.elapsed_ms());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -3961,13 +4049,25 @@ err:
|
|||
|
||||
if (ndb_apply_status_share)
|
||||
{
|
||||
/* ndb_share reference binlog extra free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s binlog extra free use_count: %u",
|
||||
ndb_apply_status_share->key,
|
||||
ndb_apply_status_share->use_count));
|
||||
free_share(&ndb_apply_status_share);
|
||||
ndb_apply_status_share= 0;
|
||||
}
|
||||
if (ndb_schema_share)
|
||||
{
|
||||
/* begin protect ndb_schema_share */
|
||||
pthread_mutex_lock(&ndb_schema_share_mutex);
|
||||
/* ndb_share reference binlog extra free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s binlog extra free use_count: %u",
|
||||
ndb_schema_share->key,
|
||||
ndb_schema_share->use_count));
|
||||
free_share(&ndb_schema_share);
|
||||
ndb_schema_share= 0;
|
||||
pthread_mutex_unlock(&ndb_schema_share_mutex);
|
||||
/* end protect ndb_schema_share */
|
||||
}
|
||||
|
||||
/* remove all event operations */
|
||||
|
@ -3985,6 +4085,9 @@ err:
|
|||
DBUG_ASSERT(share->op == op ||
|
||||
share->op_old == op);
|
||||
share->op= share->op_old= 0;
|
||||
/* ndb_share reference binlog free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s binlog free use_count: %u",
|
||||
share->key, share->use_count));
|
||||
free_share(&share);
|
||||
s_ndb->dropEventOperation(op);
|
||||
}
|
||||
|
@ -4005,6 +4108,9 @@ err:
|
|||
DBUG_ASSERT(share->op == op ||
|
||||
share->op_old == op);
|
||||
share->op= share->op_old= 0;
|
||||
/* ndb_share reference binlog free */
|
||||
DBUG_PRINT("NDB_SHARE", ("%s binlog free use_count: %u",
|
||||
share->key, share->use_count));
|
||||
free_share(&share);
|
||||
i_ndb->dropEventOperation(op);
|
||||
}
|
||||
|
|
|
@ -208,11 +208,6 @@ inline void free_share(NDB_SHARE **share, bool have_lock= FALSE)
|
|||
ndbcluster_free_share(share, have_lock);
|
||||
}
|
||||
|
||||
inline void real_free_share(NDB_SHARE **share)
|
||||
{
|
||||
ndbcluster_real_free_share(share);
|
||||
}
|
||||
|
||||
inline
|
||||
Thd_ndb *
|
||||
get_thd_ndb(THD *thd) { return (Thd_ndb *) thd->ha_data[ndbcluster_hton->slot]; }
|
||||
|
|
|
@ -5702,9 +5702,26 @@ int Rows_log_event::exec_event(st_relay_log_info *rli)
|
|||
{
|
||||
if (!need_reopen)
|
||||
{
|
||||
slave_print_msg(ERROR_LEVEL, rli, error,
|
||||
"Error in %s event: when locking tables",
|
||||
get_type_str());
|
||||
if (thd->query_error || thd->is_fatal_error)
|
||||
{
|
||||
/*
|
||||
Error reporting borrowed from Query_log_event with many excessive
|
||||
simplifications (we don't honour --slave-skip-errors)
|
||||
*/
|
||||
uint actual_error= thd->net.last_errno;
|
||||
slave_print_msg(ERROR_LEVEL, rli, actual_error,
|
||||
"Error '%s' in %s event: when locking tables",
|
||||
(actual_error ? thd->net.last_error :
|
||||
"unexpected success or fatal error"),
|
||||
get_type_str());
|
||||
thd->is_fatal_error= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
slave_print_msg(ERROR_LEVEL, rli, error,
|
||||
"Error in %s event: when locking tables",
|
||||
get_type_str());
|
||||
}
|
||||
rli->clear_tables_to_lock();
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
|
|
@ -199,6 +199,12 @@ inline void reset_floating_point_exceptions()
|
|||
|
||||
} /* cplusplus */
|
||||
|
||||
|
||||
#if defined(HAVE_LINUXTHREADS)
|
||||
#define THR_KILL_SIGNAL SIGINT
|
||||
#else
|
||||
#define THR_KILL_SIGNAL SIGUSR2 // Can't use this with LinuxThreads
|
||||
#endif
|
||||
#define MYSQL_KILL_SIGNAL SIGTERM
|
||||
|
||||
#ifdef HAVE_GLIBC2_STYLE_GETHOSTBYNAME_R
|
||||
|
@ -588,7 +594,6 @@ pthread_mutex_t LOCK_server_started;
|
|||
pthread_cond_t COND_server_started;
|
||||
|
||||
int mysqld_server_started= 0;
|
||||
static uint thr_kill_signal;
|
||||
|
||||
File_parser_dummy_hook file_parser_dummy_hook;
|
||||
|
||||
|
@ -770,7 +775,7 @@ static void close_connections(void)
|
|||
DBUG_PRINT("info",("Waiting for select thread"));
|
||||
|
||||
#ifndef DONT_USE_THR_ALARM
|
||||
if (pthread_kill(select_thread, thr_client_alarm))
|
||||
if (pthread_kill(select_thread,THR_CLIENT_ALARM))
|
||||
break; // allready dead
|
||||
#endif
|
||||
set_timespec(abstime, 2);
|
||||
|
@ -2207,9 +2212,7 @@ static void init_signals(void)
|
|||
DBUG_ENTER("init_signals");
|
||||
|
||||
if (test_flags & TEST_SIGINT)
|
||||
{
|
||||
my_sigset(thr_kill_signal, end_thread_signal);
|
||||
}
|
||||
my_sigset(THR_KILL_SIGNAL,end_thread_signal);
|
||||
my_sigset(THR_SERVER_ALARM,print_signal_warning); // Should never be called!
|
||||
|
||||
if (!(test_flags & TEST_NO_STACKTRACE) || (test_flags & TEST_CORE_ON_SIGNAL))
|
||||
|
@ -2266,12 +2269,8 @@ static void init_signals(void)
|
|||
#endif
|
||||
sigaddset(&set,THR_SERVER_ALARM);
|
||||
if (test_flags & TEST_SIGINT)
|
||||
{
|
||||
// May be SIGINT
|
||||
sigdelset(&set, thr_kill_signal);
|
||||
}
|
||||
// For alarms
|
||||
sigdelset(&set, thr_client_alarm);
|
||||
sigdelset(&set,THR_KILL_SIGNAL); // May be SIGINT
|
||||
sigdelset(&set,THR_CLIENT_ALARM); // For alarms
|
||||
sigprocmask(SIG_SETMASK,&set,NULL);
|
||||
pthread_sigmask(SIG_SETMASK,&set,NULL);
|
||||
DBUG_VOID_RETURN;
|
||||
|
@ -2334,19 +2333,23 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused)))
|
|||
*/
|
||||
init_thr_alarm(max_connections +
|
||||
global_system_variables.max_insert_delayed_threads + 10);
|
||||
if (thd_lib_detected != THD_LIB_LT && (test_flags & TEST_SIGINT))
|
||||
#if SIGINT != THR_KILL_SIGNAL
|
||||
if (test_flags & TEST_SIGINT)
|
||||
{
|
||||
(void) sigemptyset(&set); // Setup up SIGINT for debug
|
||||
(void) sigaddset(&set,SIGINT); // For debugging
|
||||
(void) pthread_sigmask(SIG_UNBLOCK,&set,NULL);
|
||||
}
|
||||
#endif
|
||||
(void) sigemptyset(&set); // Setup up SIGINT for debug
|
||||
#ifdef USE_ONE_SIGNAL_HAND
|
||||
(void) sigaddset(&set,THR_SERVER_ALARM); // For alarms
|
||||
#endif
|
||||
#ifndef IGNORE_SIGHUP_SIGQUIT
|
||||
(void) sigaddset(&set,SIGQUIT);
|
||||
#if THR_CLIENT_ALARM != SIGHUP
|
||||
(void) sigaddset(&set,SIGHUP);
|
||||
#endif
|
||||
#endif
|
||||
(void) sigaddset(&set,SIGTERM);
|
||||
(void) sigaddset(&set,SIGTSTP);
|
||||
|
@ -3509,13 +3512,6 @@ int main(int argc, char **argv)
|
|||
MY_INIT(argv[0]); // init my_sys library & pthreads
|
||||
/* nothing should come before this line ^^^ */
|
||||
|
||||
/* Set signal used to kill MySQL */
|
||||
#if defined(SIGUSR2)
|
||||
thr_kill_signal= thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2;
|
||||
#else
|
||||
thr_kill_signal= SIGINT;
|
||||
#endif
|
||||
|
||||
/*
|
||||
Perform basic logger initialization logger. Should be called after
|
||||
MY_INIT, as it initializes mutexes. Log tables are inited later.
|
||||
|
|
|
@ -58,6 +58,8 @@ public:
|
|||
String *storage_packet() { return packet; }
|
||||
inline void free() { packet->free(); }
|
||||
virtual bool write();
|
||||
inline bool store(int from)
|
||||
{ return store_long((longlong) from); }
|
||||
inline bool store(uint32 from)
|
||||
{ return store_long((longlong) from); }
|
||||
inline bool store(longlong from)
|
||||
|
|
|
@ -1296,7 +1296,7 @@ bool show_master_info(THD* thd, MASTER_INFO* mi)
|
|||
rpl_filter->get_wild_ignore_table(&tmp);
|
||||
protocol->store(&tmp);
|
||||
|
||||
protocol->store((uint32) mi->rli.last_slave_errno);
|
||||
protocol->store(mi->rli.last_slave_errno);
|
||||
protocol->store(mi->rli.last_slave_error, &my_charset_bin);
|
||||
protocol->store((uint32) mi->rli.slave_skip_counter);
|
||||
protocol->store((ulonglong) mi->rli.group_master_log_pos);
|
||||
|
|
|
@ -3520,7 +3520,11 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
|
|||
continue;
|
||||
}
|
||||
|
||||
*save_pos= *use;
|
||||
#ifdef HAVE_purify
|
||||
/* Valgrind complains about overlapped memcpy when save_pos==use. */
|
||||
if (save_pos != use)
|
||||
#endif
|
||||
*save_pos= *use;
|
||||
prev=use;
|
||||
found_eq_constant= !use->used_tables;
|
||||
/* Save ptr to first use */
|
||||
|
|
|
@ -146,6 +146,7 @@ typedef ndbd_exit_classification_enum ndbd_exit_classification;
|
|||
#define NDBD_EXIT_AFS_READ_UNDERFLOW 2816
|
||||
|
||||
#define NDBD_EXIT_INVALID_LCP_FILE 2352
|
||||
#define NDBD_EXIT_INSUFFICENT_NODES 2353
|
||||
|
||||
const char *
|
||||
ndbd_exit_message(int faultId, ndbd_exit_classification *cl);
|
||||
|
|
|
@ -181,8 +181,6 @@ private:
|
|||
const class NdbTableImpl* aTable,
|
||||
NdbTransaction*);
|
||||
|
||||
int prepareSend(Uint32 TC_ConnectPtr, Uint64 TransactionId);
|
||||
|
||||
// Private attributes
|
||||
const NdbIndexImpl* m_theIndex;
|
||||
friend struct Ndb_free_list_t<NdbIndexOperation>;
|
||||
|
|
|
@ -64,12 +64,14 @@ public:
|
|||
bool order_by,
|
||||
bool order_desc = false,
|
||||
bool read_range_no = false,
|
||||
bool keyinfo = false) {
|
||||
bool keyinfo = false,
|
||||
bool multi_range = false) {
|
||||
Uint32 scan_flags =
|
||||
(SF_OrderBy & -(Int32)order_by) |
|
||||
(SF_Descending & -(Int32)order_desc) |
|
||||
(SF_ReadRangeNo & -(Int32)read_range_no) |
|
||||
(SF_KeyInfo & -(Int32)keyinfo);
|
||||
(SF_KeyInfo & -(Int32)keyinfo) |
|
||||
(SF_MultiRange & -(Int32)multi_range);
|
||||
|
||||
return readTuples(lock_mode, scan_flags, parallel, batch);
|
||||
}
|
||||
|
|
|
@ -97,6 +97,19 @@ public:
|
|||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* How should transaction be handled if operation fails
|
||||
*
|
||||
* For READ, default is AO_IgnoreError
|
||||
* DML, default is AbortOnError
|
||||
* CommittedRead does _only_ support AO_IgnoreError
|
||||
*/
|
||||
enum AbortOption {
|
||||
DefaultAbortOption = -1,///< Use default as specified by op-type
|
||||
AbortOnError = 0, ///< Abort transaction on failed operation
|
||||
AO_IgnoreError = 2 ///< Transaction continues on failed operation
|
||||
};
|
||||
|
||||
/**
|
||||
* Define the NdbOperation to be a standard operation of type insertTuple.
|
||||
* When calling NdbTransaction::execute, this operation
|
||||
|
@ -776,8 +789,13 @@ public:
|
|||
*/
|
||||
LockMode getLockMode() const { return theLockMode; }
|
||||
|
||||
/**
|
||||
* Get/set abort option
|
||||
*/
|
||||
AbortOption getAbortOption() const;
|
||||
int setAbortOption(AbortOption);
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
||||
void setAbortOption(Int8 ao) { m_abortOption = ao; }
|
||||
|
||||
/**
|
||||
* Set/get partition key
|
||||
|
@ -856,7 +874,8 @@ protected:
|
|||
|
||||
int doSend(int ProcessorId, Uint32 lastFlag);
|
||||
virtual int prepareSend(Uint32 TC_ConnectPtr,
|
||||
Uint64 TransactionId);
|
||||
Uint64 TransactionId,
|
||||
AbortOption);
|
||||
virtual void setLastFlag(NdbApiSignal* signal, Uint32 lastFlag);
|
||||
|
||||
int prepareSendInterpreted(); // Help routine to prepare*
|
||||
|
|
|
@ -38,7 +38,8 @@ class NdbScanOperation : public NdbOperation {
|
|||
public:
|
||||
/**
|
||||
* Scan flags. OR-ed together and passed as second argument to
|
||||
* readTuples.
|
||||
* readTuples. Note that SF_MultiRange has to be set if several
|
||||
* ranges (bounds) are to be passed.
|
||||
*/
|
||||
enum ScanFlag {
|
||||
SF_TupScan = (1 << 16), // scan TUP order
|
||||
|
@ -46,6 +47,7 @@ public:
|
|||
SF_OrderBy = (1 << 24), // index scan in order
|
||||
SF_Descending = (2 << 24), // index scan in descending order
|
||||
SF_ReadRangeNo = (4 << 24), // enable @ref get_range_no
|
||||
SF_MultiRange = (8 << 24), // scan is part of multi-range scan
|
||||
SF_KeyInfo = 1 // request KeyInfo to be sent back
|
||||
};
|
||||
|
||||
|
@ -72,7 +74,8 @@ public:
|
|||
*/
|
||||
#ifdef ndb_readtuples_impossible_overload
|
||||
int readTuples(LockMode lock_mode = LM_Read,
|
||||
Uint32 batch = 0, Uint32 parallel = 0, bool keyinfo = false);
|
||||
Uint32 batch = 0, Uint32 parallel = 0,
|
||||
bool keyinfo = false, bool multi_range = false);
|
||||
#endif
|
||||
|
||||
inline int readTuples(int parallell){
|
||||
|
@ -264,6 +267,7 @@ protected:
|
|||
bool m_descending;
|
||||
Uint32 m_read_range_no;
|
||||
NdbRecAttr *m_curr_row; // Pointer to last returned row
|
||||
bool m_multi_range; // Mark if operation is part of multi-range scan
|
||||
bool m_executed; // Marker if operation should be released at close
|
||||
};
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "NdbError.hpp"
|
||||
#include "NdbDictionary.hpp"
|
||||
#include "Ndb.hpp"
|
||||
#include "NdbOperation.hpp"
|
||||
|
||||
class NdbTransaction;
|
||||
class NdbOperation;
|
||||
|
@ -44,11 +45,12 @@ typedef void (* NdbAsynchCallback)(int, NdbTransaction*, void*);
|
|||
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
||||
enum AbortOption {
|
||||
CommitIfFailFree= 0,
|
||||
TryCommit= 0,
|
||||
AbortOnError= 0,
|
||||
CommitAsMuchAsPossible= 2,
|
||||
AO_IgnoreError= 2
|
||||
DefaultAbortOption = NdbOperation::DefaultAbortOption,
|
||||
CommitIfFailFree = NdbOperation::AbortOnError,
|
||||
TryCommit = NdbOperation::AbortOnError,
|
||||
AbortOnError= NdbOperation::AbortOnError,
|
||||
CommitAsMuchAsPossible = NdbOperation::AO_IgnoreError,
|
||||
AO_IgnoreError= NdbOperation::AO_IgnoreError
|
||||
};
|
||||
enum ExecType {
|
||||
NoExecTypeDef = -1,
|
||||
|
@ -144,20 +146,6 @@ class NdbTransaction
|
|||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Commit type of transaction
|
||||
*/
|
||||
enum AbortOption {
|
||||
AbortOnError= ///< Abort transaction on failed operation
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
||||
::AbortOnError
|
||||
#endif
|
||||
,AO_IgnoreError= ///< Transaction continues on failed operation
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
||||
::AO_IgnoreError
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* Execution type of transaction
|
||||
*/
|
||||
|
@ -316,13 +304,15 @@ public:
|
|||
* @return 0 if successful otherwise -1.
|
||||
*/
|
||||
int execute(ExecType execType,
|
||||
AbortOption abortOption = AbortOnError,
|
||||
NdbOperation::AbortOption = NdbOperation::DefaultAbortOption,
|
||||
int force = 0 );
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
|
||||
int execute(::ExecType execType,
|
||||
::AbortOption abortOption = ::AbortOnError,
|
||||
int force = 0 )
|
||||
{ return execute ((ExecType)execType,(AbortOption)abortOption,force); }
|
||||
::AbortOption abortOption = ::DefaultAbortOption,
|
||||
int force = 0 ) {
|
||||
return execute ((ExecType)execType,
|
||||
(NdbOperation::AbortOption)abortOption,
|
||||
force); }
|
||||
#endif
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
||||
|
@ -353,14 +343,14 @@ public:
|
|||
void executeAsynchPrepare(ExecType execType,
|
||||
NdbAsynchCallback callback,
|
||||
void* anyObject,
|
||||
AbortOption abortOption = AbortOnError);
|
||||
NdbOperation::AbortOption = NdbOperation::DefaultAbortOption);
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
|
||||
void executeAsynchPrepare(::ExecType execType,
|
||||
NdbAsynchCallback callback,
|
||||
void* anyObject,
|
||||
::AbortOption abortOption = ::AbortOnError)
|
||||
{ executeAsynchPrepare((ExecType)execType, callback, anyObject,
|
||||
(AbortOption)abortOption); }
|
||||
::AbortOption ao = ::DefaultAbortOption) {
|
||||
executeAsynchPrepare((ExecType)execType, callback, anyObject,
|
||||
(NdbOperation::AbortOption)ao); }
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -379,14 +369,14 @@ public:
|
|||
void executeAsynch(ExecType aTypeOfExec,
|
||||
NdbAsynchCallback aCallback,
|
||||
void* anyObject,
|
||||
AbortOption abortOption = AbortOnError);
|
||||
NdbOperation::AbortOption = NdbOperation::DefaultAbortOption);
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
|
||||
void executeAsynch(::ExecType aTypeOfExec,
|
||||
NdbAsynchCallback aCallback,
|
||||
void* anyObject,
|
||||
::AbortOption abortOption= ::AbortOnError)
|
||||
::AbortOption abortOption= ::DefaultAbortOption)
|
||||
{ executeAsynch((ExecType)aTypeOfExec, aCallback, anyObject,
|
||||
(AbortOption)abortOption); }
|
||||
(NdbOperation::AbortOption)abortOption); }
|
||||
#endif
|
||||
#endif
|
||||
/**
|
||||
|
@ -588,7 +578,7 @@ private:
|
|||
void init(); // Initialize connection object for new transaction
|
||||
|
||||
int executeNoBlobs(ExecType execType,
|
||||
AbortOption abortOption = AbortOnError,
|
||||
NdbOperation::AbortOption = NdbOperation::DefaultAbortOption,
|
||||
int force = 0 );
|
||||
|
||||
/**
|
||||
|
@ -642,7 +632,7 @@ private:
|
|||
int sendCOMMIT(); // Send a TC_COMMITREQ signal;
|
||||
void setGCI(int GCI); // Set the global checkpoint identity
|
||||
|
||||
int OpCompleteFailure(Uint8 abortoption, bool setFailure = true);
|
||||
int OpCompleteFailure(NdbOperation*);
|
||||
int OpCompleteSuccess();
|
||||
void CompletedOperations(); // Move active ops to list of completed
|
||||
|
||||
|
@ -732,7 +722,6 @@ private:
|
|||
|
||||
Uint32 theNoOfOpSent; // How many operations have been sent
|
||||
Uint32 theNoOfOpCompleted; // How many operations have completed
|
||||
Uint32 theNoOfOpFetched; // How many operations was actually fetched
|
||||
Uint32 theMyRef; // Our block reference
|
||||
Uint32 theTCConPtr; // Transaction Co-ordinator connection pointer.
|
||||
Uint64 theTransactionId; // theTransactionId of the transaction
|
||||
|
@ -756,7 +745,6 @@ private:
|
|||
bool theTransactionIsStarted;
|
||||
bool theInUseState;
|
||||
bool theSimpleState;
|
||||
Uint8 m_abortOption; // Type of commi
|
||||
|
||||
enum ListState {
|
||||
NotInList,
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <ndb_global.h>
|
||||
|
||||
#include <EventLogger.hpp>
|
||||
#include <TransporterCallback.hpp>
|
||||
|
||||
#include <NdbConfig.h>
|
||||
#include <kernel/BlockNumbers.h>
|
||||
|
@ -526,11 +527,100 @@ void getTextUndoLogBlocked(QQQQ) {
|
|||
theData[1],
|
||||
theData[2]);
|
||||
}
|
||||
|
||||
void getTextTransporterError(QQQQ) {
|
||||
BaseString::snprintf(m_text, m_text_len,
|
||||
"Transporter to node %d reported error 0x%x",
|
||||
theData[1],
|
||||
theData[2]);
|
||||
struct myTransporterError{
|
||||
int errorNum;
|
||||
char errorString[256];
|
||||
};
|
||||
int i = 0;
|
||||
int lenth = 0;
|
||||
static const struct myTransporterError TransporterErrorString[]=
|
||||
{
|
||||
//TE_NO_ERROR = 0
|
||||
{TE_NO_ERROR,"No error"},
|
||||
//TE_ERROR_CLOSING_SOCKET = 0x1
|
||||
{TE_ERROR_CLOSING_SOCKET,"Error found during closing of socket"},
|
||||
//TE_ERROR_IN_SELECT_BEFORE_ACCEPT = 0x2
|
||||
{TE_ERROR_IN_SELECT_BEFORE_ACCEPT,"Error found before accept. The transporter will retry"},
|
||||
//TE_INVALID_MESSAGE_LENGTH = 0x3 | TE_DO_DISCONNECT
|
||||
{TE_INVALID_MESSAGE_LENGTH,"Error found in message (invalid message length)"},
|
||||
//TE_INVALID_CHECKSUM = 0x4 | TE_DO_DISCONNECT
|
||||
{TE_INVALID_CHECKSUM,"Error found in message (checksum)"},
|
||||
//TE_COULD_NOT_CREATE_SOCKET = 0x5
|
||||
{TE_COULD_NOT_CREATE_SOCKET,"Error found while creating socket(can't create socket)"},
|
||||
//TE_COULD_NOT_BIND_SOCKET = 0x6
|
||||
{TE_COULD_NOT_BIND_SOCKET,"Error found while binding server socket"},
|
||||
//TE_LISTEN_FAILED = 0x7
|
||||
{TE_LISTEN_FAILED,"Error found while listening to server socket"},
|
||||
//TE_ACCEPT_RETURN_ERROR = 0x8
|
||||
{TE_ACCEPT_RETURN_ERROR,"Error found during accept(accept return error)"},
|
||||
//TE_SHM_DISCONNECT = 0xb | TE_DO_DISCONNECT
|
||||
{TE_SHM_DISCONNECT,"The remote node has disconnected"},
|
||||
//TE_SHM_IPC_STAT = 0xc | TE_DO_DISCONNECT
|
||||
{TE_SHM_IPC_STAT,"Unable to check shm segment"},
|
||||
//TE_SHM_UNABLE_TO_CREATE_SEGMENT = 0xd
|
||||
{TE_SHM_UNABLE_TO_CREATE_SEGMENT,"Unable to create shm segment"},
|
||||
//TE_SHM_UNABLE_TO_ATTACH_SEGMENT = 0xe
|
||||
{TE_SHM_UNABLE_TO_ATTACH_SEGMENT,"Unable to attach shm segment"},
|
||||
//TE_SHM_UNABLE_TO_REMOVE_SEGMENT = 0xf
|
||||
{TE_SHM_UNABLE_TO_REMOVE_SEGMENT,"Unable to remove shm segment"},
|
||||
//TE_TOO_SMALL_SIGID = 0x10
|
||||
{TE_TOO_SMALL_SIGID,"Sig ID too small"},
|
||||
//TE_TOO_LARGE_SIGID = 0x11
|
||||
{TE_TOO_LARGE_SIGID,"Sig ID too large"},
|
||||
//TE_WAIT_STACK_FULL = 0x12 | TE_DO_DISCONNECT
|
||||
{TE_WAIT_STACK_FULL,"Wait stack was full"},
|
||||
//TE_RECEIVE_BUFFER_FULL = 0x13 | TE_DO_DISCONNECT
|
||||
{TE_RECEIVE_BUFFER_FULL,"Receive buffer was full"},
|
||||
//TE_SIGNAL_LOST_SEND_BUFFER_FULL = 0x14 | TE_DO_DISCONNECT
|
||||
{TE_SIGNAL_LOST_SEND_BUFFER_FULL,"Send buffer was full,and trying to force send fails"},
|
||||
//TE_SIGNAL_LOST = 0x15
|
||||
{TE_SIGNAL_LOST,"Send failed for unknown reason(signal lost)"},
|
||||
//TE_SEND_BUFFER_FULL = 0x16
|
||||
{TE_SEND_BUFFER_FULL,"The send buffer was full, but sleeping for a while solved"},
|
||||
//TE_SCI_LINK_ERROR = 0x0017
|
||||
{TE_SCI_LINK_ERROR,"There is no link from this node to the switch"},
|
||||
//TE_SCI_UNABLE_TO_START_SEQUENCE = 0x18 | TE_DO_DISCONNECT
|
||||
{TE_SCI_UNABLE_TO_START_SEQUENCE,"Could not start a sequence, because system resources are exumed or no sequence has been created"},
|
||||
//TE_SCI_UNABLE_TO_REMOVE_SEQUENCE = 0x19 | TE_DO_DISCONNECT
|
||||
{TE_SCI_UNABLE_TO_REMOVE_SEQUENCE,"Could not remove a sequence"},
|
||||
//TE_SCI_UNABLE_TO_CREATE_SEQUENCE = 0x1a | TE_DO_DISCONNECT
|
||||
{TE_SCI_UNABLE_TO_CREATE_SEQUENCE,"Could not create a sequence, because system resources are exempted. Must reboot"},
|
||||
//TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR = 0x1b | TE_DO_DISCONNECT
|
||||
{TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR,"Tried to send data on redundant link but failed"},
|
||||
//TE_SCI_CANNOT_INIT_LOCALSEGMENT = 0x1c | TE_DO_DISCONNECT
|
||||
{TE_SCI_CANNOT_INIT_LOCALSEGMENT,"Cannot initialize local segment"},
|
||||
//TE_SCI_CANNOT_MAP_REMOTESEGMENT = 0x1d | TE_DO_DISCONNEC
|
||||
{TE_SCI_CANNOT_MAP_REMOTESEGMENT,"Cannot map remote segment"},
|
||||
//TE_SCI_UNABLE_TO_UNMAP_SEGMENT = 0x1e | TE_DO_DISCONNECT
|
||||
{TE_SCI_UNABLE_TO_UNMAP_SEGMENT,"Cannot free the resources used by this segment (step 1)"},
|
||||
//TE_SCI_UNABLE_TO_REMOVE_SEGMENT = 0x1f | TE_DO_DISCONNEC
|
||||
{TE_SCI_UNABLE_TO_REMOVE_SEGMENT,"Cannot free the resources used by this segment (step 2)"},
|
||||
//TE_SCI_UNABLE_TO_DISCONNECT_SEGMENT = 0x20 | TE_DO_DISCONNECT
|
||||
{TE_SCI_UNABLE_TO_DISCONNECT_SEGMENT,"Cannot disconnect from a remote segment"},
|
||||
//TE_SHM_IPC_PERMANENT = 0x21
|
||||
{TE_SHM_IPC_PERMANENT,"Shm ipc Permanent error"},
|
||||
//TE_SCI_UNABLE_TO_CLOSE_CHANNEL = 0x22
|
||||
{TE_SCI_UNABLE_TO_CLOSE_CHANNEL,"Unable to close the sci channel and the resources allocated"}
|
||||
};
|
||||
|
||||
lenth = sizeof(TransporterErrorString)/sizeof(struct myTransporterError);
|
||||
for(i=0; i<lenth; i++)
|
||||
{
|
||||
if(theData[2] == TransporterErrorString[i].errorNum)
|
||||
{
|
||||
BaseString::snprintf(m_text, m_text_len,
|
||||
"Transporter to node %d reported error: %s",
|
||||
theData[1],
|
||||
TransporterErrorString[i].errorString);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i == lenth)
|
||||
BaseString::snprintf(m_text, m_text_len,
|
||||
"Transporter to node %d reported error: no such error",
|
||||
theData[1]);
|
||||
}
|
||||
void getTextTransporterWarning(QQQQ) {
|
||||
getTextTransporterError(m_text, m_text_len, theData);
|
||||
|
|
|
@ -2405,6 +2405,18 @@ Backup::defineBackupRef(Signal* signal, BackupRecordPtr ptr, Uint32 errCode)
|
|||
if(ptr.p->is_lcp())
|
||||
{
|
||||
jam();
|
||||
if (ptr.p->ctlFilePtr == RNIL) {
|
||||
ptr.p->m_gsn = GSN_DEFINE_BACKUP_REF;
|
||||
ndbrequire(ptr.p->errorCode != 0);
|
||||
DefineBackupRef* ref = (DefineBackupRef*)signal->getDataPtrSend();
|
||||
ref->backupId = ptr.p->backupId;
|
||||
ref->backupPtr = ptr.i;
|
||||
ref->errorCode = ptr.p->errorCode;
|
||||
ref->nodeId = getOwnNodeId();
|
||||
sendSignal(ptr.p->masterRef, GSN_DEFINE_BACKUP_REF, signal,
|
||||
DefineBackupRef::SignalLength, JBB);
|
||||
return;
|
||||
}
|
||||
|
||||
BackupFilePtr filePtr LINT_SET_PTR;
|
||||
ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr);
|
||||
|
|
|
@ -1194,11 +1194,58 @@ void Dbdih::execTAB_COMMITREQ(Signal* signal)
|
|||
void Dbdih::execDIH_RESTARTREQ(Signal* signal)
|
||||
{
|
||||
jamEntry();
|
||||
cntrlblockref = signal->theData[0];
|
||||
if(m_ctx.m_config.getInitialStart()){
|
||||
sendSignal(cntrlblockref, GSN_DIH_RESTARTREF, signal, 1, JBB);
|
||||
} else {
|
||||
readGciFileLab(signal);
|
||||
if (signal->theData[0])
|
||||
{
|
||||
jam();
|
||||
cntrlblockref = signal->theData[0];
|
||||
if(m_ctx.m_config.getInitialStart()){
|
||||
sendSignal(cntrlblockref, GSN_DIH_RESTARTREF, signal, 1, JBB);
|
||||
} else {
|
||||
readGciFileLab(signal);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
* Precondition, (not checked)
|
||||
* atleast 1 node in each node group
|
||||
*/
|
||||
Uint32 i;
|
||||
NdbNodeBitmask mask;
|
||||
mask.assign(NdbNodeBitmask::Size, signal->theData + 1);
|
||||
Uint32 *node_gcis = signal->theData+1+NdbNodeBitmask::Size;
|
||||
Uint32 node_group_gcis[MAX_NDB_NODES+1];
|
||||
bzero(node_group_gcis, sizeof(node_group_gcis));
|
||||
for (i = 0; i<MAX_NDB_NODES; i++)
|
||||
{
|
||||
if (mask.get(i))
|
||||
{
|
||||
jam();
|
||||
Uint32 ng = Sysfile::getNodeGroup(i, SYSFILE->nodeGroups);
|
||||
ndbrequire(ng < MAX_NDB_NODES);
|
||||
Uint32 gci = node_gcis[i];
|
||||
if (gci > node_group_gcis[ng])
|
||||
{
|
||||
jam();
|
||||
node_group_gcis[ng] = gci;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i<MAX_NDB_NODES && node_group_gcis[i] == 0; i++);
|
||||
|
||||
Uint32 gci = node_group_gcis[i];
|
||||
for (i++ ; i<MAX_NDB_NODES; i++)
|
||||
{
|
||||
jam();
|
||||
if (node_group_gcis[i] && node_group_gcis[i] != gci)
|
||||
{
|
||||
jam();
|
||||
signal->theData[0] = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
signal->theData[0] = MAX_NDB_NODES;
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}//Dbdih::execDIH_RESTARTREQ()
|
||||
|
@ -1525,10 +1572,26 @@ void Dbdih::ndbStartReqLab(Signal* signal, BlockReference ref)
|
|||
*/
|
||||
SYSFILE->lastCompletedGCI[nodePtr.i] = 0;
|
||||
ndbrequire(nodePtr.p->nodeStatus != NodeRecord::ALIVE);
|
||||
warningEvent("Making filesystem for node %d unusable",
|
||||
warningEvent("Making filesystem for node %d unusable (need --initial)",
|
||||
nodePtr.i);
|
||||
}
|
||||
else if (nodePtr.p->nodeStatus == NodeRecord::ALIVE &&
|
||||
SYSFILE->lastCompletedGCI[nodePtr.i] == 0)
|
||||
{
|
||||
jam();
|
||||
CRASH_INSERTION(7170);
|
||||
char buf[255];
|
||||
BaseString::snprintf(buf, sizeof(buf),
|
||||
"Cluster requires this node to be started "
|
||||
" with --initial as partial start has been performed"
|
||||
" and this filesystem is unusable");
|
||||
progError(__LINE__,
|
||||
NDBD_EXIT_SR_RESTARTCONFLICT,
|
||||
buf);
|
||||
ndbrequire(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This set which GCI we will try to restart to
|
||||
*/
|
||||
|
@ -12375,7 +12438,7 @@ void Dbdih::makeNodeGroups(Uint32 nodeArray[])
|
|||
(buf, sizeof(buf),
|
||||
"Illegal initial start, no alive node in nodegroup %u", i);
|
||||
progError(__LINE__,
|
||||
NDBD_EXIT_SR_RESTARTCONFLICT,
|
||||
NDBD_EXIT_INSUFFICENT_NODES,
|
||||
buf);
|
||||
|
||||
}
|
||||
|
@ -12515,14 +12578,23 @@ void Dbdih::newCrashedReplica(Uint32 nodeId, ReplicaRecordPtr ncrReplicaPtr)
|
|||
/* THAT THE NEW REPLICA IS NOT STARTED YET AND REPLICA_LAST_GCI IS*/
|
||||
/* SET TO -1 TO INDICATE THAT IT IS NOT DEAD YET. */
|
||||
/*----------------------------------------------------------------------*/
|
||||
Uint32 lastGCI = SYSFILE->lastCompletedGCI[nodeId];
|
||||
arrGuardErr(ncrReplicaPtr.p->noCrashedReplicas + 1, 8,
|
||||
NDBD_EXIT_MAX_CRASHED_REPLICAS);
|
||||
ncrReplicaPtr.p->replicaLastGci[ncrReplicaPtr.p->noCrashedReplicas] =
|
||||
SYSFILE->lastCompletedGCI[nodeId];
|
||||
lastGCI;
|
||||
ncrReplicaPtr.p->noCrashedReplicas = ncrReplicaPtr.p->noCrashedReplicas + 1;
|
||||
ncrReplicaPtr.p->createGci[ncrReplicaPtr.p->noCrashedReplicas] = 0;
|
||||
ncrReplicaPtr.p->replicaLastGci[ncrReplicaPtr.p->noCrashedReplicas] =
|
||||
(Uint32)-1;
|
||||
|
||||
if (ncrReplicaPtr.p->noCrashedReplicas == 7 && lastGCI)
|
||||
{
|
||||
jam();
|
||||
SYSFILE->lastCompletedGCI[nodeId] = 0;
|
||||
warningEvent("Making filesystem for node %d unusable (need --initial)",
|
||||
nodeId);
|
||||
}
|
||||
}//Dbdih::newCrashedReplica()
|
||||
|
||||
/*************************************************************************/
|
||||
|
|
|
@ -582,6 +582,26 @@ Dblqh::execDEFINE_BACKUP_REF(Signal* signal)
|
|||
{
|
||||
jamEntry();
|
||||
m_backup_ptr = RNIL;
|
||||
DefineBackupRef* ref = (DefineBackupRef*)signal->getDataPtrSend();
|
||||
int err_code = 0;
|
||||
char * extra_msg = NULL;
|
||||
|
||||
switch(ref->errorCode){
|
||||
case DefineBackupRef::Undefined:
|
||||
case DefineBackupRef::FailedToSetupFsBuffers:
|
||||
case DefineBackupRef::FailedToAllocateBuffers:
|
||||
case DefineBackupRef::FailedToAllocateTables:
|
||||
case DefineBackupRef::FailedAllocateTableMem:
|
||||
case DefineBackupRef::FailedToAllocateFileRecord:
|
||||
case DefineBackupRef::FailedToAllocateAttributeRecord:
|
||||
case DefineBackupRef::FailedInsertFileHeader:
|
||||
case DefineBackupRef::FailedInsertTableList:
|
||||
jam();
|
||||
err_code = NDBD_EXIT_INVALID_CONFIG;
|
||||
extra_msg = "Probably Backup parameters configuration error, Please consult the manual";
|
||||
progError(__LINE__, err_code, extra_msg);
|
||||
}
|
||||
|
||||
sendsttorryLab(signal);
|
||||
}
|
||||
|
||||
|
@ -2479,8 +2499,16 @@ Dblqh::execREMOVE_MARKER_ORD(Signal* signal)
|
|||
|
||||
CommitAckMarkerPtr removedPtr;
|
||||
m_commitAckMarkerHash.remove(removedPtr, key);
|
||||
#if defined VM_TRACE || defined ERROR_INSERT
|
||||
ndbrequire(removedPtr.i != RNIL);
|
||||
m_commitAckMarkerPool.release(removedPtr);
|
||||
#else
|
||||
if (removedPtr.i != RNIL)
|
||||
{
|
||||
jam();
|
||||
m_commitAckMarkerPool.release(removedPtr);
|
||||
}
|
||||
#endif
|
||||
#ifdef MARKER_TRACE
|
||||
ndbout_c("Rem marker[%.8x %.8x]", key.transid1, key.transid2);
|
||||
#endif
|
||||
|
@ -3138,20 +3166,23 @@ void Dblqh::lqhAttrinfoLab(Signal* signal, Uint32* dataPtr, Uint32 length)
|
|||
{
|
||||
TcConnectionrec * const regTcPtr = tcConnectptr.p;
|
||||
if (regTcPtr->operation != ZREAD) {
|
||||
if (regTcPtr->opExec != 1) {
|
||||
if (saveTupattrbuf(signal, dataPtr, length) == ZOK) {
|
||||
;
|
||||
} else {
|
||||
jam();
|
||||
if (regTcPtr->operation != ZDELETE)
|
||||
{
|
||||
if (regTcPtr->opExec != 1) {
|
||||
if (saveTupattrbuf(signal, dataPtr, length) == ZOK) {
|
||||
;
|
||||
} else {
|
||||
jam();
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* WE MIGHT BE WAITING FOR RESPONSE FROM SOME BLOCK HERE. THUS WE NEED TO */
|
||||
/* GO THROUGH THE STATE MACHINE FOR THE OPERATION. */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
localAbortStateHandlerLab(signal);
|
||||
return;
|
||||
localAbortStateHandlerLab(signal);
|
||||
return;
|
||||
}//if
|
||||
}//if
|
||||
}//if
|
||||
}//if
|
||||
}
|
||||
c_tup->receive_attrinfo(signal, regTcPtr->tupConnectrec, dataPtr, length);
|
||||
}//Dblqh::lqhAttrinfoLab()
|
||||
|
||||
|
@ -3405,7 +3436,7 @@ void Dblqh::execLQHKEYREQ(Signal* signal)
|
|||
markerPtr.p->tcNodeId = tcNodeId;
|
||||
|
||||
CommitAckMarkerPtr tmp;
|
||||
#ifdef VM_TRACE
|
||||
#if defined VM_TRACE || defined ERROR_INSERT
|
||||
#ifdef MARKER_TRACE
|
||||
ndbout_c("Add marker[%.8x %.8x]", markerPtr.p->transid1, markerPtr.p->transid2);
|
||||
#endif
|
||||
|
@ -7197,7 +7228,8 @@ void Dblqh::execACC_ABORTCONF(Signal* signal)
|
|||
TRACE_OP(regTcPtr, "ACC_ABORTCONF");
|
||||
signal->theData[0] = regTcPtr->tupConnectrec;
|
||||
EXECUTE_DIRECT(DBTUP, GSN_TUP_ABORTREQ, signal, 1);
|
||||
|
||||
|
||||
jamEntry();
|
||||
continueAbortLab(signal);
|
||||
return;
|
||||
}//Dblqh::execACC_ABORTCONF()
|
||||
|
@ -9628,7 +9660,7 @@ Uint32 Dblqh::initScanrec(const ScanFragReq* scanFragReq)
|
|||
active.add(scanptr);
|
||||
if(scanptr.p->scanKeyinfoFlag){
|
||||
jam();
|
||||
#ifdef VM_TRACE
|
||||
#if defined VM_TRACE || defined ERROR_INSERT
|
||||
ScanRecordPtr tmp;
|
||||
ndbrequire(!c_scanTakeOverHash.find(tmp, * scanptr.p));
|
||||
#endif
|
||||
|
@ -9752,7 +9784,7 @@ void Dblqh::finishScanrec(Signal* signal)
|
|||
scans.add(restart);
|
||||
if(restart.p->scanKeyinfoFlag){
|
||||
jam();
|
||||
#ifdef VM_TRACE
|
||||
#if defined VM_TRACE || defined ERROR_INSERT
|
||||
ScanRecordPtr tmp;
|
||||
ndbrequire(!c_scanTakeOverHash.find(tmp, * restart.p));
|
||||
#endif
|
||||
|
|
|
@ -2522,7 +2522,7 @@ void Dbtc::execTCKEYREQ(Signal* signal)
|
|||
ApiConnectRecord * const regApiPtr = &localApiConnectRecord[TapiIndex];
|
||||
apiConnectptr.p = regApiPtr;
|
||||
|
||||
Uint32 TstartFlag = tcKeyReq->getStartFlag(Treqinfo);
|
||||
Uint32 TstartFlag = TcKeyReq::getStartFlag(Treqinfo);
|
||||
Uint32 TexecFlag = TcKeyReq::getExecuteFlag(Treqinfo);
|
||||
|
||||
Uint8 isIndexOp = regApiPtr->isIndexOp;
|
||||
|
@ -2692,14 +2692,14 @@ void Dbtc::execTCKEYREQ(Signal* signal)
|
|||
/* */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
UintR TapiVersionNo = tcKeyReq->getAPIVersion(tcKeyReq->attrLen);
|
||||
UintR TapiVersionNo = TcKeyReq::getAPIVersion(tcKeyReq->attrLen);
|
||||
UintR Tlqhkeyreqrec = regApiPtr->lqhkeyreqrec;
|
||||
regApiPtr->lqhkeyreqrec = Tlqhkeyreqrec + 1;
|
||||
regCachePtr->apiVersionNo = TapiVersionNo;
|
||||
|
||||
UintR TapiConnectptrIndex = apiConnectptr.i;
|
||||
UintR TsenderData = tcKeyReq->senderData;
|
||||
UintR TattrLen = tcKeyReq->getAttrinfoLen(tcKeyReq->attrLen);
|
||||
UintR TattrLen = TcKeyReq::getAttrinfoLen(tcKeyReq->attrLen);
|
||||
UintR TattrinfoCount = c_counters.cattrinfoCount;
|
||||
|
||||
regTcPtr->apiConnect = TapiConnectptrIndex;
|
||||
|
@ -2725,15 +2725,15 @@ void Dbtc::execTCKEYREQ(Signal* signal)
|
|||
|
||||
UintR TtabptrIndex = localTabptr.i;
|
||||
UintR TtableSchemaVersion = tcKeyReq->tableSchemaVersion;
|
||||
Uint8 TOperationType = tcKeyReq->getOperationType(Treqinfo);
|
||||
Uint8 TOperationType = TcKeyReq::getOperationType(Treqinfo);
|
||||
regCachePtr->tableref = TtabptrIndex;
|
||||
regCachePtr->schemaVersion = TtableSchemaVersion;
|
||||
regTcPtr->operation = TOperationType;
|
||||
|
||||
Uint8 TSimpleFlag = tcKeyReq->getSimpleFlag(Treqinfo);
|
||||
Uint8 TDirtyFlag = tcKeyReq->getDirtyFlag(Treqinfo);
|
||||
Uint8 TInterpretedFlag = tcKeyReq->getInterpretedFlag(Treqinfo);
|
||||
Uint8 TDistrKeyFlag = tcKeyReq->getDistributionKeyFlag(Treqinfo);
|
||||
Uint8 TSimpleFlag = TcKeyReq::getSimpleFlag(Treqinfo);
|
||||
Uint8 TDirtyFlag = TcKeyReq::getDirtyFlag(Treqinfo);
|
||||
Uint8 TInterpretedFlag = TcKeyReq::getInterpretedFlag(Treqinfo);
|
||||
Uint8 TDistrKeyFlag = TcKeyReq::getDistributionKeyFlag(Treqinfo);
|
||||
Uint8 TNoDiskFlag = TcKeyReq::getNoDiskFlag(Treqinfo);
|
||||
Uint8 TexecuteFlag = TexecFlag;
|
||||
|
||||
|
@ -2749,10 +2749,10 @@ void Dbtc::execTCKEYREQ(Signal* signal)
|
|||
Uint32 TkeyIndex;
|
||||
Uint32* TOptionalDataPtr = (Uint32*)&tcKeyReq->scanInfo;
|
||||
{
|
||||
Uint32 TDistrGHIndex = tcKeyReq->getScanIndFlag(Treqinfo);
|
||||
Uint32 TDistrGHIndex = TcKeyReq::getScanIndFlag(Treqinfo);
|
||||
Uint32 TDistrKeyIndex = TDistrGHIndex;
|
||||
|
||||
Uint32 TscanInfo = tcKeyReq->getTakeOverScanInfo(TOptionalDataPtr[0]);
|
||||
Uint32 TscanInfo = TcKeyReq::getTakeOverScanInfo(TOptionalDataPtr[0]);
|
||||
|
||||
regCachePtr->scanTakeOverInd = TDistrGHIndex;
|
||||
regCachePtr->scanInfo = TscanInfo;
|
||||
|
@ -2774,7 +2774,7 @@ void Dbtc::execTCKEYREQ(Signal* signal)
|
|||
regCachePtr->keydata[2] = Tdata3;
|
||||
regCachePtr->keydata[3] = Tdata4;
|
||||
|
||||
TkeyLength = tcKeyReq->getKeyLength(Treqinfo);
|
||||
TkeyLength = TcKeyReq::getKeyLength(Treqinfo);
|
||||
Uint32 TAIDataIndex;
|
||||
if (TkeyLength > 8) {
|
||||
TAIDataIndex = TkeyIndex + 8;
|
||||
|
@ -2787,7 +2787,7 @@ void Dbtc::execTCKEYREQ(Signal* signal)
|
|||
}//if
|
||||
Uint32* TAIDataPtr = &TOptionalDataPtr[TAIDataIndex];
|
||||
|
||||
titcLenAiInTckeyreq = tcKeyReq->getAIInTcKeyReq(Treqinfo);
|
||||
titcLenAiInTckeyreq = TcKeyReq::getAIInTcKeyReq(Treqinfo);
|
||||
regCachePtr->keylen = TkeyLength;
|
||||
regCachePtr->lenAiInTckeyreq = titcLenAiInTckeyreq;
|
||||
regCachePtr->currReclenAi = titcLenAiInTckeyreq;
|
||||
|
@ -2824,6 +2824,12 @@ void Dbtc::execTCKEYREQ(Signal* signal)
|
|||
tmp.p->apiNodeId = refToNode(regApiPtr->ndbapiBlockref);
|
||||
tmp.p->apiConnectPtr = TapiIndex;
|
||||
tmp.p->noOfLqhs = 0;
|
||||
#if defined VM_TRACE || defined ERROR_INSERT
|
||||
{
|
||||
CommitAckMarkerPtr check;
|
||||
ndbrequire(!m_commitAckMarkerHash.find(check, *tmp.p));
|
||||
}
|
||||
#endif
|
||||
m_commitAckMarkerHash.add(tmp);
|
||||
}
|
||||
}
|
||||
|
@ -2852,14 +2858,14 @@ void Dbtc::execTCKEYREQ(Signal* signal)
|
|||
}//switch
|
||||
}//if
|
||||
|
||||
Uint32 TabortOption = tcKeyReq->getAbortOption(Treqinfo);
|
||||
Uint32 TabortOption = TcKeyReq::getAbortOption(Treqinfo);
|
||||
regTcPtr->m_execAbortOption = TabortOption;
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Check error handling per operation
|
||||
* If CommitFlag is set state accordingly and check for early abort
|
||||
*------------------------------------------------------------------------*/
|
||||
if (tcKeyReq->getCommitFlag(Treqinfo) == 1) {
|
||||
if (TcKeyReq::getCommitFlag(Treqinfo) == 1) {
|
||||
ndbrequire(TexecuteFlag);
|
||||
regApiPtr->apiConnectstate = CS_REC_COMMITTING;
|
||||
} else {
|
||||
|
@ -8114,6 +8120,13 @@ void Dbtc::initApiConnectFail(Signal* signal)
|
|||
tmp.p->noOfLqhs = 1;
|
||||
tmp.p->lqhNodeId[0] = tnodeid;
|
||||
tmp.p->apiConnectPtr = apiConnectptr.i;
|
||||
|
||||
#if defined VM_TRACE || defined ERROR_INSERT
|
||||
{
|
||||
CommitAckMarkerPtr check;
|
||||
ndbrequire(!m_commitAckMarkerHash.find(check, *tmp.p));
|
||||
}
|
||||
#endif
|
||||
m_commitAckMarkerHash.add(tmp);
|
||||
}
|
||||
}//Dbtc::initApiConnectFail()
|
||||
|
@ -8270,6 +8283,12 @@ void Dbtc::updateApiStateFail(Signal* signal)
|
|||
tmp.p->noOfLqhs = 1;
|
||||
tmp.p->lqhNodeId[0] = tnodeid;
|
||||
tmp.p->apiConnectPtr = apiConnectptr.i;
|
||||
#if defined VM_TRACE || defined ERROR_INSERT
|
||||
{
|
||||
CommitAckMarkerPtr check;
|
||||
ndbrequire(!m_commitAckMarkerHash.find(check, *tmp.p));
|
||||
}
|
||||
#endif
|
||||
m_commitAckMarkerHash.add(tmp);
|
||||
} else {
|
||||
jam();
|
||||
|
@ -11472,7 +11491,7 @@ void Dbtc::execTCINDXREQ(Signal* signal)
|
|||
// If operation is readTupleExclusive or updateTuple then read index
|
||||
// table with exclusive lock
|
||||
Uint32 indexLength = TcKeyReq::getKeyLength(tcIndxRequestInfo);
|
||||
Uint32 attrLength = tcIndxReq->attrLen;
|
||||
Uint32 attrLength = TcKeyReq::getAttrinfoLen(tcIndxReq->attrLen);
|
||||
indexOp->expectedKeyInfo = indexLength;
|
||||
Uint32 includedIndexLength = MIN(indexLength, indexBufSize);
|
||||
indexOp->expectedAttrInfo = attrLength;
|
||||
|
|
|
@ -1736,7 +1736,8 @@ private:
|
|||
Operationrec* regOperPtr,
|
||||
Fragrecord* regFragPtr,
|
||||
Tablerec* regTabPtr,
|
||||
KeyReqStruct* req_struct);
|
||||
KeyReqStruct* req_struct,
|
||||
bool disk);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -814,7 +814,9 @@ void Dbtup::execTUPKEYREQ(Signal* signal)
|
|||
{
|
||||
jam();
|
||||
if (handleDeleteReq(signal, regOperPtr,
|
||||
regFragPtr, regTabPtr, &req_struct) == -1) {
|
||||
regFragPtr, regTabPtr,
|
||||
&req_struct,
|
||||
disk_page != RNIL) == -1) {
|
||||
return;
|
||||
}
|
||||
/*
|
||||
|
@ -1458,7 +1460,8 @@ int Dbtup::handleDeleteReq(Signal* signal,
|
|||
Operationrec* regOperPtr,
|
||||
Fragrecord* regFragPtr,
|
||||
Tablerec* regTabPtr,
|
||||
KeyReqStruct *req_struct)
|
||||
KeyReqStruct *req_struct,
|
||||
bool disk)
|
||||
{
|
||||
// delete must set but not increment tupVersion
|
||||
if (!regOperPtr->is_first_operation())
|
||||
|
@ -1510,8 +1513,11 @@ int Dbtup::handleDeleteReq(Signal* signal,
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return handleReadReq(signal, regOperPtr, regTabPtr, req_struct);
|
||||
|
||||
if (setup_read(req_struct, regOperPtr, regFragPtr, regTabPtr, disk))
|
||||
{
|
||||
return handleReadReq(signal, regOperPtr, regTabPtr, req_struct);
|
||||
}
|
||||
|
||||
error:
|
||||
tupkeyErrorLab(signal);
|
||||
|
|
|
@ -129,6 +129,7 @@ public:
|
|||
Uint32 m_president_candidate_gci;
|
||||
Uint16 m_regReqReqSent;
|
||||
Uint16 m_regReqReqRecv;
|
||||
Uint32 m_node_gci[MAX_NDB_NODES];
|
||||
} c_start;
|
||||
|
||||
NdbNodeBitmask c_definedNodes; // DB nodes in config
|
||||
|
|
|
@ -1092,7 +1092,8 @@ void Qmgr::execCM_REGREF(Signal* signal)
|
|||
jam();
|
||||
c_start.m_starting_nodes_w_log.set(TaddNodeno);
|
||||
}
|
||||
|
||||
c_start.m_node_gci[TaddNodeno] = node_gci;
|
||||
|
||||
skip_nodes.bitAND(c_definedNodes);
|
||||
c_start.m_skip_nodes.bitOR(skip_nodes);
|
||||
|
||||
|
@ -1241,6 +1242,7 @@ Qmgr::check_startup(Signal* signal)
|
|||
wait.bitANDC(tmp);
|
||||
|
||||
Uint32 retVal = 0;
|
||||
Uint32 incompleteng = MAX_NDB_NODES; // Illegal value
|
||||
NdbNodeBitmask report_mask;
|
||||
|
||||
if ((c_start.m_latest_gci == 0) ||
|
||||
|
@ -1325,7 +1327,7 @@ Qmgr::check_startup(Signal* signal)
|
|||
report_mask.assign(c_definedNodes);
|
||||
report_mask.bitANDC(c_start.m_starting_nodes);
|
||||
retVal = 1;
|
||||
goto start_report;
|
||||
goto check_log;
|
||||
case CheckNodeGroups::Partitioning:
|
||||
ndbrequire(result != CheckNodeGroups::Lose);
|
||||
signal->theData[1] =
|
||||
|
@ -1333,7 +1335,7 @@ Qmgr::check_startup(Signal* signal)
|
|||
report_mask.assign(c_definedNodes);
|
||||
report_mask.bitANDC(c_start.m_starting_nodes);
|
||||
retVal = 1;
|
||||
goto start_report;
|
||||
goto check_log;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1357,12 +1359,7 @@ Qmgr::check_startup(Signal* signal)
|
|||
case CheckNodeGroups::Partitioning:
|
||||
if (now < partitioned_timeout && result != CheckNodeGroups::Win)
|
||||
{
|
||||
signal->theData[1] = c_restartPartionedTimeout == (Uint32) ~0 ? 4 : 5;
|
||||
signal->theData[2] = Uint32((partitioned_timeout - now + 500) / 1000);
|
||||
report_mask.assign(c_definedNodes);
|
||||
report_mask.bitANDC(c_start.m_starting_nodes);
|
||||
retVal = 0;
|
||||
goto start_report;
|
||||
goto missinglog;
|
||||
}
|
||||
// Fall through...
|
||||
case CheckNodeGroups::Win:
|
||||
|
@ -1370,12 +1367,61 @@ Qmgr::check_startup(Signal* signal)
|
|||
all ? 0x8001 : (result == CheckNodeGroups::Win ? 0x8002 : 0x8003);
|
||||
report_mask.assign(c_definedNodes);
|
||||
report_mask.bitANDC(c_start.m_starting_nodes);
|
||||
retVal = 1;
|
||||
goto start_report;
|
||||
retVal = 2;
|
||||
goto check_log;
|
||||
}
|
||||
}
|
||||
ndbrequire(false);
|
||||
|
||||
check_log:
|
||||
jam();
|
||||
{
|
||||
Uint32 save[4+4*NdbNodeBitmask::Size];
|
||||
memcpy(save, signal->theData, sizeof(save));
|
||||
|
||||
signal->theData[0] = 0;
|
||||
c_start.m_starting_nodes.copyto(NdbNodeBitmask::Size, signal->theData+1);
|
||||
memcpy(signal->theData+1+NdbNodeBitmask::Size, c_start.m_node_gci,
|
||||
4*MAX_NDB_NODES);
|
||||
EXECUTE_DIRECT(DBDIH, GSN_DIH_RESTARTREQ, signal,
|
||||
1+NdbNodeBitmask::Size+MAX_NDB_NODES);
|
||||
|
||||
incompleteng = signal->theData[0];
|
||||
memcpy(signal->theData, save, sizeof(save));
|
||||
|
||||
if (incompleteng != MAX_NDB_NODES)
|
||||
{
|
||||
jam();
|
||||
if (retVal == 1)
|
||||
{
|
||||
jam();
|
||||
goto incomplete_log;
|
||||
}
|
||||
else if (retVal == 2)
|
||||
{
|
||||
if (now <= partitioned_timeout)
|
||||
{
|
||||
jam();
|
||||
goto missinglog;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto incomplete_log;
|
||||
}
|
||||
}
|
||||
ndbrequire(false);
|
||||
}
|
||||
}
|
||||
goto start_report;
|
||||
|
||||
missinglog:
|
||||
signal->theData[1] = c_restartPartionedTimeout == (Uint32) ~0 ? 4 : 5;
|
||||
signal->theData[2] = Uint32((partitioned_timeout - now + 500) / 1000);
|
||||
report_mask.assign(c_definedNodes);
|
||||
report_mask.bitANDC(c_start.m_starting_nodes);
|
||||
retVal = 0;
|
||||
goto start_report;
|
||||
|
||||
start_report:
|
||||
jam();
|
||||
{
|
||||
|
@ -1394,17 +1440,32 @@ start_report:
|
|||
|
||||
missing_nodegroup:
|
||||
jam();
|
||||
char buf[100], mask1[100], mask2[100];
|
||||
c_start.m_starting_nodes.getText(mask1);
|
||||
tmp.assign(c_start.m_starting_nodes);
|
||||
tmp.bitANDC(c_start.m_starting_nodes_w_log);
|
||||
tmp.getText(mask2);
|
||||
BaseString::snprintf(buf, sizeof(buf),
|
||||
"Unable to start missing node group! "
|
||||
" starting: %s (missing fs for: %s)",
|
||||
mask1, mask2);
|
||||
progError(__LINE__, NDBD_EXIT_SR_RESTARTCONFLICT, buf);
|
||||
return 0; // Deadcode
|
||||
{
|
||||
char buf[100], mask1[100], mask2[100];
|
||||
c_start.m_starting_nodes.getText(mask1);
|
||||
tmp.assign(c_start.m_starting_nodes);
|
||||
tmp.bitANDC(c_start.m_starting_nodes_w_log);
|
||||
tmp.getText(mask2);
|
||||
BaseString::snprintf(buf, sizeof(buf),
|
||||
"Unable to start missing node group! "
|
||||
" starting: %s (missing fs for: %s)",
|
||||
mask1, mask2);
|
||||
progError(__LINE__, NDBD_EXIT_INSUFFICENT_NODES, buf);
|
||||
return 0; // Deadcode
|
||||
}
|
||||
|
||||
incomplete_log:
|
||||
jam();
|
||||
{
|
||||
char buf[100], mask1[100];
|
||||
c_start.m_starting_nodes.getText(mask1);
|
||||
BaseString::snprintf(buf, sizeof(buf),
|
||||
"Incomplete log for node group: %d! "
|
||||
" starting nodes: %s",
|
||||
incompleteng, mask1);
|
||||
progError(__LINE__, NDBD_EXIT_INSUFFICENT_NODES, buf);
|
||||
return 0; // Deadcode
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -3523,8 +3584,10 @@ void Qmgr::execCOMMIT_FAILREQ(Signal* signal)
|
|||
nodePtr.p->phase = ZFAIL_CLOSING;
|
||||
nodePtr.p->failState = WAITING_FOR_NDB_FAILCONF;
|
||||
setNodeInfo(nodePtr.i).m_heartbeat_cnt= 0;
|
||||
setNodeInfo(nodePtr.i).m_version = 0;
|
||||
c_clusterNodes.clear(nodePtr.i);
|
||||
}//for
|
||||
recompute_version_info(NodeInfo::DB);
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* WE INFORM THE API'S WE HAVE CONNECTED ABOUT THE FAILED NODES. */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
|
|
@ -4668,9 +4668,7 @@ Suma::out_of_buffer(Signal* signal)
|
|||
m_out_of_buffer_gci = m_last_complete_gci - 1;
|
||||
infoEvent("Out of event buffer: nodefailure will cause event failures");
|
||||
|
||||
signal->theData[0] = SumaContinueB::OUT_OF_BUFFER_RELEASE;
|
||||
signal->theData[1] = 0;
|
||||
sendSignal(SUMA_REF, GSN_CONTINUEB, signal, 2, JBB);
|
||||
out_of_buffer_release(signal, 0);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -4738,7 +4736,8 @@ loop:
|
|||
|
||||
Uint32 count;
|
||||
m_tup->allocConsPages(16, count, ref);
|
||||
ndbrequire(count > 0);
|
||||
if (count == 0)
|
||||
return RNIL;
|
||||
|
||||
ndbout_c("alloc_chunk(%d %d) - ", ref, count);
|
||||
|
||||
|
|
|
@ -160,6 +160,7 @@ static const ErrStruct errArray[] =
|
|||
{NDBD_EXIT_AFS_READ_UNDERFLOW , XFI, "Read underflow"},
|
||||
|
||||
{NDBD_EXIT_INVALID_LCP_FILE, XFI, "Invalid LCP" },
|
||||
{NDBD_EXIT_INSUFFICENT_NODES, XRE, "Insufficent nodes for system restart" },
|
||||
|
||||
/* Sentinel */
|
||||
{0, XUE,
|
||||
|
|
|
@ -2054,6 +2054,18 @@ CommandInterpreter::executeStatus(int processId,
|
|||
ndbout << processId << ": Node not found" << endl;
|
||||
return -1;
|
||||
}
|
||||
if (cl->node_states[i].node_type != NDB_MGM_NODE_TYPE_NDB){
|
||||
if (cl->node_states[i].version != 0){
|
||||
ndbout << "Node "<< cl->node_states[i].node_id <<": connected" ;
|
||||
ndbout_c(" (Version %d.%d.%d)",
|
||||
getMajor(version) ,
|
||||
getMinor(version),
|
||||
getBuild(version));
|
||||
|
||||
}else
|
||||
ndbout << "Node "<< cl->node_states[i].node_id <<": not connected" << endl;
|
||||
return 0;
|
||||
}
|
||||
status = cl->node_states[i].node_status;
|
||||
startPhase = cl->node_states[i].start_phase;
|
||||
version = cl->node_states[i].version;
|
||||
|
|
|
@ -3613,6 +3613,7 @@ check_node_vs_replicas(Vector<ConfigInfo::ConfigRuleSection>§ions,
|
|||
Uint32 db_nodes= 0;
|
||||
Uint32 replicas= 0;
|
||||
Uint32 db_host_count= 0;
|
||||
bool with_arbitration_rank= false;
|
||||
ctx.m_userProperties.get(DB_TOKEN, &db_nodes);
|
||||
ctx.m_userProperties.get("NoOfReplicas", &replicas);
|
||||
if((db_nodes % replicas) != 0){
|
||||
|
@ -3648,83 +3649,90 @@ check_node_vs_replicas(Vector<ConfigInfo::ConfigRuleSection>§ions,
|
|||
tmp->get("HostName", &host);
|
||||
|
||||
if (strcmp(type,DB_TOKEN) == 0)
|
||||
{
|
||||
{
|
||||
Uint32 ii;
|
||||
if (!p_db_hosts.get(host,&ii))
|
||||
db_host_count++;
|
||||
p_db_hosts.put(host,i);
|
||||
if (p_arbitrators.get(host,&ii))
|
||||
{
|
||||
arbitration_warning.appfmt(arbit_warn_fmt, ii, i, host);
|
||||
p_arbitrators.remove(host); // only one warning per db node
|
||||
}
|
||||
}
|
||||
{
|
||||
unsigned j;
|
||||
BaseString str, str2;
|
||||
str.assfmt("#group%d_",group);
|
||||
p_db_hosts.put(str.c_str(),i_group,host);
|
||||
str2.assfmt("##group%d_",group);
|
||||
p_db_hosts.put(str2.c_str(),i_group,i);
|
||||
for (j= 0; j < i_group; j++)
|
||||
{
|
||||
const char *other_host;
|
||||
p_db_hosts.get(str.c_str(),j,&other_host);
|
||||
if (strcmp(host,other_host) == 0) {
|
||||
unsigned int other_i, c= 0;
|
||||
p_db_hosts.get(str2.c_str(),j,&other_i);
|
||||
p_db_hosts.get(str.c_str(),&c);
|
||||
if (c == 0) // first warning in this node group
|
||||
node_group_warning.appfmt(" Node group %d", group);
|
||||
c|= 1 << j;
|
||||
p_db_hosts.put(str.c_str(),c);
|
||||
|
||||
node_group_warning.appfmt(",\n db node with id %d and id %d "
|
||||
"on same host %s", other_i, i, host);
|
||||
}
|
||||
}
|
||||
i_group++;
|
||||
DBUG_ASSERT(i_group <= replicas);
|
||||
if (i_group == replicas)
|
||||
{
|
||||
unsigned c= 0;
|
||||
p_db_hosts.get(str.c_str(),&c);
|
||||
if (c+1 == (1u << (replicas-1))) // all nodes on same machine
|
||||
node_group_warning.append(".\n Host failure will "
|
||||
"cause complete cluster shutdown.");
|
||||
else if (c > 0)
|
||||
node_group_warning.append(".\n Host failure may "
|
||||
"cause complete cluster shutdown.");
|
||||
group++;
|
||||
i_group= 0;
|
||||
}
|
||||
}
|
||||
{
|
||||
{
|
||||
Uint32 ii;
|
||||
if (!p_db_hosts.get(host,&ii))
|
||||
db_host_count++;
|
||||
p_db_hosts.put(host,i);
|
||||
if (p_arbitrators.get(host,&ii))
|
||||
{
|
||||
arbitration_warning.appfmt(arbit_warn_fmt, ii, i, host);
|
||||
p_arbitrators.remove(host); // only one warning per db node
|
||||
}
|
||||
}
|
||||
{
|
||||
unsigned j;
|
||||
BaseString str, str2;
|
||||
str.assfmt("#group%d_",group);
|
||||
p_db_hosts.put(str.c_str(),i_group,host);
|
||||
str2.assfmt("##group%d_",group);
|
||||
p_db_hosts.put(str2.c_str(),i_group,i);
|
||||
for (j= 0; j < i_group; j++)
|
||||
{
|
||||
const char *other_host;
|
||||
p_db_hosts.get(str.c_str(),j,&other_host);
|
||||
if (strcmp(host,other_host) == 0) {
|
||||
unsigned int other_i, c= 0;
|
||||
p_db_hosts.get(str2.c_str(),j,&other_i);
|
||||
p_db_hosts.get(str.c_str(),&c);
|
||||
if (c == 0) // first warning in this node group
|
||||
node_group_warning.appfmt(" Node group %d", group);
|
||||
c|= 1 << j;
|
||||
p_db_hosts.put(str.c_str(),c);
|
||||
node_group_warning.appfmt(",\n db node with id %d and id %d "
|
||||
"on same host %s", other_i, i, host);
|
||||
}
|
||||
}
|
||||
i_group++;
|
||||
DBUG_ASSERT(i_group <= replicas);
|
||||
if (i_group == replicas)
|
||||
{
|
||||
unsigned c= 0;
|
||||
p_db_hosts.get(str.c_str(),&c);
|
||||
if (c+1 == (1u << (replicas-1))) // all nodes on same machine
|
||||
node_group_warning.append(".\n Host failure will "
|
||||
"cause complete cluster shutdown.");
|
||||
else if (c > 0)
|
||||
node_group_warning.append(".\n Host failure may "
|
||||
"cause complete cluster shutdown.");
|
||||
group++;
|
||||
i_group= 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strcmp(type,API_TOKEN) == 0 ||
|
||||
strcmp(type,MGM_TOKEN) == 0)
|
||||
{
|
||||
Uint32 rank;
|
||||
if(tmp->get("ArbitrationRank", &rank) && rank > 0)
|
||||
{
|
||||
if(host && host[0] != 0)
|
||||
{
|
||||
Uint32 ii;
|
||||
p_arbitrators.put(host,i);
|
||||
if (p_db_hosts.get(host,&ii))
|
||||
{
|
||||
arbitration_warning.appfmt(arbit_warn_fmt, i, ii, host);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
arbitration_warning.appfmt(arbit_warn_fmt2, i);
|
||||
}
|
||||
}
|
||||
{
|
||||
Uint32 rank;
|
||||
if(tmp->get("ArbitrationRank", &rank) && rank > 0)
|
||||
{
|
||||
with_arbitration_rank = true; //check whether MGM or API node configured with rank >0
|
||||
if(host && host[0] != 0)
|
||||
{
|
||||
Uint32 ii;
|
||||
p_arbitrators.put(host,i);
|
||||
if (p_db_hosts.get(host,&ii))
|
||||
{
|
||||
arbitration_warning.appfmt(arbit_warn_fmt, i, ii, host);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
arbitration_warning.appfmt(arbit_warn_fmt2, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (db_host_count > 1 && node_group_warning.length() > 0)
|
||||
ndbout_c("Cluster configuration warning:\n%s",node_group_warning.c_str());
|
||||
if (!with_arbitration_rank)
|
||||
{
|
||||
ndbout_c("Cluster configuration warning:"
|
||||
"\n Neither %s nor %s nodes are configured with arbitrator,"
|
||||
"\n may cause complete cluster shutdown in case of host failure.",
|
||||
MGM_TOKEN, API_TOKEN);
|
||||
}
|
||||
if (db_host_count > 1 && arbitration_warning.length() > 0)
|
||||
ndbout_c("Cluster configuration warning:%s%s",arbitration_warning.c_str(),
|
||||
"\n Running arbitrator on the same host as a database node may"
|
||||
|
|
|
@ -131,8 +131,6 @@ bool g_StopServer;
|
|||
bool g_RestartServer;
|
||||
extern EventLogger g_eventLogger;
|
||||
|
||||
extern int global_mgmt_server_check;
|
||||
|
||||
enum ndb_mgmd_options {
|
||||
OPT_INTERACTIVE = NDB_STD_OPTIONS_LAST,
|
||||
OPT_NO_NODEID_CHECKS,
|
||||
|
@ -206,8 +204,6 @@ int main(int argc, char** argv)
|
|||
start:
|
||||
glob= new MgmGlobals;
|
||||
|
||||
global_mgmt_server_check = 1;
|
||||
|
||||
if (opt_interactive ||
|
||||
opt_non_interactive ||
|
||||
g_print_full_config) {
|
||||
|
|
|
@ -360,8 +360,6 @@ ClusterMgr::execAPI_REGREQ(const Uint32 * theData){
|
|||
theFacade.sendSignalUnCond(&signal, nodeId);
|
||||
}
|
||||
|
||||
int global_mgmt_server_check = 0; // set to one in mgmtsrvr main;
|
||||
|
||||
void
|
||||
ClusterMgr::execAPI_REGCONF(const Uint32 * theData){
|
||||
const ApiRegConf * const apiRegConf = (ApiRegConf *)&theData[0];
|
||||
|
@ -379,7 +377,7 @@ ClusterMgr::execAPI_REGCONF(const Uint32 * theData){
|
|||
|
||||
if(node.m_info.m_version != apiRegConf->version){
|
||||
node.m_info.m_version = apiRegConf->version;
|
||||
if (global_mgmt_server_check == 1)
|
||||
if(theNodes[theFacade.ownId()].m_info.m_type == NodeInfo::MGM)
|
||||
node.compatible = ndbCompatible_mgmt_ndb(NDB_VERSION,
|
||||
node.m_info.m_version);
|
||||
else
|
||||
|
|
|
@ -1075,7 +1075,7 @@ Ndb::opTupleIdOnNdb(const NdbTableImpl* table,
|
|||
tOperation->incValue("NEXTID", opValue);
|
||||
tRecAttrResult = tOperation->getValue("NEXTID");
|
||||
|
||||
if (tConnection->execute( Commit ) == -1 )
|
||||
if (tConnection->execute( NdbTransaction::Commit ) == -1 )
|
||||
goto error_handler;
|
||||
|
||||
tValue = tRecAttrResult->u_64_value();
|
||||
|
@ -1090,7 +1090,7 @@ Ndb::opTupleIdOnNdb(const NdbTableImpl* table,
|
|||
tOperation->equal("SYSKEY_0", aTableId );
|
||||
tOperation->setValue("NEXTID", opValue);
|
||||
|
||||
if (tConnection->execute( Commit ) == -1 )
|
||||
if (tConnection->execute( NdbTransaction::Commit ) == -1 )
|
||||
goto error_handler;
|
||||
|
||||
range.reset();
|
||||
|
@ -1107,7 +1107,7 @@ Ndb::opTupleIdOnNdb(const NdbTableImpl* table,
|
|||
tOperation->def_label(0);
|
||||
tOperation->interpret_exit_nok(9999);
|
||||
|
||||
if (tConnection->execute( Commit ) == -1)
|
||||
if (tConnection->execute( NdbTransaction::Commit ) == -1)
|
||||
{
|
||||
if (tConnection->theError.code != 9999)
|
||||
goto error_handler;
|
||||
|
@ -1124,7 +1124,7 @@ Ndb::opTupleIdOnNdb(const NdbTableImpl* table,
|
|||
tOperation->readTuple();
|
||||
tOperation->equal("SYSKEY_0", aTableId );
|
||||
tRecAttrResult = tOperation->getValue("NEXTID");
|
||||
if (tConnection->execute( Commit ) == -1 )
|
||||
if (tConnection->execute( NdbTransaction::Commit ) == -1 )
|
||||
goto error_handler;
|
||||
opValue = tRecAttrResult->u_64_value(); // out
|
||||
break;
|
||||
|
|
|
@ -1133,7 +1133,7 @@ NdbBlob::readTableParts(char* buf, Uint32 part, Uint32 count)
|
|||
setErrorCode(tOp);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
tOp->m_abortOption = NdbTransaction::AbortOnError;
|
||||
tOp->m_abortOption = NdbOperation::AbortOnError;
|
||||
buf += thePartSize;
|
||||
n++;
|
||||
thePendingBlobOps |= (1 << NdbOperation::ReadRequest);
|
||||
|
@ -1169,7 +1169,7 @@ NdbBlob::insertParts(const char* buf, Uint32 part, Uint32 count)
|
|||
setErrorCode(tOp);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
tOp->m_abortOption = NdbTransaction::AbortOnError;
|
||||
tOp->m_abortOption = NdbOperation::AbortOnError;
|
||||
buf += thePartSize;
|
||||
n++;
|
||||
thePendingBlobOps |= (1 << NdbOperation::InsertRequest);
|
||||
|
@ -1193,7 +1193,7 @@ NdbBlob::updateParts(const char* buf, Uint32 part, Uint32 count)
|
|||
setErrorCode(tOp);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
tOp->m_abortOption = NdbTransaction::AbortOnError;
|
||||
tOp->m_abortOption = NdbOperation::AbortOnError;
|
||||
buf += thePartSize;
|
||||
n++;
|
||||
thePendingBlobOps |= (1 << NdbOperation::UpdateRequest);
|
||||
|
@ -1216,7 +1216,7 @@ NdbBlob::deleteParts(Uint32 part, Uint32 count)
|
|||
setErrorCode(tOp);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
tOp->m_abortOption = NdbTransaction::AbortOnError;
|
||||
tOp->m_abortOption = NdbOperation::AbortOnError;
|
||||
n++;
|
||||
thePendingBlobOps |= (1 << NdbOperation::DeleteRequest);
|
||||
theNdbCon->thePendingBlobOps |= (1 << NdbOperation::DeleteRequest);
|
||||
|
@ -1252,7 +1252,7 @@ NdbBlob::deletePartsUnknown(Uint32 part)
|
|||
setErrorCode(tOp);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
tOp->m_abortOption= NdbTransaction::AO_IgnoreError;
|
||||
tOp->m_abortOption= NdbOperation::AO_IgnoreError;
|
||||
n++;
|
||||
}
|
||||
DBUG_PRINT("info", ("bat=%u", bat));
|
||||
|
@ -1588,7 +1588,7 @@ NdbBlob::preExecute(NdbTransaction::ExecType anExecType, bool& batch)
|
|||
DBUG_RETURN(-1);
|
||||
}
|
||||
if (isWriteOp()) {
|
||||
tOp->m_abortOption = NdbTransaction::AO_IgnoreError;
|
||||
tOp->m_abortOption = NdbOperation::AO_IgnoreError;
|
||||
}
|
||||
theHeadInlineReadOp = tOp;
|
||||
// execute immediately
|
||||
|
@ -1634,7 +1634,7 @@ NdbBlob::preExecute(NdbTransaction::ExecType anExecType, bool& batch)
|
|||
DBUG_RETURN(-1);
|
||||
}
|
||||
if (isWriteOp()) {
|
||||
tOp->m_abortOption = NdbTransaction::AO_IgnoreError;
|
||||
tOp->m_abortOption = NdbOperation::AO_IgnoreError;
|
||||
}
|
||||
theHeadInlineReadOp = tOp;
|
||||
// execute immediately
|
||||
|
@ -1807,7 +1807,7 @@ NdbBlob::postExecute(NdbTransaction::ExecType anExecType)
|
|||
setErrorCode(NdbBlobImpl::ErrAbort);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
tOp->m_abortOption = NdbTransaction::AbortOnError;
|
||||
tOp->m_abortOption = NdbOperation::AbortOnError;
|
||||
DBUG_PRINT("info", ("added op to update head+inline"));
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
|
@ -1837,7 +1837,7 @@ NdbBlob::preCommit()
|
|||
setErrorCode(NdbBlobImpl::ErrAbort);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
tOp->m_abortOption = NdbTransaction::AbortOnError;
|
||||
tOp->m_abortOption = NdbOperation::AbortOnError;
|
||||
DBUG_PRINT("info", ("added op to update head+inline"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1609,17 +1609,24 @@ NdbEventBuffer::insert_event(NdbEventOperationImpl* impl,
|
|||
Uint32 &oid_ref)
|
||||
{
|
||||
NdbEventOperationImpl *dropped_ev_op = m_dropped_ev_op;
|
||||
DBUG_PRINT("info", ("gci: %u", data.gci));
|
||||
do
|
||||
{
|
||||
do
|
||||
{
|
||||
oid_ref = impl->m_oid;
|
||||
insertDataL(impl, &data, ptr);
|
||||
if (impl->m_node_bit_mask.get(0u))
|
||||
{
|
||||
oid_ref = impl->m_oid;
|
||||
insertDataL(impl, &data, ptr);
|
||||
}
|
||||
NdbEventOperationImpl* blob_op = impl->theBlobOpList;
|
||||
while (blob_op != NULL)
|
||||
{
|
||||
oid_ref = blob_op->m_oid;
|
||||
insertDataL(blob_op, &data, ptr);
|
||||
if (blob_op->m_node_bit_mask.get(0u))
|
||||
{
|
||||
oid_ref = blob_op->m_oid;
|
||||
insertDataL(blob_op, &data, ptr);
|
||||
}
|
||||
blob_op = blob_op->m_next;
|
||||
}
|
||||
} while((impl = impl->m_next));
|
||||
|
@ -1804,6 +1811,7 @@ NdbEventBuffer::insertDataL(NdbEventOperationImpl *op,
|
|||
switch (operation)
|
||||
{
|
||||
case NdbDictionary::Event::_TE_NODE_FAILURE:
|
||||
DBUG_ASSERT(op->m_node_bit_mask.get(0u) != 0);
|
||||
op->m_node_bit_mask.clear(SubTableData::getNdbdNodeId(ri));
|
||||
DBUG_PRINT("info",
|
||||
("_TE_NODE_FAILURE: m_ref_count: %u for op: %p id: %u",
|
||||
|
@ -1819,29 +1827,23 @@ NdbEventBuffer::insertDataL(NdbEventOperationImpl *op,
|
|||
DBUG_RETURN_EVENT(0);
|
||||
break;
|
||||
case NdbDictionary::Event::_TE_CLUSTER_FAILURE:
|
||||
if (op->m_node_bit_mask.get(0))
|
||||
DBUG_ASSERT(op->m_node_bit_mask.get(0u) != 0);
|
||||
op->m_node_bit_mask.clear();
|
||||
DBUG_ASSERT(op->m_ref_count > 0);
|
||||
// remove kernel reference
|
||||
// added in execute_nolock
|
||||
op->m_ref_count--;
|
||||
DBUG_PRINT("info", ("_TE_CLUSTER_FAILURE: m_ref_count: %u for op: %p",
|
||||
op->m_ref_count, op));
|
||||
if (op->theMainOp)
|
||||
{
|
||||
op->m_node_bit_mask.clear();
|
||||
DBUG_ASSERT(op->m_ref_count > 0);
|
||||
// remove kernel reference
|
||||
// added in execute_nolock
|
||||
op->m_ref_count--;
|
||||
DBUG_PRINT("info", ("_TE_CLUSTER_FAILURE: m_ref_count: %u for op: %p",
|
||||
op->m_ref_count, op));
|
||||
if (op->theMainOp)
|
||||
{
|
||||
DBUG_ASSERT(op->m_ref_count == 0);
|
||||
DBUG_ASSERT(op->theMainOp->m_ref_count > 0);
|
||||
// remove blob reference in main op
|
||||
// added in execute_no_lock
|
||||
op->theMainOp->m_ref_count--;
|
||||
DBUG_PRINT("info", ("m_ref_count: %u for op: %p",
|
||||
op->theMainOp->m_ref_count, op->theMainOp));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DBUG_ASSERT(op->m_node_bit_mask.isclear() != 0);
|
||||
DBUG_ASSERT(op->m_ref_count == 0);
|
||||
DBUG_ASSERT(op->theMainOp->m_ref_count > 0);
|
||||
// remove blob reference in main op
|
||||
// added in execute_no_lock
|
||||
op->theMainOp->m_ref_count--;
|
||||
DBUG_PRINT("info", ("m_ref_count: %u for op: %p",
|
||||
op->theMainOp->m_ref_count, op->theMainOp));
|
||||
}
|
||||
break;
|
||||
case NdbDictionary::Event::_TE_STOP:
|
||||
|
|
|
@ -172,237 +172,6 @@ NdbIndexOperation::getIndex() const
|
|||
return m_theIndex;
|
||||
}
|
||||
|
||||
int
|
||||
NdbIndexOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransactionId)
|
||||
{
|
||||
Uint32 tTransId1, tTransId2;
|
||||
Uint32 tReqInfo;
|
||||
Uint32 tSignalCount = 0;
|
||||
Uint32 tInterpretInd = theInterpretIndicator;
|
||||
|
||||
theErrorLine = 0;
|
||||
|
||||
if (tInterpretInd != 1) {
|
||||
OperationType tOpType = theOperationType;
|
||||
OperationStatus tStatus = theStatus;
|
||||
if ((tOpType == UpdateRequest) ||
|
||||
(tOpType == InsertRequest) ||
|
||||
(tOpType == WriteRequest)) {
|
||||
if (tStatus != SetValue) {
|
||||
setErrorCodeAbort(4506);
|
||||
return -1;
|
||||
}//if
|
||||
} else if ((tOpType == ReadRequest) || (tOpType == ReadExclusive) ||
|
||||
(tOpType == DeleteRequest)) {
|
||||
if (tStatus != GetValue) {
|
||||
setErrorCodeAbort(4506);
|
||||
return -1;
|
||||
}//if
|
||||
} else {
|
||||
setErrorCodeAbort(4507);
|
||||
return -1;
|
||||
}//if
|
||||
} else {
|
||||
if (prepareSendInterpreted() == -1) {
|
||||
return -1;
|
||||
}//if
|
||||
}//if
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// We start by filling in the first 8 unconditional words of the
|
||||
// TCINDXREQ signal.
|
||||
//-------------------------------------------------------------
|
||||
TcKeyReq * tcKeyReq =
|
||||
CAST_PTR(TcKeyReq, theTCREQ->getDataPtrSend());
|
||||
|
||||
Uint32 tTotalCurrAI_Len = theTotalCurrAI_Len;
|
||||
Uint32 tIndexId = m_theIndex->m_id;
|
||||
Uint32 tSchemaVersion = m_theIndex->m_version;
|
||||
|
||||
tcKeyReq->apiConnectPtr = aTC_ConnectPtr;
|
||||
tcKeyReq->senderData = ptr2int();
|
||||
tcKeyReq->attrLen = tTotalCurrAI_Len;
|
||||
tcKeyReq->tableId = tIndexId;
|
||||
tcKeyReq->tableSchemaVersion = tSchemaVersion;
|
||||
|
||||
tTransId1 = (Uint32) aTransactionId;
|
||||
tTransId2 = (Uint32) (aTransactionId >> 32);
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// Simple is simple if simple or both start and commit is set.
|
||||
//-------------------------------------------------------------
|
||||
// Temporarily disable simple stuff
|
||||
Uint8 tSimpleIndicator = 0;
|
||||
// Uint8 tSimpleIndicator = theSimpleIndicator;
|
||||
Uint8 tCommitIndicator = theCommitIndicator;
|
||||
Uint8 tStartIndicator = theStartIndicator;
|
||||
// if ((theNdbCon->theLastOpInList == this) && (theCommitIndicator == 0))
|
||||
// abort();
|
||||
// Temporarily disable simple stuff
|
||||
Uint8 tSimpleAlt = 0;
|
||||
// Uint8 tSimpleAlt = tStartIndicator & tCommitIndicator;
|
||||
tSimpleIndicator = tSimpleIndicator | tSimpleAlt;
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// Simple state is set if start and commit is set and it is
|
||||
// a read request. Otherwise it is set to zero.
|
||||
//-------------------------------------------------------------
|
||||
//theNdbCon->theSimpleState = tSimpleState;
|
||||
|
||||
tcKeyReq->transId1 = tTransId1;
|
||||
tcKeyReq->transId2 = tTransId2;
|
||||
|
||||
tReqInfo = 0;
|
||||
|
||||
if (tTotalCurrAI_Len <= TcKeyReq::MaxAttrInfo) {
|
||||
tcKeyReq->setAIInTcKeyReq(tReqInfo, tTotalCurrAI_Len);
|
||||
} else {
|
||||
tcKeyReq->setAIInTcKeyReq(tReqInfo, TcKeyReq::MaxAttrInfo);
|
||||
}//if
|
||||
|
||||
tcKeyReq->setSimpleFlag(tReqInfo, tSimpleIndicator);
|
||||
tcKeyReq->setCommitFlag(tReqInfo, tCommitIndicator);
|
||||
tcKeyReq->setStartFlag(tReqInfo, tStartIndicator);
|
||||
const Uint8 tInterpretIndicator = theInterpretIndicator;
|
||||
tcKeyReq->setInterpretedFlag(tReqInfo, tInterpretIndicator);
|
||||
|
||||
Uint8 tDirtyIndicator = theDirtyIndicator;
|
||||
OperationType tOperationType = theOperationType;
|
||||
Uint32 tIndexLen = theTupKeyLen;
|
||||
Uint8 abortOption = theNdbCon->m_abortOption;
|
||||
|
||||
tcKeyReq->setDirtyFlag(tReqInfo, tDirtyIndicator);
|
||||
tcKeyReq->setOperationType(tReqInfo, tOperationType);
|
||||
tcKeyReq->setKeyLength(tReqInfo, tIndexLen);
|
||||
tcKeyReq->setAbortOption(tReqInfo, abortOption);
|
||||
|
||||
Uint8 tDistrKeyIndicator = theDistrKeyIndicator_;
|
||||
Uint8 tScanIndicator = theScanInfo & 1;
|
||||
|
||||
tcKeyReq->setDistributionKeyFlag(tReqInfo, tDistrKeyIndicator);
|
||||
tcKeyReq->setScanIndFlag(tReqInfo, tScanIndicator);
|
||||
|
||||
tcKeyReq->requestInfo = tReqInfo;
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// The next step is to fill in the upto three conditional words.
|
||||
//-------------------------------------------------------------
|
||||
Uint32* tOptionalDataPtr = &tcKeyReq->scanInfo;
|
||||
Uint32 tDistrGHIndex = tScanIndicator;
|
||||
Uint32 tDistrKeyIndex = tDistrGHIndex;
|
||||
|
||||
Uint32 tScanInfo = theScanInfo;
|
||||
Uint32 tDistrKey = theDistributionKey;
|
||||
|
||||
tOptionalDataPtr[0] = tScanInfo;
|
||||
tOptionalDataPtr[tDistrKeyIndex] = tDistrKey;
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// The next is step is to compress the key data part of the
|
||||
// TCKEYREQ signal.
|
||||
//-------------------------------------------------------------
|
||||
Uint32 tKeyIndex = tDistrKeyIndex + tDistrKeyIndicator;
|
||||
Uint32* tKeyDataPtr = &tOptionalDataPtr[tKeyIndex];
|
||||
Uint32 Tdata1 = tcKeyReq->keyInfo[0];
|
||||
Uint32 Tdata2 = tcKeyReq->keyInfo[1];
|
||||
Uint32 Tdata3 = tcKeyReq->keyInfo[2];
|
||||
Uint32 Tdata4 = tcKeyReq->keyInfo[3];
|
||||
Uint32 Tdata5;
|
||||
|
||||
tKeyDataPtr[0] = Tdata1;
|
||||
tKeyDataPtr[1] = Tdata2;
|
||||
tKeyDataPtr[2] = Tdata3;
|
||||
tKeyDataPtr[3] = Tdata4;
|
||||
if (tIndexLen > 4) {
|
||||
Tdata1 = tcKeyReq->keyInfo[4];
|
||||
Tdata2 = tcKeyReq->keyInfo[5];
|
||||
Tdata3 = tcKeyReq->keyInfo[6];
|
||||
Tdata4 = tcKeyReq->keyInfo[7];
|
||||
|
||||
tKeyDataPtr[4] = Tdata1;
|
||||
tKeyDataPtr[5] = Tdata2;
|
||||
tKeyDataPtr[6] = Tdata3;
|
||||
tKeyDataPtr[7] = Tdata4;
|
||||
}//if
|
||||
//-------------------------------------------------------------
|
||||
// Finally we also compress the INDXATTRINFO part of the signal.
|
||||
// We optimise by using the if-statement for sending INDXKEYINFO
|
||||
// signals to calculating the new Attrinfo Index.
|
||||
//-------------------------------------------------------------
|
||||
Uint32 tAttrInfoIndex;
|
||||
|
||||
if (tIndexLen > TcKeyReq::MaxKeyInfo) {
|
||||
/**
|
||||
* Set transid and TC connect ptr in the INDXKEYINFO signals
|
||||
*/
|
||||
NdbApiSignal* tSignal = theTCREQ->next();
|
||||
Uint32 remainingKey = tIndexLen - TcKeyReq::MaxKeyInfo;
|
||||
|
||||
do {
|
||||
Uint32* tSigDataPtr = tSignal->getDataPtrSend();
|
||||
NdbApiSignal* tnextSignal = tSignal->next();
|
||||
tSignalCount++;
|
||||
tSigDataPtr[0] = aTC_ConnectPtr;
|
||||
tSigDataPtr[1] = tTransId1;
|
||||
tSigDataPtr[2] = tTransId2;
|
||||
if (remainingKey > IndxKeyInfo::DataLength) {
|
||||
// The signal is full
|
||||
tSignal->setLength(IndxKeyInfo::MaxSignalLength);
|
||||
remainingKey -= IndxKeyInfo::DataLength;
|
||||
}
|
||||
else {
|
||||
// Last signal
|
||||
tSignal->setLength(IndxKeyInfo::HeaderLength + remainingKey);
|
||||
remainingKey = 0;
|
||||
}
|
||||
tSignal = tnextSignal;
|
||||
} while (tSignal != NULL);
|
||||
tAttrInfoIndex = tKeyIndex + TcKeyReq::MaxKeyInfo;
|
||||
} else {
|
||||
tAttrInfoIndex = tKeyIndex + tIndexLen;
|
||||
}//if
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// Perform the Attrinfo packing in the TCKEYREQ signal started
|
||||
// above.
|
||||
//-------------------------------------------------------------
|
||||
Uint32* tAIDataPtr = &tOptionalDataPtr[tAttrInfoIndex];
|
||||
Tdata1 = tcKeyReq->attrInfo[0];
|
||||
Tdata2 = tcKeyReq->attrInfo[1];
|
||||
Tdata3 = tcKeyReq->attrInfo[2];
|
||||
Tdata4 = tcKeyReq->attrInfo[3];
|
||||
Tdata5 = tcKeyReq->attrInfo[4];
|
||||
|
||||
theTCREQ->setLength(tcKeyReq->getAIInTcKeyReq(tReqInfo) +
|
||||
tAttrInfoIndex + TcKeyReq::StaticLength);
|
||||
tAIDataPtr[0] = Tdata1;
|
||||
tAIDataPtr[1] = Tdata2;
|
||||
tAIDataPtr[2] = Tdata3;
|
||||
tAIDataPtr[3] = Tdata4;
|
||||
tAIDataPtr[4] = Tdata5;
|
||||
|
||||
/***************************************************
|
||||
* Send the INDXATTRINFO signals.
|
||||
***************************************************/
|
||||
if (tTotalCurrAI_Len > 5) {
|
||||
// Set the last signal's length.
|
||||
NdbApiSignal* tSignal = theFirstATTRINFO;
|
||||
theCurrentATTRINFO->setLength(theAI_LenInCurrAI);
|
||||
do {
|
||||
Uint32* tSigDataPtr = tSignal->getDataPtrSend();
|
||||
NdbApiSignal* tnextSignal = tSignal->next();
|
||||
tSignalCount++;
|
||||
tSigDataPtr[0] = aTC_ConnectPtr;
|
||||
tSigDataPtr[1] = tTransId1;
|
||||
tSigDataPtr[2] = tTransId2;
|
||||
tSignal = tnextSignal;
|
||||
} while (tSignal != NULL);
|
||||
}//if
|
||||
theStatus = WaitResponse;
|
||||
theReceiver.prepareSend();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
int receiveTCINDXREF( NdbApiSignal* aSignal)
|
||||
|
||||
|
|
|
@ -426,7 +426,7 @@ NdbIndexStat::records_in_range(const NdbDictionary::Index* index, NdbIndexScanOp
|
|||
DBUG_RETURN(-1);
|
||||
}
|
||||
if (trans->execute(NdbTransaction::NoCommit,
|
||||
NdbTransaction::AbortOnError, forceSend) == -1) {
|
||||
NdbOperation::AbortOnError, forceSend) == -1) {
|
||||
m_error = trans->getNdbError();
|
||||
DBUG_PRINT("error", ("trans:%d op:%d", trans->getNdbError().code,
|
||||
op->getNdbError().code));
|
||||
|
|
|
@ -44,6 +44,7 @@ NdbOperation::insertTuple()
|
|||
tNdbCon->theSimpleState = 0;
|
||||
theErrorLine = tErrorLine++;
|
||||
theLockMode = LM_Exclusive;
|
||||
m_abortOption = AbortOnError;
|
||||
return 0;
|
||||
} else {
|
||||
setErrorCode(4200);
|
||||
|
@ -64,6 +65,7 @@ NdbOperation::updateTuple()
|
|||
theOperationType = UpdateRequest;
|
||||
theErrorLine = tErrorLine++;
|
||||
theLockMode = LM_Exclusive;
|
||||
m_abortOption = AbortOnError;
|
||||
return 0;
|
||||
} else {
|
||||
setErrorCode(4200);
|
||||
|
@ -84,12 +86,35 @@ NdbOperation::writeTuple()
|
|||
theOperationType = WriteRequest;
|
||||
theErrorLine = tErrorLine++;
|
||||
theLockMode = LM_Exclusive;
|
||||
m_abortOption = AbortOnError;
|
||||
return 0;
|
||||
} else {
|
||||
setErrorCode(4200);
|
||||
return -1;
|
||||
}//if
|
||||
}//NdbOperation::writeTuple()
|
||||
/*****************************************************************************
|
||||
* int deleteTuple();
|
||||
*****************************************************************************/
|
||||
int
|
||||
NdbOperation::deleteTuple()
|
||||
{
|
||||
NdbTransaction* tNdbCon = theNdbCon;
|
||||
int tErrorLine = theErrorLine;
|
||||
if (theStatus == Init) {
|
||||
theStatus = OperationDefined;
|
||||
tNdbCon->theSimpleState = 0;
|
||||
theOperationType = DeleteRequest;
|
||||
theErrorLine = tErrorLine++;
|
||||
theLockMode = LM_Exclusive;
|
||||
m_abortOption = AbortOnError;
|
||||
return 0;
|
||||
} else {
|
||||
setErrorCode(4200);
|
||||
return -1;
|
||||
}//if
|
||||
}//NdbOperation::deleteTuple()
|
||||
|
||||
/******************************************************************************
|
||||
* int readTuple();
|
||||
*****************************************************************************/
|
||||
|
@ -124,6 +149,7 @@ NdbOperation::readTuple()
|
|||
theOperationType = ReadRequest;
|
||||
theErrorLine = tErrorLine++;
|
||||
theLockMode = LM_Read;
|
||||
m_abortOption = AO_IgnoreError;
|
||||
return 0;
|
||||
} else {
|
||||
setErrorCode(4200);
|
||||
|
@ -131,27 +157,6 @@ NdbOperation::readTuple()
|
|||
}//if
|
||||
}//NdbOperation::readTuple()
|
||||
|
||||
/*****************************************************************************
|
||||
* int deleteTuple();
|
||||
*****************************************************************************/
|
||||
int
|
||||
NdbOperation::deleteTuple()
|
||||
{
|
||||
NdbTransaction* tNdbCon = theNdbCon;
|
||||
int tErrorLine = theErrorLine;
|
||||
if (theStatus == Init) {
|
||||
theStatus = OperationDefined;
|
||||
tNdbCon->theSimpleState = 0;
|
||||
theOperationType = DeleteRequest;
|
||||
theErrorLine = tErrorLine++;
|
||||
theLockMode = LM_Exclusive;
|
||||
return 0;
|
||||
} else {
|
||||
setErrorCode(4200);
|
||||
return -1;
|
||||
}//if
|
||||
}//NdbOperation::deleteTuple()
|
||||
|
||||
/******************************************************************************
|
||||
* int readTupleExclusive();
|
||||
*****************************************************************************/
|
||||
|
@ -166,6 +171,7 @@ NdbOperation::readTupleExclusive()
|
|||
theOperationType = ReadExclusive;
|
||||
theErrorLine = tErrorLine++;
|
||||
theLockMode = LM_Exclusive;
|
||||
m_abortOption = AO_IgnoreError;
|
||||
return 0;
|
||||
} else {
|
||||
setErrorCode(4200);
|
||||
|
@ -222,6 +228,7 @@ NdbOperation::committedRead()
|
|||
theDirtyIndicator = 1;
|
||||
theErrorLine = tErrorLine++;
|
||||
theLockMode = LM_CommittedRead;
|
||||
m_abortOption = AO_IgnoreError;
|
||||
return 0;
|
||||
} else {
|
||||
setErrorCode(4200);
|
||||
|
@ -245,6 +252,7 @@ NdbOperation::dirtyUpdate()
|
|||
theDirtyIndicator = 1;
|
||||
theErrorLine = tErrorLine++;
|
||||
theLockMode = LM_CommittedRead;
|
||||
m_abortOption = AbortOnError;
|
||||
return 0;
|
||||
} else {
|
||||
setErrorCode(4200);
|
||||
|
@ -268,6 +276,7 @@ NdbOperation::dirtyWrite()
|
|||
theDirtyIndicator = 1;
|
||||
theErrorLine = tErrorLine++;
|
||||
theLockMode = LM_CommittedRead;
|
||||
m_abortOption = AbortOnError;
|
||||
return 0;
|
||||
} else {
|
||||
setErrorCode(4200);
|
||||
|
@ -290,6 +299,7 @@ NdbOperation::interpretedUpdateTuple()
|
|||
theAI_LenInCurrAI = 25;
|
||||
theLockMode = LM_Exclusive;
|
||||
theErrorLine = tErrorLine++;
|
||||
m_abortOption = AbortOnError;
|
||||
initInterpreter();
|
||||
return 0;
|
||||
} else {
|
||||
|
@ -314,6 +324,7 @@ NdbOperation::interpretedDeleteTuple()
|
|||
theErrorLine = tErrorLine++;
|
||||
theAI_LenInCurrAI = 25;
|
||||
theLockMode = LM_Exclusive;
|
||||
m_abortOption = AbortOnError;
|
||||
initInterpreter();
|
||||
return 0;
|
||||
} else {
|
||||
|
|
|
@ -99,7 +99,9 @@ Parameters: aTC_ConnectPtr: the Connect pointer to TC.
|
|||
Remark: Puts the the data into TCKEYREQ signal and optional KEYINFO and ATTRINFO signals.
|
||||
***************************************************************************/
|
||||
int
|
||||
NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId)
|
||||
NdbOperation::prepareSend(Uint32 aTC_ConnectPtr,
|
||||
Uint64 aTransId,
|
||||
AbortOption ao)
|
||||
{
|
||||
Uint32 tTransId1, tTransId2;
|
||||
Uint32 tReqInfo;
|
||||
|
@ -147,8 +149,8 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId)
|
|||
//-------------------------------------------------------------
|
||||
TcKeyReq * const tcKeyReq = CAST_PTR(TcKeyReq, theTCREQ->getDataPtrSend());
|
||||
|
||||
Uint32 tTableId = m_currentTable->m_id;
|
||||
Uint32 tSchemaVersion = m_currentTable->m_version;
|
||||
Uint32 tTableId = m_accessTable->m_id;
|
||||
Uint32 tSchemaVersion = m_accessTable->m_version;
|
||||
|
||||
tcKeyReq->apiConnectPtr = aTC_ConnectPtr;
|
||||
tcKeyReq->apiOperationPtr = ptr2int();
|
||||
|
@ -177,6 +179,8 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId)
|
|||
// Simple state is set if start and commit is set and it is
|
||||
// a read request. Otherwise it is set to zero.
|
||||
//-------------------------------------------------------------
|
||||
Uint8 tReadInd = (theOperationType == ReadRequest);
|
||||
Uint8 tSimpleState = tReadInd & tSimpleIndicator;
|
||||
|
||||
tcKeyReq->transId1 = tTransId1;
|
||||
tcKeyReq->transId2 = tTransId2;
|
||||
|
@ -196,16 +200,16 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId)
|
|||
|
||||
OperationType tOperationType = theOperationType;
|
||||
Uint32 tTupKeyLen = theTupKeyLen;
|
||||
Uint8 abortOption =
|
||||
m_abortOption != -1 ? m_abortOption : theNdbCon->m_abortOption;
|
||||
Uint8 abortOption = (ao == DefaultAbortOption) ? m_abortOption : ao;
|
||||
|
||||
tcKeyReq->setDirtyFlag(tReqInfo, tDirtyIndicator);
|
||||
tcKeyReq->setOperationType(tReqInfo, tOperationType);
|
||||
tcKeyReq->setKeyLength(tReqInfo, tTupKeyLen);
|
||||
|
||||
// A simple read is always ignore error
|
||||
abortOption = tSimpleIndicator ? (Uint8) AO_IgnoreError : abortOption;
|
||||
abortOption = tSimpleState ? AO_IgnoreError : abortOption;
|
||||
tcKeyReq->setAbortOption(tReqInfo, abortOption);
|
||||
m_abortOption = abortOption;
|
||||
|
||||
Uint8 tDistrKeyIndicator = theDistrKeyIndicator_;
|
||||
Uint8 tScanIndicator = theScanInfo & 1;
|
||||
|
@ -541,21 +545,16 @@ NdbOperation::receiveTCKEYREF( NdbApiSignal* aSignal)
|
|||
return -1;
|
||||
}//if
|
||||
|
||||
AbortOption ao = (AbortOption)
|
||||
(m_abortOption != -1 ? m_abortOption : theNdbCon->m_abortOption);
|
||||
setErrorCode(aSignal->readData(4));
|
||||
theStatus = Finished;
|
||||
theReceiver.m_received_result_length = ~0;
|
||||
|
||||
theStatus = Finished;
|
||||
// blobs want this
|
||||
if (m_abortOption != AO_IgnoreError)
|
||||
// not simple read
|
||||
if(! (theOperationType == ReadRequest && theSimpleIndicator))
|
||||
{
|
||||
theNdbCon->theReturnStatus = NdbTransaction::ReturnFailure;
|
||||
theNdbCon->OpCompleteFailure(this);
|
||||
return -1;
|
||||
}
|
||||
theError.code = aSignal->readData(4);
|
||||
theNdbCon->setOperationErrorCodeAbort(aSignal->readData(4), ao);
|
||||
|
||||
if(theOperationType != ReadRequest || !theSimpleIndicator) // not simple read
|
||||
return theNdbCon->OpCompleteFailure(ao, m_abortOption != AO_IgnoreError);
|
||||
|
||||
/**
|
||||
* If TCKEYCONF has arrived
|
||||
|
@ -563,23 +562,8 @@ NdbOperation::receiveTCKEYREF( NdbApiSignal* aSignal)
|
|||
*/
|
||||
if(theReceiver.m_expected_result_length)
|
||||
{
|
||||
return theNdbCon->OpCompleteFailure(AbortOnError);
|
||||
return theNdbCon->OpCompleteFailure(this);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
NdbOperation::handleFailedAI_ElemLen()
|
||||
{
|
||||
NdbRecAttr* tRecAttr = theReceiver.theFirstRecAttr;
|
||||
while (tRecAttr != NULL) {
|
||||
tRecAttr->setNULL();
|
||||
tRecAttr = tRecAttr->next();
|
||||
}//while
|
||||
}//NdbOperation::handleFailedAI_ElemLen()
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -994,6 +994,7 @@ NdbScanOperation::takeOverScanOp(OperationType opType, NdbTransaction* pTrans)
|
|||
|
||||
newOp->theTupKeyLen = len;
|
||||
newOp->theOperationType = opType;
|
||||
newOp->m_abortOption = AbortOnError;
|
||||
switch (opType) {
|
||||
case (ReadRequest):
|
||||
newOp->theLockMode = theLockMode;
|
||||
|
@ -1224,7 +1225,7 @@ NdbIndexScanOperation::setBound(const NdbColumnImpl* tAttrInfo,
|
|||
* so it's safe to use [tIndexAttrId]
|
||||
* (instead of looping as is NdbOperation::equal_impl)
|
||||
*/
|
||||
if(type == BoundEQ && tDistrKey)
|
||||
if(type == BoundEQ && tDistrKey && !m_multi_range)
|
||||
{
|
||||
theNoOfTupKeyLeft--;
|
||||
return handle_distribution_key(valPtr, sizeInWords);
|
||||
|
@ -1310,7 +1311,8 @@ NdbIndexScanOperation::readTuples(LockMode lm,
|
|||
const bool order_by = scan_flags & SF_OrderBy;
|
||||
const bool order_desc = scan_flags & SF_Descending;
|
||||
const bool read_range_no = scan_flags & SF_ReadRangeNo;
|
||||
|
||||
m_multi_range = scan_flags & SF_MultiRange;
|
||||
|
||||
int res = NdbScanOperation::readTuples(lm, scan_flags, parallel, batch);
|
||||
if(!res && read_range_no)
|
||||
{
|
||||
|
@ -1791,6 +1793,12 @@ NdbIndexScanOperation::reset_bounds(bool forceSend){
|
|||
int
|
||||
NdbIndexScanOperation::end_of_bound(Uint32 no)
|
||||
{
|
||||
DBUG_ENTER("end_of_bound");
|
||||
DBUG_PRINT("info", ("Range number %u", no));
|
||||
/* Check that SF_MultiRange has been specified if more
|
||||
than one range is specified */
|
||||
if (no > 0 && !m_multi_range)
|
||||
DBUG_RETURN(-1);
|
||||
if(no < (1 << 13)) // Only 12-bits no of ranges
|
||||
{
|
||||
Uint32 bound_head = * m_first_bound_word;
|
||||
|
@ -1799,9 +1807,9 @@ NdbIndexScanOperation::end_of_bound(Uint32 no)
|
|||
|
||||
m_first_bound_word = theKEYINFOptr + theTotalNrOfKeyWordInSignal;;
|
||||
m_this_bound_start = theTupKeyLen;
|
||||
return 0;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
return -1;
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -56,7 +56,6 @@ NdbTransaction::NdbTransaction( Ndb* aNdb ) :
|
|||
theCompletedLastOp(NULL),
|
||||
theNoOfOpSent(0),
|
||||
theNoOfOpCompleted(0),
|
||||
theNoOfOpFetched(0),
|
||||
theMyRef(0),
|
||||
theTCConPtr(0),
|
||||
theTransactionId(0),
|
||||
|
@ -131,7 +130,6 @@ NdbTransaction::init()
|
|||
theNdb->theImpl->m_ndb_cluster_connection.get_latest_trans_gci();
|
||||
theCommitStatus = Started;
|
||||
theCompletionStatus = NotCompleted;
|
||||
m_abortOption = AbortOnError;
|
||||
|
||||
theError.code = 0;
|
||||
theErrorLine = 0;
|
||||
|
@ -176,12 +174,9 @@ void
|
|||
NdbTransaction::setOperationErrorCodeAbort(int error, int abortOption)
|
||||
{
|
||||
DBUG_ENTER("NdbTransaction::setOperationErrorCodeAbort");
|
||||
if (abortOption == -1)
|
||||
abortOption = m_abortOption;
|
||||
if (theTransactionIsStarted == false) {
|
||||
theCommitStatus = Aborted;
|
||||
} else if ((abortOption == AbortOnError) &&
|
||||
(theCommitStatus != Committed) &&
|
||||
} else if ((theCommitStatus != Committed) &&
|
||||
(theCommitStatus != Aborted)) {
|
||||
theCommitStatus = NeedAbort;
|
||||
}//if
|
||||
|
@ -263,8 +258,8 @@ Remark: Initialise connection object for new transaction.
|
|||
*****************************************************************************/
|
||||
int
|
||||
NdbTransaction::execute(ExecType aTypeOfExec,
|
||||
AbortOption abortOption,
|
||||
int forceSend)
|
||||
NdbOperation::AbortOption abortOption,
|
||||
int forceSend)
|
||||
{
|
||||
NdbError savedError= theError;
|
||||
DBUG_ENTER("NdbTransaction::execute");
|
||||
|
@ -354,40 +349,14 @@ NdbTransaction::execute(ExecType aTypeOfExec,
|
|||
theCompletedLastOp = NULL;
|
||||
}
|
||||
|
||||
if (executeNoBlobs(tExecType, abortOption, forceSend) == -1)
|
||||
if (executeNoBlobs(tExecType,
|
||||
NdbOperation::DefaultAbortOption,
|
||||
forceSend) == -1)
|
||||
{
|
||||
ret = -1;
|
||||
if(savedError.code==0)
|
||||
savedError= theError;
|
||||
|
||||
/**
|
||||
* If AO_IgnoreError, error codes arent always set on individual
|
||||
* operations, making postExecute impossible
|
||||
*/
|
||||
if (abortOption == AO_IgnoreError)
|
||||
{
|
||||
if (theCompletedFirstOp != NULL)
|
||||
{
|
||||
if (tCompletedFirstOp != NULL)
|
||||
{
|
||||
tCompletedLastOp->next(theCompletedFirstOp);
|
||||
theCompletedFirstOp = tCompletedFirstOp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
theCompletedFirstOp = tCompletedFirstOp;
|
||||
theCompletedLastOp = tCompletedLastOp;
|
||||
}
|
||||
if (tPrepOp != NULL && tRestOp != NULL) {
|
||||
if (theFirstOpInList == NULL)
|
||||
theFirstOpInList = tRestOp;
|
||||
else
|
||||
theLastOpInList->next(tRestOp);
|
||||
theLastOpInList = tLastOp;
|
||||
}
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
|
||||
#ifdef ndb_api_crash_on_complex_blob_abort
|
||||
|
@ -447,9 +416,9 @@ NdbTransaction::execute(ExecType aTypeOfExec,
|
|||
}
|
||||
|
||||
int
|
||||
NdbTransaction::executeNoBlobs(ExecType aTypeOfExec,
|
||||
AbortOption abortOption,
|
||||
int forceSend)
|
||||
NdbTransaction::executeNoBlobs(NdbTransaction::ExecType aTypeOfExec,
|
||||
NdbOperation::AbortOption abortOption,
|
||||
int forceSend)
|
||||
{
|
||||
DBUG_ENTER("NdbTransaction::executeNoBlobs");
|
||||
DBUG_PRINT("enter", ("aTypeOfExec: %d, abortOption: %d",
|
||||
|
@ -527,10 +496,10 @@ Parameters : aTypeOfExec: Type of execute.
|
|||
Remark: Prepare a part of a transaction in an asynchronous manner.
|
||||
*****************************************************************************/
|
||||
void
|
||||
NdbTransaction::executeAsynchPrepare( ExecType aTypeOfExec,
|
||||
NdbTransaction::executeAsynchPrepare(NdbTransaction::ExecType aTypeOfExec,
|
||||
NdbAsynchCallback aCallback,
|
||||
void* anyObject,
|
||||
AbortOption abortOption)
|
||||
NdbOperation::AbortOption abortOption)
|
||||
{
|
||||
DBUG_ENTER("NdbTransaction::executeAsynchPrepare");
|
||||
DBUG_PRINT("enter", ("aTypeOfExec: %d, aCallback: 0x%lx, anyObject: Ox%lx",
|
||||
|
@ -570,7 +539,6 @@ NdbTransaction::executeAsynchPrepare( ExecType aTypeOfExec,
|
|||
theReturnStatus = ReturnSuccess;
|
||||
theCallbackFunction = aCallback;
|
||||
theCallbackObject = anyObject;
|
||||
m_abortOption = abortOption;
|
||||
m_waitForReply = true;
|
||||
tNdb->thePreparedTransactionsArray[tnoOfPreparedTransactions] = this;
|
||||
theTransArrayIndex = tnoOfPreparedTransactions;
|
||||
|
@ -665,8 +633,7 @@ NdbTransaction::executeAsynchPrepare( ExecType aTypeOfExec,
|
|||
while (tOp) {
|
||||
int tReturnCode;
|
||||
NdbOperation* tNextOp = tOp->next();
|
||||
|
||||
tReturnCode = tOp->prepareSend(theTCConPtr, theTransactionId);
|
||||
tReturnCode = tOp->prepareSend(theTCConPtr, theTransactionId, abortOption);
|
||||
if (tReturnCode == -1) {
|
||||
theSendStatus = sendABORTfail;
|
||||
DBUG_VOID_RETURN;
|
||||
|
@ -1799,14 +1766,8 @@ from other transactions.
|
|||
}
|
||||
} else if ((tNoComp >= tNoSent) &&
|
||||
(theLastExecOpInList->theCommitIndicator == 1)){
|
||||
|
||||
|
||||
if (m_abortOption == AO_IgnoreError && theError.code != 0){
|
||||
/**
|
||||
* There's always a TCKEYCONF when using IgnoreError
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
// We sent the transaction with Commit flag set and received a CONF with
|
||||
// no Commit flag set. This is clearly an anomaly.
|
||||
|
@ -1980,13 +1941,6 @@ NdbTransaction::receiveTCINDXCONF(const TcIndxConf * indxConf,
|
|||
} else if ((tNoComp >= tNoSent) &&
|
||||
(theLastExecOpInList->theCommitIndicator == 1)){
|
||||
|
||||
if (m_abortOption == AO_IgnoreError && theError.code != 0){
|
||||
/**
|
||||
* There's always a TCKEYCONF when using IgnoreError
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
// We sent the transaction with Commit flag set and received a CONF with
|
||||
// no Commit flag set. This is clearly an anomaly.
|
||||
|
@ -2010,41 +1964,6 @@ NdbTransaction::receiveTCINDXCONF(const TcIndxConf * indxConf,
|
|||
return -1;
|
||||
}//NdbTransaction::receiveTCINDXCONF()
|
||||
|
||||
/*****************************************************************************
|
||||
int receiveTCINDXREF( NdbApiSignal* aSignal)
|
||||
|
||||
Return Value: Return 0 : send was succesful.
|
||||
Return -1: In all other case.
|
||||
Parameters: aSignal: the signal object that contains the
|
||||
TCINDXREF signal from TC.
|
||||
Remark: Handles the reception of the TCINDXREF signal.
|
||||
*****************************************************************************/
|
||||
int
|
||||
NdbTransaction::receiveTCINDXREF( NdbApiSignal* aSignal)
|
||||
{
|
||||
if(checkState_TransId(aSignal->getDataPtr()+1)){
|
||||
theError.code = aSignal->readData(4); // Override any previous errors
|
||||
|
||||
/**********************************************************************/
|
||||
/* A serious error has occured. This could be due to deadlock or */
|
||||
/* lack of resources or simply a programming error in NDB. This */
|
||||
/* transaction will be aborted. Actually it has already been */
|
||||
/* and we only need to report completion and return with the */
|
||||
/* error code to the application. */
|
||||
/**********************************************************************/
|
||||
theCompletionStatus = NdbTransaction::CompletedFailure;
|
||||
theCommitStatus = NdbTransaction::Aborted;
|
||||
theReturnStatus = NdbTransaction::ReturnFailure;
|
||||
return 0;
|
||||
} else {
|
||||
#ifdef NDB_NO_DROPPED_SIGNAL
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
return -1;
|
||||
}//NdbTransaction::receiveTCINDXREF()
|
||||
|
||||
/*******************************************************************************
|
||||
int OpCompletedFailure();
|
||||
|
||||
|
@ -2054,36 +1973,15 @@ Parameters: aErrorCode: The error code.
|
|||
Remark: An operation was completed with failure.
|
||||
*******************************************************************************/
|
||||
int
|
||||
NdbTransaction::OpCompleteFailure(Uint8 abortOption, bool setFailure)
|
||||
NdbTransaction::OpCompleteFailure(NdbOperation* op)
|
||||
{
|
||||
Uint32 tNoComp = theNoOfOpCompleted;
|
||||
Uint32 tNoSent = theNoOfOpSent;
|
||||
if (setFailure)
|
||||
theCompletionStatus = NdbTransaction::CompletedFailure;
|
||||
|
||||
tNoComp++;
|
||||
theNoOfOpCompleted = tNoComp;
|
||||
if (tNoComp == tNoSent) {
|
||||
//------------------------------------------------------------------------
|
||||
//If the transaction consists of only simple reads we can set
|
||||
//Commit state Aborted. Otherwise this simple operation cannot
|
||||
//decide the success of the whole transaction since a simple
|
||||
//operation is not really part of that transaction.
|
||||
//------------------------------------------------------------------------
|
||||
if (abortOption == AO_IgnoreError){
|
||||
/**
|
||||
* There's always a TCKEYCONF when using IgnoreError
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0; // Last operation received
|
||||
} else if (tNoComp > tNoSent) {
|
||||
setOperationErrorCodeAbort(4113); // Too many operations,
|
||||
// stop waiting for more
|
||||
return 0;
|
||||
} else {
|
||||
return -1; // Continue waiting for more signals
|
||||
}//if
|
||||
|
||||
return (tNoComp == tNoSent) ? 0 : -1;
|
||||
}//NdbTransaction::OpCompleteFailure()
|
||||
|
||||
/******************************************************************************
|
||||
|
|
|
@ -1403,7 +1403,7 @@ int PollGuard::wait_for_input_in_loop(int wait_time, bool forceSend)
|
|||
}
|
||||
if (wait_time == -1)
|
||||
{
|
||||
#ifdef VM_TRACE
|
||||
#ifdef NOT_USED
|
||||
ndbout << "Waited WAITFOR_RESPONSE_TIMEOUT, continuing wait" << endl;
|
||||
#endif
|
||||
continue;
|
||||
|
|
|
@ -106,8 +106,8 @@ public:
|
|||
|
||||
NDBT_ResultRow& get_row(Uint32 idx) { return *rows[idx];}
|
||||
|
||||
int execute_async(Ndb*, NdbTransaction::ExecType, NdbTransaction::AbortOption = NdbTransaction::AbortOnError);
|
||||
int execute_async_prepare(Ndb*, NdbTransaction::ExecType, NdbTransaction::AbortOption = NdbTransaction::AbortOnError);
|
||||
int execute_async(Ndb*, NdbTransaction::ExecType, NdbOperation::AbortOption = NdbOperation::AbortOnError);
|
||||
int execute_async_prepare(Ndb*, NdbTransaction::ExecType, NdbOperation::AbortOption = NdbOperation::AbortOnError);
|
||||
|
||||
int wait_async(Ndb*, int timeout = -1);
|
||||
|
||||
|
|
|
@ -1272,6 +1272,52 @@ runBug25090(NDBT_Context* ctx, NDBT_Step* step){
|
|||
return NDBT_OK;
|
||||
}
|
||||
|
||||
int
|
||||
runDeleteRead(NDBT_Context* ctx, NDBT_Step* step){
|
||||
|
||||
Ndb* pNdb = GETNDB(step);
|
||||
|
||||
const NdbDictionary::Table* tab = ctx->getTab();
|
||||
NDBT_ResultRow row(*ctx->getTab());
|
||||
HugoTransactions tmp(*ctx->getTab());
|
||||
|
||||
int a;
|
||||
int loops = ctx->getNumLoops();
|
||||
const int rows = ctx->getNumRecords();
|
||||
|
||||
while (loops--)
|
||||
{
|
||||
NdbTransaction* pTrans = pNdb->startTransaction();
|
||||
NdbOperation* pOp = pTrans->getNdbOperation(tab->getName());
|
||||
pOp->deleteTuple();
|
||||
for(a = 0; a<tab->getNoOfColumns(); a++)
|
||||
{
|
||||
if (tab->getColumn(a)->getPrimaryKey() == true)
|
||||
{
|
||||
if(tmp.equalForAttr(pOp, a, 0) != 0)
|
||||
{
|
||||
ERR(pTrans->getNdbError());
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Define attributes to read
|
||||
for(a = 0; a<tab->getNoOfColumns(); a++)
|
||||
{
|
||||
if((row.attributeStore(a) = pOp->getValue(tab->getColumn(a)->getName())) == 0) {
|
||||
ERR(pTrans->getNdbError());
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
pTrans->execute(Commit);
|
||||
pTrans->close();
|
||||
}
|
||||
|
||||
return NDBT_OK;
|
||||
}
|
||||
|
||||
NDBT_TESTSUITE(testBasic);
|
||||
TESTCASE("PkInsert",
|
||||
"Verify that we can insert and delete from this table using PK"
|
||||
|
@ -1542,6 +1588,12 @@ TESTCASE("Bug25090",
|
|||
"Verify what happens when we fill the db" ){
|
||||
STEP(runBug25090);
|
||||
}
|
||||
TESTCASE("DeleteRead",
|
||||
"Verify Delete+Read" ){
|
||||
INITIALIZER(runLoadTable);
|
||||
INITIALIZER(runDeleteRead);
|
||||
FINALIZER(runClearTable2);
|
||||
}
|
||||
NDBT_TESTSUITE_END(testBasic);
|
||||
|
||||
#if 0
|
||||
|
|
|
@ -734,7 +734,7 @@ verifyHeadInline(const Tup& tup)
|
|||
if (! g_opt.m_oneblob)
|
||||
CHK((ra2 = g_opr->getValue("BL2")) != 0);
|
||||
if (tup.m_exists) {
|
||||
CHK(g_con->execute(Commit) == 0);
|
||||
CHK(g_con->execute(Commit, AbortOnError) == 0);
|
||||
DBG("verifyHeadInline BL1");
|
||||
CHK(verifyHeadInline(g_opt.m_blob1, tup.m_blob1, ra1) == 0);
|
||||
if (! g_opt.m_oneblob) {
|
||||
|
@ -742,7 +742,8 @@ verifyHeadInline(const Tup& tup)
|
|||
CHK(verifyHeadInline(g_opt.m_blob2, tup.m_blob2, ra2) == 0);
|
||||
}
|
||||
} else {
|
||||
CHK(g_con->execute(Commit) == -1 && g_con->getNdbError().code == 626);
|
||||
CHK(g_con->execute(Commit, AbortOnError) == -1 &&
|
||||
g_con->getNdbError().code == 626);
|
||||
}
|
||||
g_ndb->closeTransaction(g_con);
|
||||
g_opr = 0;
|
||||
|
@ -1534,7 +1535,7 @@ testperf()
|
|||
g_dic = g_ndb->getDictionary();
|
||||
NdbDictionary::Table tab(g_opt.m_tnameperf);
|
||||
if (g_dic->getTable(tab.getName()) != 0)
|
||||
CHK(g_dic->dropTable(tab) == 0);
|
||||
CHK(g_dic->dropTable(tab.getName()) == 0);
|
||||
// col A - pk
|
||||
{ NdbDictionary::Column col("A");
|
||||
col.setType(NdbDictionary::Column::Unsigned);
|
||||
|
|
|
@ -1249,6 +1249,274 @@ int runScan_4006(NDBT_Context* ctx, NDBT_Step* step){
|
|||
return result;
|
||||
}
|
||||
|
||||
char pkIdxName[255];
|
||||
|
||||
int createPkIndex(NDBT_Context* ctx, NDBT_Step* step){
|
||||
bool orderedIndex = ctx->getProperty("OrderedIndex", (unsigned)0);
|
||||
|
||||
const NdbDictionary::Table* pTab = ctx->getTab();
|
||||
Ndb* pNdb = GETNDB(step);
|
||||
|
||||
bool logged = ctx->getProperty("LoggedIndexes", 1);
|
||||
|
||||
// Create index
|
||||
BaseString::snprintf(pkIdxName, 255, "IDC_PK_%s", pTab->getName());
|
||||
if (orderedIndex)
|
||||
ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "ordered index "
|
||||
<< pkIdxName << " (";
|
||||
else
|
||||
ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "unique index "
|
||||
<< pkIdxName << " (";
|
||||
|
||||
NdbDictionary::Index pIdx(pkIdxName);
|
||||
pIdx.setTable(pTab->getName());
|
||||
if (orderedIndex)
|
||||
pIdx.setType(NdbDictionary::Index::OrderedIndex);
|
||||
else
|
||||
pIdx.setType(NdbDictionary::Index::UniqueHashIndex);
|
||||
for (int c = 0; c< pTab->getNoOfColumns(); c++){
|
||||
const NdbDictionary::Column * col = pTab->getColumn(c);
|
||||
if(col->getPrimaryKey()){
|
||||
pIdx.addIndexColumn(col->getName());
|
||||
ndbout << col->getName() <<" ";
|
||||
}
|
||||
}
|
||||
|
||||
pIdx.setStoredIndex(logged);
|
||||
ndbout << ") ";
|
||||
if (pNdb->getDictionary()->createIndex(pIdx) != 0){
|
||||
ndbout << "FAILED!" << endl;
|
||||
const NdbError err = pNdb->getDictionary()->getNdbError();
|
||||
ERR(err);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
ndbout << "OK!" << endl;
|
||||
return NDBT_OK;
|
||||
}
|
||||
|
||||
int createPkIndex_Drop(NDBT_Context* ctx, NDBT_Step* step){
|
||||
const NdbDictionary::Table* pTab = ctx->getTab();
|
||||
Ndb* pNdb = GETNDB(step);
|
||||
|
||||
// Drop index
|
||||
ndbout << "Dropping index " << pkIdxName << " ";
|
||||
if (pNdb->getDictionary()->dropIndex(pkIdxName,
|
||||
pTab->getName()) != 0){
|
||||
ndbout << "FAILED!" << endl;
|
||||
ERR(pNdb->getDictionary()->getNdbError());
|
||||
return NDBT_FAILED;
|
||||
} else {
|
||||
ndbout << "OK!" << endl;
|
||||
}
|
||||
|
||||
return NDBT_OK;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
op_row(NdbTransaction* pTrans, HugoOperations& hugoOps,
|
||||
const NdbDictionary::Table* pTab, int op, int row)
|
||||
{
|
||||
NdbOperation * pOp = 0;
|
||||
switch(op){
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
pOp = pTrans->getNdbOperation(pTab->getName());
|
||||
break;
|
||||
case 9:
|
||||
return 0;
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
case 10:
|
||||
case 11:
|
||||
pOp = pTrans->getNdbIndexOperation(pkIdxName, pTab->getName());
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch(op){
|
||||
case 0:
|
||||
case 6:
|
||||
pOp->readTuple();
|
||||
break;
|
||||
case 1:
|
||||
case 7:
|
||||
pOp->committedRead();
|
||||
break;
|
||||
case 2:
|
||||
case 8:
|
||||
pOp->readTupleExclusive();
|
||||
break;
|
||||
case 3:
|
||||
case 9:
|
||||
pOp->insertTuple();
|
||||
break;
|
||||
case 4:
|
||||
case 10:
|
||||
pOp->updateTuple();
|
||||
break;
|
||||
case 5:
|
||||
case 11:
|
||||
pOp->deleteTuple();
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
for(int a = 0; a<pTab->getNoOfColumns(); a++){
|
||||
if (pTab->getColumn(a)->getPrimaryKey() == true){
|
||||
if(hugoOps.equalForAttr(pOp, a, row) != 0){
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch(op){
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
for(int a = 0; a<pTab->getNoOfColumns(); a++){
|
||||
pOp->getValue(a);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
case 10:
|
||||
for(int a = 0; a<pTab->getNoOfColumns(); a++){
|
||||
if (pTab->getColumn(a)->getPrimaryKey() == false){
|
||||
if(hugoOps.setValueForAttr(pOp, a, row, 2) != 0){
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
case 11:
|
||||
pOp->deleteTuple();
|
||||
break;
|
||||
case 9:
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
return NDBT_OK;
|
||||
}
|
||||
|
||||
static void print(int op)
|
||||
{
|
||||
const char * str = 0;
|
||||
switch(op){
|
||||
case 0: str = "pk read-sh"; break;
|
||||
case 1: str = "pk read-nl"; break;
|
||||
case 2: str = "pk read-ex"; break;
|
||||
case 3: str = "pk insert "; break;
|
||||
case 4: str = "pk update "; break;
|
||||
case 5: str = "pk delete "; break;
|
||||
case 6: str = "uk read-sh"; break;
|
||||
case 7: str = "uk read-nl"; break;
|
||||
case 8: str = "uk read-ex"; break;
|
||||
case 9: str = "noop "; break;
|
||||
case 10: str = "uk update "; break;
|
||||
case 11: str = "uk delete "; break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
printf("%s ", str);
|
||||
}
|
||||
|
||||
int
|
||||
runTestIgnoreError(NDBT_Context* ctx, NDBT_Step* step)
|
||||
{
|
||||
int result = NDBT_OK;
|
||||
Uint32 loops = ctx->getNumRecords();
|
||||
const NdbDictionary::Table* pTab = ctx->getTab();
|
||||
|
||||
HugoOperations hugoOps(*pTab);
|
||||
HugoTransactions hugoTrans(*pTab);
|
||||
|
||||
Ndb* pNdb = GETNDB(step);
|
||||
|
||||
struct {
|
||||
ExecType et;
|
||||
AbortOption ao;
|
||||
} tests[] = {
|
||||
{ Commit, AbortOnError },
|
||||
{ Commit, AO_IgnoreError },
|
||||
{ NoCommit, AbortOnError },
|
||||
{ NoCommit, AO_IgnoreError },
|
||||
};
|
||||
|
||||
printf("case: <op1> <op2> c/nc ao/ie\n");
|
||||
Uint32 tno = 0;
|
||||
for (Uint32 op1 = 0; op1 < 12; op1++)
|
||||
{
|
||||
for (Uint32 op2 = op1; op2 < 12; op2++)
|
||||
{
|
||||
int ret;
|
||||
NdbTransaction* pTrans = 0;
|
||||
|
||||
for (Uint32 i = 0; i<4; i++, tno++)
|
||||
{
|
||||
if (loops != 1000 && loops != tno)
|
||||
continue;
|
||||
ExecType et = tests[i].et;
|
||||
AbortOption ao = tests[i].ao;
|
||||
|
||||
printf("%.3d : ", tno);
|
||||
print(op1);
|
||||
print(op2);
|
||||
switch(et){
|
||||
case Commit: printf("c "); break;
|
||||
case NoCommit: printf("nc "); break;
|
||||
}
|
||||
switch(ao){
|
||||
case AbortOnError: printf("aoe "); break;
|
||||
case AO_IgnoreError: printf("ie "); break;
|
||||
}
|
||||
printf(": ");
|
||||
|
||||
|
||||
hugoTrans.loadTable(pNdb, 1);
|
||||
pTrans = pNdb->startTransaction();
|
||||
op_row(pTrans, hugoOps, pTab, op1, 0);
|
||||
ret = pTrans->execute(et, ao);
|
||||
pTrans->close();
|
||||
printf("%d ", ret);
|
||||
hugoTrans.clearTable(pNdb);
|
||||
|
||||
hugoTrans.loadTable(pNdb, 1);
|
||||
pTrans = pNdb->startTransaction();
|
||||
op_row(pTrans, hugoOps, pTab, op1, 1);
|
||||
ret = pTrans->execute(et, ao);
|
||||
pTrans->close();
|
||||
printf("%d ", ret);
|
||||
hugoTrans.clearTable(pNdb);
|
||||
|
||||
hugoTrans.loadTable(pNdb, 1);
|
||||
pTrans = pNdb->startTransaction();
|
||||
op_row(pTrans, hugoOps, pTab, op1, 0);
|
||||
op_row(pTrans, hugoOps, pTab, op2, 1);
|
||||
ret = pTrans->execute(et, ao);
|
||||
pTrans->close();
|
||||
printf("%d\n", ret);
|
||||
hugoTrans.clearTable(pNdb);
|
||||
|
||||
hugoTrans.clearTable(pNdb);
|
||||
}
|
||||
}
|
||||
}
|
||||
return NDBT_OK;
|
||||
}
|
||||
|
||||
template class Vector<NdbScanOperation*>;
|
||||
|
||||
|
||||
|
@ -1342,6 +1610,12 @@ TESTCASE("Scan_4006",
|
|||
INITIALIZER(runScan_4006);
|
||||
FINALIZER(runClearTable);
|
||||
}
|
||||
TESTCASE("IgnoreError", ""){
|
||||
INITIALIZER(createPkIndex);
|
||||
STEP(runTestIgnoreError);
|
||||
FINALIZER(runClearTable);
|
||||
FINALIZER(createPkIndex_Drop);
|
||||
}
|
||||
NDBT_TESTSUITE_END(testNdbApi);
|
||||
|
||||
int main(int argc, const char** argv){
|
||||
|
|
|
@ -1178,6 +1178,101 @@ int runBug25554(NDBT_Context* ctx, NDBT_Step* step){
|
|||
return NDBT_OK;
|
||||
}
|
||||
|
||||
int runBug25984(NDBT_Context* ctx, NDBT_Step* step){
|
||||
|
||||
int result = NDBT_OK;
|
||||
int loops = ctx->getNumLoops();
|
||||
int records = ctx->getNumRecords();
|
||||
NdbRestarter restarter;
|
||||
|
||||
if (restarter.getNumDbNodes() < 2)
|
||||
return NDBT_OK;
|
||||
|
||||
if (restarter.restartAll(true, true, true))
|
||||
return NDBT_FAILED;
|
||||
|
||||
if (restarter.waitClusterNoStart())
|
||||
return NDBT_FAILED;
|
||||
|
||||
if (restarter.startAll())
|
||||
return NDBT_FAILED;
|
||||
|
||||
if (restarter.waitClusterStarted())
|
||||
return NDBT_FAILED;
|
||||
|
||||
int val2[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 1 };
|
||||
int master = restarter.getMasterNodeId();
|
||||
int victim = restarter.getRandomNodeOtherNodeGroup(master, rand());
|
||||
if (victim == -1)
|
||||
victim = restarter.getRandomNodeSameNodeGroup(master, rand());
|
||||
|
||||
restarter.restartOneDbNode(victim, false, true, true);
|
||||
|
||||
for (Uint32 i = 0; i<6; i++)
|
||||
{
|
||||
ndbout_c("Loop: %d", i);
|
||||
if (restarter.waitNodesNoStart(&victim, 1))
|
||||
return NDBT_FAILED;
|
||||
|
||||
if (restarter.dumpStateOneNode(victim, val2, 2))
|
||||
return NDBT_FAILED;
|
||||
|
||||
if (restarter.insertErrorInNode(victim, 7016))
|
||||
return NDBT_FAILED;
|
||||
|
||||
if (restarter.startNodes(&victim, 1))
|
||||
return NDBT_FAILED;
|
||||
|
||||
if (restarter.waitNodesStartPhase(&victim, 1, 2))
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
if (restarter.waitNodesNoStart(&victim, 1))
|
||||
return NDBT_FAILED;
|
||||
|
||||
if (restarter.dumpStateOneNode(victim, val2, 2))
|
||||
return NDBT_FAILED;
|
||||
|
||||
if (restarter.insertErrorInNode(victim, 7170))
|
||||
return NDBT_FAILED;
|
||||
|
||||
if (restarter.startNodes(&victim, 1))
|
||||
return NDBT_FAILED;
|
||||
|
||||
if (restarter.waitNodesNoStart(&victim, 1))
|
||||
return NDBT_FAILED;
|
||||
|
||||
if (restarter.restartAll(false, true, true))
|
||||
return NDBT_FAILED;
|
||||
|
||||
if (restarter.insertErrorInAllNodes(932))
|
||||
return NDBT_FAILED;
|
||||
|
||||
if (restarter.insertErrorInNode(master, 7170))
|
||||
return NDBT_FAILED;
|
||||
|
||||
if (restarter.dumpStateAllNodes(val2, 2))
|
||||
return NDBT_FAILED;
|
||||
|
||||
restarter.startNodes(&master, 1);
|
||||
NdbSleep_MilliSleep(3000);
|
||||
restarter.startAll();
|
||||
|
||||
if (restarter.waitClusterNoStart())
|
||||
return NDBT_FAILED;
|
||||
|
||||
if (restarter.restartOneDbNode(victim, true, true, true))
|
||||
return NDBT_FAILED;
|
||||
|
||||
if (restarter.startAll())
|
||||
return NDBT_FAILED;
|
||||
|
||||
if (restarter.waitClusterStarted())
|
||||
return NDBT_FAILED;
|
||||
|
||||
return NDBT_OK;
|
||||
}
|
||||
|
||||
|
||||
NDBT_TESTSUITE(testNodeRestart);
|
||||
TESTCASE("NoLoad",
|
||||
|
@ -1514,6 +1609,9 @@ TESTCASE("Bug25468", ""){
|
|||
TESTCASE("Bug25554", ""){
|
||||
INITIALIZER(runBug25554);
|
||||
}
|
||||
TESTCASE("Bug25984", ""){
|
||||
INITIALIZER(runBug25984);
|
||||
}
|
||||
NDBT_TESTSUITE_END(testNodeRestart);
|
||||
|
||||
int main(int argc, const char** argv){
|
||||
|
|
|
@ -79,6 +79,10 @@ max-time: 660
|
|||
cmd: testBasic
|
||||
args: -n UpdateAndRead
|
||||
|
||||
max-time: 500
|
||||
cmd: testBasic
|
||||
args: -n DeleteRead
|
||||
|
||||
max-time: 500
|
||||
cmd: testBasic
|
||||
args: -n PkReadAndLocker T6 D1 D2
|
||||
|
@ -461,7 +465,7 @@ max-time: 500
|
|||
cmd: testScan
|
||||
args: -n Bug24447 T1
|
||||
|
||||
max-time: 500
|
||||
max-time: 1000
|
||||
cmd: testScan
|
||||
args: -n ScanVariants
|
||||
|
||||
|
@ -521,6 +525,10 @@ max-time: 1000
|
|||
cmd: testNodeRestart
|
||||
args: -n Bug25554 T1
|
||||
|
||||
max-time: 1000
|
||||
cmd: testNodeRestart
|
||||
args: -n Bug25984
|
||||
|
||||
#
|
||||
# DICT TESTS
|
||||
max-time: 1500
|
||||
|
|
|
@ -457,7 +457,7 @@ HugoOperations::callback(int res, NdbTransaction* pCon)
|
|||
|
||||
int
|
||||
HugoOperations::execute_async(Ndb* pNdb, NdbTransaction::ExecType et,
|
||||
NdbTransaction::AbortOption eao){
|
||||
NdbOperation::AbortOption eao){
|
||||
|
||||
m_async_reply= 0;
|
||||
pTrans->executeAsynchPrepare(et,
|
||||
|
@ -472,7 +472,7 @@ HugoOperations::execute_async(Ndb* pNdb, NdbTransaction::ExecType et,
|
|||
|
||||
int
|
||||
HugoOperations::execute_async_prepare(Ndb* pNdb, NdbTransaction::ExecType et,
|
||||
NdbTransaction::AbortOption eao){
|
||||
NdbOperation::AbortOption eao){
|
||||
|
||||
m_async_reply= 0;
|
||||
pTrans->executeAsynchPrepare(et,
|
||||
|
|
|
@ -94,7 +94,7 @@ HugoTransactions::scanReadRecords(Ndb* pNdb,
|
|||
}
|
||||
}
|
||||
|
||||
check = pTrans->execute(NoCommit);
|
||||
check = pTrans->execute(NoCommit, AbortOnError);
|
||||
if( check == -1 ) {
|
||||
const NdbError err = pTrans->getNdbError();
|
||||
if (err.status == NdbError::TemporaryError){
|
||||
|
@ -245,7 +245,7 @@ HugoTransactions::scanReadRecords(Ndb* pNdb,
|
|||
}
|
||||
}
|
||||
|
||||
check = pTrans->execute(NoCommit);
|
||||
check = pTrans->execute(NoCommit, AbortOnError);
|
||||
if( check == -1 ) {
|
||||
const NdbError err = pTrans->getNdbError();
|
||||
if (err.status == NdbError::TemporaryError){
|
||||
|
@ -421,7 +421,7 @@ restart:
|
|||
}
|
||||
}
|
||||
|
||||
check = pTrans->execute(NoCommit);
|
||||
check = pTrans->execute(NoCommit, AbortOnError);
|
||||
if( check == -1 ) {
|
||||
const NdbError err = pTrans->getNdbError();
|
||||
ERR(err);
|
||||
|
@ -474,7 +474,7 @@ restart:
|
|||
} while((check = pOp->nextResult(false)) == 0);
|
||||
|
||||
if(check != -1){
|
||||
check = pTrans->execute(Commit);
|
||||
check = pTrans->execute(Commit, AbortOnError);
|
||||
if(check != -1)
|
||||
m_latest_gci = pTrans->getGCI();
|
||||
pTrans->restart();
|
||||
|
@ -587,14 +587,14 @@ HugoTransactions::loadTable(Ndb* pNdb,
|
|||
closeTrans = false;
|
||||
if (!abort)
|
||||
{
|
||||
check = pTrans->execute( Commit );
|
||||
check = pTrans->execute(Commit, AbortOnError);
|
||||
if(check != -1)
|
||||
m_latest_gci = pTrans->getGCI();
|
||||
pTrans->restart();
|
||||
}
|
||||
else
|
||||
{
|
||||
check = pTrans->execute( NoCommit );
|
||||
check = pTrans->execute(NoCommit, AbortOnError);
|
||||
if (check != -1)
|
||||
{
|
||||
check = pTrans->execute( Rollback );
|
||||
|
@ -603,7 +603,7 @@ HugoTransactions::loadTable(Ndb* pNdb,
|
|||
}
|
||||
} else {
|
||||
closeTrans = false;
|
||||
check = pTrans->execute( NoCommit );
|
||||
check = pTrans->execute(NoCommit, AbortOnError);
|
||||
}
|
||||
if(check == -1 ) {
|
||||
const NdbError err = pTrans->getNdbError();
|
||||
|
@ -717,7 +717,7 @@ HugoTransactions::fillTable(Ndb* pNdb,
|
|||
}
|
||||
|
||||
// Execute the transaction and insert the record
|
||||
check = pTrans->execute( Commit, CommitAsMuchAsPossible );
|
||||
check = pTrans->execute(Commit, CommitAsMuchAsPossible);
|
||||
if(check == -1 ) {
|
||||
const NdbError err = pTrans->getNdbError();
|
||||
closeTransaction(pNdb);
|
||||
|
@ -829,7 +829,7 @@ HugoTransactions::pkReadRecords(Ndb* pNdb,
|
|||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
check = pTrans->execute(Commit);
|
||||
check = pTrans->execute(Commit, AbortOnError);
|
||||
if( check == -1 ) {
|
||||
const NdbError err = pTrans->getNdbError();
|
||||
|
||||
|
@ -950,7 +950,7 @@ HugoTransactions::pkUpdateRecords(Ndb* pNdb,
|
|||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
check = pTrans->execute(NoCommit);
|
||||
check = pTrans->execute(NoCommit, AbortOnError);
|
||||
if( check == -1 ) {
|
||||
const NdbError err = pTrans->getNdbError();
|
||||
|
||||
|
@ -991,7 +991,7 @@ HugoTransactions::pkUpdateRecords(Ndb* pNdb,
|
|||
|
||||
if(check != 2)
|
||||
break;
|
||||
if((check = pTrans->execute(NoCommit)) != 0)
|
||||
if((check = pTrans->execute(NoCommit, AbortOnError)) != 0)
|
||||
break;
|
||||
}
|
||||
if(check != 1 || rows_found != batch)
|
||||
|
@ -1019,7 +1019,7 @@ HugoTransactions::pkUpdateRecords(Ndb* pNdb,
|
|||
return NDBT_FAILED;
|
||||
}
|
||||
}
|
||||
check = pTrans->execute(Commit);
|
||||
check = pTrans->execute(Commit, AbortOnError);
|
||||
}
|
||||
if( check == -1 ) {
|
||||
const NdbError err = pTrans->getNdbError();
|
||||
|
@ -1119,7 +1119,7 @@ HugoTransactions::pkInterpretedUpdateRecords(Ndb* pNdb,
|
|||
}
|
||||
}
|
||||
|
||||
check = pTrans->execute(NoCommit);
|
||||
check = pTrans->execute(NoCommit, AbortOnError);
|
||||
if( check == -1 ) {
|
||||
const NdbError err = pTrans->getNdbError();
|
||||
|
||||
|
@ -1194,7 +1194,7 @@ HugoTransactions::pkInterpretedUpdateRecords(Ndb* pNdb,
|
|||
|
||||
|
||||
|
||||
check = pTrans->execute(Commit);
|
||||
check = pTrans->execute(Commit, AbortOnError);
|
||||
if( check == -1 ) {
|
||||
const NdbError err = pTrans->getNdbError();
|
||||
|
||||
|
@ -1274,7 +1274,7 @@ HugoTransactions::pkDelRecords(Ndb* pNdb,
|
|||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
check = pTrans->execute(Commit);
|
||||
check = pTrans->execute(Commit, AbortOnError);
|
||||
if( check == -1) {
|
||||
const NdbError err = pTrans->getNdbError();
|
||||
|
||||
|
@ -1387,7 +1387,7 @@ HugoTransactions::lockRecords(Ndb* pNdb,
|
|||
int lockCount = lockTime / sleepInterval;
|
||||
int commitCount = 0;
|
||||
do {
|
||||
check = pTrans->execute(NoCommit);
|
||||
check = pTrans->execute(NoCommit, AbortOnError);
|
||||
if( check == -1) {
|
||||
const NdbError err = pTrans->getNdbError();
|
||||
|
||||
|
@ -1413,7 +1413,7 @@ HugoTransactions::lockRecords(Ndb* pNdb,
|
|||
} while (commitCount < lockCount);
|
||||
|
||||
// Really commit the trans, puuh!
|
||||
check = pTrans->execute(Commit);
|
||||
check = pTrans->execute(Commit, AbortOnError);
|
||||
if( check == -1) {
|
||||
const NdbError err = pTrans->getNdbError();
|
||||
|
||||
|
@ -1543,7 +1543,7 @@ HugoTransactions::indexReadRecords(Ndb* pNdb,
|
|||
}
|
||||
}
|
||||
|
||||
check = pTrans->execute(Commit);
|
||||
check = pTrans->execute(Commit, AbortOnError);
|
||||
check = (check == -1 ? -1 : !ordered ? check : sOp->nextResult(true));
|
||||
if( check == -1 ) {
|
||||
const NdbError err = pTrans->getNdbError();
|
||||
|
@ -1684,7 +1684,7 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb,
|
|||
}
|
||||
}
|
||||
|
||||
check = pTrans->execute(NoCommit);
|
||||
check = pTrans->execute(NoCommit, AbortOnError);
|
||||
check = (check == -1 ? -1 : !ordered ? check : sOp->nextResult(true));
|
||||
if( check == -1 ) {
|
||||
const NdbError err = pTrans->getNdbError();
|
||||
|
@ -1756,7 +1756,7 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb,
|
|||
}
|
||||
}
|
||||
|
||||
check = pTrans->execute(Commit);
|
||||
check = pTrans->execute(Commit, AbortOnError);
|
||||
if( check == -1 ) {
|
||||
const NdbError err = pTrans->getNdbError();
|
||||
ERR(err);
|
||||
|
|
|
@ -121,7 +121,7 @@ UtilTransactions::clearTable3(Ndb* pNdb,
|
|||
goto failed;
|
||||
}
|
||||
|
||||
if(pTrans->execute(NoCommit) != 0){
|
||||
if(pTrans->execute(NoCommit, AbortOnError) != 0){
|
||||
err = pTrans->getNdbError();
|
||||
if(err.status == NdbError::TemporaryError){
|
||||
ERR(err);
|
||||
|
@ -141,7 +141,7 @@ UtilTransactions::clearTable3(Ndb* pNdb,
|
|||
} while((check = pOp->nextResult(false)) == 0);
|
||||
|
||||
if(check != -1){
|
||||
check = pTrans->execute(Commit);
|
||||
check = pTrans->execute(Commit, AbortOnError);
|
||||
pTrans->restart();
|
||||
}
|
||||
|
||||
|
@ -245,7 +245,7 @@ UtilTransactions::copyTableData(Ndb* pNdb,
|
|||
}
|
||||
}
|
||||
|
||||
check = pTrans->execute(NoCommit);
|
||||
check = pTrans->execute(NoCommit, AbortOnError);
|
||||
if( check == -1 ) {
|
||||
ERR(pTrans->getNdbError());
|
||||
closeTransaction(pNdb);
|
||||
|
@ -262,7 +262,7 @@ UtilTransactions::copyTableData(Ndb* pNdb,
|
|||
}
|
||||
} while((eof = pOp->nextResult(false)) == 0);
|
||||
|
||||
check = pTrans->execute(Commit);
|
||||
check = pTrans->execute(Commit, AbortOnError);
|
||||
pTrans->restart();
|
||||
if( check == -1 ) {
|
||||
const NdbError err = pTrans->getNdbError();
|
||||
|
@ -414,7 +414,7 @@ UtilTransactions::scanReadRecords(Ndb* pNdb,
|
|||
}
|
||||
// *************************************************
|
||||
|
||||
check = pTrans->execute(NoCommit);
|
||||
check = pTrans->execute(NoCommit, AbortOnError);
|
||||
if( check == -1 ) {
|
||||
const NdbError err = pTrans->getNdbError();
|
||||
|
||||
|
@ -520,7 +520,7 @@ UtilTransactions::selectCount(Ndb* pNdb,
|
|||
}
|
||||
|
||||
|
||||
check = pTrans->execute(NoCommit);
|
||||
check = pTrans->execute(NoCommit, AbortOnError);
|
||||
if( check == -1 ) {
|
||||
ERR(pTrans->getNdbError());
|
||||
closeTransaction(pNdb);
|
||||
|
@ -693,7 +693,7 @@ restart:
|
|||
}
|
||||
}
|
||||
|
||||
check = pTrans->execute(NoCommit);
|
||||
check = pTrans->execute(NoCommit, AbortOnError);
|
||||
if( check == -1 ) {
|
||||
const NdbError err = pTrans->getNdbError();
|
||||
|
||||
|
@ -956,7 +956,7 @@ UtilTransactions::readRowFromTableAndIndex(Ndb* pNdb,
|
|||
printf("\n");
|
||||
#endif
|
||||
scanTrans->refresh();
|
||||
check = pTrans1->execute(Commit);
|
||||
check = pTrans1->execute(Commit, AbortOnError);
|
||||
if( check == -1 ) {
|
||||
const NdbError err = pTrans1->getNdbError();
|
||||
|
||||
|
@ -1078,7 +1078,7 @@ UtilTransactions::verifyOrderedIndex(Ndb* pNdb,
|
|||
abort();
|
||||
}
|
||||
|
||||
check = pTrans->execute(NoCommit);
|
||||
check = pTrans->execute(NoCommit, AbortOnError);
|
||||
if( check == -1 ) {
|
||||
const NdbError err = pTrans->getNdbError();
|
||||
|
||||
|
@ -1137,7 +1137,7 @@ UtilTransactions::verifyOrderedIndex(Ndb* pNdb,
|
|||
goto error;
|
||||
}
|
||||
|
||||
check = pTrans->execute(NoCommit);
|
||||
check = pTrans->execute(NoCommit, AbortOnError);
|
||||
if(check)
|
||||
goto error;
|
||||
|
||||
|
@ -1376,7 +1376,7 @@ loop:
|
|||
}
|
||||
}
|
||||
|
||||
if( pTrans->execute(NoCommit) == -1 ) {
|
||||
if( pTrans->execute(NoCommit, AbortOnError) == -1 ) {
|
||||
ERR(err= pTrans->getNdbError());
|
||||
goto error;
|
||||
}
|
||||
|
@ -1398,7 +1398,8 @@ loop:
|
|||
ERR(err= cmp.getTransaction()->getNdbError());
|
||||
goto error;
|
||||
}
|
||||
if(cmp.execute_Commit(pNdb) != NDBT_OK)
|
||||
if(cmp.execute_Commit(pNdb) != NDBT_OK ||
|
||||
cmp.getTransaction()->getNdbError().code)
|
||||
{
|
||||
ERR(err= cmp.getTransaction()->getNdbError());
|
||||
goto error;
|
||||
|
|
|
@ -178,6 +178,9 @@ main(int argc, const char** argv){
|
|||
}
|
||||
}
|
||||
end:
|
||||
for(i= 0; i<(int)event_ops.size(); i++)
|
||||
MyNdb.dropEventOperation(event_ops[i]);
|
||||
|
||||
return NDBT_ProgramExit(NDBT_OK);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue