void start_T1(Ndb * pNDB, ThreadData * td, int async){ DEBUG2("T1(%.*s): - Starting", SUBSCRIBER_NUMBER_LENGTH, td->transactionData.number); NdbConnection * pCON = 0; while((pCON = startTransaction(pNDB, td)) == 0){ CHECK_ALLOWED_ERROR("T1: startTransaction", td, pNDB->getNdbError()); NdbSleep_MilliSleep(10); } NdbOperation *MyOp = pCON->getNdbOperation(SUBSCRIBER_TABLE); if (MyOp != NULL) { MyOp->updateTuple(); MyOp->equal(IND_SUBSCRIBER_NUMBER, td->transactionData.number); MyOp->setValue(IND_SUBSCRIBER_LOCATION, (char *)&td->transactionData.location); MyOp->setValue(IND_SUBSCRIBER_CHANGED_BY, td->transactionData.changed_by); MyOp->setValue(IND_SUBSCRIBER_CHANGED_TIME, td->transactionData.changed_time); if (async == 1) { pCON->executeAsynchPrepare( Commit , T1_Callback, td); } else { int result = pCON->execute(Commit); T1_Callback(result, pCON, (void*)td); return; }//if } else { CHECK_NULL(MyOp, "T1: getNdbOperation", td, pCON->getNdbError()); }//if }
/** * Transaction 1 - T1 * * Update location and changed by/time on a subscriber * * Input: * SubscriberNumber, * Location, * ChangedBy, * ChangedTime * * Output: */ void start_T1(Ndb * pNDB, ThreadData * td){ DEBUG2("T1(%.*s): - Starting\n", SUBSCRIBER_NUMBER_LENGTH, td->transactionData.number); int check; NdbConnection * pCON = pNDB->startTransaction(); if (pCON != NULL) { NdbOperation *MyOp = pCON->getNdbOperation(SUBSCRIBER_TABLE); if (MyOp != NULL) { MyOp->updateTuple(); MyOp->equal(IND_SUBSCRIBER_NUMBER, td->transactionData.number); MyOp->setValue(IND_SUBSCRIBER_LOCATION, (char *)&td->transactionData.location); MyOp->setValue(IND_SUBSCRIBER_CHANGED_BY, td->transactionData.changed_by); MyOp->setValue(IND_SUBSCRIBER_CHANGED_TIME, td->transactionData.changed_time); pCON->executeAsynchPrepare( Commit , T1_Callback, td); } else { CHECK_NULL(MyOp, "T1: getNdbOperation", pCON); }//if } else { error_handler("T1-1: startTranscation", pNDB->getNdbErrorString(), pNDB->getNdbError()); }//if }
/** * Transaction 1 - T1 * * Update location and changed by/time on a subscriber * * Input: * SubscriberNumber, * Location, * ChangedBy, * ChangedTime * * Output: */ int T1(void * obj, const SubscriberNumber number, const Location new_location, const ChangedBy changed_by, const ChangedTime changed_time, BenchmarkTime * transaction_time){ Ndb * pNDB = (Ndb *) obj; DEBUG2("T1(%.*s):\n", SUBSCRIBER_NUMBER_LENGTH, number); BenchmarkTime start; get_time(&start); int check; NdbRecAttr * check2; NdbConnection * MyTransaction = pNDB->startTransaction(); if (MyTransaction == NULL) error_handler("T1-1: startTranscation", pNDB->getNdbErrorString(), 0); NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); CHECK_NULL(MyOperation, "T1: getNdbOperation", MyTransaction); check = MyOperation->updateTuple(); CHECK_MINUS_ONE(check, "T1: updateTuple", MyTransaction); check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, number); CHECK_MINUS_ONE(check, "T1: equal subscriber", MyTransaction); check = MyOperation->setValue(IND_SUBSCRIBER_LOCATION, (char *)&new_location); CHECK_MINUS_ONE(check, "T1: setValue location", MyTransaction); check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_BY, changed_by); CHECK_MINUS_ONE(check, "T1: setValue changed_by", MyTransaction); check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_TIME, changed_time); CHECK_MINUS_ONE(check, "T1: setValue changed_time", MyTransaction); check = MyTransaction->execute( Commit ); CHECK_MINUS_ONE(check, "T1: Commit", MyTransaction); pNDB->closeTransaction(MyTransaction); get_time(transaction_time); time_diff(transaction_time, &start); return 0; }
void write_rows (Ndb* pMyNdb) { /**************************************************************** * Insert rows into SimpleTable * ***************************************************************/ int check = -1 ; int loop_count_ops = nRecords ; NdbOperation *MyOperation = NULL ; NdbConnection *MyTransaction = NULL ; ndbout << endl << "Writing records ..." << flush; for (int count=0 ; count < loop_count_ops ; count++) { MyTransaction = pMyNdb->startTransaction(); if (!MyTransaction) { error_handler(pMyNdb->getNdbError(), NO_FAIL); }//if MyOperation = MyTransaction->getNdbOperation(tableName); if (!MyOperation) { error_handler(pMyNdb->getNdbError(), NO_FAIL); }//if check = MyOperation->writeTuple(); if( check == -1 ) error_handler(MyTransaction->getNdbError(), NO_FAIL); check = MyOperation->equal( attrName[0],(char*)&pkValue[count] ); if( check == -1 ) error_handler(MyTransaction->getNdbError(), NO_FAIL); // Update the columns, index column already ok. for (int i = 1 ; i < MAXATTR; i++) { if ((i == 2) && (count > 4)) { check = MyOperation->setValue(attrName[i], (char*)&attrValue[count + 1]); } else { check = MyOperation->setValue(attrName[i], (char*)&attrValue[count]); } if( check == -1 ) error_handler(MyTransaction->getNdbError(), NO_FAIL); } check = MyTransaction->execute( Commit ); if(check == -1 ) error_handler(MyTransaction->getNdbError(), NO_FAIL); pMyNdb->closeTransaction(MyTransaction); } ndbout <<" \tOK" << endl; return; }
int UpdateTransaction(Ndb* pNdb, long iContextId, NdbError& err) { int iRes = -1; NdbConnection* pNdbConnection = pNdb->startTransaction(0, (const char*)&iContextId, 4); if(pNdbConnection) { NdbOperation* pNdbOperation = pNdbConnection->getNdbOperation(g_szTableName); if(pNdbOperation) { if(!pNdbOperation->updateTuple() && !pNdbOperation->equal(c_szContextId, (Int32)iContextId) && !pNdbOperation->setValue(c_szContextData, STATUS_DATA, g_nStatusDataSize)) { if(!pNdbConnection->execute(Commit)) iRes = 0; else err = pNdbConnection->getNdbError(); } else err = pNdbOperation->getNdbError(); } else err = pNdbConnection->getNdbError(); pNdb->closeTransaction(pNdbConnection); } else err = pNdb->getNdbError(); return iRes; }
int UtilTransactions::addRowToInsert(Ndb* pNdb, NdbConnection* pInsTrans, NDBT_ResultRow & row, const char *insertTabName){ int check; NdbOperation* pInsOp; pInsOp = pInsTrans->getNdbOperation(insertTabName); if (pInsOp == NULL) { ERR(pInsTrans->getNdbError()); return NDBT_FAILED; } check = pInsOp->insertTuple(); if( check == -1 ) { ERR(pInsTrans->getNdbError()); return NDBT_FAILED; } // Set all attributes for (int a = 0; a < tab.getNoOfColumns(); a++){ NdbRecAttr* r = row.attributeStore(a); int sz = r->get_size_in_bytes(); if (pInsOp->setValue(tab.getColumn(a)->getName(), r->aRef(), sz) != 0) { ERR(pInsTrans->getNdbError()); return NDBT_FAILED; } } return NDBT_OK; }
int userDbInsertServer(UserHandle *uh, ServerId serverId, SubscriberSuffix suffix, ServerName name) { int check; uint32 noOfRead = 0; uint32 noOfInsert = 0; uint32 noOfDelete = 0; NdbConnection * MyTransaction = 0; if(uh->pCurrTrans != 0){ MyTransaction = uh->pCurrTrans; } else { uh->pCurrTrans = MyTransaction = uh->pNDB->startTransaction(); } if (MyTransaction == NULL) error_handler("startTranscation", uh->pNDB->getNdbError(), 0); NdbOperation *MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); CHECK_NULL(MyOperation, "getNdbOperation", MyTransaction); check = MyOperation->insertTuple(); CHECK_MINUS_ONE(check, "insert tuple", MyTransaction); check = MyOperation->equal(SERVER_ID, (char*)&serverId); CHECK_MINUS_ONE(check, "setValue id", MyTransaction); check = MyOperation->setValue(SERVER_SUBSCRIBER_SUFFIX, suffix); CHECK_MINUS_ONE(check, "setValue suffix", MyTransaction); check = MyOperation->setValue(SERVER_NAME, name); CHECK_MINUS_ONE(check, "setValue name", MyTransaction); check = MyOperation->setValue(SERVER_READS, (char*)&noOfRead); CHECK_MINUS_ONE(check, "setValue reads", MyTransaction); check = MyOperation->setValue(SERVER_INSERTS, (char*)&noOfInsert); CHECK_MINUS_ONE(check, "setValue inserts", MyTransaction); check = MyOperation->setValue(SERVER_DELETES, (char*)&noOfDelete); CHECK_MINUS_ONE(check, "setValue deletes", MyTransaction); return 0; }
int insert_server(void * obj, ServerId serverId, SubscriberSuffix suffix, ServerName name, Counter noOfRead, Counter noOfInsert, Counter noOfDelete){ Ndb * pNDB = (Ndb *)obj; int check; NdbConnection * MyTransaction = pNDB->startTransaction(); if (MyTransaction == NULL) error_handler("startTranscation", pNDB->getNdbErrorString(), 0); NdbOperation *MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); CHECK_NULL(MyOperation, "getNdbOperation", MyTransaction); check = MyOperation->insertTuple(); CHECK_MINUS_ONE(check, "insert tuple", MyTransaction); check = MyOperation->equal(SERVER_ID, (char*)&serverId); CHECK_MINUS_ONE(check, "setValue id", MyTransaction); check = MyOperation->setValue(SERVER_SUBSCRIBER_SUFFIX, suffix); CHECK_MINUS_ONE(check, "setValue suffix", MyTransaction); check = MyOperation->setValue(SERVER_NAME, name); CHECK_MINUS_ONE(check, "setValue name", MyTransaction); check = MyOperation->setValue(SERVER_READS, (char*)&noOfRead); CHECK_MINUS_ONE(check, "setValue reads", MyTransaction); check = MyOperation->setValue(SERVER_INSERTS, (char*)&noOfInsert); CHECK_MINUS_ONE(check, "setValue inserts", MyTransaction); check = MyOperation->setValue(SERVER_DELETES, (char*)&noOfDelete); CHECK_MINUS_ONE(check, "setValue deletes", MyTransaction); check = MyTransaction->execute( Commit ); CHECK_MINUS_ONE(check, "commit", MyTransaction); pNDB->closeTransaction(MyTransaction); return 0; }
static void run_master_update(struct Xxx &xxx, struct XxxR &xxxr) { Ndb *ndb = xxx.ndb; const NdbDictionary::Table *myTable = xxx.table; int retry_sleep= 10; /* 10 milliseconds */ int retries= 100; while (1) { Uint32 val; NdbTransaction *trans = ndb->startTransaction(); if (trans == NULL) goto err; { NdbOperation *op = trans->getNdbOperation(myTable); if (op == NULL) APIERROR(trans->getNdbError()); op->readTupleExclusive(); op->equal(xxx.pk_col, xxxr.pk_val); op->getValue(xxx.col, (char *)&val); } if (trans->execute(NdbTransaction::NoCommit)) goto err; //fprintf(stderr, "read %u\n", val); xxxr.val = val + 1; { NdbOperation *op = trans->getNdbOperation(myTable); if (op == NULL) APIERROR(trans->getNdbError()); op->updateTuple(); op->equal(xxx.pk_col, xxxr.pk_val); op->setValue(xxx.col, xxxr.val); } if (trans->execute(NdbTransaction::Commit)) goto err; ndb->closeTransaction(trans); //fprintf(stderr, "updated to %u\n", xxxr.val); break; err: const NdbError this_error= trans ? trans->getNdbError() : ndb->getNdbError(); if (this_error.status == NdbError::TemporaryError) { if (retries--) { if (trans) ndb->closeTransaction(trans); NdbSleep_MilliSleep(retry_sleep); continue; // retry } } if (trans) ndb->closeTransaction(trans); APIERROR(this_error); } /* update done start timer */ gettimeofday(&xxxr.start_time, 0); }
int InsertTransaction(Ndb* pNdb, long iContextID, long iVersion, long iLockFlag, long iLockTime, long iLockTimeUSec, const char* pchContextData, NdbError& err) { int iRes = -1; NdbConnection* pNdbConnection = pNdb->startTransaction(0, (const char*)&iContextID, 4); if(pNdbConnection) { NdbOperation* pNdbOperation = pNdbConnection->getNdbOperation(g_szTableName); if(pNdbOperation) { if(!(g_bWriteTuple ? pNdbOperation->writeTuple() : pNdbOperation->insertTuple()) && !pNdbOperation->equal(c_szContextId, (Int32)iContextID) && !pNdbOperation->setValue(c_szVersion, (Int32)iVersion) && !pNdbOperation->setValue(c_szLockFlag, (Int32)iLockFlag) && !pNdbOperation->setValue(c_szLockTime, (Int32)iLockTime) && !pNdbOperation->setValue(c_szLockTimeUSec, (Int32)iLockTimeUSec) && !pNdbOperation->setValue(c_szContextData, pchContextData, g_nStatusDataSize)) { if(!pNdbConnection->execute(Commit)) iRes = 0; else err = pNdbConnection->getNdbError(); } else err = pNdbOperation->getNdbError(); } else err = pNdbConnection->getNdbError(); pNdb->closeTransaction(pNdbConnection); } else err = pNdb->getNdbError(); return iRes; }
int insert_group(void * obj, GroupId groupId, GroupName name, Permission allowRead, Permission allowInsert, Permission allowDelete){ Ndb * pNDB = (Ndb *)obj; int check; NdbConnection * MyTransaction = pNDB->startTransaction(); if (MyTransaction == NULL) error_handler("startTranscation", pNDB->getNdbErrorString(), 0); NdbOperation *MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); CHECK_NULL(MyOperation, "getNdbOperation", MyTransaction); check = MyOperation->insertTuple(); CHECK_MINUS_ONE(check, "insertTuple", MyTransaction); check = MyOperation->equal(GROUP_ID, (char*)&groupId); CHECK_MINUS_ONE(check, "equal", MyTransaction); check = MyOperation->setValue(GROUP_NAME, name); CHECK_MINUS_ONE(check, "setValue name", MyTransaction); check = MyOperation->setValue(GROUP_ALLOW_READ, (char*)&allowRead); CHECK_MINUS_ONE(check, "setValue allowRead", MyTransaction); check = MyOperation->setValue(GROUP_ALLOW_INSERT, (char*)&allowInsert); CHECK_MINUS_ONE(check, "setValue allowInsert", MyTransaction); check = MyOperation->setValue(GROUP_ALLOW_DELETE, (char*)&allowDelete); CHECK_MINUS_ONE(check, "setValue allowDelete", MyTransaction); check = MyTransaction->execute( Commit ); CHECK_MINUS_ONE(check, "commit", MyTransaction); pNDB->closeTransaction(MyTransaction); return 0; }
int userDbInsertGroup(UserHandle *uh, GroupId groupId, GroupName name, Permission allowRead, Permission allowInsert, Permission allowDelete) { int check; NdbConnection * MyTransaction = 0; if(uh->pCurrTrans != 0){ MyTransaction = uh->pCurrTrans; } else { uh->pCurrTrans = MyTransaction = uh->pNDB->startTransaction(); } if (MyTransaction == NULL) error_handler("startTranscation", uh->pNDB->getNdbError(), 0); NdbOperation *MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); CHECK_NULL(MyOperation, "getNdbOperation", MyTransaction); check = MyOperation->insertTuple(); CHECK_MINUS_ONE(check, "insertTuple", MyTransaction); check = MyOperation->equal(GROUP_ID, (char*)&groupId); CHECK_MINUS_ONE(check, "equal", MyTransaction); check = MyOperation->setValue(NDB_GROUP_NAME, name); CHECK_MINUS_ONE(check, "setValue name", MyTransaction); check = MyOperation->setValue(GROUP_ALLOW_READ, (char*)&allowRead); CHECK_MINUS_ONE(check, "setValue allowRead", MyTransaction); check = MyOperation->setValue(GROUP_ALLOW_INSERT, (char*)&allowInsert); CHECK_MINUS_ONE(check, "setValue allowInsert", MyTransaction); check = MyOperation->setValue(GROUP_ALLOW_DELETE, (char*)&allowDelete); CHECK_MINUS_ONE(check, "setValue allowDelete", MyTransaction); return 0; }
/** * Transaction 1 - T1 * * Update location and changed by/time on a subscriber * * Input: * SubscriberNumber, * Location, * ChangedBy, * ChangedTime * * Output: */ void userTransaction_T1(UserHandle * uh, SubscriberNumber number, Location new_location, ChangedBy changed_by, ChangedTime changed_time){ Ndb * pNDB = uh->pNDB; DEBUG2("T1(%.*s):\n", SUBSCRIBER_NUMBER_LENGTH, number); int check; NdbRecAttr * check2; NdbConnection * MyTransaction = pNDB->startTransaction(); if (MyTransaction != NULL) { NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); if (MyOperation != NULL) { MyOperation->updateTuple(); MyOperation->equal(IND_SUBSCRIBER_NUMBER, number); MyOperation->setValue(IND_SUBSCRIBER_LOCATION, (char *)&new_location); MyOperation->setValue(IND_SUBSCRIBER_CHANGED_BY, changed_by); MyOperation->setValue(IND_SUBSCRIBER_CHANGED_TIME, changed_time); check = MyTransaction->execute( Commit ); if (check != -1) { pNDB->closeTransaction(MyTransaction); return; } else { CHECK_MINUS_ONE(check, "T1: Commit", MyTransaction); }//if } else { CHECK_NULL(MyOperation, "T1: getNdbOperation", MyTransaction); }//if } else { error_handler("T1-1: startTranscation", pNDB->getNdbErrorString(), pNDB->getNdbError()); }//if }
// // Example insert // @param myNdb Ndb object representing NDB Cluster // @param myTransaction NdbTransaction used for transaction // @param myTable Table to insert into // @param error NdbError object returned in case of errors // @return -1 in case of failures, 0 otherwise // int insert(int transactionId, NdbTransaction* myTransaction, const NdbDictionary::Table *myTable) { NdbOperation *myOperation; // For other operations myOperation = myTransaction->getNdbOperation(myTable); if (myOperation == NULL) return -1; if (myOperation->insertTuple() || myOperation->equal("ATTR1", transactionId) || myOperation->setValue("ATTR2", transactionId)) { APIERROR(myOperation->getNdbError()); exit(-1); } return myTransaction->execute(NdbTransaction::NoCommit); }
int userDbInsertSubscriber(UserHandle *uh, SubscriberNumber number, uint32 groupId, SubscriberName name) { int check; uint32 activeSessions = 0; Location l = 0; ChangedBy changedBy; ChangedTime changedTime; BaseString::snprintf(changedBy, sizeof(changedBy), "ChangedBy"); BaseString::snprintf(changedTime, sizeof(changedTime), "ChangedTime"); NdbConnection * MyTransaction = 0; if(uh->pCurrTrans != 0){ MyTransaction = uh->pCurrTrans; } else { uh->pCurrTrans = MyTransaction = uh->pNDB->startTransaction(); } if (MyTransaction == NULL) error_handler("startTranscation", uh->pNDB->getNdbError(), 0); NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); CHECK_NULL(MyOperation, "getNdbOperation", MyTransaction); check = MyOperation->insertTuple(); CHECK_MINUS_ONE(check, "insertTuple", MyTransaction); check = MyOperation->equal(SUBSCRIBER_NUMBER, number); CHECK_MINUS_ONE(check, "equal", MyTransaction); check = MyOperation->setValue(SUBSCRIBER_NAME, name); CHECK_MINUS_ONE(check, "setValue name", MyTransaction); check = MyOperation->setValue(SUBSCRIBER_GROUP, (char*)&groupId); CHECK_MINUS_ONE(check, "setValue group", MyTransaction); check = MyOperation->setValue(SUBSCRIBER_LOCATION, (char*)&l); CHECK_MINUS_ONE(check, "setValue location", MyTransaction); check = MyOperation->setValue(SUBSCRIBER_SESSIONS, (char*)&activeSessions); CHECK_MINUS_ONE(check, "setValue sessions", MyTransaction); check = MyOperation->setValue(SUBSCRIBER_CHANGED_BY, changedBy); CHECK_MINUS_ONE(check, "setValue changedBy", MyTransaction); check = MyOperation->setValue(SUBSCRIBER_CHANGED_TIME, changedTime); CHECK_MINUS_ONE(check, "setValue changedTime", MyTransaction); return 0; }
int insert_subscriber(void * obj, SubscriberNumber number, SubscriberName name, GroupId groupId, Location l, ActiveSessions activeSessions, ChangedBy changedBy, ChangedTime changedTime){ Ndb * pNDB = (Ndb *)obj; int check; NdbConnection * MyTransaction = pNDB->startTransaction(); if (MyTransaction == NULL) error_handler("startTranscation", pNDB->getNdbErrorString(), 0); NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); CHECK_NULL(MyOperation, "getNdbOperation", MyTransaction); check = MyOperation->insertTuple(); CHECK_MINUS_ONE(check, "insertTuple", MyTransaction); check = MyOperation->equal(SUBSCRIBER_NUMBER, number); CHECK_MINUS_ONE(check, "equal", MyTransaction); check = MyOperation->setValue(SUBSCRIBER_NAME, name); CHECK_MINUS_ONE(check, "setValue name", MyTransaction); check = MyOperation->setValue(SUBSCRIBER_GROUP, (char*)&groupId); CHECK_MINUS_ONE(check, "setValue group", MyTransaction); check = MyOperation->setValue(SUBSCRIBER_LOCATION, (char*)&l); CHECK_MINUS_ONE(check, "setValue location", MyTransaction); check = MyOperation->setValue(SUBSCRIBER_SESSIONS, (char*)&activeSessions); CHECK_MINUS_ONE(check, "setValue sessions", MyTransaction); check = MyOperation->setValue(SUBSCRIBER_CHANGED_BY, changedBy); CHECK_MINUS_ONE(check, "setValue changedBy", MyTransaction); check = MyOperation->setValue(SUBSCRIBER_CHANGED_TIME, changedTime); CHECK_MINUS_ONE(check, "setValue changedTime", MyTransaction); check = MyTransaction->execute( Commit ); CHECK_MINUS_ONE(check, "commit", MyTransaction); pNDB->closeTransaction(MyTransaction); return 0; }
/************************************************************************ * populate() * 1. Prepare 'parallelism' number of insert transactions. * 2. Send transactions to NDB and wait for callbacks to execute */ int populate(Ndb * myNdb, int data, async_callback_t * cbData) { NdbOperation* myNdbOperation; // For operations const NdbDictionary::Dictionary* myDict= myNdb->getDictionary(); const NdbDictionary::Table *myTable= myDict->getTable("api_async"); if (myTable == NULL) APIERROR(myDict->getNdbError()); async_callback_t * cb; int retries = 0; int current = 0; for(int i=0; i<1024; i++) { if(transaction[i].used == 0) { current = i; if (cbData == 0) { /** * We already have a callback * This is an absolutely new transaction */ cb = new async_callback_t; cb->retries = 0; } else { /** * We already have a callback */ cb =cbData; retries = cbData->retries; } /** * Set data used by the callback */ cb->ndb = myNdb; //handle to Ndb object so that we can close transaction // in the callback (alt. make myNdb global). cb->data = data; //this is the data we want to insert cb->transaction = current; //This is the number (id) of this transaction transaction[current].used = 1 ; //Mark the transaction as used break; } } if(!current) return -1; while(retries < MAX_RETRIES) { transaction[current].conn = myNdb->startTransaction(); if (transaction[current].conn == NULL) { /** * no transaction to close since conn == null */ milliSleep(10); retries++; continue; } myNdbOperation = transaction[current].conn->getNdbOperation(myTable); if (myNdbOperation == NULL) { if (asynchErrorHandler(transaction[current].conn, myNdb)) { myNdb->closeTransaction(transaction[current].conn); transaction[current].conn = 0; milliSleep(10); retries++; continue; } asynchExitHandler(myNdb); } // if if(myNdbOperation->insertTuple() < 0 || myNdbOperation->equal("REG_NO", data) < 0 || myNdbOperation->setValue("BRAND", "Mercedes") <0 || myNdbOperation->setValue("COLOR", "Blue") < 0) { if (asynchErrorHandler(transaction[current].conn, myNdb)) { myNdb->closeTransaction(transaction[current].conn); transaction[current].conn = 0; retries++; milliSleep(10); continue; } asynchExitHandler(myNdb); } /*Prepare transaction (the transaction is NOT yet sent to NDB)*/ transaction[current].conn->executeAsynchPrepare(NdbTransaction::Commit, &callback, cb); /** * When we have prepared parallelism number of transactions -> * send the transaction to ndb. * Next time we will deal with the transactions are in the * callback. There we will see which ones that were successful * and which ones to retry. */ if (nPreparedTransactions == parallelism-1) { // send-poll all transactions // close transaction is done in callback myNdb->sendPollNdb(3000, parallelism ); nPreparedTransactions=0; } else nPreparedTransactions++; return 1; } std::cout << "Unable to recover from errors. Exiting..." << std::endl; asynchExitHandler(myNdb); return -1; }
void T4_Callback_2(int result, NdbConnection * pCON, void * threadData){ ThreadData * td = (ThreadData *)threadData; if (result == -1) { CHECK_ALLOWED_ERROR("T4-2: execute", td, pCON->getNdbError()); td->pNDB->closeTransaction(pCON); start_T4(td->pNDB, td, stat_async); return; }//if Uint32 permission = td->transactionData.permission; Uint32 sessions = td->transactionData.sessions; Uint32 server_bit = td->transactionData.server_bit; if(((permission & server_bit) == server_bit) && ((sessions & server_bit) == 0)){ memcpy(td->transactionData.suffix, &td->transactionData.number[SFX_START], SUBSCRIBER_NUMBER_SUFFIX_LENGTH); DEBUG5("T4(%.*s, %.2d): - Callback 2 - inserting(%.*s)", SUBSCRIBER_NUMBER_LENGTH, td->transactionData.number, td->transactionData.server_id, SUBSCRIBER_NUMBER_SUFFIX_LENGTH, td->transactionData.suffix); /* Operation 3 */ NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE); CHECK_NULL(MyOp, "T4-3: getNdbOperation", td, pCON->getNdbError()); MyOp->insertTuple(); MyOp->equal(IND_SESSION_SUBSCRIBER, (char*)td->transactionData.number); MyOp->equal(IND_SESSION_SERVER, (char*)&td->transactionData.server_id); MyOp->setValue(SESSION_DATA, (char *)td->transactionData.session_details); /* Operation 4 */ /* Operation 5 */ MyOp = pCON->getNdbOperation(SERVER_TABLE); CHECK_NULL(MyOp, "T4-5: getNdbOperation", td, pCON->getNdbError()); MyOp->interpretedUpdateTuple(); MyOp->equal(IND_SERVER_ID, (char*)&td->transactionData.server_id); MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX, (char*)td->transactionData.suffix); MyOp->incValue(IND_SERVER_INSERTS, (uint32)1); td->transactionData.branchExecuted = 1; } else { td->transactionData.branchExecuted = 0; DEBUG5("T4(%.*s, %.2d): - Callback 2 - %s %s", SUBSCRIBER_NUMBER_LENGTH, td->transactionData.number, td->transactionData.server_id, ((permission & server_bit) ? "permission - " : "no permission - "), ((sessions & server_bit) ? "in session - " : "no in session - ")); } if(!td->transactionData.do_rollback && td->transactionData.branchExecuted){ if (stat_async == 1) { pCON->executeAsynchPrepare( Commit , T4_Callback_3, td); } else { int result = pCON->execute( Commit ); T4_Callback_3(result, pCON, (void*)td); return; }//if } else { if (stat_async == 1) { pCON->executeAsynchPrepare( Rollback , T4_Callback_3, td); } else { int result = pCON->execute( Rollback ); T4_Callback_3(result, pCON, (void*)td); return; }//if } }
void start_T1(Ndb * pNDB, ThreadData * td, int async) { DEBUG2("T1(%.*s): - Starting", SUBSCRIBER_NUMBER_LENGTH, td->transactionData.number); NdbConnection * pCON = 0; while((pCON = startTransaction(pNDB, td)) == 0) { CHECK_ALLOWED_ERROR("T1: startTransaction", td, pNDB->getNdbError()); NdbSleep_MilliSleep(10); } const NdbOperation* op= NULL; if (td->ndbRecordSharedData) { char* rowPtr= (char*) &td->transactionData; const NdbRecord* record= td->ndbRecordSharedData-> subscriberTableNdbRecord; Uint32 m=0; unsigned char* mask= (unsigned char*) &m; //SET_MASK(mask, IND_SUBSCRIBER_NUMBER); SET_MASK(mask, IND_SUBSCRIBER_LOCATION); SET_MASK(mask, IND_SUBSCRIBER_CHANGED_BY); SET_MASK(mask, IND_SUBSCRIBER_CHANGED_TIME); op= pCON->updateTuple(record, rowPtr, record, rowPtr, mask); } else { NdbOperation *MyOp = pCON->getNdbOperation(SUBSCRIBER_TABLE); op= MyOp; if (MyOp != NULL) { MyOp->updateTuple(); MyOp->equal(IND_SUBSCRIBER_NUMBER, td->transactionData.number); MyOp->setValue(IND_SUBSCRIBER_LOCATION, (char *)&td->transactionData.location); MyOp->setValue(IND_SUBSCRIBER_CHANGED_BY, td->transactionData.changed_by); MyOp->setValue(IND_SUBSCRIBER_CHANGED_TIME, td->transactionData.changed_time); } } if (op != NULL) { if (async == 1) { pCON->executeAsynchPrepare( Commit , T1_Callback, td); } else { int result = pCON->execute(Commit); T1_Callback(result, pCON, (void*)td); return; }//if } else { CHECK_NULL(NULL, "T1: getNdbOperation", td, pCON->getNdbError()); }//if }
int scan_update(Ndb* myNdb, int update_column, const char * before_color, const char * after_color) { // Scan all records exclusive and update // them one by one int retryAttempt = 0; const int retryMax = 10; int updatedRows = 0; int check; NdbError err; NdbTransaction *myTrans; NdbScanOperation *myScanOp; const NdbDictionary::Dictionary* myDict= myNdb->getDictionary(); const NdbDictionary::Table *myTable= myDict->getTable("api_scan"); if (myTable == NULL) APIERROR(myDict->getNdbError()); /** * Loop as long as : * retryMax not reached * failed operations due to TEMPORARY erros * * Exit loop; * retryMax reached * Permanent error (return -1) */ while (true) { if (retryAttempt >= retryMax) { std::cout << "ERROR: has retried this operation " << retryAttempt << " times, failing!" << std::endl; return -1; } myTrans = myNdb->startTransaction(); if (myTrans == NULL) { const NdbError err = myNdb->getNdbError(); if (err.status == NdbError::TemporaryError) { milliSleep(50); retryAttempt++; continue; } std::cout << err.message << std::endl; return -1; } /** * Get a scan operation. */ myScanOp = myTrans->getNdbScanOperation(myTable); if (myScanOp == NULL) { std::cout << myTrans->getNdbError().message << std::endl; myNdb->closeTransaction(myTrans); return -1; } /** * Define a result set for the scan. */ if( myScanOp->readTuples(NdbOperation::LM_Exclusive) ) { std::cout << myTrans->getNdbError().message << std::endl; myNdb->closeTransaction(myTrans); return -1; } /** * Use NdbScanFilter to define a search critera */ NdbScanFilter filter(myScanOp) ; if(filter.begin(NdbScanFilter::AND) < 0 || filter.cmp(NdbScanFilter::COND_EQ, update_column, before_color, 20) <0|| filter.end() <0) { std::cout << myTrans->getNdbError().message << std::endl; myNdb->closeTransaction(myTrans); return -1; } /** * Start scan (NoCommit since we are only reading at this stage); */ if(myTrans->execute(NdbTransaction::NoCommit) != 0) { err = myTrans->getNdbError(); if(err.status == NdbError::TemporaryError){ std::cout << myTrans->getNdbError().message << std::endl; myNdb->closeTransaction(myTrans); milliSleep(50); continue; } std::cout << myTrans->getNdbError().code << std::endl; myNdb->closeTransaction(myTrans); return -1; } /** * start of loop: nextResult(true) means that "parallelism" number of * rows are fetched from NDB and cached in NDBAPI */ while((check = myScanOp->nextResult(true)) == 0){ do { /** * Get update operation */ NdbOperation * myUpdateOp = myScanOp->updateCurrentTuple(); if (myUpdateOp == 0) { std::cout << myTrans->getNdbError().message << std::endl; myNdb->closeTransaction(myTrans); return -1; } updatedRows++; /** * do the update */ myUpdateOp->setValue(update_column, after_color); /** * nextResult(false) means that the records * cached in the NDBAPI are modified before * fetching more rows from NDB. */ } while((check = myScanOp->nextResult(false)) == 0); /** * NoCommit when all cached tuple have been updated */ if(check != -1) { check = myTrans->execute(NdbTransaction::NoCommit); } /** * Check for errors */ err = myTrans->getNdbError(); if(check == -1) { if(err.status == NdbError::TemporaryError){ std::cout << myTrans->getNdbError().message << std::endl; myNdb->closeTransaction(myTrans); milliSleep(50); continue; } } /** * End of loop */ } /** * Commit all prepared operations */ if(myTrans->execute(NdbTransaction::Commit) == -1) { if(err.status == NdbError::TemporaryError){ std::cout << myTrans->getNdbError().message << std::endl; myNdb->closeTransaction(myTrans); milliSleep(50); continue; } } std::cout << myTrans->getNdbError().message << std::endl; myNdb->closeTransaction(myTrans); return 0; } if(myTrans!=0) { std::cout << myTrans->getNdbError().message << std::endl; myNdb->closeTransaction(myTrans); } return -1; }
/* set all the unique attrs of this objectclass into the table */ extern "C" int ndb_oc_attrs( NdbTransaction *txn, const NdbDictionary::Table *myTable, Entry *e, NdbOcInfo *no, NdbAttrInfo **attrs, int nattrs, Attribute *old ) { char buf[65538], *ptr; Attribute **an, **ao, *a; NdbOperation *myop; int i, j, max = 0; int changed, rc; Uint64 eid = e->e_id; if ( !nattrs ) return 0; an = (Attribute **)ch_malloc( 2 * nattrs * sizeof(Attribute *)); ao = an + nattrs; /* Turn lists of attrs into arrays for easier access */ for ( i=0; i<nattrs; i++ ) { if ( attrs[i]->na_oi != no ) { an[i] = NULL; ao[i] = NULL; continue; } for ( a=e->e_attrs; a; a=a->a_next ) { if ( a->a_desc == slap_schema.si_ad_objectClass ) continue; if ( a->a_desc->ad_type == attrs[i]->na_attr ) { /* Don't process same attr twice */ if ( a->a_flags & SLAP_ATTR_IXADD ) a = NULL; else a->a_flags |= SLAP_ATTR_IXADD; break; } } an[i] = a; if ( a && a->a_numvals > max ) max = a->a_numvals; for ( a=old; a; a=a->a_next ) { if ( a->a_desc == slap_schema.si_ad_objectClass ) continue; if ( a->a_desc->ad_type == attrs[i]->na_attr ) break; } ao[i] = a; if ( a && a->a_numvals > max ) max = a->a_numvals; } for ( i=0; i<max; i++ ) { myop = NULL; for ( j=0; j<nattrs; j++ ) { if ( !an[j] && !ao[j] ) continue; changed = 0; if ( an[j] && an[j]->a_numvals > i ) { /* both old and new are present, compare for changes */ if ( ao[j] && ao[j]->a_numvals > i ) { if ( ber_bvcmp( &ao[j]->a_nvals[i], &an[j]->a_nvals[i] )) changed = V_REP; } else { changed = V_INS; } } else { if ( ao[j] && ao[j]->a_numvals > i ) changed = V_DEL; } if ( changed ) { if ( !myop ) { rc = LDAP_OTHER; myop = txn->getNdbOperation( myTable ); if ( !myop ) { goto done; } if ( old ) { if ( myop->writeTuple()) { goto done; } } else { if ( myop->insertTuple()) { goto done; } } if ( myop->equal( EID_COLUMN, eid )) { goto done; } if ( myop->equal( VID_COLUMN, i )) { goto done; } } if ( attrs[j]->na_flag & NDB_INFO_ATBLOB ) { NdbBlob *myBlob = myop->getBlobHandle( attrs[j]->na_column ); rc = LDAP_OTHER; if ( !myBlob ) { Debug( LDAP_DEBUG_TRACE, "ndb_oc_attrs: getBlobHandle failed %s (%d)\n", myop->getNdbError().message, myop->getNdbError().code, 0 ); goto done; } if ( slapMode & SLAP_TOOL_MODE ) ndb_flush_blobs = 1; if ( changed & V_INS ) { if ( myBlob->setValue( an[j]->a_vals[i].bv_val, an[j]->a_vals[i].bv_len )) { Debug( LDAP_DEBUG_TRACE, "ndb_oc_attrs: blob->setValue failed %s (%d)\n", myBlob->getNdbError().message, myBlob->getNdbError().code, 0 ); goto done; } } else { if ( myBlob->setValue( NULL, 0 )) { Debug( LDAP_DEBUG_TRACE, "ndb_oc_attrs: blob->setValue failed %s (%d)\n", myBlob->getNdbError().message, myBlob->getNdbError().code, 0 ); goto done; } } } else { if ( changed & V_INS ) { if ( an[j]->a_vals[i].bv_len > attrs[j]->na_len ) { Debug( LDAP_DEBUG_ANY, "ndb_oc_attrs: attribute %s too long for column\n", attrs[j]->na_name.bv_val, 0, 0 ); rc = LDAP_CONSTRAINT_VIOLATION; goto done; } ptr = buf; *ptr++ = an[j]->a_vals[i].bv_len & 0xff; if ( attrs[j]->na_len > 255 ) { /* MedVar */ *ptr++ = an[j]->a_vals[i].bv_len >> 8; } memcpy( ptr, an[j]->a_vals[i].bv_val, an[j]->a_vals[i].bv_len ); ptr = buf; } else { ptr = NULL; } if ( myop->setValue( attrs[j]->na_column, ptr )) { rc = LDAP_OTHER; goto done; } } } }
void BackupRestore::logEntry(const LogEntry & tup) { if (!m_restore) return; NdbTransaction * trans = m_ndb->startTransaction(); if (trans == NULL) { // TODO: handle the error ndbout << "Cannot start transaction" << endl; exit(-1); } // if const TableS * table = tup.m_table; NdbOperation * op = trans->getNdbOperation(table->getTableName()); if (op == NULL) { ndbout << "Cannot get operation: "; ndbout << trans->getNdbError() << endl; exit(-1); } // if int check = 0; switch(tup.m_type) { case LogEntry::LE_INSERT: check = op->insertTuple(); break; case LogEntry::LE_UPDATE: check = op->updateTuple(); break; case LogEntry::LE_DELETE: check = op->deleteTuple(); break; default: ndbout << "Log entry has wrong operation type." << " Exiting..."; exit(-1); } for (int i = 0; i < tup.m_values.size(); i++) { const AttributeS * attr = tup.m_values[i]; int size = attr->Desc->size; int arraySize = attr->Desc->arraySize; const char * dataPtr = attr->Data.string_value; const Uint32 length = (size / 8) * arraySize; if (attr->Desc->m_column->getPrimaryKey()) op->equal(attr->Desc->attrId, dataPtr, length); else op->setValue(attr->Desc->attrId, dataPtr, length); } #if 1 trans->execute(Commit); #else const int ret = trans->execute(Commit); // Both insert update and delete can fail during log running // and it's ok if (ret != 0) { ndbout << "execute failed: "; ndbout << trans->getNdbError() << endl; exit(-1); } #endif m_ndb->closeTransaction(trans); m_logCount++; }
int populate(Ndb * myNdb) { int i; Car cars[15]; const NdbDictionary::Dictionary* myDict= myNdb->getDictionary(); const NdbDictionary::Table *myTable= myDict->getTable("api_scan"); if (myTable == NULL) APIERROR(myDict->getNdbError()); /** * Five blue mercedes */ for (i = 0; i < 5; i++) { cars[i].reg_no = i; sprintf(cars[i].brand, "Mercedes"); sprintf(cars[i].color, "Blue"); } /** * Five black bmw */ for (i = 5; i < 10; i++) { cars[i].reg_no = i; sprintf(cars[i].brand, "BMW"); sprintf(cars[i].color, "Black"); } /** * Five pink toyotas */ for (i = 10; i < 15; i++) { cars[i].reg_no = i; sprintf(cars[i].brand, "Toyota"); sprintf(cars[i].color, "Pink"); } NdbTransaction* myTrans = myNdb->startTransaction(); if (myTrans == NULL) APIERROR(myNdb->getNdbError()); for (i = 0; i < 15; i++) { NdbOperation* myNdbOperation = myTrans->getNdbOperation(myTable); if (myNdbOperation == NULL) APIERROR(myTrans->getNdbError()); myNdbOperation->insertTuple(); myNdbOperation->equal("REG_NO", cars[i].reg_no); myNdbOperation->setValue("BRAND", cars[i].brand); myNdbOperation->setValue("COLOR", cars[i].color); } int check = myTrans->execute(NdbTransaction::Commit); myTrans->close(); return check != -1; }
void BackupRestore::tuple_a(restore_callback_t *cb) { while (cb->retries < 10) { /** * start transactions */ cb->connection = m_ndb->startTransaction(); if (cb->connection == NULL) { /* if (asynchErrorHandler(cb->connection, m_ndb)) { cb->retries++; continue; } */ asynchExitHandler(); } // if const TupleS &tup = *(cb->tup); const TableS * table = tup.getTable(); NdbOperation * op = cb->connection->getNdbOperation(table->getTableName()); if (op == NULL) { if (asynchErrorHandler(cb->connection, m_ndb)) { cb->retries++; continue; } asynchExitHandler(); } // if if (op->writeTuple() == -1) { if (asynchErrorHandler(cb->connection, m_ndb)) { cb->retries++; continue; } asynchExitHandler(); } // if Uint32 ret = 0; for (int i = 0; i < tup.getNoOfAttributes(); i++) { const AttributeS * attr = tup[i]; int size = attr->Desc->size; int arraySize = attr->Desc->arraySize; char * dataPtr = attr->Data.string_value; Uint32 length = (size * arraySize) / 8; if (attr->Desc->m_column->getPrimaryKey()) { ret = op->equal(i, dataPtr, length); } else { if (attr->Data.null) ret = op->setValue(i, NULL, 0); else ret = op->setValue(i, dataPtr, length); } if (ret<0) { ndbout_c("Column: %d type %d",i, tup.getTable()->m_dictTable->getColumn(i)->getType()); if (asynchErrorHandler(cb->connection, m_ndb)) { cb->retries++; break; } asynchExitHandler(); } } if (ret < 0) continue; // Prepare transaction (the transaction is NOT yet sent to NDB) cb->connection->executeAsynchPrepare(Commit, &callback, cb); m_transactions++; } ndbout_c("Unable to recover from errors. Exiting..."); asynchExitHandler(); }
void BackupRestore::tuple(const TupleS & tup) { if (!m_restore) return; while (1) { NdbTransaction * trans = m_ndb->startTransaction(); if (trans == NULL) { // TODO: handle the error ndbout << "Cannot start transaction" << endl; exit(-1); } // if const TableS * table = tup.getTable(); NdbOperation * op = trans->getNdbOperation(table->getTableName()); if (op == NULL) { ndbout << "Cannot get operation: "; ndbout << trans->getNdbError() << endl; exit(-1); } // if // TODO: check return value and handle error if (op->writeTuple() == -1) { ndbout << "writeTuple call failed: "; ndbout << trans->getNdbError() << endl; exit(-1); } // if for (int i = 0; i < tup.getNoOfAttributes(); i++) { const AttributeS * attr = tup[i]; int size = attr->Desc->size; int arraySize = attr->Desc->arraySize; const char * dataPtr = attr->Data.string_value; const Uint32 length = (size * arraySize) / 8; if (attr->Desc->m_column->getPrimaryKey()) op->equal(i, dataPtr, length); } for (int i = 0; i < tup.getNoOfAttributes(); i++) { const AttributeS * attr = tup[i]; int size = attr->Desc->size; int arraySize = attr->Desc->arraySize; const char * dataPtr = attr->Data.string_value; const Uint32 length = (size * arraySize) / 8; if (!attr->Desc->m_column->getPrimaryKey()) if (attr->Data.null) op->setValue(i, NULL, 0); else op->setValue(i, dataPtr, length); } int ret = trans->execute(Commit); if (ret != 0) { ndbout << "execute failed: "; ndbout << trans->getNdbError() << endl; exit(-1); } m_ndb->closeTransaction(trans); if (ret == 0) break; } m_dataCount++; }
void BackupRestore::tuple_a(restore_callback_t *cb) { Uint32 partition_id = cb->fragId; while (cb->retries < 10) { /** * start transactions */ cb->connection = m_ndb->startTransaction(); if (cb->connection == NULL) { if (errorHandler(cb)) { m_ndb->sendPollNdb(3000, 1); continue; } err << "Cannot start transaction" << endl; exitHandler(); } // if const TupleS &tup = cb->tup; const NdbDictionary::Table * table = get_table(tup.getTable()->m_dictTable); NdbOperation * op = cb->connection->getNdbOperation(table); if (op == NULL) { if (errorHandler(cb)) continue; err << "Cannot get operation: " << cb->connection->getNdbError() << endl; exitHandler(); } // if if (op->writeTuple() == -1) { if (errorHandler(cb)) continue; err << "Error defining op: " << cb->connection->getNdbError() << endl; exitHandler(); } // if if (table->getFragmentType() == NdbDictionary::Object::UserDefined) { if (table->getDefaultNoPartitionsFlag()) { /* This can only happen for HASH partitioning with user defined hash function where user hasn't specified the number of partitions and we have to calculate it. We use the hash value stored in the record to calculate the partition to use. */ int i = tup.getNoOfAttributes() - 1; const AttributeData *attr_data = tup.getData(i); Uint32 hash_value = *attr_data->u_int32_value; op->setPartitionId(get_part_id(table, hash_value)); } else { /* Either RANGE or LIST (with or without subparts) OR HASH partitioning with user defined hash function but with fixed set of partitions. */ op->setPartitionId(partition_id); } } int ret = 0; for (int j = 0; j < 2; j++) { for (int i = 0; i < tup.getNoOfAttributes(); i++) { const AttributeDesc * attr_desc = tup.getDesc(i); const AttributeData * attr_data = tup.getData(i); int size = attr_desc->size; int arraySize = attr_desc->arraySize; char * dataPtr = attr_data->string_value; Uint32 length = 0; if (!attr_data->null) { const unsigned char * src = (const unsigned char *)dataPtr; switch(attr_desc->m_column->getType()){ case NdbDictionary::Column::Varchar: case NdbDictionary::Column::Varbinary: length = src[0] + 1; break; case NdbDictionary::Column::Longvarchar: case NdbDictionary::Column::Longvarbinary: length = src[0] + (src[1] << 8) + 2; break; default: length = attr_data->size; break; } } if (j == 0 && tup.getTable()->have_auto_inc(i)) tup.getTable()->update_max_auto_val(dataPtr,size*arraySize); if (attr_desc->m_column->getPrimaryKey()) { if (j == 1) continue; ret = op->equal(i, dataPtr, length); } else { if (j == 0) continue; if (attr_data->null) ret = op->setValue(i, NULL, 0); else ret = op->setValue(i, dataPtr, length); } if (ret < 0) { ndbout_c("Column: %d type %d %d %d %d",i, attr_desc->m_column->getType(), size, arraySize, length); break; } } if (ret < 0) break; } if (ret < 0) { if (errorHandler(cb)) continue; err << "Error defining op: " << cb->connection->getNdbError() << endl; exitHandler(); } // Prepare transaction (the transaction is NOT yet sent to NDB) cb->connection->executeAsynchPrepare(NdbTransaction::Commit, &callback, cb); m_transactions++; return; } err << "Retried transaction " << cb->retries << " times.\nLast error" << m_ndb->getNdbError(cb->error_code) << endl << "...Unable to recover from errors. Exiting..." << endl; exitHandler(); }
/* Test for correct behaviour using primary key operations * when an NDBD node's SegmentedSection pool is exhausted. */ int testSegmentedSectionPk(NDBT_Context* ctx, NDBT_Step* step){ /* * Signal type Exhausted @ How * ----------------------------------------------------- * Long TCKEYREQ Initial import Consume + send * Long TCKEYREQ Initial import, not first * TCKEYREQ in batch Consume + send * Long TCKEYREQ Initial import, not last * TCKEYREQ in batch Consume + send * No testing of short TCKEYREQ variants as they cannot be * generated in mysql-5.1-telco-6.4+ * TODO : Add short variant testing to testUpgrade. */ /* We just run on one table */ if (strcmp(ctx->getTab()->getName(), "WIDE_2COL") != 0) return NDBT_OK; const Uint32 maxRowBytes= NDB_MAX_TUPLE_SIZE_IN_WORDS * sizeof(Uint32); const Uint32 srcBuffBytes= NDBT_Tables::MaxVarTypeKeyBytes; const Uint32 maxAttrBytes= NDBT_Tables::MaxKeyMaxVarTypeAttrBytes; char smallKey[50]; char srcBuff[srcBuffBytes]; char smallRowBuf[maxRowBytes]; char bigKeyRowBuf[maxRowBytes]; char bigAttrRowBuf[maxRowBytes]; /* Small key for hinting to same TC */ Uint32 smallKeySize= setLongVarchar(&smallKey[0], "ShortKey", 8); /* Large value source */ memset(srcBuff, 'B', srcBuffBytes); const NdbRecord* record= ctx->getTab()->getDefaultRecord(); /* Setup buffers * Small row buffer with small key and small data */ setLongVarchar(NdbDictionary::getValuePtr(record, smallRowBuf, 0), "ShortKey", 8); NdbDictionary::setNull(record, smallRowBuf, 0, false); setLongVarchar(NdbDictionary::getValuePtr(record, smallRowBuf, 1), "ShortData", 9); NdbDictionary::setNull(record, smallRowBuf, 1, false); /* Big key buffer with big key and small data*/ setLongVarchar(NdbDictionary::getValuePtr(record, bigKeyRowBuf, 0), &srcBuff[0], srcBuffBytes); NdbDictionary::setNull(record, bigKeyRowBuf, 0, false); setLongVarchar(NdbDictionary::getValuePtr(record, bigKeyRowBuf, 1), "ShortData", 9); NdbDictionary::setNull(record, bigKeyRowBuf, 1, false); /* Big AttrInfo buffer with small key and big data */ setLongVarchar(NdbDictionary::getValuePtr(record, bigAttrRowBuf, 0), "ShortKey", 8); NdbDictionary::setNull(record, bigAttrRowBuf, 0, false); setLongVarchar(NdbDictionary::getValuePtr(record, bigAttrRowBuf, 1), &srcBuff[0], maxAttrBytes); NdbDictionary::setNull(record, bigAttrRowBuf, 1, false); NdbRestarter restarter; Ndb* pNdb= GETNDB(step); /* Start a transaction on a specific node */ NdbTransaction* trans= pNdb->startTransaction(ctx->getTab(), &smallKey[0], smallKeySize); CHECKNOTNULL(trans); /* Activate error insert 8065 in this transaction, limits * any single import/append to 1 section */ CHECKEQUAL(NDBT_OK, activateErrorInsert(trans, record, ctx->getTab(), smallRowBuf, &restarter, 8065)); /* Ok, let's try an insert with a key bigger than 1 section. * Since it's part of the same transaction, it'll go via * the same TC. */ const NdbOperation* bigInsert = trans->insertTuple(record, bigKeyRowBuf); CHECKNOTNULL(bigInsert); CHECKEQUAL(-1, trans->execute(NdbTransaction::NoCommit)); /* ZGET_DATABUF_ERR expected */ CHECKEQUAL(218, trans->getNdbError().code) trans->close(); /* Ok, now a long TCKEYREQ to the same TC - this * has slightly different abort handling since no other * operations exist in this new transaction. * We also change it so that import overflow occurs * on the AttrInfo section */ /* Start transaction on the same node */ CHECKNOTNULL(trans= pNdb->startTransaction(ctx->getTab(), &smallKey[0], smallKeySize)); CHECKNOTNULL(bigInsert = trans->insertTuple(record, bigAttrRowBuf)); CHECKEQUAL(-1,trans->execute(NdbTransaction::NoCommit)); /* ZGET_DATABUF_ERR expected */ CHECKEQUAL(218, trans->getNdbError().code); trans->close(); /* Ok, now a long TCKEYREQ where we run out of SegmentedSections * on the first TCKEYREQ, but there are other TCKEYREQs following * in the same batch. Check that abort handling is correct */ /* Start transaction on the same node */ CHECKNOTNULL(trans= pNdb->startTransaction(ctx->getTab(), &smallKey[0], smallKeySize)); /* First op in batch, will cause overflow */ CHECKNOTNULL(bigInsert = trans->insertTuple(record, bigAttrRowBuf)); /* Second op in batch, what happens to it? */ const NdbOperation* secondOp; CHECKNOTNULL(secondOp = trans->insertTuple(record, bigAttrRowBuf)); CHECKEQUAL(-1,trans->execute(NdbTransaction::NoCommit)); /* ZGET_DATABUF_ERR expected */ CHECKEQUAL(218, trans->getNdbError().code); trans->close(); /* Now try with a 'short' TCKEYREQ, generated using the old Api * with a big key value */ /* Start transaction on the same node */ CHECKNOTNULL(trans= pNdb->startTransaction(ctx->getTab(), &smallKey[0], smallKeySize)); NdbOperation* bigInsertOldApi; CHECKNOTNULL(bigInsertOldApi= trans->getNdbOperation(ctx->getTab())); CHECKEQUAL(0, bigInsertOldApi->insertTuple()); CHECKEQUAL(0, bigInsertOldApi->equal((Uint32)0, NdbDictionary::getValuePtr (record, bigKeyRowBuf, 0))); CHECKEQUAL(0, bigInsertOldApi->setValue(1, NdbDictionary::getValuePtr (record, bigKeyRowBuf, 1))); CHECKEQUAL(-1, trans->execute(NdbTransaction::NoCommit)); /* ZGET_DATABUF_ERR expected */ CHECKEQUAL(218, trans->getNdbError().code) trans->close(); /* Now try with a 'short' TCKEYREQ, generated using the old Api * with a big data value */ CHECKNOTNULL(trans= pNdb->startTransaction(ctx->getTab(), &smallKey[0], smallKeySize)); CHECKNOTNULL(bigInsertOldApi= trans->getNdbOperation(ctx->getTab())); CHECKEQUAL(0, bigInsertOldApi->insertTuple()); CHECKEQUAL(0, bigInsertOldApi->equal((Uint32)0, NdbDictionary::getValuePtr (record, bigAttrRowBuf, 0))); CHECKEQUAL(0, bigInsertOldApi->setValue(1, NdbDictionary::getValuePtr (record, bigAttrRowBuf, 1))); CHECKEQUAL(-1, trans->execute(NdbTransaction::NoCommit)); /* ZGET_DATABUF_ERR expected */ CHECKEQUAL(218, trans->getNdbError().code) trans->close(); // TODO : Add code to testUpgrade #if 0 /* * Short TCKEYREQ KeyInfo accumulate Consume + send long * (TCKEYREQ + KEYINFO) * Short TCKEYREQ AttrInfo accumulate Consume + send short key * + long AI * (TCKEYREQ + ATTRINFO) */ /* Change error insert so that next TCKEYREQ will grab * all but one SegmentedSection so that we can then test SegmentedSection * exhaustion when importing the Key/AttrInfo words from the * TCKEYREQ signal itself. */ restarter.insertErrorInAllNodes(8066); /* Now a 'short' TCKEYREQ, there will be space to import the * short key, but not the AttrInfo */ /* Start transaction on same node */ CHECKNOTNULL(trans= pNdb->startTransaction(ctx->getTab(), &smallKey[0], smallKeySize)); CHECKNOTNULL(bigInsertOldApi= trans->getNdbOperation(ctx->getTab())); CHECKEQUAL(0, bigInsertOldApi->insertTuple()); CHECKEQUAL(0, bigInsertOldApi->equal((Uint32)0, NdbDictionary::getValuePtr (record, smallRowBuf, 0))); CHECKEQUAL(0, bigInsertOldApi->setValue(1, NdbDictionary::getValuePtr (record, smallRowBuf, 1))); CHECKEQUAL(-1, trans->execute(NdbTransaction::NoCommit)); /* ZGET_DATABUF_ERR expected */ CHECKEQUAL(218, trans->getNdbError().code) trans->close(); /* Change error insert so that there are no SectionSegments * This will cause failure when attempting to import the * KeyInfo from the TCKEYREQ */ restarter.insertErrorInAllNodes(8067); /* Now a 'short' TCKEYREQ - there will be no space to import the key */ CHECKNOTNULL(trans= pNdb->startTransaction(ctx->getTab(), &smallKey[0], smallKeySize)); CHECKNOTNULL(bigInsertOldApi= trans->getNdbOperation(ctx->getTab())); CHECKEQUAL(0, bigInsertOldApi->insertTuple()); CHECKEQUAL(0, bigInsertOldApi->equal((Uint32)0, NdbDictionary::getValuePtr (record, smallRowBuf, 0))); CHECKEQUAL(0, bigInsertOldApi->setValue(1, NdbDictionary::getValuePtr (record, smallRowBuf, 1))); CHECKEQUAL(-1, trans->execute(NdbTransaction::NoCommit)); /* ZGET_DATABUF_ERR expected */ CHECKEQUAL(218, trans->getNdbError().code) trans->close(); #endif /* Finished with error insert, cleanup the error insertion * Error insert 8068 will free the hoarded segments */ CHECKNOTNULL(trans= pNdb->startTransaction(ctx->getTab(), &smallKey[0], smallKeySize)); CHECKEQUAL(NDBT_OK, activateErrorInsert(trans, record, ctx->getTab(), smallRowBuf, &restarter, 8068)); trans->execute(NdbTransaction::Rollback); CHECKEQUAL(0, trans->getNdbError().code); trans->close(); return NDBT_OK; }
/** * Transaction 4 - T4 * * Create session * * Input: * SubscriberNumber * ServerId * ServerBit * SessionDetails, * DoRollback * Output: * ChangedBy * ChangedTime * Location * BranchExecuted */ int T4(void * obj, const SubscriberNumber inNumber, const SubscriberSuffix inSuffix, const ServerId inServerId, const ServerBit inServerBit, const SessionDetails inSessionDetails, ChangedBy outChangedBy, ChangedTime outChangedTime, Location * outLocation, DoRollback inDoRollback, BranchExecuted * outBranchExecuted, BenchmarkTime * outTransactionTime) { Ndb * pNDB = (Ndb *) obj; GroupId groupId; ActiveSessions sessions; Permission permission; BenchmarkTime start; get_time(&start); int check; NdbRecAttr * check2; NdbConnection * MyTransaction = pNDB->startTransaction(); if (MyTransaction == NULL) error_handler("T4-1: startTranscation", pNDB->getNdbErrorString(), 0); DEBUG3("T4(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); NdbOperation * MyOperation = 0; MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); CHECK_NULL(MyOperation, "T4-1: getNdbOperation", MyTransaction); check = MyOperation->readTupleExclusive(); CHECK_MINUS_ONE(check, "T4-1: readTuple", MyTransaction); check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, inNumber); CHECK_MINUS_ONE(check, "T4-1: equal subscriber", MyTransaction); check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, (char *)outLocation); CHECK_NULL(check2, "T4-1: getValue location", MyTransaction); check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, outChangedBy); CHECK_NULL(check2, "T4-1: getValue changed_by", MyTransaction); check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, outChangedTime); CHECK_NULL(check2, "T4-1: getValue changed_time", MyTransaction); check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, (char *)&groupId); CHECK_NULL(check2, "T4-1: getValue group", MyTransaction); check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, (char *)&sessions); CHECK_NULL(check2, "T4-1: getValue sessions", MyTransaction); check = MyTransaction->execute( NoCommit ); CHECK_MINUS_ONE(check, "T4-1: NoCommit", MyTransaction); /* Operation 2 */ MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); CHECK_NULL(MyOperation, "T4-2: getNdbOperation", MyTransaction); check = MyOperation->readTuple(); CHECK_MINUS_ONE(check, "T4-2: readTuple", MyTransaction); check = MyOperation->equal(IND_GROUP_ID, (char*)&groupId); CHECK_MINUS_ONE(check, "T4-2: equal group", MyTransaction); check2 = MyOperation->getValue(IND_GROUP_ALLOW_INSERT, (char *)&permission); CHECK_NULL(check2, "T4-2: getValue allow_insert", MyTransaction); check = MyTransaction->execute( NoCommit ); CHECK_MINUS_ONE(check, "T4-2: NoCommit", MyTransaction); if(((permission & inServerBit) == inServerBit) && ((sessions & inServerBit) == 0)) { DEBUG("inserting - "); /* Operation 3 */ MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); CHECK_NULL(MyOperation, "T4-3: getNdbOperation", MyTransaction); check = MyOperation->insertTuple(); CHECK_MINUS_ONE(check, "T4-3: insertTuple", MyTransaction); check = MyOperation->equal(IND_SESSION_SUBSCRIBER, (char*)inNumber); CHECK_MINUS_ONE(check, "T4-3: equal number", MyTransaction); check = MyOperation->equal(IND_SESSION_SERVER, (char*)&inServerId); CHECK_MINUS_ONE(check, "T4-3: equal server id", MyTransaction); check = MyOperation->setValue(SESSION_DATA, (char *)inSessionDetails); CHECK_MINUS_ONE(check, "T4-3: setValue session details", MyTransaction); check = MyTransaction->execute( NoCommit ); CHECK_MINUS_ONE(check, "T4-3: NoCommit", MyTransaction); /* Operation 4 */ MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); CHECK_NULL(MyOperation, "T4-4: getNdbOperation", MyTransaction); check = MyOperation->interpretedUpdateTuple(); CHECK_MINUS_ONE(check, "T4-4: interpretedUpdateTuple", MyTransaction); check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, (char*)inNumber); CHECK_MINUS_ONE(check, "T4-4: equal number", MyTransaction); check = MyOperation->incValue(IND_SUBSCRIBER_SESSIONS, (uint32)inServerBit); CHECK_MINUS_ONE(check, "T4-4: inc value", MyTransaction); check = MyTransaction->execute( NoCommit ); CHECK_MINUS_ONE(check, "T4-4: NoCommit", MyTransaction); /* Operation 5 */ MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); CHECK_NULL(MyOperation, "T4-5: getNdbOperation", MyTransaction); check = MyOperation->interpretedUpdateTuple(); CHECK_MINUS_ONE(check, "T4-5: interpretedUpdateTuple", MyTransaction); check = MyOperation->equal(IND_SERVER_ID, (char*)&inServerId); CHECK_MINUS_ONE(check, "T4-5: equal serverId", MyTransaction); check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, (char*)inSuffix); CHECK_MINUS_ONE(check, "T4-5: equal suffix", MyTransaction); check = MyOperation->incValue(IND_SERVER_INSERTS, (uint32)1); CHECK_MINUS_ONE(check, "T4-5: inc value", MyTransaction); check = MyTransaction->execute( NoCommit ); CHECK_MINUS_ONE(check, "T4-5: NoCommit", MyTransaction); (* outBranchExecuted) = 1; } else { DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); (* outBranchExecuted) = 0; } if(!inDoRollback) { DEBUG("commit\n"); check = MyTransaction->execute( Commit ); CHECK_MINUS_ONE(check, "T4: Commit", MyTransaction); } else { DEBUG("rollback\n"); check = MyTransaction->execute(Rollback); CHECK_MINUS_ONE(check, "T4:Rollback", MyTransaction); } pNDB->closeTransaction(MyTransaction); get_time(outTransactionTime); time_diff(outTransactionTime, &start); return 0; }
inline int ScanInterpretTest::addRowToInsert(Ndb* pNdb, NdbConnection* pInsTrans){ NdbOperation* pOp = pInsTrans->getNdbOperation(restab.getName()); if (pOp == NULL) { ERR(pInsTrans->getNdbError()); pNdb->closeTransaction(pInsTrans); return NDBT_FAILED; } if( pOp->insertTuple() == -1 ) { ERR(pInsTrans->getNdbError()); pNdb->closeTransaction(pInsTrans); return NDBT_FAILED; } // Copy all attribute to the new operation for (int a = 0; a<restab.getNoOfColumns(); a++){ const NdbDictionary::Column* attr = tab.getColumn(a); NdbRecAttr* reca = row.attributeStore(a); int check = -1; switch (attr->getType()){ case NdbDictionary::Column::Char: case NdbDictionary::Column::Varchar: case NdbDictionary::Column::Binary: case NdbDictionary::Column::Varbinary:{ check = pOp->setValue( attr->getName(), reca->aRef()); break; } case NdbDictionary::Column::Int:{ check = pOp->setValue( attr->getName(), reca->int32_value()); } break; case NdbDictionary::Column::Bigint:{ check = pOp->setValue( attr->getName(), reca->int64_value()); } break; case NdbDictionary::Column::Unsigned:{ check = pOp->setValue( attr->getName(), reca->u_32_value()); } break; case NdbDictionary::Column::Bigunsigned:{ check = pOp->setValue( attr->getName(), reca->u_64_value()); } break; case NdbDictionary::Column::Float: check = pOp->setValue( attr->getName(), reca->float_value()); break; default: check = -1; break; } if(check != 0){ ERR(pInsTrans->getNdbError()); pNdb->closeTransaction(pInsTrans); return NDBT_FAILED; } } return NDBT_OK; }
void T4_Callback_2(int result, NdbConnection * pCON, void * threadData){ CHECK_MINUS_ONE(result, "T4-2: NoCommit", pCON); ThreadData * td = (ThreadData *)threadData; Uint32 permission = td->transactionData.permission; Uint32 sessions = td->transactionData.sessions; Uint32 server_bit = td->transactionData.server_bit; if(((permission & server_bit) == server_bit) && ((sessions & server_bit) == 0)){ memcpy(td->transactionData.suffix, &td->transactionData.number [SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], SUBSCRIBER_NUMBER_SUFFIX_LENGTH); DEBUG5("T4(%.*s, %.2d): - Callback 2 - inserting(%.*s)\n", SUBSCRIBER_NUMBER_LENGTH, td->transactionData.number, td->transactionData.server_id, SUBSCRIBER_NUMBER_SUFFIX_LENGTH, td->transactionData.suffix); /* Operation 3 */ NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE); CHECK_NULL(MyOp, "T4-3: getNdbOperation", pCON); MyOp->insertTuple(); MyOp->equal(IND_SESSION_SUBSCRIBER, (char*)td->transactionData.number); MyOp->equal(IND_SESSION_SERVER, (char*)&td->transactionData.server_id); MyOp->setValue(SESSION_DATA, (char *)td->transactionData.session_details); /* Operation 4 */ /* Operation 5 */ MyOp = pCON->getNdbOperation(SERVER_TABLE); CHECK_NULL(MyOp, "T4-5: getNdbOperation", pCON); MyOp->interpretedUpdateTuple(); MyOp->equal(IND_SERVER_ID, (char*)&td->transactionData.server_id); MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX, (char*)td->transactionData.suffix); MyOp->incValue(IND_SERVER_INSERTS, (uint32)1); td->transactionData.branchExecuted = 1; } else { td->transactionData.branchExecuted = 0; DEBUG5("T4(%.*s, %.2d): - Callback 2 - %s %s\n", SUBSCRIBER_NUMBER_LENGTH, td->transactionData.number, td->transactionData.server_id, ((permission & server_bit) ? "permission - " : "no permission - "), ((sessions & server_bit) ? "in session - " : "no in session - ")); } if(!td->transactionData.do_rollback && td->transactionData.branchExecuted){ pCON->executeAsynchPrepare(Commit, T4_Callback_3, td); } else { pCON->executeAsynchPrepare(Rollback, T4_Callback_3, td); } }