ndb - bug#21271

  make each fragment use own LCP file, so that (s/n)r can use different LCP-no for different fragments
parent 9cc27b67
...@@ -136,9 +136,11 @@ private: ...@@ -136,9 +136,11 @@ private:
*/ */
static Uint32 v5_getLcpNo(const Uint32 fileNumber[]); static Uint32 v5_getLcpNo(const Uint32 fileNumber[]);
static Uint32 v5_getTableId(const Uint32 fileNumber[]); static Uint32 v5_getTableId(const Uint32 fileNumber[]);
static Uint32 v5_getFragmentId(const Uint32 fileNumber[]);
static void v5_setLcpNo(Uint32 fileNumber[], Uint32 no); static void v5_setLcpNo(Uint32 fileNumber[], Uint32 no);
static void v5_setTableId(Uint32 fileNumber[], Uint32 no); static void v5_setTableId(Uint32 fileNumber[], Uint32 no);
static void v5_setFragmentId(Uint32 fileNumber[], Uint32 no);
}; };
/** /**
...@@ -318,5 +320,15 @@ void FsOpenReq::v5_setLcpNo(Uint32 fileNumber[], Uint32 val){ ...@@ -318,5 +320,15 @@ void FsOpenReq::v5_setLcpNo(Uint32 fileNumber[], Uint32 val){
fileNumber[1] = val; fileNumber[1] = val;
} }
inline
Uint32 FsOpenReq::v5_getFragmentId(const Uint32 fileNumber[]){
return fileNumber[2];
}
inline
void FsOpenReq::v5_setFragmentId(Uint32 fileNumber[], Uint32 val){
fileNumber[2] = val;
}
#endif #endif
...@@ -3,7 +3,7 @@ Next NDBCNTR 1000 ...@@ -3,7 +3,7 @@ Next NDBCNTR 1000
Next NDBFS 2000 Next NDBFS 2000
Next DBACC 3002 Next DBACC 3002
Next DBTUP 4024 Next DBTUP 4024
Next DBLQH 5043 Next DBLQH 5045
Next DBDICT 6007 Next DBDICT 6007
Next DBDIH 7177 Next DBDIH 7177
Next DBTC 8037 Next DBTC 8037
......
...@@ -3796,20 +3796,28 @@ Backup::fragmentCompleted(Signal* signal, BackupFilePtr filePtr) ...@@ -3796,20 +3796,28 @@ Backup::fragmentCompleted(Signal* signal, BackupFilePtr filePtr)
BackupRecordPtr ptr; BackupRecordPtr ptr;
c_backupPool.getPtr(ptr, filePtr.p->backupPtr); c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
BackupFragmentConf * conf = (BackupFragmentConf*)signal->getDataPtrSend(); if (ptr.p->is_lcp())
conf->backupId = ptr.p->backupId; {
conf->backupPtr = ptr.i; ptr.p->slaveState.setState(STOPPING);
conf->tableId = filePtr.p->tableId; filePtr.p->operation.dataBuffer.eof();
conf->fragmentNo = filePtr.p->fragmentNo; }
conf->noOfRecordsLow = (Uint32)(op.noOfRecords & 0xFFFFFFFF); else
conf->noOfRecordsHigh = (Uint32)(op.noOfRecords >> 32); {
conf->noOfBytesLow = (Uint32)(op.noOfBytes & 0xFFFFFFFF); BackupFragmentConf * conf = (BackupFragmentConf*)signal->getDataPtrSend();
conf->noOfBytesHigh = (Uint32)(op.noOfBytes >> 32); conf->backupId = ptr.p->backupId;
sendSignal(ptr.p->masterRef, GSN_BACKUP_FRAGMENT_CONF, signal, conf->backupPtr = ptr.i;
BackupFragmentConf::SignalLength, JBB); conf->tableId = filePtr.p->tableId;
conf->fragmentNo = filePtr.p->fragmentNo;
ptr.p->m_gsn = GSN_BACKUP_FRAGMENT_CONF; conf->noOfRecordsLow = (Uint32)(op.noOfRecords & 0xFFFFFFFF);
ptr.p->slaveState.setState(STARTED); conf->noOfRecordsHigh = (Uint32)(op.noOfRecords >> 32);
conf->noOfBytesLow = (Uint32)(op.noOfBytes & 0xFFFFFFFF);
conf->noOfBytesHigh = (Uint32)(op.noOfBytes >> 32);
sendSignal(ptr.p->masterRef, GSN_BACKUP_FRAGMENT_CONF, signal,
BackupFragmentConf::SignalLength, JBB);
ptr.p->m_gsn = GSN_BACKUP_FRAGMENT_CONF;
ptr.p->slaveState.setState(STARTED);
}
return; return;
} }
...@@ -4719,29 +4727,8 @@ Backup::execLCP_PREPARE_REQ(Signal* signal) ...@@ -4719,29 +4727,8 @@ Backup::execLCP_PREPARE_REQ(Signal* signal)
BackupRecordPtr ptr; BackupRecordPtr ptr;
c_backupPool.getPtr(ptr, req.backupPtr); c_backupPool.getPtr(ptr, req.backupPtr);
bool first= true;
TablePtr tabPtr; TablePtr tabPtr;
if(ptr.p->tables.first(tabPtr) && tabPtr.p->tableId != req.tableId) if(ptr.p->errorCode == 0)
{
jam();
first= false;
tabPtr.p->attributes.release();
tabPtr.p->fragments.release();
ptr.p->tables.release();
ptr.p->errorCode = 0;
}
if(ptr.p->tables.first(tabPtr) && ptr.p->errorCode == 0)
{
jam();
FragmentPtr fragPtr;
tabPtr.p->fragments.getPtr(fragPtr, 0);
fragPtr.p->fragmentId = req.fragmentId;
lcp_open_file_done(signal, ptr);
return;
}
else if(ptr.p->errorCode == 0)
{ {
jam(); jam();
FragmentPtr fragPtr; FragmentPtr fragPtr;
...@@ -4759,6 +4746,9 @@ Backup::execLCP_PREPARE_REQ(Signal* signal) ...@@ -4759,6 +4746,9 @@ Backup::execLCP_PREPARE_REQ(Signal* signal)
fragPtr.p->scanned = 0; fragPtr.p->scanned = 0;
fragPtr.p->scanning = 0; fragPtr.p->scanning = 0;
fragPtr.p->tableId = req.tableId; fragPtr.p->tableId = req.tableId;
ptr.p->backupId= req.backupId;
lcp_open_file(signal, ptr);
} }
else else
{ {
...@@ -4767,43 +4757,38 @@ Backup::execLCP_PREPARE_REQ(Signal* signal) ...@@ -4767,43 +4757,38 @@ Backup::execLCP_PREPARE_REQ(Signal* signal)
tabPtr.p->fragments.getPtr(fragPtr, 0); tabPtr.p->fragments.getPtr(fragPtr, 0);
fragPtr.p->fragmentId = req.fragmentId; fragPtr.p->fragmentId = req.fragmentId;
defineBackupRef(signal, ptr, ptr.p->errorCode); defineBackupRef(signal, ptr, ptr.p->errorCode);
return;
}
if(first)
{
jam();
// start file thread
ptr.p->backupId= req.backupId;
lcp_open_file(signal, ptr);
return;
}
else
{
jam();
ndbrequire(ptr.p->backupId == req.backupId);
} }
/**
* Close previous file
*/
jam();
BackupFilePtr filePtr;
c_backupFilePool.getPtr(filePtr, ptr.p->dataFilePtr);
filePtr.p->operation.dataBuffer.eof();
} }
void void
Backup::lcp_close_file_conf(Signal* signal, BackupRecordPtr ptr) Backup::lcp_close_file_conf(Signal* signal, BackupRecordPtr ptr)
{ {
if(!ptr.p->tables.isEmpty()) jam();
{
jam(); TablePtr tabPtr;
lcp_open_file(signal, ptr); ndbrequire(ptr.p->tables.first(tabPtr));
return; Uint32 tableId = tabPtr.p->tableId;
}
FragmentPtr fragPtr;
tabPtr.p->fragments.getPtr(fragPtr, 0);
Uint32 fragmentId = fragPtr.p->fragmentId;
tabPtr.p->attributes.release();
tabPtr.p->fragments.release();
ptr.p->tables.release();
ptr.p->errorCode = 0;
lcp_send_end_lcp_conf(signal, ptr); BackupFragmentConf * conf = (BackupFragmentConf*)signal->getDataPtrSend();
conf->backupId = ptr.p->backupId;
conf->backupPtr = ptr.i;
conf->tableId = tableId;
conf->fragmentNo = fragmentId;
conf->noOfRecordsLow = 0;
conf->noOfRecordsHigh = 0;
conf->noOfBytesLow = 0;
conf->noOfBytesHigh = 0;
sendSignal(ptr.p->masterRef, GSN_BACKUP_FRAGMENT_CONF, signal,
BackupFragmentConf::SignalLength, JBB);
} }
void void
...@@ -4840,6 +4825,7 @@ Backup::lcp_open_file(Signal* signal, BackupRecordPtr ptr) ...@@ -4840,6 +4825,7 @@ Backup::lcp_open_file(Signal* signal, BackupRecordPtr ptr)
FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_DATA); FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_DATA);
FsOpenReq::v5_setLcpNo(req->fileNumber, fragPtr.p->lcp_no); FsOpenReq::v5_setLcpNo(req->fileNumber, fragPtr.p->lcp_no);
FsOpenReq::v5_setTableId(req->fileNumber, tabPtr.p->tableId); FsOpenReq::v5_setTableId(req->fileNumber, tabPtr.p->tableId);
FsOpenReq::v5_setFragmentId(req->fileNumber, fragPtr.p->fragmentId);
sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA); sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA);
} }
...@@ -4872,38 +4858,15 @@ Backup::execEND_LCPREQ(Signal* signal) ...@@ -4872,38 +4858,15 @@ Backup::execEND_LCPREQ(Signal* signal)
c_backupPool.getPtr(ptr, req->backupPtr); c_backupPool.getPtr(ptr, req->backupPtr);
ndbrequire(ptr.p->backupId == req->backupId); ndbrequire(ptr.p->backupId == req->backupId);
ptr.p->slaveState.setState(STOPPING);
TablePtr tabPtr;
if(ptr.p->tables.first(tabPtr))
{
tabPtr.p->attributes.release();
tabPtr.p->fragments.release();
ptr.p->tables.release();
BackupFilePtr filePtr;
c_backupFilePool.getPtr(filePtr, ptr.p->dataFilePtr);
filePtr.p->operation.dataBuffer.eof();
return;
}
lcp_send_end_lcp_conf(signal, ptr);
}
void
Backup::lcp_send_end_lcp_conf(Signal* signal, BackupRecordPtr ptr)
{
EndLcpConf* conf= (EndLcpConf*)signal->getDataPtr();
conf->senderData = ptr.p->clientData;
conf->senderRef = reference();
ptr.p->errorCode = 0; ptr.p->errorCode = 0;
ptr.p->slaveState.setState(CLEANING); ptr.p->slaveState.setState(CLEANING);
ptr.p->slaveState.setState(INITIAL); ptr.p->slaveState.setState(INITIAL);
ptr.p->slaveState.setState(DEFINING); ptr.p->slaveState.setState(DEFINING);
ptr.p->slaveState.setState(DEFINED); ptr.p->slaveState.setState(DEFINED);
EndLcpConf* conf= (EndLcpConf*)signal->getDataPtr();
conf->senderData = ptr.p->clientData;
conf->senderRef = reference();
sendSignal(ptr.p->masterRef, GSN_END_LCPCONF, sendSignal(ptr.p->masterRef, GSN_END_LCPCONF,
signal, EndLcpConf::SignalLength, JBB); signal, EndLcpConf::SignalLength, JBB);
} }
...@@ -645,7 +645,6 @@ public: ...@@ -645,7 +645,6 @@ public:
void lcp_open_file(Signal* signal, BackupRecordPtr ptr); void lcp_open_file(Signal* signal, BackupRecordPtr ptr);
void lcp_open_file_done(Signal*, BackupRecordPtr); void lcp_open_file_done(Signal*, BackupRecordPtr);
void lcp_close_file_conf(Signal* signal, BackupRecordPtr); void lcp_close_file_conf(Signal* signal, BackupRecordPtr);
void lcp_send_end_lcp_conf(Signal* signal, BackupRecordPtr);
bool ready_to_write(bool ready, Uint32 sz, bool eof, BackupFile *fileP); bool ready_to_write(bool ready, Uint32 sz, bool eof, BackupFile *fileP);
}; };
......
...@@ -2794,10 +2794,10 @@ private: ...@@ -2794,10 +2794,10 @@ private:
/*THIS VARIABLE IS THE HEAD OF A LINKED LIST OF FRAGMENTS WAITING TO BE */ /*THIS VARIABLE IS THE HEAD OF A LINKED LIST OF FRAGMENTS WAITING TO BE */
/*RESTORED FROM DISK. */ /*RESTORED FROM DISK. */
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
DLList<Fragrecord> c_lcp_waiting_fragments; // StartFragReq'ed DLFifoList<Fragrecord> c_lcp_waiting_fragments; // StartFragReq'ed
DLList<Fragrecord> c_lcp_restoring_fragments; // Restoring as we speek DLFifoList<Fragrecord> c_lcp_restoring_fragments; // Restoring as we speek
DLList<Fragrecord> c_lcp_complete_fragments; // Restored DLFifoList<Fragrecord> c_lcp_complete_fragments; // Restored
DLList<Fragrecord> c_redo_complete_fragments; // Redo'ed DLFifoList<Fragrecord> c_redo_complete_fragments; // Redo'ed
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
/*USED DURING SYSTEM RESTART, INDICATES THE OLDEST GCI THAT CAN BE RESTARTED */ /*USED DURING SYSTEM RESTART, INDICATES THE OLDEST GCI THAT CAN BE RESTARTED */
......
...@@ -427,17 +427,20 @@ void Dblqh::execCONTINUEB(Signal* signal) ...@@ -427,17 +427,20 @@ void Dblqh::execCONTINUEB(Signal* signal)
signal->theData[0] = fragptr.p->tabRef; signal->theData[0] = fragptr.p->tabRef;
signal->theData[1] = fragptr.p->fragId; signal->theData[1] = fragptr.p->fragId;
sendSignal(DBACC_REF, GSN_EXPANDCHECK2, signal, 2, JBB); sendSignal(DBACC_REF, GSN_EXPANDCHECK2, signal, 2, JBB);
Ptr<Fragrecord> save = fragptr;
c_redo_complete_fragments.next(fragptr); c_redo_complete_fragments.next(fragptr);
signal->theData[0] = ZENABLE_EXPAND_CHECK; signal->theData[0] = ZENABLE_EXPAND_CHECK;
signal->theData[1] = fragptr.i; signal->theData[1] = fragptr.i;
sendSignal(DBLQH_REF, GSN_CONTINUEB, signal, 2, JBB); sendSignal(DBLQH_REF, GSN_CONTINUEB, signal, 2, JBB);
c_redo_complete_fragments.remove(save);
return; return;
} }
else else
{ {
jam(); jam();
c_redo_complete_fragments.remove(); ndbrequire(c_redo_complete_fragments.isEmpty());
StartRecConf * conf = (StartRecConf*)signal->getDataPtrSend(); StartRecConf * conf = (StartRecConf*)signal->getDataPtrSend();
conf->startingNodeId = getOwnNodeId(); conf->startingNodeId = getOwnNodeId();
sendSignal(cmasterDihBlockref, GSN_START_RECCONF, signal, sendSignal(cmasterDihBlockref, GSN_START_RECCONF, signal,
...@@ -11269,8 +11272,22 @@ void Dblqh::execLCP_PREPARE_CONF(Signal* signal) ...@@ -11269,8 +11272,22 @@ void Dblqh::execLCP_PREPARE_CONF(Signal* signal)
else else
#endif #endif
{ {
sendSignal(BACKUP_REF, GSN_BACKUP_FRAGMENT_REQ, signal, if (ERROR_INSERTED(5044) &&
BackupFragmentReq::SignalLength, JBB); (fragptr.p->tabRef == c_error_insert_table_id) &&
fragptr.p->fragId) // Not first frag
{
/**
* Force CRASH_INSERTION in 10s
*/
ndbout_c("table: %d frag: %d", fragptr.p->tabRef, fragptr.p->fragId);
SET_ERROR_INSERT_VALUE(5027);
sendSignalWithDelay(reference(), GSN_START_RECREQ, signal, 10000, 1);
}
else
{
sendSignal(BACKUP_REF, GSN_BACKUP_FRAGMENT_REQ, signal,
BackupFragmentReq::SignalLength, JBB);
}
} }
} }
} }
...@@ -13745,7 +13762,7 @@ void Dblqh::execSTART_FRAGREQ(Signal* signal) ...@@ -13745,7 +13762,7 @@ void Dblqh::execSTART_FRAGREQ(Signal* signal)
fragptr.p->newestGci = cnewestGci; fragptr.p->newestGci = cnewestGci;
}//if }//if
if (lcpNo == ZNIL || fragptr.i != tabptr.p->fragrec[0]) if (lcpNo == ZNIL)
{ {
jam(); jam();
/** /**
...@@ -18470,10 +18487,17 @@ Dblqh::execDUMP_STATE_ORD(Signal* signal) ...@@ -18470,10 +18487,17 @@ Dblqh::execDUMP_STATE_ORD(Signal* signal)
} }
} }
if (dumpState->args[0] == DumpStateOrd::LqhErrorInsert5042 && signal->getLength() == 2) if (dumpState->args[0] == DumpStateOrd::LqhErrorInsert5042 && (signal->getLength() >= 2))
{ {
c_error_insert_table_id = dumpState->args[1]; c_error_insert_table_id = dumpState->args[1];
SET_ERROR_INSERT_VALUE(5042); if (signal->getLength() == 2)
{
SET_ERROR_INSERT_VALUE(5042);
}
else
{
SET_ERROR_INSERT_VALUE(dumpState->args[2]);
}
} }
TcConnectionrec *regTcConnectionrec = tcConnectionrec; TcConnectionrec *regTcConnectionrec = tcConnectionrec;
......
...@@ -149,7 +149,8 @@ Filename::set(Filename::NameSpec& spec, ...@@ -149,7 +149,8 @@ Filename::set(Filename::NameSpec& spec,
{ {
Uint32 tableId = FsOpenReq::v5_getTableId(filenumber); Uint32 tableId = FsOpenReq::v5_getTableId(filenumber);
Uint32 lcpNo = FsOpenReq::v5_getLcpNo(filenumber); Uint32 lcpNo = FsOpenReq::v5_getLcpNo(filenumber);
BaseString::snprintf(buf, sizeof(buf), "LCP/%d/T%d", lcpNo, tableId); Uint32 fragId = FsOpenReq::v5_getFragmentId(filenumber);
BaseString::snprintf(buf, sizeof(buf), "LCP/%d/T%dF%d", lcpNo, tableId, fragId);
strcat(theName, buf); strcat(theName, buf);
break; break;
} }
......
...@@ -264,7 +264,7 @@ Restore::init_file(const RestoreLcpReq* req, FilePtr file_ptr) ...@@ -264,7 +264,7 @@ Restore::init_file(const RestoreLcpReq* req, FilePtr file_ptr)
file_ptr.p->m_status = File::FIRST_READ; file_ptr.p->m_status = File::FIRST_READ;
file_ptr.p->m_table_id = req->tableId; file_ptr.p->m_table_id = req->tableId;
file_ptr.p->m_fragment_id = RNIL; file_ptr.p->m_fragment_id = req->fragmentId;
file_ptr.p->m_table_version = RNIL; file_ptr.p->m_table_version = RNIL;
file_ptr.p->m_bytes_left = 0; // Bytes read from FS file_ptr.p->m_bytes_left = 0; // Bytes read from FS
...@@ -361,6 +361,7 @@ Restore::open_file(Signal* signal, FilePtr file_ptr, Uint32 lcpNo) ...@@ -361,6 +361,7 @@ Restore::open_file(Signal* signal, FilePtr file_ptr, Uint32 lcpNo)
FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_DATA); FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_DATA);
FsOpenReq::v5_setLcpNo(req->fileNumber, lcpNo); FsOpenReq::v5_setLcpNo(req->fileNumber, lcpNo);
FsOpenReq::v5_setTableId(req->fileNumber, file_ptr.p->m_table_id); FsOpenReq::v5_setTableId(req->fileNumber, file_ptr.p->m_table_id);
FsOpenReq::v5_setFragmentId(req->fileNumber, file_ptr.p->m_fragment_id);
sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA); sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA);
} }
...@@ -475,6 +476,11 @@ Restore::restore_next(Signal* signal, FilePtr file_ptr) ...@@ -475,6 +476,11 @@ Restore::restore_next(Signal* signal, FilePtr file_ptr)
*/ */
ndbout_c("records: %d len: %x left: %d", ndbout_c("records: %d len: %x left: %d",
status & File::READING_RECORDS, 4*len, left); status & File::READING_RECORDS, 4*len, left);
if (unlikely((status & File:: FILE_THREAD_RUNNING) == 0))
{
ndbrequire(false);
}
len= 0; len= 0;
break; break;
} }
......
...@@ -931,6 +931,41 @@ retry: ...@@ -931,6 +931,41 @@ retry:
return NDBT_OK; return NDBT_OK;
} }
int
runBug21271(NDBT_Context* ctx, NDBT_Step* step){
int result = NDBT_OK;
int loops = ctx->getNumLoops();
int records = ctx->getNumRecords();
NdbRestarter restarter;
HugoOperations hugoOps(*ctx->getTab());
Ndb* pNdb = GETNDB(step);
const int masterNode = restarter.getMasterNodeId();
const int nodeId = restarter.getRandomNodeSameNodeGroup(masterNode, rand());
int val2[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 1 };
if (restarter.dumpStateOneNode(nodeId, val2, 2))
return NDBT_FAILED;
Uint32 tableId = ctx->getTab()->getTableId();
int dump[] = { DumpStateOrd::LqhErrorInsert5042, 0, 5044 };
dump[1] = tableId;
if (restarter.dumpStateOneNode(nodeId, dump, 3))
return NDBT_FAILED;
restarter.waitNodesNoStart(&nodeId, 1);
ctx->stopTest();
restarter.startNodes(&nodeId, 1);
if (restarter.waitClusterStarted() != 0)
return NDBT_FAILED;
return NDBT_OK;
return NDBT_OK;
}
NDBT_TESTSUITE(testNodeRestart); NDBT_TESTSUITE(testNodeRestart);
TESTCASE("NoLoad", TESTCASE("NoLoad",
...@@ -1244,6 +1279,13 @@ TESTCASE("Bug20185", ...@@ -1244,6 +1279,13 @@ TESTCASE("Bug20185",
STEP(runBug20185); STEP(runBug20185);
FINALIZER(runClearTable); FINALIZER(runClearTable);
} }
TESTCASE("Bug21271",
""){
INITIALIZER(runLoadTable);
STEP(runBug21271);
STEP(runPkUpdateUntilStopped);
FINALIZER(runClearTable);
}
NDBT_TESTSUITE_END(testNodeRestart); NDBT_TESTSUITE_END(testNodeRestart);
int main(int argc, const char** argv){ int main(int argc, const char** argv){
......
...@@ -489,6 +489,10 @@ max-time: 1000 ...@@ -489,6 +489,10 @@ max-time: 1000
cmd: testNodeRestart cmd: testNodeRestart
args: -n Bug20185 T1 args: -n Bug20185 T1
max-time: 1000
cmd: testNodeRestart
args: -n Bug21271 T6
# #
# DICT TESTS # DICT TESTS
max-time: 1500 max-time: 1500
......
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