Merge kahlann.erinye.com:/home/df/mysql/build/mysql-5.0

into  kahlann.erinye.com:/home/df/mysql/build/mysql-5.0-build-work
This commit is contained in:
df@kahlann.erinye.com 2007-01-24 09:24:52 +01:00
commit cb6c5f7ee7
35 changed files with 639 additions and 171 deletions

View file

@ -749,3 +749,19 @@ f1 f2 f3
222222 bbbbbb 2 222222 bbbbbb 2
drop table t1; drop table t1;
Illegal ndb error code: 1186 Illegal ndb error code: 1186
CREATE TABLE t1 (
a VARBINARY(40) NOT NULL,
b VARCHAR (256) CHARACTER SET UTF8 NOT NULL,
c VARCHAR(256) CHARACTER SET UTF8 NOT NULL,
PRIMARY KEY (b,c)) ENGINE=ndbcluster;
INSERT INTO t1 VALUES
("a","ab","abc"),("b","abc","abcd"),("c","abc","ab"),("d","ab","ab"),("e","abc","abc");
SELECT * FROM t1 ORDER BY a;
a b c
a ab abc
b abc abcd
c abc ab
d ab ab
e abc abc
DROP TABLE t1;
End of 5.0 tests

View file

@ -658,3 +658,11 @@ insert into t1 (a, c) values (1,'aaa'),(3,'bbb');
select count(*) from t1 where c<'bbb'; select count(*) from t1 where c<'bbb';
count(*) count(*)
1 1
create table nationaldish (DishID int(10) unsigned NOT NULL AUTO_INCREMENT,
CountryCode char(3) NOT NULL,
DishTitle varchar(64) NOT NULL,
calories smallint(5) unsigned DEFAULT NULL,
PRIMARY KEY (DishID),
INDEX i USING HASH (countrycode,calories)
) ENGINE=ndbcluster;
ERROR HY000: Can't create table './test/nationaldish.frm' (errno: 138)

View file

@ -367,3 +367,17 @@ a b c
406994 67 2006-02-27 11:26:46 406994 67 2006-02-27 11:26:46
406995 67 2006-02-28 11:55:00 406995 67 2006-02-28 11:55:00
DROP TABLE t1, t11, t12, t21, t22; DROP TABLE t1, t11, t12, t21, t22;
CREATE TABLE t1 (id varchar(255) NOT NULL,
tag int(11) NOT NULL,
doc text NOT NULL,
type varchar(150) NOT NULL,
modified timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
) ENGINE=ndbcluster;
INSERT INTO t1 VALUES ('sakila',1,'Some text goes here','text',CURRENT_TIMESTAMP);
SELECT id, tag, doc, type FROM t1 WHERE id IN ('flipper','orka');
id tag doc type
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;

View file

@ -710,3 +710,22 @@ drop table t1;
--error 1 --error 1
--exec $MY_PERROR --ndb 1186 2>&1 --exec $MY_PERROR --ndb 1186 2>&1
#
# Bug #25746 - VARCHAR UTF8 PK issue
# - prior to bugfix 4209, illegal length parameter would be
# returned in SELECT *
CREATE TABLE t1 (
a VARBINARY(40) NOT NULL,
b VARCHAR (256) CHARACTER SET UTF8 NOT NULL,
c VARCHAR(256) CHARACTER SET UTF8 NOT NULL,
PRIMARY KEY (b,c)) ENGINE=ndbcluster;
INSERT INTO t1 VALUES
("a","ab","abc"),("b","abc","abcd"),("c","abc","ab"),("d","ab","ab"),("e","abc","abc");
SELECT * FROM t1 ORDER BY a;
DROP TABLE t1;
# End of 5.0 tests
--echo End of 5.0 tests

View file

@ -356,3 +356,15 @@ insert into t1 (a, c) values (1,'aaa'),(3,'bbb');
select count(*) from t1 where c<'bbb'; select count(*) from t1 where c<'bbb';
# End of 4.1 tests # End of 4.1 tests
# bug#24820 CREATE INDEX ....USING HASH on NDB table creates ordered index, not HASH index
--error ER_CANT_CREATE_TABLE
create table nationaldish (DishID int(10) unsigned NOT NULL AUTO_INCREMENT,
CountryCode char(3) NOT NULL,
DishTitle varchar(64) NOT NULL,
calories smallint(5) unsigned DEFAULT NULL,
PRIMARY KEY (DishID),
INDEX i USING HASH (countrycode,calories)
) ENGINE=ndbcluster;

View file

@ -238,3 +238,18 @@ select * from t12 order by 1,2,3;
select * from t21 order by 1,2,3; select * from t21 order by 1,2,3;
select * from t22 order by 1,2,3; select * from t22 order by 1,2,3;
DROP TABLE t1, t11, t12, t21, t22; DROP TABLE t1, t11, t12, t21, t22;
# bug#19956
CREATE TABLE t1 (id varchar(255) NOT NULL,
tag int(11) NOT NULL,
doc text NOT NULL,
type varchar(150) NOT NULL,
modified timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
) ENGINE=ndbcluster;
INSERT INTO t1 VALUES ('sakila',1,'Some text goes here','text',CURRENT_TIMESTAMP);
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;

View file

@ -67,6 +67,7 @@ public:
// 100-105 TUP and ACC // 100-105 TUP and ACC
// 200-240 UTIL // 200-240 UTIL
// 300-305 TRIX // 300-305 TRIX
QmgrErr935 = 935,
NdbfsDumpFileStat = 400, NdbfsDumpFileStat = 400,
NdbfsDumpAllFiles = 401, NdbfsDumpAllFiles = 401,
NdbfsDumpOpenFiles = 402, NdbfsDumpOpenFiles = 402,

View file

@ -540,6 +540,16 @@ extern "C" {
*/ */
const char *ndb_mgm_get_connectstring(NdbMgmHandle handle, char *buf, int buf_sz); const char *ndb_mgm_get_connectstring(NdbMgmHandle handle, char *buf, int buf_sz);
/**
* Sets the number of seconds to wait for connect(2) during ndb_mgm_connect
* Default is no timeout
*
* @param handle NdbMgmHandle
* @param seconds number of seconds
* @return non-zero on success
*/
int ndb_mgm_set_connect_timeout(NdbMgmHandle handle, unsigned int seconds);
/** /**
* Connects to a management server. Connectstring is set by * Connects to a management server. Connectstring is set by
* ndb_mgm_set_connectstring(). * ndb_mgm_set_connectstring().

View file

@ -65,7 +65,7 @@ void NdbMem_Free(void* ptr);
* NdbMem_MemLockAll * NdbMem_MemLockAll
* Locks virtual memory in main memory * Locks virtual memory in main memory
*/ */
int NdbMem_MemLockAll(void); int NdbMem_MemLockAll(int);
/** /**
* NdbMem_MemUnlockAll * NdbMem_MemUnlockAll

View file

@ -23,6 +23,7 @@ class SocketClient
{ {
NDB_SOCKET_TYPE m_sockfd; NDB_SOCKET_TYPE m_sockfd;
struct sockaddr_in m_servaddr; struct sockaddr_in m_servaddr;
unsigned int m_connect_timeout_sec;
unsigned short m_port; unsigned short m_port;
char *m_server_name; char *m_server_name;
SocketAuthenticator *m_auth; SocketAuthenticator *m_auth;
@ -34,6 +35,9 @@ public:
m_port = port; m_port = port;
m_servaddr.sin_port = htons(m_port); m_servaddr.sin_port = htons(m_port);
}; };
void set_connect_timeout(unsigned int s) {
m_connect_timeout_sec= s;
}
unsigned short get_port() { return m_port; }; unsigned short get_port() { return m_port; };
char *get_server_name() { return m_server_name; }; char *get_server_name() { return m_server_name; };
int bind(const char* toaddress, unsigned short toport); int bind(const char* toaddress, unsigned short toport);

View file

@ -115,7 +115,8 @@ void getTextNDBStopForced(QQQQ) {
int sphase = theData[4]; int sphase = theData[4];
int extra = theData[5]; int extra = theData[5];
getRestartAction(theData[1],action_str); getRestartAction(theData[1],action_str);
reason_str.appfmt(" Initiated by signal %d.", signum); if (signum)
reason_str.appfmt(" Initiated by signal %d.", signum);
if (error) if (error)
{ {
ndbd_exit_classification cl; ndbd_exit_classification cl;

View file

@ -56,7 +56,15 @@ void NdbMem_Free(void* ptr)
} }
int NdbMem_MemLockAll(){ int NdbMem_MemLockAll(int i){
if (i == 1)
{
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) && defined (MCL_FUTURE)
return mlockall(MCL_CURRENT | MCL_FUTURE);
#else
return -1;
#endif
}
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) #if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
return mlockall(MCL_CURRENT); return mlockall(MCL_CURRENT);
#else #else

View file

@ -79,9 +79,13 @@ Transporter::Transporter(TransporterRegistry &t_reg,
if (isServer) if (isServer)
m_socket_client= 0; m_socket_client= 0;
else else
{
m_socket_client= new SocketClient(remoteHostName, s_port, m_socket_client= new SocketClient(remoteHostName, s_port,
new SocketAuthSimple("ndbd", new SocketAuthSimple("ndbd",
"ndbd passwd")); "ndbd passwd"));
m_socket_client->set_connect_timeout((m_timeOutMillis+999)/1000);
}
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@ -140,9 +144,9 @@ Transporter::connect_client() {
} }
sockfd= m_socket_client->connect(); sockfd= m_socket_client->connect();
} }
return connect_client(sockfd); return connect_client(sockfd);
} }
bool bool
Transporter::connect_client(NDB_SOCKET_TYPE sockfd) { Transporter::connect_client(NDB_SOCKET_TYPE sockfd) {

View file

@ -48,7 +48,7 @@ static const char Magic[] = { 'N', 'D', 'B', 'C', 'O', 'N', 'F', 'V' };
//#define DEBUG_CV //#define DEBUG_CV
#ifdef DEBUG_CV #ifdef DEBUG_CV
#define DEBUG #define DEBUG if(getenv("CV_DEBUG"))
#else #else
#define DEBUG if(0) #define DEBUG if(0)
#endif #endif
@ -216,62 +216,60 @@ ConfigValues::Iterator::set(Uint32 key, const char * value){
static static
bool bool
findKey(const Uint32 * values, Uint32 sz, Uint32 key, Uint32 * _pos){ findKey(const Uint32 * values, Uint32 sz, Uint32 key, Uint32 * _pos){
Uint32 pos = hash(key, sz); Uint32 lo = 0;
Uint32 count = 0; Uint32 hi = sz;
while((values[pos] & KP_MASK) != key && count < sz){ Uint32 pos = (hi + lo) >> 1;
pos = nextHash(key, sz, pos, ++count);
DEBUG printf("findKey(H'%.8x %d)", key, sz);
if (sz == 0)
{
DEBUG ndbout_c(" -> false, 0");
* _pos = 0;
return false;
} }
if((values[pos] & KP_MASK)== key){ Uint32 val = 0;
*_pos = pos; Uint32 oldpos = pos + 1;
return true; while (pos != oldpos)
} {
DEBUG printf(" [ %d %d %d ] ", lo, pos, hi);
assert(pos < hi);
assert(pos >= lo);
val = values[2*pos] & KP_MASK;
if (key > val)
{
lo = pos;
}
else if (key < val)
{
hi = pos;
}
else
{
* _pos = 2*pos;
DEBUG ndbout_c(" -> true, %d", pos);
return true;
}
oldpos = pos;
pos = (hi + lo) >> 1;
}
DEBUG printf(" pos: %d (key %.8x val: %.8x values[pos]: %x) key>val: %d ",
pos, key, val, values[2*pos] & KP_MASK,
key > val);
pos += (key > val) ? 1 : 0;
* _pos = 2*pos;
DEBUG ndbout_c(" -> false, %d", pos);
return false; return false;
} }
static
Uint32
hash(Uint32 key, Uint32 size){
Uint32 tmp = (key >> 16) ^ (key & 0xFFFF);
return (((tmp << 16) | tmp) % size) << 1;
}
static
Uint32
nextHash(Uint32 key, Uint32 size, Uint32 pos, Uint32 count){
Uint32 p = (pos >> 1);
if((key % size) != 0)
p += key;
else
p += 1;
return (p % size) << 1;
}
static
Uint32
directory(Uint32 sz){
const Uint32 _input = sz;
if((sz & 1) == 0)
sz ++;
bool prime = false;
while(!prime){
prime = true;
for(Uint32 n = 3; n*n <= sz; n += 2){
if((sz % n) == 0){
prime = false;
sz += 2;
break;
}
}
}
DEBUG printf("directory %d -> %d\n", _input, sz);
return sz;
}
ConfigValuesFactory::ConfigValuesFactory(Uint32 keys, Uint32 data){ ConfigValuesFactory::ConfigValuesFactory(Uint32 keys, Uint32 data){
m_sectionCounter = (1 << KP_SECTION_SHIFT); m_sectionCounter = (1 << KP_SECTION_SHIFT);
m_freeKeys = directory(keys); m_freeKeys = keys;
m_freeData = (data + 7) & ~7; m_freeData = (data + 7) & ~7;
m_currentSection = 0; m_currentSection = 0;
m_cfg = create(m_freeKeys, m_freeData); m_cfg = create(m_freeKeys, m_freeData);
@ -330,11 +328,14 @@ ConfigValuesFactory::expand(Uint32 fk, Uint32 fs){
return ; return ;
} }
DEBUG printf("[ fk fd ] : [ %d %d ]", m_freeKeys, m_freeData);
m_freeKeys = (m_freeKeys >= fk ? m_cfg->m_size : fk + m_cfg->m_size); m_freeKeys = (m_freeKeys >= fk ? m_cfg->m_size : fk + m_cfg->m_size);
m_freeData = (m_freeData >= fs ? m_cfg->m_dataSize : fs + m_cfg->m_dataSize); m_freeData = (m_freeData >= fs ? m_cfg->m_dataSize : fs + m_cfg->m_dataSize);
m_freeKeys = directory(m_freeKeys);
m_freeData = (m_freeData + 7) & ~7; m_freeData = (m_freeData + 7) & ~7;
DEBUG ndbout_c(" [ %d %d ]", m_freeKeys, m_freeData);
ConfigValues * m_tmp = m_cfg; ConfigValues * m_tmp = m_cfg;
m_cfg = create(m_freeKeys, m_freeData); m_cfg = create(m_freeKeys, m_freeData);
put(* m_tmp); put(* m_tmp);
@ -350,7 +351,6 @@ ConfigValuesFactory::shrink(){
m_freeKeys = m_cfg->m_size - m_freeKeys; m_freeKeys = m_cfg->m_size - m_freeKeys;
m_freeData = m_cfg->m_dataSize - m_freeData; m_freeData = m_cfg->m_dataSize - m_freeData;
m_freeKeys = directory(m_freeKeys);
m_freeData = (m_freeData + 7) & ~7; m_freeData = (m_freeData + 7) & ~7;
ConfigValues * m_tmp = m_cfg; ConfigValues * m_tmp = m_cfg;
@ -429,52 +429,58 @@ ConfigValuesFactory::put(const ConfigValues::Entry & entry){
} }
const Uint32 tmp = entry.m_key | m_currentSection; const Uint32 tmp = entry.m_key | m_currentSection;
const Uint32 sz = m_cfg->m_size; const Uint32 sz = m_cfg->m_size - m_freeKeys;
Uint32 pos = hash(tmp, sz);
Uint32 count = 0;
Uint32 val = m_cfg->m_values[pos];
while((val & KP_MASK) != tmp && val != CFV_KEY_FREE && count < sz){ Uint32 pos;
pos = nextHash(tmp, sz, pos, ++count); if (findKey(m_cfg->m_values, sz, tmp, &pos))
val = m_cfg->m_values[pos]; {
}
if((val & KP_MASK) == tmp){
DEBUG ndbout_c("key %x already found at pos: %d", tmp, pos); DEBUG ndbout_c("key %x already found at pos: %d", tmp, pos);
return false; return false;
} }
if(count >= sz){ DEBUG {
pos = hash(tmp, sz); printf("H'before ");
count = 0; Uint32 prev = 0;
Uint32 val = m_cfg->m_values[pos]; for (Uint32 i = 0; i<sz; i++)
{
printf("key: %d, (key %% size): %d\n", entry.m_key, (entry.m_key % sz)); Uint32 val = m_cfg->m_values[2*i] & KP_MASK;
printf("pos: %d", pos); ndbout_c("%.8x", val);
while((val & KP_MASK) != tmp && val != CFV_KEY_FREE && count < sz){ assert(val >= prev);
pos = nextHash(tmp, sz, pos, ++count); prev = val;
val = m_cfg->m_values[pos];
printf(" %d", pos);
} }
printf("\n"); }
abort(); if (pos != 2*sz)
printf("Full\n"); {
return false; DEBUG ndbout_c("pos: %d sz: %d", pos, sz);
memmove(m_cfg->m_values + pos + 2, m_cfg->m_values + pos,
4 * (2*sz - pos));
} }
assert(pos < (sz << 1));
Uint32 key = tmp; Uint32 key = tmp;
key |= (entry.m_type << KP_TYPE_SHIFT); key |= (entry.m_type << KP_TYPE_SHIFT);
m_cfg->m_values[pos] = key; m_cfg->m_values[pos] = key;
DEBUG {
printf("H'after ");
Uint32 prev = 0;
for (Uint32 i = 0; i<=sz; i++)
{
Uint32 val = m_cfg->m_values[2*i] & KP_MASK;
ndbout_c("%.8x", val);
assert(val >= prev);
prev = val;
}
}
switch(entry.m_type){ switch(entry.m_type){
case ConfigValues::IntType: case ConfigValues::IntType:
case ConfigValues::SectionType: case ConfigValues::SectionType:
m_cfg->m_values[pos+1] = entry.m_int; m_cfg->m_values[pos+1] = entry.m_int;
m_freeKeys--; m_freeKeys--;
DEBUG printf("Putting at: %d(%d) (loop = %d) key: %d value: %d\n", DEBUG printf("Putting at: %d(%d) (loop = %d) key: %d value: %d\n",
pos, sz, count, pos, sz, 0,
(key >> KP_KEYVAL_SHIFT) & KP_KEYVAL_MASK, (key >> KP_KEYVAL_SHIFT) & KP_KEYVAL_MASK,
entry.m_int); entry.m_int);
return true; return true;
@ -486,7 +492,7 @@ ConfigValuesFactory::put(const ConfigValues::Entry & entry){
m_freeKeys--; m_freeKeys--;
m_freeData -= sizeof(char *); m_freeData -= sizeof(char *);
DEBUG printf("Putting at: %d(%d) (loop = %d) key: %d value(%d): %s\n", DEBUG printf("Putting at: %d(%d) (loop = %d) key: %d value(%d): %s\n",
pos, sz, count, pos, sz, 0,
(key >> KP_KEYVAL_SHIFT) & KP_KEYVAL_MASK, (key >> KP_KEYVAL_SHIFT) & KP_KEYVAL_MASK,
index, index,
entry.m_string); entry.m_string);
@ -499,7 +505,7 @@ ConfigValuesFactory::put(const ConfigValues::Entry & entry){
m_freeKeys--; m_freeKeys--;
m_freeData -= 8; m_freeData -= 8;
DEBUG printf("Putting at: %d(%d) (loop = %d) key: %d value64(%d): %lld\n", DEBUG printf("Putting at: %d(%d) (loop = %d) key: %d value64(%d): %lld\n",
pos, sz, count, pos, sz, 0,
(key >> KP_KEYVAL_SHIFT) & KP_KEYVAL_MASK, (key >> KP_KEYVAL_SHIFT) & KP_KEYVAL_MASK,
index, index,
entry.m_int64); entry.m_int64);
@ -662,7 +668,9 @@ ConfigValuesFactory::unpack(const void * _src, Uint32 len){
} }
const char * src = (const char *)_src; const char * src = (const char *)_src;
const char * end = src + len - 4;
src += sizeof(Magic);
{ {
Uint32 len32 = (len >> 2); Uint32 len32 = (len >> 2);
const Uint32 * tmp = (const Uint32*)_src; const Uint32 * tmp = (const Uint32*)_src;
@ -677,9 +685,37 @@ ConfigValuesFactory::unpack(const void * _src, Uint32 len){
} }
} }
const char * end = src + len - 4; const char * save = src;
src += sizeof(Magic);
{
Uint32 keys = 0;
Uint32 data = 0;
while(end - src > 4){
Uint32 tmp = ntohl(* (const Uint32 *)src); src += 4;
keys++;
switch(::getTypeOf(tmp)){
case ConfigValues::IntType:
case ConfigValues::SectionType:
src += 4;
break;
case ConfigValues::Int64Type:
src += 8;
data += 8;
break;
case ConfigValues::StringType:{
Uint32 s_len = ntohl(* (const Uint32 *)src);
src += 4 + mod4(s_len);
data += sizeof(char*);
break;
}
default:
break;
}
}
expand(keys, data);
}
src = save;
ConfigValues::Entry entry; ConfigValues::Entry entry;
while(end - src > 4){ while(end - src > 4){
Uint32 tmp = ntohl(* (const Uint32 *)src); src += 4; Uint32 tmp = ntohl(* (const Uint32 *)src); src += 4;

View file

@ -26,6 +26,7 @@ SocketClient::SocketClient(const char *server_name, unsigned short port, SocketA
m_port= port; m_port= port;
m_server_name= server_name ? strdup(server_name) : 0; m_server_name= server_name ? strdup(server_name) : 0;
m_sockfd= NDB_INVALID_SOCKET; m_sockfd= NDB_INVALID_SOCKET;
m_connect_timeout_sec= 0;
} }
SocketClient::~SocketClient() SocketClient::~SocketClient()
@ -58,7 +59,7 @@ SocketClient::init()
if (m_sockfd == NDB_INVALID_SOCKET) { if (m_sockfd == NDB_INVALID_SOCKET) {
return false; return false;
} }
DBUG_PRINT("info",("NDB_SOCKET: %d", m_sockfd)); DBUG_PRINT("info",("NDB_SOCKET: %d", m_sockfd));
return true; return true;
@ -104,6 +105,13 @@ SocketClient::bind(const char* bindaddress, unsigned short localport)
NDB_SOCKET_TYPE NDB_SOCKET_TYPE
SocketClient::connect(const char *toaddress, unsigned short toport) SocketClient::connect(const char *toaddress, unsigned short toport)
{ {
fd_set rset, wset;
struct timeval tval;
int r;
bool use_timeout;
SOCKOPT_OPTLEN_TYPE len;
int flags;
if (m_sockfd == NDB_INVALID_SOCKET) if (m_sockfd == NDB_INVALID_SOCKET)
{ {
if (!init()) { if (!init()) {
@ -127,14 +135,58 @@ SocketClient::connect(const char *toaddress, unsigned short toport)
if (Ndb_getInAddr(&m_servaddr.sin_addr, m_server_name)) if (Ndb_getInAddr(&m_servaddr.sin_addr, m_server_name))
return NDB_INVALID_SOCKET; return NDB_INVALID_SOCKET;
} }
const int r = ::connect(m_sockfd, (struct sockaddr*) &m_servaddr, sizeof(m_servaddr)); flags= fcntl(m_sockfd, F_GETFL, 0);
if (r == -1) { fcntl(m_sockfd, F_SETFL, flags | O_NONBLOCK);
r= ::connect(m_sockfd, (struct sockaddr*) &m_servaddr, sizeof(m_servaddr));
if (r == 0)
goto done; // connected immediately.
if (r < 0 && (errno != EINPROGRESS)) {
NDB_CLOSE_SOCKET(m_sockfd); NDB_CLOSE_SOCKET(m_sockfd);
m_sockfd= NDB_INVALID_SOCKET; m_sockfd= NDB_INVALID_SOCKET;
return NDB_INVALID_SOCKET; return NDB_INVALID_SOCKET;
} }
FD_ZERO(&rset);
FD_SET(m_sockfd, &rset);
wset= rset;
tval.tv_sec= m_connect_timeout_sec;
tval.tv_usec= 0;
use_timeout= m_connect_timeout_sec;
if ((r= select(m_sockfd+1, &rset, &wset, NULL,
use_timeout? &tval : NULL)) == 0)
{
NDB_CLOSE_SOCKET(m_sockfd);
m_sockfd= NDB_INVALID_SOCKET;
return NDB_INVALID_SOCKET;
}
if (FD_ISSET(m_sockfd, &rset) || FD_ISSET(m_sockfd, &wset))
{
len= sizeof(r);
if (getsockopt(m_sockfd, SOL_SOCKET, SO_ERROR, &r, &len) < 0 || r)
{
// Solaris got an error... different than others
NDB_CLOSE_SOCKET(m_sockfd);
m_sockfd= NDB_INVALID_SOCKET;
return NDB_INVALID_SOCKET;
}
}
else
{
// select error, probably m_sockfd not set.
NDB_CLOSE_SOCKET(m_sockfd);
m_sockfd= NDB_INVALID_SOCKET;
return NDB_INVALID_SOCKET;
}
done:
fcntl(m_sockfd, F_SETFL, flags);
if (m_auth) { if (m_auth) {
if (!m_auth->client_authenticate(m_sockfd)) if (!m_auth->client_authenticate(m_sockfd))
{ {

View file

@ -21,6 +21,9 @@ Crash president when he starts to run in ArbitState 1-9.
910: Crash new president after node crash 910: Crash new president after node crash
935 : Crash master on node failure (delayed)
and skip sending GSN_COMMIT_FAILREQ to specified node
ERROR CODES FOR TESTING NODE FAILURE, GLOBAL CHECKPOINT HANDLING: ERROR CODES FOR TESTING NODE FAILURE, GLOBAL CHECKPOINT HANDLING:
----------------------------------------------------------------- -----------------------------------------------------------------

View file

@ -341,9 +341,9 @@ void Cmvmi::execSTTOR(Signal* signal)
if (theStartPhase == 1){ if (theStartPhase == 1){
jam(); jam();
if(theConfig.lockPagesInMainMemory()) if(theConfig.lockPagesInMainMemory() == 1)
{ {
int res = NdbMem_MemLockAll(); int res = NdbMem_MemLockAll(0);
if(res != 0){ if(res != 0){
g_eventLogger.warning("Failed to memlock pages"); g_eventLogger.warning("Failed to memlock pages");
warningEvent("Failed to memlock pages"); warningEvent("Failed to memlock pages");
@ -788,6 +788,21 @@ Cmvmi::execSTART_ORD(Signal* signal) {
if(globalData.theStartLevel == NodeState::SL_CMVMI){ if(globalData.theStartLevel == NodeState::SL_CMVMI){
jam(); jam();
if(theConfig.lockPagesInMainMemory() == 2)
{
int res = NdbMem_MemLockAll(1);
if(res != 0)
{
g_eventLogger.warning("Failed to memlock pages");
warningEvent("Failed to memlock pages");
}
else
{
g_eventLogger.info("Locked future allocations");
}
}
globalData.theStartLevel = NodeState::SL_STARTING; globalData.theStartLevel = NodeState::SL_STARTING;
globalData.theRestartFlag = system_started; globalData.theRestartFlag = system_started;
/** /**

View file

@ -3554,7 +3554,6 @@ void Dbdih::endTakeOver(Uint32 takeOverPtrI)
takeOverPtr.i = takeOverPtrI; takeOverPtr.i = takeOverPtrI;
ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord); ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
releaseTakeOver(takeOverPtrI);
if ((takeOverPtr.p->toMasterStatus != TakeOverRecord::IDLE) && if ((takeOverPtr.p->toMasterStatus != TakeOverRecord::IDLE) &&
(takeOverPtr.p->toMasterStatus != TakeOverRecord::TO_WAIT_START_TAKE_OVER)) { (takeOverPtr.p->toMasterStatus != TakeOverRecord::TO_WAIT_START_TAKE_OVER)) {
jam(); jam();
@ -3568,6 +3567,7 @@ void Dbdih::endTakeOver(Uint32 takeOverPtrI)
}//if }//if
setAllowNodeStart(takeOverPtr.p->toStartingNode, true); setAllowNodeStart(takeOverPtr.p->toStartingNode, true);
initTakeOver(takeOverPtr); initTakeOver(takeOverPtr);
releaseTakeOver(takeOverPtrI);
}//Dbdih::endTakeOver() }//Dbdih::endTakeOver()
void Dbdih::releaseTakeOver(Uint32 takeOverPtrI) void Dbdih::releaseTakeOver(Uint32 takeOverPtrI)
@ -4709,6 +4709,7 @@ void Dbdih::handleTakeOverNewMaster(Signal* signal, Uint32 takeOverPtrI)
break; break;
} }
ndbrequire(ok); ndbrequire(ok);
endTakeOver(takeOverPtr.i);
}//if }//if
}//Dbdih::handleTakeOverNewMaster() }//Dbdih::handleTakeOverNewMaster()

View file

@ -138,7 +138,6 @@
#define ZNOT_FOUND 626 #define ZNOT_FOUND 626
#define ZALREADYEXIST 630 #define ZALREADYEXIST 630
#define ZINCONSISTENTHASHINDEX 892
#define ZNOTUNIQUE 893 #define ZNOTUNIQUE 893
#define ZINVALID_KEY 290 #define ZINVALID_KEY 290

View file

@ -425,6 +425,10 @@ private:
StopReq c_stopReq; StopReq c_stopReq;
bool check_multi_node_shutdown(Signal* signal); bool check_multi_node_shutdown(Signal* signal);
#ifdef ERROR_INSERT
Uint32 c_error_insert_extra;
#endif
}; };
#endif #endif

View file

@ -2894,6 +2894,17 @@ void Qmgr::failReportLab(Signal* signal, Uint16 aFailedNode,
systemErrorLab(signal, __LINE__); systemErrorLab(signal, __LINE__);
return; return;
}//if }//if
if (getNodeState().startLevel < NodeState::SL_STARTED)
{
jam();
CRASH_INSERTION(932);
char buf[100];
BaseString::snprintf(buf, 100, "Node failure during restart");
progError(__LINE__, NDBD_EXIT_SR_OTHERNODEFAILED, buf);
ndbrequire(false);
}
TnoFailedNodes = cnoFailedNodes; TnoFailedNodes = cnoFailedNodes;
failReport(signal, failedNodePtr.i, (UintR)ZTRUE, aFailCause); failReport(signal, failedNodePtr.i, (UintR)ZTRUE, aFailCause);
if (cpresident == getOwnNodeId()) { if (cpresident == getOwnNodeId()) {
@ -2980,6 +2991,16 @@ void Qmgr::execPREP_FAILREQ(Signal* signal)
return; return;
}//if }//if
if (getNodeState().startLevel < NodeState::SL_STARTED)
{
jam();
CRASH_INSERTION(932);
char buf[100];
BaseString::snprintf(buf, 100, "Node failure during restart");
progError(__LINE__, NDBD_EXIT_SR_OTHERNODEFAILED, buf);
ndbrequire(false);
}
guard0 = cnoPrepFailedNodes - 1; guard0 = cnoPrepFailedNodes - 1;
arrGuard(guard0, MAX_NDB_NODES); arrGuard(guard0, MAX_NDB_NODES);
for (Tindex = 0; Tindex <= guard0; Tindex++) { for (Tindex = 0; Tindex <= guard0; Tindex++) {
@ -3157,6 +3178,18 @@ Qmgr::sendCommitFailReq(Signal* signal)
for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
jam(); jam();
ptrAss(nodePtr, nodeRec); ptrAss(nodePtr, nodeRec);
#ifdef ERROR_INSERT
if (ERROR_INSERTED(935) && nodePtr.i == c_error_insert_extra)
{
ndbout_c("skipping node %d", c_error_insert_extra);
CLEAR_ERROR_INSERT_VALUE;
signal->theData[0] = 9999;
sendSignalWithDelay(CMVMI_REF, GSN_NDB_TAMPER, signal, 1000, 1);
continue;
}
#endif
if (nodePtr.p->phase == ZRUNNING) { if (nodePtr.p->phase == ZRUNNING) {
jam(); jam();
nodePtr.p->sendCommitFailReqStatus = Q_ACTIVE; nodePtr.p->sendCommitFailReqStatus = Q_ACTIVE;
@ -3227,6 +3260,33 @@ void Qmgr::execPREP_FAILREF(Signal* signal)
return; return;
}//Qmgr::execPREP_FAILREF() }//Qmgr::execPREP_FAILREF()
static
Uint32
clear_nodes(Uint32 dstcnt, Uint16 dst[], Uint32 srccnt, const Uint16 src[])
{
if (srccnt == 0)
return dstcnt;
Uint32 pos = 0;
for (Uint32 i = 0; i<dstcnt; i++)
{
Uint32 node = dst[i];
for (Uint32 j = 0; j<srccnt; j++)
{
if (node == dst[j])
{
node = RNIL;
break;
}
}
if (node != RNIL)
{
dst[pos++] = node;
}
}
return pos;
}
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* THE PRESIDENT IS NOW COMMITTING THE PREVIOUSLY PREPARED NODE FAILURE. */ /* THE PRESIDENT IS NOW COMMITTING THE PREVIOUSLY PREPARED NODE FAILURE. */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -3314,19 +3374,18 @@ void Qmgr::execCOMMIT_FAILREQ(Signal* signal)
NodeFailRep::SignalLength, JBB); NodeFailRep::SignalLength, JBB);
}//if }//if
}//for }//for
if (cpresident != getOwnNodeId()) {
jam(); /**
cnoFailedNodes = cnoCommitFailedNodes - cnoFailedNodes; * Remove committed nodes from failed/prepared
if (cnoFailedNodes > 0) { */
jam(); cnoFailedNodes = clear_nodes(cnoFailedNodes,
guard0 = cnoFailedNodes - 1; cfailedNodes,
arrGuard(guard0 + cnoCommitFailedNodes, MAX_NDB_NODES); cnoCommitFailedNodes,
for (Tj = 0; Tj <= guard0; Tj++) { ccommitFailedNodes);
jam(); cnoPrepFailedNodes = clear_nodes(cnoPrepFailedNodes,
cfailedNodes[Tj] = cfailedNodes[Tj + cnoCommitFailedNodes]; cprepFailedNodes,
}//for cnoCommitFailedNodes,
}//if ccommitFailedNodes);
}//if
cnoCommitFailedNodes = 0; cnoCommitFailedNodes = 0;
}//if }//if
/**----------------------------------------------------------------------- /**-----------------------------------------------------------------------
@ -4705,6 +4764,14 @@ Qmgr::execDUMP_STATE_ORD(Signal* signal)
default: default:
; ;
}//switch }//switch
#ifdef ERROR_INSERT
if (signal->theData[0] == 935 && signal->getLength() == 2)
{
SET_ERROR_INSERT_VALUE(935);
c_error_insert_extra = signal->theData[1];
}
#endif
}//Qmgr::execDUMP_STATE_ORD() }//Qmgr::execDUMP_STATE_ORD()
void Qmgr::execSET_VAR_REQ(Signal* signal) void Qmgr::execSET_VAR_REQ(Signal* signal)

View file

@ -479,7 +479,7 @@ Configuration::setupConfiguration(){
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
bool Uint32
Configuration::lockPagesInMainMemory() const { Configuration::lockPagesInMainMemory() const {
return _lockPagesInMainMemory; return _lockPagesInMainMemory;
} }

View file

@ -36,7 +36,7 @@ public:
void setupConfiguration(); void setupConfiguration();
void closeConfiguration(bool end_session= true); void closeConfiguration(bool end_session= true);
bool lockPagesInMainMemory() const; Uint32 lockPagesInMainMemory() const;
int timeBetweenWatchDogCheck() const ; int timeBetweenWatchDogCheck() const ;
void timeBetweenWatchDogCheck(int value); void timeBetweenWatchDogCheck(int value);

View file

@ -93,6 +93,7 @@ struct ndb_mgm_handle {
char last_error_desc[NDB_MGM_MAX_ERR_DESC_SIZE]; char last_error_desc[NDB_MGM_MAX_ERR_DESC_SIZE];
int read_timeout; int read_timeout;
int write_timeout; int write_timeout;
unsigned int connect_timeout;
NDB_SOCKET_TYPE socket; NDB_SOCKET_TYPE socket;
@ -159,6 +160,7 @@ ndb_mgm_create_handle()
h->socket = NDB_INVALID_SOCKET; h->socket = NDB_INVALID_SOCKET;
h->read_timeout = 50000; h->read_timeout = 50000;
h->write_timeout = 100; h->write_timeout = 100;
h->connect_timeout = 0;
h->cfg_i = -1; h->cfg_i = -1;
h->errstream = stdout; h->errstream = stdout;
h->m_name = 0; h->m_name = 0;
@ -426,6 +428,16 @@ int ndb_mgm_is_connected(NdbMgmHandle handle)
return handle->connected; return handle->connected;
} }
extern "C"
int ndb_mgm_set_connect_timeout(NdbMgmHandle handle, unsigned int seconds)
{
if(!handle)
return -1;
handle->connect_timeout= seconds;
return 0;
}
/** /**
* Connect to a management server * Connect to a management server
*/ */
@ -456,6 +468,7 @@ ndb_mgm_connect(NdbMgmHandle handle, int no_retries,
Uint32 i; Uint32 i;
int binderror = 0; int binderror = 0;
SocketClient s(0, 0); SocketClient s(0, 0);
s.set_connect_timeout(handle->connect_timeout);
if (!s.init()) if (!s.init())
{ {
fprintf(handle->errstream, fprintf(handle->errstream,

View file

@ -563,10 +563,10 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
"If set to yes, then NDB Cluster data will not be swapped out to disk", "If set to yes, then NDB Cluster data will not be swapped out to disk",
ConfigInfo::CI_USED, ConfigInfo::CI_USED,
true, true,
ConfigInfo::CI_BOOL, ConfigInfo::CI_INT,
"false", "0",
"false", "1",
"true" }, "2" },
{ {
CFG_DB_WATCHDOG_INTERVAL, CFG_DB_WATCHDOG_INTERVAL,

View file

@ -137,8 +137,11 @@ MgmtSrvr::logLevelThreadRun()
m_started_nodes.erase(0, false); m_started_nodes.erase(0, false);
m_started_nodes.unlock(); m_started_nodes.unlock();
setEventReportingLevelImpl(node, req); if (setEventReportingLevelImpl(node, req))
{
ndbout_c("setEventReportingLevelImpl(%d): failed", node);
}
SetLogLevelOrd ord; SetLogLevelOrd ord;
ord = m_nodeLogLevel[node]; ord = m_nodeLogLevel[node];
setNodeLogLevelImpl(node, ord); setNodeLogLevelImpl(node, ord);
@ -155,10 +158,16 @@ MgmtSrvr::logLevelThreadRun()
m_log_level_requests.erase(0, false); m_log_level_requests.erase(0, false);
m_log_level_requests.unlock(); m_log_level_requests.unlock();
if(req.blockRef == 0){ if(req.blockRef == 0)
{
req.blockRef = _ownReference; req.blockRef = _ownReference;
setEventReportingLevelImpl(0, req); if (setEventReportingLevelImpl(0, req))
} else { {
ndbout_c("setEventReportingLevelImpl: failed 2!");
}
}
else
{
SetLogLevelOrd ord; SetLogLevelOrd ord;
ord = req; ord = req;
setNodeLogLevelImpl(req.blockRef, ord); setNodeLogLevelImpl(req.blockRef, ord);
@ -1376,9 +1385,6 @@ int MgmtSrvr::restartDB(bool nostart, bool initialStart,
NodeId nodeId = 0; NodeId nodeId = 0;
NDB_TICKS maxTime = NdbTick_CurrentMillisecond() + waitTime; NDB_TICKS maxTime = NdbTick_CurrentMillisecond() + waitTime;
ndbout_c(" %d", nodes.get(1));
ndbout_c(" %d", nodes.get(2));
while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) { while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) {
if (!nodes.get(nodeId)) if (!nodes.get(nodeId))
continue; continue;
@ -1584,6 +1590,11 @@ MgmtSrvr::setEventReportingLevelImpl(int nodeId,
} }
} }
if (nodes.isclear())
{
return SEND_OR_RECEIVE_FAILED;
}
int error = 0; int error = 0;
while (!nodes.isclear()) while (!nodes.isclear())
{ {
@ -1600,16 +1611,24 @@ MgmtSrvr::setEventReportingLevelImpl(int nodeId,
error = 1; error = 1;
break; break;
} }
// Since sending okToSend(true),
// there is no guarantee that NF_COMPLETEREP will come
// i.e listen also to NODE_FAILREP
case GSN_NODE_FAILREP: {
const NodeFailRep * const rep =
CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
NdbNodeBitmask mask;
mask.assign(NdbNodeBitmask::Size, rep->theNodes);
nodes.bitANDC(mask);
break;
}
case GSN_NF_COMPLETEREP:{ case GSN_NF_COMPLETEREP:{
const NFCompleteRep * const rep = const NFCompleteRep * const rep =
CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr()); CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
nodes.clear(rep->failedNodeId); nodes.clear(rep->failedNodeId);
break; break;
} }
case GSN_NODE_FAILREP:{
// ignore, NF_COMPLETEREP will arrive later
break;
}
default: default:
report_unknown_signal(signal); report_unknown_signal(signal);
return SEND_OR_RECEIVE_FAILED; return SEND_OR_RECEIVE_FAILED;
@ -1909,7 +1928,10 @@ MgmtSrvr::handleStatus(NodeId nodeId, bool alive, bool nfComplete)
theData[1] = nodeId; theData[1] = nodeId;
if (alive) { if (alive) {
m_started_nodes.push_back(nodeId); if (nodeTypes[nodeId] == NODE_TYPE_DB)
{
m_started_nodes.push_back(nodeId);
}
rep->setEventType(NDB_LE_Connected); rep->setEventType(NDB_LE_Connected);
} else { } else {
rep->setEventType(NDB_LE_Disconnected); rep->setEventType(NDB_LE_Disconnected);

View file

@ -507,6 +507,7 @@ ClusterMgr::reportConnected(NodeId nodeId){
theNode.m_info.m_version = 0; theNode.m_info.m_version = 0;
theNode.compatible = true; theNode.compatible = true;
theNode.nfCompleteRep = true; theNode.nfCompleteRep = true;
theNode.m_state.startLevel = NodeState::SL_NOTHING;
theFacade.ReportNodeAlive(nodeId); theFacade.ReportNodeAlive(nodeId);
} }
@ -518,14 +519,13 @@ ClusterMgr::reportDisconnected(NodeId nodeId){
noOfConnectedNodes--; noOfConnectedNodes--;
theNodes[nodeId].connected = false; theNodes[nodeId].connected = false;
theNodes[nodeId].m_state.m_connected_nodes.clear(); theNodes[nodeId].m_state.m_connected_nodes.clear();
reportNodeFailed(nodeId); reportNodeFailed(nodeId, true);
} }
void void
ClusterMgr::reportNodeFailed(NodeId nodeId){ ClusterMgr::reportNodeFailed(NodeId nodeId, bool disconnect){
Node & theNode = theNodes[nodeId]; Node & theNode = theNodes[nodeId];
@ -536,10 +536,11 @@ ClusterMgr::reportNodeFailed(NodeId nodeId){
{ {
theFacade.doDisconnect(nodeId); theFacade.doDisconnect(nodeId);
} }
const bool report = (theNode.m_state.startLevel != NodeState::SL_NOTHING); const bool report = (theNode.m_state.startLevel != NodeState::SL_NOTHING);
theNode.m_state.startLevel = NodeState::SL_NOTHING; theNode.m_state.startLevel = NodeState::SL_NOTHING;
if(report) if(disconnect || report)
{ {
theFacade.ReportNodeDead(nodeId); theFacade.ReportNodeDead(nodeId);
} }

View file

@ -97,8 +97,8 @@ private:
NdbMutex* clusterMgrThreadMutex; NdbMutex* clusterMgrThreadMutex;
void showState(NodeId nodeId); void showState(NodeId nodeId);
void reportNodeFailed(NodeId nodeId); void reportNodeFailed(NodeId nodeId, bool disconnect = false);
/** /**
* Signals received * Signals received
*/ */

View file

@ -19,6 +19,14 @@
#include <signaldata/NFCompleteRep.hpp> #include <signaldata/NFCompleteRep.hpp>
#include <signaldata/NodeFailRep.hpp> #include <signaldata/NodeFailRep.hpp>
static
void
require(bool x)
{
if (!x)
abort();
}
SimpleSignal::SimpleSignal(bool dealloc){ SimpleSignal::SimpleSignal(bool dealloc){
memset(this, 0, sizeof(* this)); memset(this, 0, sizeof(* this));
deallocSections = dealloc; deallocSections = dealloc;
@ -145,6 +153,7 @@ SignalSender::waitFor(Uint32 timeOutMillis, T & t)
{ {
SimpleSignal * s = t.check(m_jobBuffer); SimpleSignal * s = t.check(m_jobBuffer);
if(s != 0){ if(s != 0){
m_usedBuffer.push_back(s);
return s; return s;
} }

View file

@ -208,7 +208,6 @@ ErrorBundle ErrorCodes[] = {
/** /**
* Internal errors * Internal errors
*/ */
{ 892, IE, "Inconsistent hash index. The index needs to be dropped and recreated" },
{ 896, IE, "Tuple corrupted - wrong checksum or column data in invalid format" }, { 896, IE, "Tuple corrupted - wrong checksum or column data in invalid format" },
{ 901, IE, "Inconsistent ordered index. The index needs to be dropped and recreated" }, { 901, IE, "Inconsistent ordered index. The index needs to be dropped and recreated" },
{ 202, IE, "202" }, { 202, IE, "202" },

View file

@ -954,6 +954,96 @@ int runBug24717(NDBT_Context* ctx, NDBT_Step* step){
return NDBT_OK; return NDBT_OK;
} }
int runBug25364(NDBT_Context* ctx, NDBT_Step* step){
int result = NDBT_OK;
NdbRestarter restarter;
Ndb* pNdb = GETNDB(step);
int loops = ctx->getNumLoops();
if (restarter.getNumDbNodes() < 4)
return NDBT_OK;
int val2[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 1 };
for (; loops; loops --)
{
int master = restarter.getMasterNodeId();
int victim = restarter.getRandomNodeOtherNodeGroup(master, rand());
int second = restarter.getRandomNodeSameNodeGroup(victim, rand());
int dump[] = { 935, victim } ;
if (restarter.dumpStateOneNode(master, dump, 2))
return NDBT_FAILED;
if (restarter.dumpStateOneNode(master, val2, 2))
return NDBT_FAILED;
if (restarter.restartOneDbNode(second, false, true, true))
return NDBT_FAILED;
int nodes[2] = { master, second };
if (restarter.waitNodesNoStart(nodes, 2))
return NDBT_FAILED;
restarter.startNodes(nodes, 2);
if (restarter.waitNodesStarted(nodes, 2))
return NDBT_FAILED;
}
return NDBT_OK;
}
int runBug25554(NDBT_Context* ctx, NDBT_Step* step){
int result = NDBT_OK;
int loops = ctx->getNumLoops();
int records = ctx->getNumRecords();
NdbRestarter restarter;
if (restarter.getNumDbNodes() < 4)
return NDBT_OK;
for (int i = 0; i<loops; i++)
{
int master = restarter.getMasterNodeId();
int node1 = restarter.getRandomNodeOtherNodeGroup(master, rand());
restarter.restartOneDbNode(node1, false, true, true);
int val2[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 1 };
if (restarter.dumpStateOneNode(master, val2, 2))
return NDBT_FAILED;
if (restarter.insertErrorInNode(master, 7141))
return NDBT_FAILED;
if (restarter.waitNodesNoStart(&node1, 1))
return NDBT_FAILED;
if (restarter.dumpStateOneNode(node1, val2, 2))
return NDBT_FAILED;
if (restarter.insertErrorInNode(node1, 932))
return NDBT_FAILED;
if (restarter.startNodes(&node1, 1))
return NDBT_FAILED;
int nodes[] = { master, node1 };
if (restarter.waitNodesNoStart(nodes, 2))
return NDBT_FAILED;
if (restarter.startNodes(nodes, 2))
return NDBT_FAILED;
if (restarter.waitClusterStarted())
return NDBT_FAILED;
}
return NDBT_OK;
}
NDBT_TESTSUITE(testNodeRestart); NDBT_TESTSUITE(testNodeRestart);
TESTCASE("NoLoad", TESTCASE("NoLoad",
@ -1270,6 +1360,12 @@ TESTCASE("Bug20185",
TESTCASE("Bug24717", ""){ TESTCASE("Bug24717", ""){
INITIALIZER(runBug24717); INITIALIZER(runBug24717);
} }
TESTCASE("Bug25364", ""){
INITIALIZER(runBug25364);
}
TESTCASE("Bug25554", ""){
INITIALIZER(runBug25554);
}
NDBT_TESTSUITE_END(testNodeRestart); NDBT_TESTSUITE_END(testNodeRestart);
int main(int argc, const char** argv){ int main(int argc, const char** argv){

View file

@ -469,6 +469,14 @@ max-time: 1000
cmd: testNodeRestart cmd: testNodeRestart
args: -n Bug24717 T1 args: -n Bug24717 T1
max-time: 1000
cmd: testNodeRestart
args: -n Bug25364 T1
max-time: 1000
cmd: testNodeRestart
args: -n Bug25554 T1
# OLD FLEX # OLD FLEX
max-time: 500 max-time: 500
cmd: flexBench cmd: flexBench

View file

@ -1106,6 +1106,16 @@ int ha_ndbcluster::build_index_list(Ndb *ndb, TABLE *tab, enum ILBP phase)
error= create_unique_index(unique_index_name, key_info); error= create_unique_index(unique_index_name, key_info);
break; break;
case ORDERED_INDEX: case ORDERED_INDEX:
if (key_info->algorithm == HA_KEY_ALG_HASH)
{
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
ER_UNSUPPORTED_EXTENSION,
ER(ER_UNSUPPORTED_EXTENSION),
"Ndb does not support non-unique "
"hash based indexes");
error= HA_ERR_UNSUPPORTED;
break;
}
error= create_ordered_index(index_name, key_info); error= create_ordered_index(index_name, key_info);
break; break;
default: default:
@ -2955,13 +2965,10 @@ KEY* key_info;
DBUG_RETURN(error == HA_ERR_KEY_NOT_FOUND ? HA_ERR_END_OF_FILE : error); DBUG_RETURN(error == HA_ERR_KEY_NOT_FOUND ? HA_ERR_END_OF_FILE : error);
} }
else if (type == UNIQUE_INDEX) else if (type == UNIQUE_INDEX)
{ DBUG_RETURN(unique_index_scan(key_info,
error= unique_index_scan(key_info, start_key->key,
start_key->key, start_key->length,
start_key->length, buf));
buf);
DBUG_RETURN(error == HA_ERR_KEY_NOT_FOUND ? HA_ERR_END_OF_FILE : error);
}
break; break;
default: default:
break; break;
@ -3137,20 +3144,26 @@ void ha_ndbcluster::position(const byte *record)
size_t len = key_part->length; size_t len = key_part->length;
const byte * ptr = record + key_part->offset; const byte * ptr = record + key_part->offset;
Field *field = key_part->field; Field *field = key_part->field;
if ((field->type() == MYSQL_TYPE_VARCHAR) && if (field->type() == MYSQL_TYPE_VARCHAR)
((Field_varstring*)field)->length_bytes == 1)
{ {
/** if (((Field_varstring*)field)->length_bytes == 1)
* Keys always use 2 bytes length {
*/ /**
buff[0] = ptr[0]; * Keys always use 2 bytes length
buff[1] = 0; */
memcpy(buff+2, ptr + 1, len); buff[0] = ptr[0];
len += 2; buff[1] = 0;
memcpy(buff+2, ptr + 1, len);
}
else
{
memcpy(buff, ptr, len + 2);
}
len += 2;
} }
else else
{ {
memcpy(buff, ptr, len); memcpy(buff, ptr, len);
} }
buff += len; buff += len;
} }
@ -4172,19 +4185,29 @@ static int create_ndb_column(NDBCOL &col,
col.setType(NDBCOL::Text); col.setType(NDBCOL::Text);
col.setCharset(cs); col.setCharset(cs);
} }
// Use "<=" even if "<" is the exact condition
if (field->max_length() <= (1 << 8))
goto mysql_type_tiny_blob;
else if (field->max_length() <= (1 << 16))
{ {
col.setInlineSize(256); Field_blob *field_blob= (Field_blob *)field;
col.setPartSize(2000); /*
col.setStripeSize(16); * max_data_length is 2^8-1, 2^16-1, 2^24-1 for tiny, blob, medium.
* Tinyblob gets no blob parts. The other cases are just a crude
* way to control part size and striping.
*
* In mysql blob(256) is promoted to blob(65535) so it does not
* in fact fit "inline" in NDB.
*/
if (field_blob->max_data_length() < (1 << 8))
goto mysql_type_tiny_blob;
else if (field_blob->max_data_length() < (1 << 16))
{
col.setInlineSize(256);
col.setPartSize(2000);
col.setStripeSize(16);
}
else if (field_blob->max_data_length() < (1 << 24))
goto mysql_type_medium_blob;
else
goto mysql_type_long_blob;
} }
else if (field->max_length() <= (1 << 24))
goto mysql_type_medium_blob;
else
goto mysql_type_long_blob;
break; break;
mysql_type_medium_blob: mysql_type_medium_blob:
case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_MEDIUM_BLOB:

View file

@ -4577,8 +4577,8 @@ enum options_mysqld
OPT_LOG_BIN_TRUST_FUNCTION_CREATORS, OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
OPT_SAFE_SHOW_DB, OPT_INNODB_SAFE_BINLOG, OPT_SAFE_SHOW_DB, OPT_INNODB_SAFE_BINLOG,
OPT_INNODB, OPT_ISAM, OPT_INNODB, OPT_ISAM,
OPT_ENGINE_CONDITION_PUSHDOWN, OPT_ENGINE_CONDITION_PUSHDOWN, OPT_NDBCLUSTER, OPT_NDB_CONNECTSTRING,
OPT_NDBCLUSTER, OPT_NDB_CONNECTSTRING, OPT_NDB_USE_EXACT_COUNT, OPT_NDB_USE_EXACT_COUNT, OPT_NDB_USE_TRANSACTIONS,
OPT_NDB_FORCE_SEND, OPT_NDB_AUTOINCREMENT_PREFETCH_SZ, OPT_NDB_FORCE_SEND, OPT_NDB_AUTOINCREMENT_PREFETCH_SZ,
OPT_NDB_SHM, OPT_NDB_OPTIMIZED_NODE_SELECTION, OPT_NDB_CACHE_CHECK_TIME, OPT_NDB_SHM, OPT_NDB_OPTIMIZED_NODE_SELECTION, OPT_NDB_CACHE_CHECK_TIME,
OPT_NDB_MGMD, OPT_NDB_NODEID, OPT_NDB_MGMD, OPT_NDB_NODEID,
@ -5213,6 +5213,17 @@ Disable with --skip-ndbcluster (will save memory).",
(gptr*) &global_system_variables.ndb_use_exact_count, (gptr*) &global_system_variables.ndb_use_exact_count,
(gptr*) &global_system_variables.ndb_use_exact_count, (gptr*) &global_system_variables.ndb_use_exact_count,
0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0}, 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
{"ndb-use-transactions", OPT_NDB_USE_TRANSACTIONS,
"Use transactions for large inserts, if enabled then large "
"inserts will be split into several smaller transactions",
(gptr*) &global_system_variables.ndb_use_transactions,
(gptr*) &global_system_variables.ndb_use_transactions,
0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
{"ndb_use_transactions", OPT_NDB_USE_TRANSACTIONS,
"same as --ndb-use-transactions.",
(gptr*) &global_system_variables.ndb_use_transactions,
(gptr*) &global_system_variables.ndb_use_transactions,
0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
{"ndb-shm", OPT_NDB_SHM, {"ndb-shm", OPT_NDB_SHM,
"Use shared memory connections when available.", "Use shared memory connections when available.",
(gptr*) &opt_ndb_shm, (gptr*) &opt_ndb_shm,

View file

@ -290,9 +290,6 @@ void THD::init(void)
variables.date_format); variables.date_format);
variables.datetime_format= date_time_format_copy((THD*) 0, variables.datetime_format= date_time_format_copy((THD*) 0,
variables.datetime_format); variables.datetime_format);
#ifdef HAVE_NDBCLUSTER_DB
variables.ndb_use_transactions= 1;
#endif
pthread_mutex_unlock(&LOCK_global_system_variables); pthread_mutex_unlock(&LOCK_global_system_variables);
server_status= SERVER_STATUS_AUTOCOMMIT; server_status= SERVER_STATUS_AUTOCOMMIT;
if (variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) if (variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES)