int main(int argc, char **argv) { const int DEBUG_LVL_TO_DUMP_SYSCAT_RPT = 4; #ifdef _MSC_VER //FIXME #else setuid( 0 ); // set effective ID to root; ignore return status #endif setlocale(LC_ALL, ""); WriteEngine::Config::initConfigCache(); // load Calpont.xml config settings InputMgr mgr("299"); //@bug 391 if (! mgr.input(argc, argv)) return 1; int debugLevel = atoi(mgr.getParm( WriteEngine::XMLGenData::RPT_DEBUG).c_str()); bool bUseLogFile = true; bool bSysCatRpt = false; if (debugLevel == DEBUG_LVL_TO_DUMP_SYSCAT_RPT) { cout << "\nRunning colxml to dump system catalog report:\n\n"; bUseLogFile = false; bSysCatRpt = true; } else { cout << "\nRunning colxml with the following parameters:\n"; } WriteEngine::XMLGenProc curJob(&mgr, bUseLogFile, bSysCatRpt); if( debugLevel > 0 && debugLevel <= 3 ) { curJob.setDebugLevel( debugLevel ); cout << "\nDebug level is set to " << debugLevel << endl; } BRM::DBRM dbrm; if (dbrm.getSystemReady() < 1) { std::string errMsg( "System is not ready. Verify that InfiniDB is up and ready " "before running colxml."); if (bUseLogFile) curJob.logErrorMessage(errMsg); else cout << errMsg << endl; return 1; } bool rc = false; const WriteEngine::XMLGenData::TableList& tables = mgr.getTables(); try { if (tables.empty()) mgr.loadCatalogTables(); if (tables.empty()) { string msg = "Either schema name is invalid or no table " "is in the schema."; curJob.logErrorMessage(msg); } else { curJob.startXMLFile( ); for (InputMgr::TableList::const_iterator tbl = tables.begin(); tbl != tables.end() ; ++tbl) { curJob.makeTableData( *tbl ); rc = curJob.makeColumnData(*tbl); if (!rc) cout << "No columns for " << tbl->table << endl; } } } catch (runtime_error& ex) { curJob.logErrorMessage(string( "colxml runtime exception: ") + ex.what() ); cout << curJob.errorString() << endl; return 1; } catch (exception& ex) { curJob.logErrorMessage(string( "colxml exception: ") + ex.what() ); cout << curJob.errorString() << endl; return 1; } catch (...) { curJob.logErrorMessage(string("colxml unknown exception ")); cout << curJob.errorString() << endl; return 1; } if (rc) { if (debugLevel == DEBUG_LVL_TO_DUMP_SYSCAT_RPT) { std::string xmlFileName("-"); curJob.writeXMLFile( xmlFileName ); cout << "\nDump completed for tables:\n\t"; } else { std::string xmlFileName = curJob.genJobXMLFileName( ); cout << "Creating job description file: " << xmlFileName << endl; curJob.writeXMLFile( xmlFileName ); cout << "File completed for tables:\n\t"; } copy(tables.begin(), tables.end(), ostream_iterator<execplan::CalpontSystemCatalog::TableName> (cout, "\n\t")); cout << "\nNormal exit.\n"; } else { cout << "File not made.\n"; cout << curJob.errorString(); return 1; } return 0; }
//------------------------------------------------------------------------------ // Main entry point to this program //------------------------------------------------------------------------------ int main(int argc, char** argv) { int c; bool clearLockOnly = false; bool rollbackOnly = false; uint32_t tableOID = 0; while ((c = getopt(argc, argv, "hlr:")) != EOF) { switch (c) { case 'l': clearLockOnly = true; break; //Only allow '-r' option for development/debugging #if 1 case 'r': // hidden option to rollback specified table w/o a lock rollbackOnly = true; tableOID = ::strtoull(optarg, 0, 10); break; #endif case 'h': case '?': default: usage(); return (c == 'h' ? 0 : 1); break; } } if ((argc - optind) != 1 ) { usage(); return 1; } // Get the table lock ID specified by the user uint64_t lockID = ::strtoull(argv[optind], 0, 10); // If user specified both clearlock and rollback then we need to do both if (clearLockOnly && rollbackOnly) { clearLockOnly = false; rollbackOnly = false; } //-------------------------------------------------------------------------- // Verify that BRM is up and in a read/write state //-------------------------------------------------------------------------- BRM::DBRM brm; int brmRc = brm.isReadWrite(); if (brmRc != BRM::ERR_OK) { std::string brmErrMsg; BRM::errString(brmRc, brmErrMsg); std::cout << "BRM error: " << brmErrMsg << std::endl; std::cout << "Table lock " << lockID << " is not cleared." << std::endl; return 1; } if (brm.getSystemReady() < 1) { std::cout << "System is not ready. Verify that EryDB " "is up and ready before running this program" << std::endl; return 1; } //-------------------------------------------------------------------------- //@Bug 3711 Check whether the table is locked; does the table lock exist. //-------------------------------------------------------------------------- execplan::erydbSystemCatalog::TableName tblName; BRM::TableLockInfo tInfo; std::string task; std::vector<uint32_t> pmList; int rc; const std::string taskSysCat("getting system catalog information"); try { if (rollbackOnly) { tInfo.id = lockID; tInfo.tableOID = tableOID; tInfo.ownerPID = 0; tInfo.ownerSessionID = 1; tInfo.state = BRM::LOADING; // Construct PM list using all PMs, since we don't have a table // lock with the list of applicable DBRoots. task = "constructing total PM list"; rc = constructPMList( pmList ); if (rc != 0) { return 1; } } else { task = "getting table lock"; bool lockExists = brm.getTableLockInfo( lockID, &tInfo ); if (!lockExists) { std::cout << "Table lock " << lockID << " does not exist." << std::endl; return 1; } // Construct PM list based on list of affected DBRoots task = "mapping DBRoots to PMs"; rc = constructPMList( tInfo.dbrootList, pmList ); if (rc != 0) { return 1; } } uint32_t sessionID = 1; task = taskSysCat; boost::shared_ptr<execplan::erydbSystemCatalog> systemCatalogPtr = execplan::erydbSystemCatalog::makeerydbSystemCatalog( sessionID ); systemCatalogPtr->identity(execplan::erydbSystemCatalog::EC); tblName = systemCatalogPtr->tableName( tInfo.tableOID ); } catch (std::exception& ex) { std::cout << "Error " << task << ". " << ex.what() << std::endl; if (clearLockOnly && (task == taskSysCat)) { tblName.schema= "[unknown name]"; tblName.table.clear(); std::cout << "Will still try to clear table lock." << std::endl; } else { std::cout << "Table lock " << lockID << " is not cleared." << std::endl; return 1; } } catch (...) { std::cout << "Error " << task << ". " << std::endl; if (clearLockOnly && (task == taskSysCat)) { tblName.schema= "[unknown name]"; tblName.table.clear(); std::cout << "Will still try to clear table lock." << std::endl; } else { std::cout << "Table lock " << lockID << " is not cleared." << std::endl; return 1; } } logInitStatus( tblName.toString(), lockID ); if (rollbackOnly) { std::cout << "Rolling back table " << tblName.toString() << std::endl << std::endl; } else if (clearLockOnly) { std::cout << "Clearing table lock " << lockID << " for table " << tblName.toString() << std::endl << std::endl; } else { std::cout << "Rolling back and clearing table lock for table " << tblName.toString() << "; table lock " << lockID << std::endl << std::endl; } //-------------------------------------------------------------------------- // Perform bulk rollback //-------------------------------------------------------------------------- std::string errMsg; if (!clearLockOnly) { std::vector<boost::shared_ptr<messageqcpp::MessageQueueClient> > msgQueClts; rc = createMsgQueClts(pmList, msgQueClts, errMsg); if (rc != 0) { logFinalStatus( tblName.toString(), lockID, errMsg ); std::cout << errMsg << std::endl; std::cout << "Table lock " << lockID << " for table " << tblName.toString() << " is not cleared." << std::endl; return rc; } rc = execBulkRollbackReq( msgQueClts, pmList, &brm, tInfo, tblName.toString(), rollbackOnly, errMsg ); if (rc != 0) { logFinalStatus( tblName.toString(), lockID, errMsg ); std::cout << "Rollback error: " << errMsg << std::endl; std::cout << "Table lock " << lockID << " for table " << tblName.toString() << " is not cleared." << std::endl; return rc; } //---------------------------------------------------------------------- // Change the state of the table lock to cleanup state. // We ignore the return stateChange flag. //---------------------------------------------------------------------- if (!rollbackOnly) { try { brm.changeState( tInfo.id, BRM::CLEANUP ); } catch (std::exception& ex) { std::ostringstream oss; oss << "Error changing state. " << ex.what(); logFinalStatus( tblName.toString(), lockID, oss.str() ); std::cout << oss.str() << std::endl; std::cout << "Table lock " << lockID << " is not cleared." << std::endl; return 1; } catch (...) { std::ostringstream oss; oss << "Error changing state. " << std::endl; logFinalStatus( tblName.toString(), lockID, oss.str() ); std::cout << oss.str() << std::endl; std::cout << "Table lock " << lockID << " is not cleared." << std::endl; return 1; } } //---------------------------------------------------------------------- // Delete the meta data files //---------------------------------------------------------------------- rc = execFileCleanupReq( msgQueClts, pmList, &brm, tInfo, tblName.toString(), errMsg ); if (rc != 0) { //@Bug 4517. Release tablelock if remove meta files failed const std::string APPLNAME("cleartablelock command"); const int SUBSYSTEM_ID = 19; // writeengine? const int COMP_MSG_NUM = logging::M0089; logging::Message::Args msgArgs; logging::Message logMsg( COMP_MSG_NUM ); msgArgs.add( APPLNAME ); msgArgs.add( tblName.toString() ); msgArgs.add( lockID ); msgArgs.add( errMsg ); logMsg.format( msgArgs ); logging::LoggingID lid( SUBSYSTEM_ID ); logging::MessageLog ml( lid ); ml.logWarningMessage( logMsg ); std::cout << "File cleanup error: " << errMsg << std::endl; } } // end of: if (!clearLockOnly) //-------------------------------------------------------------------------- // Finally, release the actual table lock //-------------------------------------------------------------------------- std::cout << std::endl; if (rollbackOnly) { logFinalStatus( tblName.toString(), lockID, std::string() ); std::cout << "Bulk Rollback Only for table " << tblName.toString() << " completed successfully." << std::endl; } else { try { brm.releaseTableLock( lockID ); // ignore boolean return value } catch (std::exception& ex) { logFinalStatus( tblName.toString(), lockID, ex.what() ); std::cout << "Error releasing table lock " << lockID << " for table " << tblName.toString() << std::endl; std::cout << ex.what() << std::endl; return 1; } catch (...) { std::string unknownErr("Unknown exception"); logFinalStatus( tblName.toString(), lockID, unknownErr ); std::cout << "Error releasing table lock " << lockID << " for table " << tblName.toString() << std::endl; std::cout << unknownErr << std::endl; return 1; } logFinalStatus( tblName.toString(), lockID, std::string() ); std::cout << "Table lock " << lockID << " for table " << tblName.toString() << " is cleared." << std::endl; } return 0; }