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:
unknown 2007-02-08 16:02:58 -07:00
commit c4fdf11e58
57 changed files with 1600 additions and 870 deletions

View file

@ -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

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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 */

View file

@ -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 */

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}

View file

@ -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]; }

View file

@ -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);
}

View file

@ -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.

View file

@ -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)

View file

@ -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);

View file

@ -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 */

View file

@ -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);

View file

@ -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>;

View file

@ -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);
}

View file

@ -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*

View file

@ -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
};

View file

@ -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,

View file

@ -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);

View file

@ -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);

View file

@ -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()
/*************************************************************************/

View file

@ -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

View file

@ -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;

View file

@ -1736,7 +1736,8 @@ private:
Operationrec* regOperPtr,
Fragrecord* regFragPtr,
Tablerec* regTabPtr,
KeyReqStruct* req_struct);
KeyReqStruct* req_struct,
bool disk);
//------------------------------------------------------------------
//------------------------------------------------------------------

View file

@ -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);

View file

@ -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

View file

@ -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. */
/*----------------------------------------------------------------------*/

View file

@ -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);

View file

@ -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,

View file

@ -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;

View file

@ -3613,6 +3613,7 @@ check_node_vs_replicas(Vector<ConfigInfo::ConfigRuleSection>&sections,
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>&sections,
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"

View file

@ -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) {

View file

@ -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

View file

@ -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;

View file

@ -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"));
}
}

View file

@ -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:

View file

@ -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)

View file

@ -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));

View file

@ -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 {

View file

@ -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()

View file

@ -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

View file

@ -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()
/******************************************************************************

View file

@ -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;

View file

@ -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);

View file

@ -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

View file

@ -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);

View file

@ -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){

View file

@ -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){

View file

@ -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

View file

@ -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,

View file

@ -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);

View file

@ -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;

View file

@ -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);
}