=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp' --- storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp 2010-09-03 05:30:17 +0000 +++ storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp 2010-09-14 17:29:23 +0000 @@ -2138,6 +2138,7 @@ Dbtup::start_restore_lcp(Uint32 tableId, tabPtr.p->m_dropTable.tabUserPtr= tabPtr.p->m_attributes[DD].m_no_of_fixsize; tabPtr.p->m_dropTable.tabUserRef= tabPtr.p->m_attributes[DD].m_no_of_varsize; + tabPtr.p->m_dropTable.m_lcpno = (tabPtr.p->m_bits & Tablerec::TR_RowGCI)? 1 : 0; Uint32 *tabDesc = (Uint32*)(tableDescriptor+tabPtr.p->tabDescriptor); for(Uint32 i= 0; im_no_of_attributes; i++) @@ -2154,6 +2155,8 @@ Dbtup::start_restore_lcp(Uint32 tableId, tabPtr.p->m_no_of_disk_attributes = 0; tabPtr.p->m_attributes[DD].m_no_of_fixsize = 0; tabPtr.p->m_attributes[DD].m_no_of_varsize = 0; + /* Avoid LQH trampling GCI restored in raw format */ + tabPtr.p->m_bits &= ~((Uint16) Tablerec::TR_RowGCI); } void Dbtup::complete_restore_lcp(Signal* signal, @@ -2166,7 +2169,8 @@ Dbtup::complete_restore_lcp(Signal* sign tabPtr.p->m_attributes[DD].m_no_of_fixsize= tabPtr.p->m_dropTable.tabUserPtr; tabPtr.p->m_attributes[DD].m_no_of_varsize= tabPtr.p->m_dropTable.tabUserRef; - + tabPtr.p->m_bits |= ((tabPtr.p->m_dropTable.m_lcpno & 1) ? Tablerec::TR_RowGCI : 0); + tabPtr.p->m_no_of_disk_attributes = tabPtr.p->m_attributes[DD].m_no_of_fixsize + tabPtr.p->m_attributes[DD].m_no_of_varsize; === modified file 'storage/ndb/test/ndbapi/testRestartGci.cpp' --- storage/ndb/test/ndbapi/testRestartGci.cpp 2009-05-26 18:53:34 +0000 +++ storage/ndb/test/ndbapi/testRestartGci.cpp 2010-09-14 17:24:51 +0000 @@ -76,25 +76,16 @@ int runInsertRememberGci(NDBT_Context* c CHECK(hugoOps.closeTransaction(pNdb) == 0); i++; + /* Sleep so that records will have > 1 GCI between them */ + NdbSleep_MilliSleep(10); }; return result; } -int runRestartGciControl(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); +int runRestart(NDBT_Context* ctx, NDBT_Step* step){ Ndb* pNdb = GETNDB(step); - UtilTransactions utilTrans(*ctx->getTab()); NdbRestarter restarter; - - // Wait until we have enough records in db - int count = 0; - while (count < records){ - if (utilTrans.selectCount(pNdb, 64, &count) != 0){ - ctx->stopTest(); - return NDBT_FAILED; - } - } // Restart cluster with abort if (restarter.restartAll(false, false, true) != 0){ @@ -102,9 +93,6 @@ int runRestartGciControl(NDBT_Context* c return NDBT_FAILED; } - // Stop the other thread - ctx->stopTest(); - if (restarter.waitClusterStarted(300) != 0){ return NDBT_FAILED; } @@ -116,6 +104,26 @@ int runRestartGciControl(NDBT_Context* c return NDBT_OK; } +int runRestartGciControl(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + Ndb* pNdb = GETNDB(step); + UtilTransactions utilTrans(*ctx->getTab()); + + // Wait until we have enough records in db + int count = 0; + while (count < records){ + if (utilTrans.selectCount(pNdb, 64, &count) != 0){ + ctx->stopTest(); + return NDBT_FAILED; + } + } + + // Stop the other thread + ctx->stopTest(); + + return runRestart(ctx,step); +} + int runVerifyInserts(NDBT_Context* ctx, NDBT_Step* step){ int result = NDBT_OK; Ndb* pNdb = GETNDB(step); @@ -147,9 +155,19 @@ int runVerifyInserts(NDBT_Context* ctx, // RULE2: The records found in db should have same or lower // gci as in the vector + int recordsWithIncorrectGci = 0; for (i = 0; i < savedRecords.size(); i++){ CHECK(hugoOps.startTransaction(pNdb) == 0); + /* First read of row to check contents */ CHECK(hugoOps.pkReadRecord(pNdb, i) == 0); + /* Second read of row to get GCI */ + NdbTransaction* trans = hugoOps.getTransaction(); + NdbOperation* readOp = trans->getNdbOperation(ctx->getTab()); + CHECK(readOp != NULL); + CHECK(readOp->readTuple() == 0); + CHECK(hugoOps.equalForRow(readOp, i) == 0); + NdbRecAttr* rowGci = readOp->getValue(NdbDictionary::Column::ROW_GCI); + CHECK(rowGci != NULL); if (hugoOps.execute_Commit(pNdb) != 0){ // Record was not found in db' @@ -158,6 +176,14 @@ int runVerifyInserts(NDBT_Context* ctx, ndbout << "ERR: Record "< restartGCI){ ndbout << "ERR: Record "<int32_value()){ + ndbout << "ERR: Record "<int32_value() << endl; + recordsWithIncorrectGci++; + result = NDBT_FAILED; + } } CHECK(hugoOps.closeTransaction(pNdb) == 0); @@ -184,6 +218,9 @@ int runVerifyInserts(NDBT_Context* ctx, ndbout << "There are " << recordsWithLowerOrSameGci << " records with lower or same gci than " << restartGCI << endl; + ndbout << "There are " << recordsWithIncorrectGci + << " records with incorrect Gci on recovery." << endl; + return result; } @@ -212,6 +249,11 @@ TESTCASE("InsertRestartGci", STEP(runInsertRememberGci); STEP(runRestartGciControl); VERIFIER(runVerifyInserts); + /* Restart again - LCP after first restart will mean that this + * time we recover from LCP, not Redo + */ + VERIFIER(runRestart); + VERIFIER(runVerifyInserts); // Check GCIs again FINALIZER(runClearTable); } NDBT_TESTSUITE_END(testRestartGci);