Commit 38814b22 authored by jonas@perch.ndb.mysql.com's avatar jonas@perch.ndb.mysql.com

Merge joreland@bk-internal.mysql.com:/home/bk/mysql-5.1-telco-gca

into  perch.ndb.mysql.com:/home/jonas/src/51-work
parents ce68810d 60ab46bd
...@@ -3817,7 +3817,7 @@ int ha_ndbcluster::info(uint flag) ...@@ -3817,7 +3817,7 @@ int ha_ndbcluster::info(uint flag)
if (flag & HA_STATUS_AUTO) if (flag & HA_STATUS_AUTO)
{ {
DBUG_PRINT("info", ("HA_STATUS_AUTO")); DBUG_PRINT("info", ("HA_STATUS_AUTO"));
if (m_table) if (m_table && table->found_next_number_field)
{ {
Ndb *ndb= get_ndb(); Ndb *ndb= get_ndb();
Ndb_tuple_id_range_guard g(m_share); Ndb_tuple_id_range_guard g(m_share);
......
...@@ -212,7 +212,8 @@ public: ...@@ -212,7 +212,8 @@ public:
NullablePrimaryKey = 740, NullablePrimaryKey = 740,
UnsupportedChange = 741, UnsupportedChange = 741,
BackupInProgress = 762, BackupInProgress = 762,
IncompatibleVersions = 763 IncompatibleVersions = 763,
SingleUser = 299
}; };
private: private:
......
...@@ -208,6 +208,7 @@ public: ...@@ -208,6 +208,7 @@ public:
AllocationError = 4252, AllocationError = 4252,
CreateIndexTableFailed = 4253, CreateIndexTableFailed = 4253,
DuplicateAttributes = 4258, DuplicateAttributes = 4258,
SingleUser = 299,
TableIsTemporary = 776, TableIsTemporary = 776,
TableIsNotTemporary = 777, TableIsNotTemporary = 777,
NoLoggingTemporaryIndex = 778 NoLoggingTemporaryIndex = 778
......
...@@ -92,6 +92,7 @@ public: ...@@ -92,6 +92,7 @@ public:
InvalidPrimaryKeySize = 739, InvalidPrimaryKeySize = 739,
NullablePrimaryKey = 740, NullablePrimaryKey = 740,
InvalidCharset = 743, InvalidCharset = 743,
SingleUser = 299,
InvalidTablespace = 755, InvalidTablespace = 755,
VarsizeBitfieldNotSupported = 757, VarsizeBitfieldNotSupported = 757,
NotATablespace = 758, NotATablespace = 758,
......
...@@ -172,7 +172,8 @@ public: ...@@ -172,7 +172,8 @@ public:
IndexNotFound = 4243, IndexNotFound = 4243,
BadRequestType = 4247, BadRequestType = 4247,
InvalidName = 4248, InvalidName = 4248,
NotAnIndex = 4254 NotAnIndex = 4254,
SingleUser = 299
}; };
STATIC_CONST( SignalLength = DropIndxConf::SignalLength + 3 ); STATIC_CONST( SignalLength = DropIndxConf::SignalLength + 3 );
......
...@@ -58,7 +58,8 @@ public: ...@@ -58,7 +58,8 @@ public:
InvalidTableVersion = 241, InvalidTableVersion = 241,
DropInProgress = 283, DropInProgress = 283,
NoDropTableRecordAvailable = 1229, NoDropTableRecordAvailable = 1229,
BackupInProgress = 761 BackupInProgress = 761,
SingleUser = 299
}; };
}; };
......
...@@ -107,7 +107,10 @@ public: ...@@ -107,7 +107,10 @@ public:
CmvmiDumpLongSignalMemory = 2601, CmvmiDumpLongSignalMemory = 2601,
CmvmiSetRestartOnErrorInsert = 2602, CmvmiSetRestartOnErrorInsert = 2602,
CmvmiTestLongSigWithDelay = 2603, CmvmiTestLongSigWithDelay = 2603,
CmvmiDumpSubscriptions = 2604, /* note: done to respective outfile
to be able to debug if events
for some reason does not end up
in clusterlog */
LCPContinue = 5900, LCPContinue = 5900,
// 7000 DIH // 7000 DIH
// 7001 DIH // 7001 DIH
......
...@@ -96,6 +96,8 @@ printPACKED_SIGNAL(FILE * output, const Uint32 * theData, Uint32 len, Uint16 rec ...@@ -96,6 +96,8 @@ printPACKED_SIGNAL(FILE * output, const Uint32 * theData, Uint32 len, Uint16 rec
} }
default: default:
fprintf(output, "Unknown signal type\n"); fprintf(output, "Unknown signal type\n");
i = len; // terminate printing
break;
} }
}//for }//for
fprintf(output, "--------- End Packed Signals ----------\n"); fprintf(output, "--------- End Packed Signals ----------\n");
......
...@@ -921,7 +921,7 @@ void Cmvmi::execSET_VAR_REQ(Signal* signal) ...@@ -921,7 +921,7 @@ void Cmvmi::execSET_VAR_REQ(Signal* signal)
case TimeToWaitAlive: case TimeToWaitAlive:
// QMGR // QMGR
case HeartbeatIntervalDbDb: // TODO ev till Ndbcnt ocks case HeartbeatIntervalDbDb: // TODO possibly Ndbcnt too
case HeartbeatIntervalDbApi: case HeartbeatIntervalDbApi:
case ArbitTimeout: case ArbitTimeout:
sendSignal(QMGR_REF, GSN_SET_VAR_REQ, signal, 3, JBB); sendSignal(QMGR_REF, GSN_SET_VAR_REQ, signal, 3, JBB);
...@@ -1129,6 +1129,24 @@ Cmvmi::execDUMP_STATE_ORD(Signal* signal) ...@@ -1129,6 +1129,24 @@ Cmvmi::execDUMP_STATE_ORD(Signal* signal)
} }
} }
if (arg == DumpStateOrd::CmvmiDumpSubscriptions)
{
SubscriberPtr ptr;
subscribers.first(ptr);
g_eventLogger.info("List subscriptions:");
while(ptr.i != RNIL)
{
g_eventLogger.info("Subscription: %u, nodeId: %u, ref: 0x%x",
ptr.i, refToNode(ptr.p->blockRef), ptr.p->blockRef);
for(Uint32 i = 0; i < LogLevel::LOGLEVEL_CATEGORIES; i++)
{
Uint32 level = ptr.p->logLevel.getLogLevel((LogLevel::EventCategory)i);
g_eventLogger.info("Category %u Level %u", i, level);
}
subscribers.next(ptr);
}
}
if (arg == DumpStateOrd::CmvmiDumpLongSignalMemory){ if (arg == DumpStateOrd::CmvmiDumpLongSignalMemory){
infoEvent("Cmvmi: g_sectionSegmentPool size: %d free: %d", infoEvent("Cmvmi: g_sectionSegmentPool size: %d free: %d",
g_sectionSegmentPool.getSize(), g_sectionSegmentPool.getSize(),
......
...@@ -3759,6 +3759,15 @@ Dbdict::execCREATE_TABLE_REQ(Signal* signal){ ...@@ -3759,6 +3759,15 @@ Dbdict::execCREATE_TABLE_REQ(Signal* signal){
break; break;
} }
if(getNodeState().getSingleUserMode() &&
(refToNode(signal->getSendersBlockRef()) !=
getNodeState().getSingleUserApi()))
{
jam();
parseRecord.errorCode = CreateTableRef::SingleUser;
break;
}
CreateTableRecordPtr createTabPtr; CreateTableRecordPtr createTabPtr;
c_opCreateTable.seize(createTabPtr); c_opCreateTable.seize(createTabPtr);
...@@ -3951,6 +3960,15 @@ Dbdict::execALTER_TABLE_REQ(Signal* signal) ...@@ -3951,6 +3960,15 @@ Dbdict::execALTER_TABLE_REQ(Signal* signal)
return; return;
} }
if(getNodeState().getSingleUserMode() &&
(refToNode(signal->getSendersBlockRef()) !=
getNodeState().getSingleUserApi()))
{
jam();
alterTableRef(signal, req, AlterTableRef::SingleUser);
return;
}
const TableRecord::TabState tabState = tablePtr.p->tabState; const TableRecord::TabState tabState = tablePtr.p->tabState;
bool ok = false; bool ok = false;
switch(tabState){ switch(tabState){
...@@ -6550,6 +6568,15 @@ Dbdict::execDROP_TABLE_REQ(Signal* signal){ ...@@ -6550,6 +6568,15 @@ Dbdict::execDROP_TABLE_REQ(Signal* signal){
return; return;
} }
if(getNodeState().getSingleUserMode() &&
(refToNode(signal->getSendersBlockRef()) !=
getNodeState().getSingleUserApi()))
{
jam();
dropTableRef(signal, req, DropTableRef::SingleUser);
return;
}
const TableRecord::TabState tabState = tablePtr.p->tabState; const TableRecord::TabState tabState = tablePtr.p->tabState;
bool ok = false; bool ok = false;
switch(tabState){ switch(tabState){
...@@ -7758,6 +7785,13 @@ Dbdict::execCREATE_INDX_REQ(Signal* signal) ...@@ -7758,6 +7785,13 @@ Dbdict::execCREATE_INDX_REQ(Signal* signal)
jam(); jam();
tmperr = CreateIndxRef::Busy; tmperr = CreateIndxRef::Busy;
} }
else if(getNodeState().getSingleUserMode() &&
(refToNode(senderRef) !=
getNodeState().getSingleUserApi()))
{
jam();
tmperr = CreateIndxRef::SingleUser;
}
if (tmperr != CreateIndxRef::NoError) { if (tmperr != CreateIndxRef::NoError) {
releaseSections(signal); releaseSections(signal);
OpCreateIndex opBusy; OpCreateIndex opBusy;
...@@ -8401,6 +8435,13 @@ Dbdict::execDROP_INDX_REQ(Signal* signal) ...@@ -8401,6 +8435,13 @@ Dbdict::execDROP_INDX_REQ(Signal* signal)
jam(); jam();
tmperr = DropIndxRef::Busy; tmperr = DropIndxRef::Busy;
} }
else if(getNodeState().getSingleUserMode() &&
(refToNode(senderRef) !=
getNodeState().getSingleUserApi()))
{
jam();
tmperr = DropIndxRef::SingleUser;
}
if (tmperr != DropIndxRef::NoError) { if (tmperr != DropIndxRef::NoError) {
err = tmperr; err = tmperr;
goto error; goto error;
......
...@@ -22,7 +22,10 @@ ...@@ -22,7 +22,10 @@
#include <NdbOut.hpp> #include <NdbOut.hpp>
#include <NdbSleep.h> #include <NdbSleep.h>
#include <ErrorHandlingMacros.hpp> #include <ErrorHandlingMacros.hpp>
#include <EventLogger.hpp>
extern EventLogger g_eventLogger;
extern "C" extern "C"
void* void*
runWatchDog(void* w){ runWatchDog(void* w){
...@@ -125,7 +128,7 @@ WatchDog::run(){ ...@@ -125,7 +128,7 @@ WatchDog::run(){
last_stuck_action = "Unknown place"; last_stuck_action = "Unknown place";
break; break;
}//switch }//switch
ndbout << "Ndb kernel is stuck in: " << last_stuck_action << endl; g_eventLogger.warning("Ndb kernel is stuck in: %s", last_stuck_action);
if(alerts == 3){ if(alerts == 3){
shutdownSystem(last_stuck_action); shutdownSystem(last_stuck_action);
} }
......
...@@ -699,7 +699,7 @@ int MgmtSrvr::okToSendTo(NodeId nodeId, bool unCond) ...@@ -699,7 +699,7 @@ int MgmtSrvr::okToSendTo(NodeId nodeId, bool unCond)
return WRONG_PROCESS_TYPE; return WRONG_PROCESS_TYPE;
// Check if we have contact with it // Check if we have contact with it
if(unCond){ if(unCond){
if(theFacade->theClusterMgr->getNodeInfo(nodeId).connected) if(theFacade->theClusterMgr->getNodeInfo(nodeId).m_api_reg_conf)
return 0; return 0;
} }
else if (theFacade->get_node_alive(nodeId) == true) else if (theFacade->get_node_alive(nodeId) == true)
...@@ -1574,32 +1574,85 @@ MgmtSrvr::status(int nodeId, ...@@ -1574,32 +1574,85 @@ MgmtSrvr::status(int nodeId,
} }
int int
MgmtSrvr::setEventReportingLevelImpl(int nodeId, MgmtSrvr::setEventReportingLevelImpl(int nodeId_arg,
const EventSubscribeReq& ll) const EventSubscribeReq& ll)
{ {
SignalSender ss(theFacade); SignalSender ss(theFacade);
ss.lock(); NdbNodeBitmask nodes;
int retries = 30;
SimpleSignal ssig;
EventSubscribeReq * dst =
CAST_PTR(EventSubscribeReq, ssig.getDataPtrSend());
ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_EVENT_SUBSCRIBE_REQ,
EventSubscribeReq::SignalLength);
*dst = ll;
NodeBitmask nodes;
nodes.clear(); nodes.clear();
Uint32 max = (nodeId == 0) ? (nodeId = 1, MAX_NDB_NODES) : nodeId; while (1)
for(; (Uint32) nodeId <= max; nodeId++)
{ {
if (nodeTypes[nodeId] != NODE_TYPE_DB) Uint32 nodeId, max;
continue; ss.lock();
if (okToSendTo(nodeId, true)) SimpleSignal ssig;
continue; EventSubscribeReq * dst =
if (ss.sendSignal(nodeId, &ssig) == SEND_OK) CAST_PTR(EventSubscribeReq, ssig.getDataPtrSend());
ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_EVENT_SUBSCRIBE_REQ,
EventSubscribeReq::SignalLength);
*dst = ll;
if (nodeId_arg == 0)
{ {
nodes.set(nodeId); // all nodes
nodeId = 1;
max = MAX_NDB_NODES;
}
else
{
// only one node
max = nodeId = nodeId_arg;
}
// first make sure nodes are sendable
for(; nodeId <= max; nodeId++)
{
if (nodeTypes[nodeId] != NODE_TYPE_DB)
continue;
if (okToSendTo(nodeId, true))
{
if (theFacade->theClusterMgr->getNodeInfo(nodeId).connected == false)
{
// node not connected we can safely skip this one
continue;
}
// api_reg_conf not recevied yet, need to retry
break;
}
}
if (nodeId <= max)
{
if (--retries)
{
ss.unlock();
NdbSleep_MilliSleep(100);
continue;
}
return SEND_OR_RECEIVE_FAILED;
}
if (nodeId_arg == 0)
{
// all nodes
nodeId = 1;
max = MAX_NDB_NODES;
}
else
{
// only one node
max = nodeId = nodeId_arg;
} }
// now send to all sendable nodes nodes
// note, lock is held, so states have not changed
for(; (Uint32) nodeId <= max; nodeId++)
{
if (nodeTypes[nodeId] != NODE_TYPE_DB)
continue;
if (theFacade->theClusterMgr->getNodeInfo(nodeId).connected == false)
continue; // node is not connected, skip
if (ss.sendSignal(nodeId, &ssig) == SEND_OK)
nodes.set(nodeId);
}
break;
} }
if (nodes.isclear()) if (nodes.isclear())
...@@ -1610,6 +1663,7 @@ MgmtSrvr::setEventReportingLevelImpl(int nodeId, ...@@ -1610,6 +1663,7 @@ MgmtSrvr::setEventReportingLevelImpl(int nodeId,
int error = 0; int error = 0;
while (!nodes.isclear()) while (!nodes.isclear())
{ {
Uint32 nodeId;
SimpleSignal *signal = ss.waitFor(); SimpleSignal *signal = ss.waitFor();
int gsn = signal->readSignalNumber(); int gsn = signal->readSignalNumber();
nodeId = refToNode(signal->header.theSendersBlockRef); nodeId = refToNode(signal->header.theSendersBlockRef);
......
...@@ -313,7 +313,7 @@ ClusterMgr::showState(NodeId nodeId){ ...@@ -313,7 +313,7 @@ ClusterMgr::showState(NodeId nodeId){
ClusterMgr::Node::Node() ClusterMgr::Node::Node()
: m_state(NodeState::SL_NOTHING) { : m_state(NodeState::SL_NOTHING) {
compatible = nfCompleteRep = true; compatible = nfCompleteRep = true;
connected = defined = m_alive = false; connected = defined = m_alive = m_api_reg_conf = false;
m_state.m_connected_nodes.clear(); m_state.m_connected_nodes.clear();
} }
...@@ -387,6 +387,8 @@ ClusterMgr::execAPI_REGCONF(const Uint32 * theData){ ...@@ -387,6 +387,8 @@ ClusterMgr::execAPI_REGCONF(const Uint32 * theData){
node.m_info.m_version); node.m_info.m_version);
} }
node.m_api_reg_conf = true;
node.m_state = apiRegConf->nodeState; node.m_state = apiRegConf->nodeState;
if (node.compatible && (node.m_state.startLevel == NodeState::SL_STARTED || if (node.compatible && (node.m_state.startLevel == NodeState::SL_STARTED ||
node.m_state.startLevel == NodeState::SL_SINGLEUSER)){ node.m_state.startLevel == NodeState::SL_SINGLEUSER)){
...@@ -503,6 +505,7 @@ ClusterMgr::reportDisconnected(NodeId nodeId){ ...@@ -503,6 +505,7 @@ ClusterMgr::reportDisconnected(NodeId nodeId){
noOfConnectedNodes--; noOfConnectedNodes--;
theNodes[nodeId].connected = false; theNodes[nodeId].connected = false;
theNodes[nodeId].m_api_reg_conf = false;
theNodes[nodeId].m_state.m_connected_nodes.clear(); theNodes[nodeId].m_state.m_connected_nodes.clear();
reportNodeFailed(nodeId, true); reportNodeFailed(nodeId, true);
......
...@@ -70,6 +70,7 @@ public: ...@@ -70,6 +70,7 @@ public:
bool compatible; // Version is compatible bool compatible; // Version is compatible
bool nfCompleteRep; // NF Complete Rep has arrived bool nfCompleteRep; // NF Complete Rep has arrived
bool m_alive; // Node is alive bool m_alive; // Node is alive
bool m_api_reg_conf;// API_REGCONF has arrived
NodeInfo m_info; NodeInfo m_info;
NodeState m_state; NodeState m_state;
......
...@@ -343,24 +343,24 @@ NdbOut& operator<<(NdbOut& out, const NdbRecAttr &r) ...@@ -343,24 +343,24 @@ NdbOut& operator<<(NdbOut& out, const NdbRecAttr &r)
} }
break; break;
case NdbDictionary::Column::Blob: case NdbDictionary::Column::Blob:
{
const NdbBlob::Head* h = (const NdbBlob::Head*)r.aRef();
out << h->length << ":";
const unsigned char* p = (const unsigned char*)(h + 1);
unsigned n = r.get_size_in_bytes() - sizeof(*h);
for (unsigned k = 0; k < n && k < h->length; k++)
out.print("%02X", (int)p[k]);
j = length;
}
break;
case NdbDictionary::Column::Text: case NdbDictionary::Column::Text:
{ {
const NdbBlob::Head* h = (const NdbBlob::Head*)r.aRef(); // user defined aRef() may not be aligned to Uint64
out << h->length << ":"; NdbBlob::Head head;
const unsigned char* p = (const unsigned char*)(h + 1); memcpy(&head, r.aRef(), sizeof(head));
unsigned n = r.get_size_in_bytes() - sizeof(*h); out << head.length << ":";
for (unsigned k = 0; k < n && k < h->length; k++) const unsigned char* p = (const unsigned char*)r.aRef() + sizeof(head);
out.print("%c", (int)p[k]); if (r.get_size_in_bytes() < sizeof(head))
out << "***error***"; // really cannot happen
else {
unsigned n = r.get_size_in_bytes() - sizeof(head);
for (unsigned k = 0; k < n && k < head.length; k++) {
if (r.getType() == NdbDictionary::Column::Blob)
out.print("%02X", (int)p[k]);
else
out.print("%c", (int)p[k]);
}
}
j = length; j = length;
} }
break; break;
......
...@@ -32,7 +32,7 @@ public: ...@@ -32,7 +32,7 @@ public:
Uint32 theData[25]; Uint32 theData[25];
LinearSectionPtr ptr[3]; LinearSectionPtr ptr[3];
int readSignalNumber() {return header.theVerId_signalNumber; } int readSignalNumber() const {return header.theVerId_signalNumber; }
Uint32 *getDataPtrSend() { return theData; } Uint32 *getDataPtrSend() { return theData; }
const Uint32 *getDataPtr() const { return theData; } const Uint32 *getDataPtr() const { return theData; }
......
...@@ -1527,7 +1527,8 @@ SignalSender::sendSignal(Uint16 nodeId, const SimpleSignal * s){ ...@@ -1527,7 +1527,8 @@ SignalSender::sendSignal(Uint16 nodeId, const SimpleSignal * s){
signalLogger.flushSignalLog(); signalLogger.flushSignalLog();
} }
#endif #endif
assert(getNodeInfo(nodeId).m_api_reg_conf == true ||
s->readSignalNumber() == GSN_API_REGREQ);
return theFacade->theTransporterRegistry->prepareSend(&s->header, return theFacade->theTransporterRegistry->prepareSend(&s->header,
1, // JBB 1, // JBB
&s->theData[0], &s->theData[0],
......
...@@ -283,6 +283,7 @@ ErrorBundle ErrorCodes[] = { ...@@ -283,6 +283,7 @@ ErrorBundle ErrorCodes[] = {
/** /**
* Application error * Application error
*/ */
{ 299, DMEC, AE, "Operation not allowed or aborted due to single user mode" },
{ 763, DMEC, AE, "Alter table requires cluster nodes to have exact same version" }, { 763, DMEC, AE, "Alter table requires cluster nodes to have exact same version" },
{ 823, DMEC, AE, "Too much attrinfo from application in tuple manager" }, { 823, DMEC, AE, "Too much attrinfo from application in tuple manager" },
{ 831, DMEC, AE, "Too many nullable/bitfields in table definition" }, { 831, DMEC, AE, "Too many nullable/bitfields in table definition" },
......
...@@ -59,7 +59,12 @@ BackupFile::Twiddle(const AttributeDesc* attr_desc, AttributeData* attr_data, Ui ...@@ -59,7 +59,12 @@ BackupFile::Twiddle(const AttributeDesc* attr_desc, AttributeData* attr_data, Ui
return true; return true;
case 64: case 64:
for(i = 0; i<arraySize; i++){ for(i = 0; i<arraySize; i++){
attr_data->u_int64_value[i] = Twiddle64(attr_data->u_int64_value[i]); // allow unaligned
char* p = (char*)&attr_data->u_int64_value[i];
Uint64 x;
memcpy(&x, p, sizeof(Uint64));
x = Twiddle64(x);
memcpy(p, &x, sizeof(Uint64));
} }
return true; return true;
default: default:
......
...@@ -667,6 +667,8 @@ BackupRestore::update_apply_status(const RestoreMetaData &metaData) ...@@ -667,6 +667,8 @@ BackupRestore::update_apply_status(const RestoreMetaData &metaData)
bool bool
BackupRestore::createSystable(const TableS & tables){ BackupRestore::createSystable(const TableS & tables){
if (!m_restore && !m_restore_meta && !m_restore_epoch)
return true;
const char *tablename = tables.getTableName(); const char *tablename = tables.getTableName();
if( strcmp(tablename, NDB_REP_DB "/def/" NDB_APPLY_TABLE) != 0 && if( strcmp(tablename, NDB_REP_DB "/def/" NDB_APPLY_TABLE) != 0 &&
......
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