Commit b66fac4f authored by tomas@whalegate.ndb.mysql.com's avatar tomas@whalegate.ndb.mysql.com

Merge whalegate.ndb.mysql.com:/home/tomas/mysql-5.1-new-ndb

into  whalegate.ndb.mysql.com:/home/tomas/mysql-5.1-new-maint
parents b37c24c4 7dd1f323
...@@ -123,7 +123,7 @@ Replicate_Ignore_Table ...@@ -123,7 +123,7 @@ Replicate_Ignore_Table
Replicate_Wild_Do_Table Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table Replicate_Wild_Ignore_Table
Last_Errno 1364 Last_Errno 1364
Last_Error Error in Write_rows event: error during transaction execution on table test.t1_nodef Last_Error Error in Write_rows event: error during transaction execution on table test.t1_nodef. Unknown error
Skip_Counter 0 Skip_Counter 0
Exec_Master_Log_Pos # Exec_Master_Log_Pos #
Relay_Log_Space # Relay_Log_Space #
......
...@@ -123,7 +123,7 @@ Replicate_Ignore_Table ...@@ -123,7 +123,7 @@ Replicate_Ignore_Table
Replicate_Wild_Do_Table Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table Replicate_Wild_Ignore_Table
Last_Errno 1364 Last_Errno 1364
Last_Error Error in Write_rows event: error during transaction execution on table test.t1_nodef Last_Error Error in Write_rows event: error during transaction execution on table test.t1_nodef. Unknown error
Skip_Counter 0 Skip_Counter 0
Exec_Master_Log_Pos # Exec_Master_Log_Pos #
Relay_Log_Space # Relay_Log_Space #
......
...@@ -10141,6 +10141,10 @@ static int ndbcluster_fill_files_table(handlerton *hton, ...@@ -10141,6 +10141,10 @@ static int ndbcluster_fill_files_table(handlerton *hton,
{ {
if (ndberr.classification == NdbError::SchemaError) if (ndberr.classification == NdbError::SchemaError)
continue; continue;
if (ndberr.classification == NdbError::UnknownResultError)
continue;
ERR_RETURN(ndberr); ERR_RETURN(ndberr);
} }
NdbDictionary::Tablespace ts= dict->getTablespace(df.getTablespace()); NdbDictionary::Tablespace ts= dict->getTablespace(df.getTablespace());
...@@ -10220,6 +10224,8 @@ static int ndbcluster_fill_files_table(handlerton *hton, ...@@ -10220,6 +10224,8 @@ static int ndbcluster_fill_files_table(handlerton *hton,
{ {
if (ndberr.classification == NdbError::SchemaError) if (ndberr.classification == NdbError::SchemaError)
continue; continue;
if (ndberr.classification == NdbError::UnknownResultError)
continue;
ERR_RETURN(ndberr); ERR_RETURN(ndberr);
} }
NdbDictionary::LogfileGroup lfg= NdbDictionary::LogfileGroup lfg=
......
...@@ -6104,8 +6104,9 @@ int Rows_log_event::do_apply_event(RELAY_LOG_INFO const *rli) ...@@ -6104,8 +6104,9 @@ int Rows_log_event::do_apply_event(RELAY_LOG_INFO const *rli)
default: default:
rli->report(ERROR_LEVEL, thd->net.last_errno, rli->report(ERROR_LEVEL, thd->net.last_errno,
"Error in %s event: row application failed", "Error in %s event: row application failed. %s",
get_type_str()); get_type_str(),
thd->net.last_error ? thd->net.last_error : "");
thd->query_error= 1; thd->query_error= 1;
break; break;
} }
...@@ -6126,9 +6127,10 @@ int Rows_log_event::do_apply_event(RELAY_LOG_INFO const *rli) ...@@ -6126,9 +6127,10 @@ int Rows_log_event::do_apply_event(RELAY_LOG_INFO const *rli)
{ /* error has occured during the transaction */ { /* error has occured during the transaction */
rli->report(ERROR_LEVEL, thd->net.last_errno, rli->report(ERROR_LEVEL, thd->net.last_errno,
"Error in %s event: error during transaction execution " "Error in %s event: error during transaction execution "
"on table %s.%s", "on table %s.%s. %s",
get_type_str(), table->s->db.str, get_type_str(), table->s->db.str,
table->s->table_name.str); table->s->table_name.str,
thd->net.last_error ? thd->net.last_error : "");
/* /*
If one day we honour --skip-slave-errors in row-based replication, and If one day we honour --skip-slave-errors in row-based replication, and
...@@ -7092,7 +7094,12 @@ replace_record(THD *thd, TABLE *table, ...@@ -7092,7 +7094,12 @@ replace_record(THD *thd, TABLE *table,
} }
if ((keynum= table->file->get_dup_key(error)) < 0) if ((keynum= table->file->get_dup_key(error)) < 0)
{ {
/* We failed to retrieve the duplicate key */ table->file->print_error(error, MYF(0));
/*
We failed to retrieve the duplicate key
- either because the error was not "duplicate key" error
- or because the information which key is not available
*/
DBUG_RETURN(error); DBUG_RETURN(error);
} }
......
...@@ -1280,6 +1280,16 @@ public: ...@@ -1280,6 +1280,16 @@ public:
* @{ * @{
*/ */
/**
* Structure for passing in pointers to startTransaction
*
*/
struct Key_part_ptr
{
const void * ptr;
unsigned len;
};
/** /**
* Start a transaction * Start a transaction
* *
...@@ -1300,6 +1310,30 @@ public: ...@@ -1300,6 +1310,30 @@ public:
const char *keyData = 0, const char *keyData = 0,
Uint32 keyLen = 0); Uint32 keyLen = 0);
/**
* Compute hash value given table/keys
*
* @param hashvalueptr - OUT, is set to hashvalue if return value is 0
* @param table Pointer to table object
* @param keyData Null-terminated array of pointers to keyParts that is
* part of distribution key.
* Length of resp. keyPart will be read from
* metadata and checked against passed value
* @param xfrmbuf Pointer to temporary buffer that will be used
* to calculate hashvalue
* @param xfrmbuflen Lengh of buffer
*
* @note if xfrmbuf is null (default) malloc/free will be made
* if xfrmbuf is not null but length is too short, method will fail
*
* @return 0 - ok - hashvalueptr is set
* else - fail, return error code
*/
static int computeHash(Uint32* hashvalueptr,
const NdbDictionary::Table*,
const struct Key_part_ptr * keyData,
void* xfrmbuf = 0, Uint32 xfrmbuflen = 0);
/** /**
* Close a transaction. * Close a transaction.
* *
......
...@@ -11795,7 +11795,7 @@ void Dblqh::sendLCP_COMPLETE_REP(Signal* signal, Uint32 lcpId) ...@@ -11795,7 +11795,7 @@ void Dblqh::sendLCP_COMPLETE_REP(Signal* signal, Uint32 lcpId)
sendEMPTY_LCP_CONF(signal, true); sendEMPTY_LCP_CONF(signal, true);
} }
if (getNodeState().getNodeRestartInProgress()) if (getNodeState().getNodeRestartInProgress() && cstartRecReq != 3)
{ {
jam(); jam();
ndbrequire(cstartRecReq == 2); ndbrequire(cstartRecReq == 2);
...@@ -14215,15 +14215,6 @@ void Dblqh::execSTART_RECREQ(Signal* signal) ...@@ -14215,15 +14215,6 @@ void Dblqh::execSTART_RECREQ(Signal* signal)
* WE ALSO NEED TO SET CNEWEST_GCI TO ENSURE THAT LOG RECORDS ARE EXECUTED * WE ALSO NEED TO SET CNEWEST_GCI TO ENSURE THAT LOG RECORDS ARE EXECUTED
* WITH A PROPER GCI. * WITH A PROPER GCI.
*------------------------------------------------------------------------ */ *------------------------------------------------------------------------ */
if(cstartType == NodeState::ST_INITIAL_NODE_RESTART){
jam();
cstartRecReq = 2;
StartRecConf * conf = (StartRecConf*)signal->getDataPtrSend();
conf->startingNodeId = getOwnNodeId();
sendSignal(cmasterDihBlockref, GSN_START_RECCONF, signal,
StartRecConf::SignalLength, JBB);
return;
}//if
if (c_lcp_restoring_fragments.isEmpty()) if (c_lcp_restoring_fragments.isEmpty())
{ {
...@@ -14276,6 +14267,19 @@ void Dblqh::execSTART_RECCONF(Signal* signal) ...@@ -14276,6 +14267,19 @@ void Dblqh::execSTART_RECCONF(Signal* signal)
jam(); jam();
csrExecUndoLogState = EULS_COMPLETED; csrExecUndoLogState = EULS_COMPLETED;
if(cstartType == NodeState::ST_INITIAL_NODE_RESTART)
{
jam();
cstartRecReq = 2;
StartRecConf * conf = (StartRecConf*)signal->getDataPtrSend();
conf->startingNodeId = getOwnNodeId();
sendSignal(cmasterDihBlockref, GSN_START_RECCONF, signal,
StartRecConf::SignalLength, JBB);
return;
}
c_lcp_complete_fragments.first(fragptr); c_lcp_complete_fragments.first(fragptr);
build_acc(signal, fragptr.i); build_acc(signal, fragptr.i);
return; return;
......
...@@ -346,6 +346,12 @@ Lgman::execCREATE_FILEGROUP_REQ(Signal* signal){ ...@@ -346,6 +346,12 @@ Lgman::execCREATE_FILEGROUP_REQ(Signal* signal){
m_logfile_group_hash.add(ptr); m_logfile_group_hash.add(ptr);
m_logfile_group_list.add(ptr); m_logfile_group_list.add(ptr);
if (getNodeState().getNodeRestartInProgress() ||
getNodeState().getSystemRestartInProgress())
{
ptr.p->m_state = Logfile_group::LG_STARTING;
}
CreateFilegroupImplConf* conf= CreateFilegroupImplConf* conf=
(CreateFilegroupImplConf*)signal->getDataPtr(); (CreateFilegroupImplConf*)signal->getDataPtr();
...@@ -370,8 +376,6 @@ Lgman::execDROP_FILEGROUP_REQ(Signal* signal) ...@@ -370,8 +376,6 @@ Lgman::execDROP_FILEGROUP_REQ(Signal* signal)
{ {
jamEntry(); jamEntry();
jamEntry();
Uint32 errorCode = 0; Uint32 errorCode = 0;
DropFilegroupImplReq req = *(DropFilegroupImplReq*)signal->getDataPtr(); DropFilegroupImplReq req = *(DropFilegroupImplReq*)signal->getDataPtr();
do do
...@@ -717,7 +721,8 @@ Lgman::create_file_commit(Signal* signal, ...@@ -717,7 +721,8 @@ Lgman::create_file_commit(Signal* signal,
Uint32 senderData = ptr.p->m_create.m_senderData; Uint32 senderData = ptr.p->m_create.m_senderData;
bool first= false; bool first= false;
if(ptr.p->m_state == Undofile::FS_CREATING) if(ptr.p->m_state == Undofile::FS_CREATING &&
(lg_ptr.p->m_state & Logfile_group::LG_ONLINE))
{ {
jam(); jam();
Local_undofile_list free(m_file_pool, lg_ptr.p->m_files); Local_undofile_list free(m_file_pool, lg_ptr.p->m_files);
...@@ -2082,13 +2087,17 @@ Lgman::execSTART_RECREQ(Signal* signal) ...@@ -2082,13 +2087,17 @@ Lgman::execSTART_RECREQ(Signal* signal)
void void
Lgman::find_log_head(Signal* signal, Ptr<Logfile_group> ptr) Lgman::find_log_head(Signal* signal, Ptr<Logfile_group> ptr)
{ {
ndbrequire(ptr.p->m_state &
(Logfile_group::LG_STARTING | Logfile_group::LG_SORTING));
if(ptr.p->m_meta_files.isEmpty() && ptr.p->m_files.isEmpty()) if(ptr.p->m_meta_files.isEmpty() && ptr.p->m_files.isEmpty())
{ {
jam(); jam();
/** /**
* Logfile_group wo/ any files * Logfile_group wo/ any files
*/ */
ptr.p->m_state &= ~(Uint32)Logfile_group::LG_STARTING;
ptr.p->m_state |= Logfile_group::LG_ONLINE;
m_logfile_group_list.next(ptr); m_logfile_group_list.next(ptr);
signal->theData[0] = LgmanContinueB::FIND_LOG_HEAD; signal->theData[0] = LgmanContinueB::FIND_LOG_HEAD;
signal->theData[1] = ptr.i; signal->theData[1] = ptr.i;
......
...@@ -175,13 +175,14 @@ public: ...@@ -175,13 +175,14 @@ public:
,LG_SORTING = 0x002 // Sorting files ,LG_SORTING = 0x002 // Sorting files
,LG_SEARCHING = 0x004 // Searching in last file ,LG_SEARCHING = 0x004 // Searching in last file
,LG_EXEC_THREAD = 0x008 // Execute thread is running ,LG_EXEC_THREAD = 0x008 // Execute thread is running
,LG_READ_THREAD = 0x010 // Read thread is running ,LG_READ_THREAD = 0x010 // Read thread is running
,LG_FORCE_SYNC_THREAD = 0x020 ,LG_FORCE_SYNC_THREAD = 0x020
,LG_SYNC_WAITERS_THREAD = 0x040 ,LG_SYNC_WAITERS_THREAD = 0x040
,LG_CUT_LOG_THREAD = 0x080 ,LG_CUT_LOG_THREAD = 0x080
,LG_WAITERS_THREAD = 0x100 ,LG_WAITERS_THREAD = 0x100
,LG_FLUSH_THREAD = 0x200 ,LG_FLUSH_THREAD = 0x200
,LG_DROPPING = 0x400 ,LG_DROPPING = 0x400
,LG_STARTING = 0x800
}; };
static const Uint32 LG_THREAD_MASK = Logfile_group::LG_FORCE_SYNC_THREAD | static const Uint32 LG_THREAD_MASK = Logfile_group::LG_FORCE_SYNC_THREAD |
......
...@@ -37,6 +37,7 @@ Name: Ndb.cpp ...@@ -37,6 +37,7 @@ Name: Ndb.cpp
#include "API.hpp" #include "API.hpp"
#include <NdbEnv.h> #include <NdbEnv.h>
#include <BaseString.hpp> #include <BaseString.hpp>
#include <NdbSqlUtil.hpp>
/**************************************************************************** /****************************************************************************
void connect(); void connect();
...@@ -304,6 +305,181 @@ Return Value: Returns a pointer to a connection object. ...@@ -304,6 +305,181 @@ Return Value: Returns a pointer to a connection object.
Return NULL otherwise. Return NULL otherwise.
Remark: Start transaction. Synchronous. Remark: Start transaction. Synchronous.
*****************************************************************************/ *****************************************************************************/
int
Ndb::computeHash(Uint32 *retval,
const NdbDictionary::Table *table,
const struct Key_part_ptr * keyData,
void* buf, Uint32 bufLen)
{
Uint32 j = 0;
Uint32 sumlen = 0; // Needed len
const NdbTableImpl* impl = &NdbTableImpl::getImpl(*table);
const NdbColumnImpl* const * cols = impl->m_columns.getBase();
Uint32 len;
NdbTransaction* trans;
char* pos;
Uint32 colcnt = impl->m_columns.size();
Uint32 parts = impl->m_noOfDistributionKeys;
if (parts == 0)
{
parts = impl->m_noOfKeys;
}
for (Uint32 i = 0; i<parts; i++)
{
if (unlikely(keyData[i].ptr == 0))
goto enullptr;
}
if (unlikely(keyData[parts].ptr != 0))
goto emissingnullptr;
const NdbColumnImpl* partcols[NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY];
for (Uint32 i = 0; i<colcnt && j < parts; i++)
{
if (cols[i]->m_distributionKey)
{
// wl3717_todo
// char allowed now as dist key so this case should be tested
partcols[j++] = cols[i];
}
}
for (Uint32 i = 0; i<parts; i++)
{
Uint32 lb, len;
if (unlikely(!NdbSqlUtil::get_var_length(partcols[i]->m_type,
keyData[i].ptr,
keyData[i].len,
lb, len)))
goto emalformedkey;
if (unlikely(keyData[i].len < (lb + len)))
goto elentosmall;
Uint32 maxlen = (partcols[i]->m_attrSize * partcols[i]->m_arraySize);
if (unlikely(lb == 0 && keyData[i].len != maxlen))
goto emalformedkey;
if (partcols[i]->m_cs)
{
Uint32 xmul = partcols[i]->m_cs->strxfrm_multiply;
xmul = xmul ? xmul : 1;
len = xmul * (maxlen - lb);
}
len = (lb + len + 3) & ~(Uint32)3;
sumlen += len;
}
if (buf)
{
UintPtr org = UintPtr(buf);
UintPtr use = (org + 7) & ~(UintPtr)7;
buf = (void*)use;
bufLen -= (use - org);
if (unlikely(sumlen > bufLen))
goto ebuftosmall;
}
else
{
buf = malloc(sumlen);
if (unlikely(buf == 0))
goto enomem;
bufLen = 0;
assert((UintPtr(buf) & 7) == 0);
}
pos = (char*)buf;
for (Uint32 i = 0; i<parts; i++)
{
Uint32 lb, len;
NdbSqlUtil::get_var_length(partcols[i]->m_type,
keyData[i].ptr, keyData[i].len, lb, len);
CHARSET_INFO* cs;
if ((cs = partcols[i]->m_cs))
{
Uint32 xmul = cs->strxfrm_multiply;
if (xmul == 0)
xmul = 1;
/*
* Varchar end-spaces are ignored in comparisons. To get same hash
* we blank-pad to maximum length via strnxfrm.
*/
Uint32 maxlen = (partcols[i]->m_attrSize * partcols[i]->m_arraySize);
Uint32 dstLen = xmul * (maxlen - lb);
int n = NdbSqlUtil::strnxfrm_bug7284(cs,
(unsigned char*)pos,
dstLen,
((unsigned char*)keyData[i].ptr)+lb,
len);
if (unlikely(n == -1))
goto emalformedstring;
while ((n & 3) != 0)
{
pos[n++] = 0;
}
pos += n;
}
else
{
len += lb;
memcpy(pos, keyData[i].ptr, len);
while (len & 3)
{
* (pos + len++) = 0;
}
pos += len;
}
}
len = UintPtr(pos) - UintPtr(buf);
assert((len & 3) == 0);
Uint32 values[4];
md5_hash(values, (const Uint64*)buf, len >> 2);
if (retval)
{
* retval = values[1];
}
if (bufLen == 0)
free(buf);
return 0;
enullptr:
return 4316;
emissingnullptr:
return 4276;
elentosmall:
return 4277;
ebuftosmall:
return 4278;
emalformedstring:
if (bufLen == 0)
free(buf);
return 4279;
emalformedkey:
return 4280;
enomem:
return 4000;
}
NdbTransaction* NdbTransaction*
Ndb::startTransaction(const NdbDictionary::Table *table, Ndb::startTransaction(const NdbDictionary::Table *table,
const char * keyData, Uint32 keyLen) const char * keyData, Uint32 keyLen)
......
...@@ -391,7 +391,7 @@ struct NdbFileImpl : public NdbDictObjectImpl { ...@@ -391,7 +391,7 @@ struct NdbFileImpl : public NdbDictObjectImpl {
NdbFileImpl(NdbDictionary::Object::Type t); NdbFileImpl(NdbDictionary::Object::Type t);
Uint64 m_size; Uint64 m_size;
Uint32 m_free; Uint64 m_free;
BaseString m_path; BaseString m_path;
BaseString m_filegroup_name; BaseString m_filegroup_name;
Uint32 m_filegroup_id; Uint32 m_filegroup_id;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment