From aad9135c007a00dfb0f8c97a057168f401512bd5 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 15 May 2007 09:08:16 +0200 Subject: [PATCH] ndb - bug#24631 add Dbdict::restartDropObj* storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp: add restartDropObj - handle undo files "specially" storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp: add restartDropObj* storage/ndb/src/kernel/blocks/lgman.cpp: allow drop of meta files storage/ndb/src/kernel/blocks/tsman.cpp: allow drop of meta files storage/ndb/test/ndbapi/testDict.cpp: add testcase storage/ndb/test/run-test/daily-basic-tests.txt: add testcase --- .../ndb/src/kernel/blocks/dbdict/Dbdict.cpp | 189 +++++++++++++++++- .../ndb/src/kernel/blocks/dbdict/Dbdict.hpp | 9 +- storage/ndb/src/kernel/blocks/lgman.cpp | 13 +- storage/ndb/src/kernel/blocks/tsman.cpp | 6 + storage/ndb/test/ndbapi/testDict.cpp | 157 +++++++++++++++ .../ndb/test/run-test/daily-basic-tests.txt | 4 + 6 files changed, 372 insertions(+), 6 deletions(-) diff --git a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index de365e886a0..e5ed9e49642 100644 --- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -188,7 +188,7 @@ struct { 0, 0, 0, 0, &Dbdict::drop_undofile_prepare_start, 0, 0, - 0, 0, + 0, &Dbdict::drop_undofile_commit_complete, 0, 0, 0 } }; @@ -3209,9 +3209,7 @@ Dbdict::restartDropTab(Signal* signal, Uint32 tableId, case DictTabInfo::LogfileGroup: case DictTabInfo::Datafile: case DictTabInfo::Undofile: - warningEvent("Dont drop object: %d", tableId); - c_restartRecord.activeTable++; - checkSchemaStatus(signal); + restartDropObj(signal, tableId, old_entry); return; } @@ -3254,6 +3252,9 @@ Dbdict::restartDropTab_complete(Signal* signal, checkSchemaStatus(signal); } +/** + * Create Obj during NR/SR + */ void Dbdict::restartCreateObj(Signal* signal, Uint32 tableId, @@ -3482,6 +3483,170 @@ Dbdict::restartCreateObj_commit_complete_done(Signal* signal, checkSchemaStatus(signal); } +/** + * Drop object during NR/SR + */ +void +Dbdict::restartDropObj(Signal* signal, + Uint32 tableId, + const SchemaFile::TableEntry * entry) +{ + jam(); + + DropObjRecordPtr dropObjPtr; + ndbrequire(c_opDropObj.seize(dropObjPtr)); + + const Uint32 key = ++c_opRecordSequence; + dropObjPtr.p->key = key; + c_opDropObj.add(dropObjPtr); + dropObjPtr.p->m_errorCode = 0; + dropObjPtr.p->m_senderRef = reference(); + dropObjPtr.p->m_senderData = tableId; + dropObjPtr.p->m_clientRef = reference(); + dropObjPtr.p->m_clientData = tableId; + + dropObjPtr.p->m_obj_id = tableId; + dropObjPtr.p->m_obj_type = entry->m_tableType; + dropObjPtr.p->m_obj_version = entry->m_tableVersion; + + dropObjPtr.p->m_callback.m_callbackData = key; + dropObjPtr.p->m_callback.m_callbackFunction= + safe_cast(&Dbdict::restartDropObj_prepare_start_done); + + ndbout_c("Dropping %d %d", tableId, entry->m_tableType); + switch(entry->m_tableType){ + case DictTabInfo::Tablespace: + case DictTabInfo::LogfileGroup:{ + jam(); + Ptr fg_ptr; + ndbrequire(c_filegroup_hash.find(fg_ptr, tableId)); + dropObjPtr.p->m_obj_ptr_i = fg_ptr.i; + dropObjPtr.p->m_vt_index = 3; + break; + } + case DictTabInfo::Datafile:{ + jam(); + Ptr file_ptr; + dropObjPtr.p->m_vt_index = 2; + ndbrequire(c_file_hash.find(file_ptr, tableId)); + dropObjPtr.p->m_obj_ptr_i = file_ptr.i; + break; + } + case DictTabInfo::Undofile:{ + jam(); + Ptr file_ptr; + dropObjPtr.p->m_vt_index = 4; + ndbrequire(c_file_hash.find(file_ptr, tableId)); + dropObjPtr.p->m_obj_ptr_i = file_ptr.i; + + /** + * Undofiles are only removed from logfile groups file list + * as drop undofile is currently not supported... + * file will be dropped by lgman when dropping filegroup + */ + dropObjPtr.p->m_callback.m_callbackFunction= + safe_cast(&Dbdict::restartDropObj_commit_complete_done); + + if (f_dict_op[dropObjPtr.p->m_vt_index].m_commit_complete) + (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_commit_complete) + (signal, dropObjPtr.p); + else + execute(signal, dropObjPtr.p->m_callback, 0); + return; + } + default: + jamLine(entry->m_tableType); + ndbrequire(false); + } + + if (f_dict_op[dropObjPtr.p->m_vt_index].m_prepare_start) + (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_prepare_start) + (signal, dropObjPtr.p); + else + execute(signal, dropObjPtr.p->m_callback, 0); +} + +void +Dbdict::restartDropObj_prepare_start_done(Signal* signal, + Uint32 callbackData, + Uint32 returnCode) +{ + jam(); + ndbrequire(returnCode == 0); + DropObjRecordPtr dropObjPtr; + ndbrequire(c_opDropObj.find(dropObjPtr, callbackData)); + ndbrequire(dropObjPtr.p->m_errorCode == 0); + + dropObjPtr.p->m_callback.m_callbackFunction = + safe_cast(&Dbdict::restartDropObj_prepare_complete_done); + + if (f_dict_op[dropObjPtr.p->m_vt_index].m_prepare_complete) + (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_prepare_complete) + (signal, dropObjPtr.p); + else + execute(signal, dropObjPtr.p->m_callback, 0); +} + +void +Dbdict::restartDropObj_prepare_complete_done(Signal* signal, + Uint32 callbackData, + Uint32 returnCode) +{ + jam(); + ndbrequire(returnCode == 0); + DropObjRecordPtr dropObjPtr; + ndbrequire(c_opDropObj.find(dropObjPtr, callbackData)); + ndbrequire(dropObjPtr.p->m_errorCode == 0); + + dropObjPtr.p->m_callback.m_callbackFunction = + safe_cast(&Dbdict::restartDropObj_commit_start_done); + + if (f_dict_op[dropObjPtr.p->m_vt_index].m_commit_start) + (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_commit_start) + (signal, dropObjPtr.p); + else + execute(signal, dropObjPtr.p->m_callback, 0); +} + +void +Dbdict::restartDropObj_commit_start_done(Signal* signal, + Uint32 callbackData, + Uint32 returnCode) +{ + jam(); + ndbrequire(returnCode == 0); + DropObjRecordPtr dropObjPtr; + ndbrequire(c_opDropObj.find(dropObjPtr, callbackData)); + ndbrequire(dropObjPtr.p->m_errorCode == 0); + + dropObjPtr.p->m_callback.m_callbackFunction = + safe_cast(&Dbdict::restartDropObj_commit_complete_done); + + if (f_dict_op[dropObjPtr.p->m_vt_index].m_commit_complete) + (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_commit_complete) + (signal, dropObjPtr.p); + else + execute(signal, dropObjPtr.p->m_callback, 0); +} + + +void +Dbdict::restartDropObj_commit_complete_done(Signal* signal, + Uint32 callbackData, + Uint32 returnCode) +{ + jam(); + ndbrequire(returnCode == 0); + DropObjRecordPtr dropObjPtr; + ndbrequire(c_opDropObj.find(dropObjPtr, callbackData)); + ndbrequire(dropObjPtr.p->m_errorCode == 0); + + c_opDropObj.release(dropObjPtr); + + c_restartRecord.activeTable++; + checkSchemaStatus(signal); +} + /* **************************************************************** */ /* ---------------------------------------------------------------- */ /* MODULE: NODE FAILURE HANDLING ------------------------- */ @@ -16239,6 +16404,22 @@ Dbdict::drop_file_commit_complete(Signal* signal, SchemaOp* op) execute(signal, op->m_callback, 0); } +void +Dbdict::drop_undofile_commit_complete(Signal* signal, SchemaOp* op) +{ + FilePtr f_ptr; + FilegroupPtr fg_ptr; + + jam(); + c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i); + ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id)); + Local_file_list list(c_file_pool, fg_ptr.p->m_logfilegroup.m_files); + list.remove(f_ptr); + release_object(f_ptr.p->m_obj_ptr_i); + c_file_hash.release(f_ptr); + execute(signal, op->m_callback, 0); +} + void Dbdict::drop_file_abort_start(Signal* signal, SchemaOp* op) { diff --git a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp index e5b918ca270..3fff330d699 100644 --- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp +++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp @@ -2565,6 +2565,12 @@ private: const SchemaFile::TableEntry *, const SchemaFile::TableEntry *); void restartDropTab_complete(Signal*, Uint32 callback, Uint32); + + void restartDropObj(Signal*, Uint32, const SchemaFile::TableEntry *); + void restartDropObj_prepare_start_done(Signal*, Uint32, Uint32); + void restartDropObj_prepare_complete_done(Signal*, Uint32, Uint32); + void restartDropObj_commit_start_done(Signal*, Uint32, Uint32); + void restartDropObj_commit_complete_done(Signal*, Uint32, Uint32); void restart_checkSchemaStatusComplete(Signal*, Uint32 callback, Uint32); void restart_writeSchemaConf(Signal*, Uint32 callbackData, Uint32); @@ -2657,7 +2663,8 @@ public: void send_drop_fg(Signal*, SchemaOp*, DropFilegroupImplReq::RequestInfo); void drop_undofile_prepare_start(Signal* signal, SchemaOp*); - + void drop_undofile_commit_complete(Signal* signal, SchemaOp*); + int checkSingleUserMode(Uint32 senderRef); }; diff --git a/storage/ndb/src/kernel/blocks/lgman.cpp b/storage/ndb/src/kernel/blocks/lgman.cpp index 4af27e25124..25cdac89737 100644 --- a/storage/ndb/src/kernel/blocks/lgman.cpp +++ b/storage/ndb/src/kernel/blocks/lgman.cpp @@ -436,7 +436,6 @@ Lgman::drop_filegroup_drop_files(Signal* signal, { jam(); ndbrequire(! (ptr.p->m_state & Logfile_group::LG_THREAD_MASK)); - ndbrequire(ptr.p->m_meta_files.isEmpty()); ndbrequire(ptr.p->m_outstanding_fs == 0); Local_undofile_list list(m_file_pool, ptr.p->m_files); @@ -452,6 +451,18 @@ Lgman::drop_filegroup_drop_files(Signal* signal, return; } + Local_undofile_list metalist(m_file_pool, ptr.p->m_meta_files); + if (metalist.first(file_ptr)) + { + jam(); + metalist.remove(file_ptr); + list.add(file_ptr); + file_ptr.p->m_create.m_senderRef = ref; + file_ptr.p->m_create.m_senderData = data; + create_file_abort(signal, ptr, file_ptr); + return; + } + free_logbuffer_memory(ptr); m_logfile_group_hash.release(ptr); DropFilegroupImplConf *conf = (DropFilegroupImplConf*)signal->getDataPtr(); diff --git a/storage/ndb/src/kernel/blocks/tsman.cpp b/storage/ndb/src/kernel/blocks/tsman.cpp index 62aa80a67fe..8f61ec0cf7b 100644 --- a/storage/ndb/src/kernel/blocks/tsman.cpp +++ b/storage/ndb/src/kernel/blocks/tsman.cpp @@ -1309,6 +1309,12 @@ Tsman::execDROP_FILE_REQ(Signal* signal) Local_datafile_list free(m_file_pool, fg_ptr.p->m_free_files); free.remove(file_ptr); } + else if(find_file_by_id(file_ptr, fg_ptr.p->m_meta_files, req.file_id)) + { + jam(); + Local_datafile_list meta(m_file_pool, fg_ptr.p->m_meta_files); + meta.remove(file_ptr); + } else { errorCode = DropFileImplRef::NoSuchFile; diff --git a/storage/ndb/test/ndbapi/testDict.cpp b/storage/ndb/test/ndbapi/testDict.cpp index 9828cb768df..13c071f968e 100644 --- a/storage/ndb/test/ndbapi/testDict.cpp +++ b/storage/ndb/test/ndbapi/testDict.cpp @@ -2204,6 +2204,159 @@ runBug21755(NDBT_Context* ctx, NDBT_Step* step) return NDBT_OK; } +static +int +create_tablespace(NdbDictionary::Dictionary* pDict, + const char * lgname, + const char * tsname, + const char * dfname) +{ + NdbDictionary::Tablespace ts; + ts.setName(tsname); + ts.setExtentSize(1024*1024); + ts.setDefaultLogfileGroup(lgname); + + if(pDict->createTablespace(ts) != 0) + { + g_err << "Failed to create tablespace:" + << endl << pDict->getNdbError() << endl; + return NDBT_FAILED; + } + + NdbDictionary::Datafile df; + df.setPath(dfname); + df.setSize(1*1024*1024); + df.setTablespace(tsname); + + if(pDict->createDatafile(df) != 0) + { + g_err << "Failed to create datafile:" + << endl << pDict->getNdbError() << endl; + return NDBT_FAILED; + } + return 0; +} + +int +runBug24631(NDBT_Context* ctx, NDBT_Step* step) +{ + char tsname[256]; + char dfname[256]; + char lgname[256]; + char ufname[256]; + NdbRestarter res; + + if (res.getNumDbNodes() < 2) + return NDBT_OK; + + Ndb* pNdb = GETNDB(step); + NdbDictionary::Dictionary* pDict = pNdb->getDictionary(); + + NdbDictionary::Dictionary::List list; + if (pDict->listObjects(list) == -1) + return NDBT_FAILED; + + const char * lgfound = 0; + + for (Uint32 i = 0; icreateLogfileGroup(lg) != 0) + { + g_err << "Failed to create logfilegroup:" + << endl << pDict->getNdbError() << endl; + return NDBT_FAILED; + } + + NdbDictionary::Undofile uf; + BaseString::snprintf(ufname, sizeof(ufname), "%s-%u", lgname, rand()); + uf.setPath(ufname); + uf.setSize(2*1024*1024); + uf.setLogfileGroup(lgname); + + if(pDict->createUndofile(uf) != 0) + { + g_err << "Failed to create undofile:" + << endl << pDict->getNdbError() << endl; + return NDBT_FAILED; + } + } + else + { + BaseString::snprintf(lgname, sizeof(lgname), "%s", lgfound); + } + + BaseString::snprintf(tsname, sizeof(tsname), "TS-%u", rand()); + BaseString::snprintf(dfname, sizeof(dfname), "%s-%u.dat", tsname, rand()); + + if (create_tablespace(pDict, lgname, tsname, dfname)) + return NDBT_FAILED; + + + int node = res.getRandomNotMasterNodeId(rand()); + res.restartOneDbNode(node, false, true, true); + NdbSleep_SecSleep(3); + + if (pDict->dropDatafile(pDict->getDatafile(0, dfname)) != 0) + { + g_err << "Failed to drop datafile: " << pDict->getNdbError() << endl; + return NDBT_FAILED; + } + + if (pDict->dropTablespace(pDict->getTablespace(tsname)) != 0) + { + g_err << "Failed to drop tablespace: " << pDict->getNdbError() << endl; + return NDBT_FAILED; + } + + if (res.waitNodesNoStart(&node, 1)) + return NDBT_FAILED; + + res.startNodes(&node, 1); + if (res.waitClusterStarted()) + return NDBT_FAILED; + + if (create_tablespace(pDict, lgname, tsname, dfname)) + return NDBT_FAILED; + + if (pDict->dropDatafile(pDict->getDatafile(0, dfname)) != 0) + { + g_err << "Failed to drop datafile: " << pDict->getNdbError() << endl; + return NDBT_FAILED; + } + + if (pDict->dropTablespace(pDict->getTablespace(tsname)) != 0) + { + g_err << "Failed to drop tablespace: " << pDict->getNdbError() << endl; + return NDBT_FAILED; + } + + if (lgfound == 0) + { + if (pDict->dropLogfileGroup(pDict->getLogfileGroup(lgname)) != 0) + return NDBT_FAILED; + } + + return NDBT_OK; +} + struct RandSchemaOp { struct Obj @@ -2707,6 +2860,10 @@ TESTCASE("DictRestart", ""){ INITIALIZER(runDictRestart); } +TESTCASE("Bug24631", + ""){ + INITIALIZER(runBug24631); +} NDBT_TESTSUITE_END(testDict); int main(int argc, const char** argv){ diff --git a/storage/ndb/test/run-test/daily-basic-tests.txt b/storage/ndb/test/run-test/daily-basic-tests.txt index e080536dad9..8f24e8826f9 100644 --- a/storage/ndb/test/run-test/daily-basic-tests.txt +++ b/storage/ndb/test/run-test/daily-basic-tests.txt @@ -619,6 +619,10 @@ max-time: 1500 cmd: testDict args: -l 25 -n DictRestart T1 +max-time: 500 +cmd: testDict +args: -n Bug24631 T1 + # # TEST NDBAPI #