int HugoAsynchTransactions::executeAsynchOperation(Ndb* pNdb, int records, int batch, int trans, int operations, NDB_OPERATION theOperation, ExecType theType) { int check = 0; // int retryAttempt = 0; // Not used at the moment // int retryMax = 5; // Not used at the moment int cTrans = 0; int cRecords = 0; int cIndex = 0; int a,t,r; transactionsCompleted = 0; allocTransactions(trans); for (int i = 0; i < batch; i++) { // For each batch while (cRecords < records*batch) { cTrans = 0; cIndex = 0; for (t = 0; t < trans; t++) { // For each transaction transactions[t] = pNdb->startTransaction(); if (transactions[t] == NULL) { ERR(pNdb->getNdbError()); return NDBT_FAILED; } for (int k = 0; k < operations; k++) { // For each operation NdbOperation* pOp = transactions[t]->getNdbOperation(tab.getName()); if (pOp == NULL) { ERR(transactions[t]->getNdbError()); pNdb->closeTransaction(transactions[t]); return NDBT_FAILED; } switch (theOperation) { case NO_INSERT: // Insert check = pOp->insertTuple(); if (check == -1) { ERR(transactions[t]->getNdbError()); pNdb->closeTransaction(transactions[t]); return NDBT_FAILED; } // Set a calculated value for each attribute in this table for (a = 0; a < tab.getNoOfColumns(); a++) { if (setValueForAttr(pOp, a, cRecords, 0 ) != 0) { ERR(transactions[t]->getNdbError()); pNdb->closeTransaction(transactions[t]); return NDBT_FAILED; } } // For each attribute break; case NO_UPDATE: // This is a special case and is handled in the calling client... break; break; case NO_READ: // Define primary keys check = pOp->readTuple(); for (a = 0; a < tab.getNoOfColumns(); a++) { if (tab.getColumn(a)->getPrimaryKey() == true) { if (equalForAttr(pOp, a, cRecords) != 0){ ERR(transactions[t]->getNdbError()); pNdb->closeTransaction(transactions[t]); return NDBT_FAILED; } } } // Define attributes to read for (a = 0; a < tab.getNoOfColumns(); a++) { if ((rows[cIndex]->attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(transactions[t]->getNdbError()); pNdb->closeTransaction(transactions[t]); return NDBT_FAILED; } } break; case NO_DELETE: // Delete check = pOp->deleteTuple(); if (check == -1) { ERR(transactions[t]->getNdbError()); pNdb->closeTransaction(transactions[t]); return NDBT_FAILED; } // Define primary keys for (a = 0; a < tab.getNoOfColumns(); a++) { if (tab.getColumn(a)->getPrimaryKey() == true){ if (equalForAttr(pOp, a, cRecords) != 0) { ERR(transactions[t]->getNdbError()); pNdb->closeTransaction(transactions[t]); return NDBT_FAILED; } } } break; default: // Should not happen... pNdb->closeTransaction(transactions[t]); return NDBT_FAILED; } cIndex++; cRecords++; } // For each operation // Let's prepare... transactions[t]->executeAsynchPrepare(theType, &asynchCallback, this); cTrans++; if (cRecords >= records) { // No more transactions needed break; } } // For each transaction // Wait for all outstanding transactions pNdb->sendPollNdb(3000, 0, 0); // ugly... it's starts to resemble flexXXX ...:( switch (theOperation) { case NO_READ: // Verify the data! for (r = 0; r < trans*operations; r++) { if (calc.verifyRowValues(rows[r]) != 0) { g_info << "|- Verify failed..." << endl; // Close all transactions for (int t = 0; t < cTrans; t++) { pNdb->closeTransaction(transactions[t]); } return NDBT_FAILED; } } break; case NO_INSERT: case NO_UPDATE: case NO_DELETE: break; } // Close all transactions for (t = 0; t < cTrans; t++) { pNdb->closeTransaction(transactions[t]); } } // while (cRecords < records*batch) } // For each batch deallocTransactions(); return NDBT_OK; }
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(); }
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 T5_Callback_2(int result, NdbConnection * pCON, void * threadData){ CHECK_MINUS_ONE(result, "T5-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) == server_bit)){ memcpy(td->transactionData.suffix, &td->transactionData.number [SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], SUBSCRIBER_NUMBER_SUFFIX_LENGTH); DEBUG5("T5(%.*s, %.2d): - Callback 2 - deleting(%.*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, "T5-3: getNdbOperation", pCON); MyOp->deleteTuple(); MyOp->equal(IND_SESSION_SUBSCRIBER, (char*)td->transactionData.number); MyOp->equal(IND_SESSION_SERVER, (char*)&td->transactionData.server_id); /* Operation 4 */ /* Operation 5 */ MyOp = pCON->getNdbOperation(SERVER_TABLE); CHECK_NULL(MyOp, "T5-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_DELETES, (uint32)1); td->transactionData.branchExecuted = 1; } else { td->transactionData.branchExecuted = 0; DEBUG5("T5(%.*s, %.2d): - Callback 2 - no delete - %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, T5_Callback_3, td); } else { pCON->executeAsynchPrepare(Rollback, T5_Callback_3, td); } }
int HugoOperations::pkReadRecord(Ndb* pNdb, int recordNo, int numRecords, NdbOperation::LockMode lm){ int a; allocRows(numRecords); int check; NdbOperation* pOp = 0; pIndexScanOp = 0; for(int r=0; r < numRecords; r++){ if(pOp == 0) { pOp = getOperation(pTrans, NdbOperation::ReadRequest); } if (pOp == NULL) { ERR(pTrans->getNdbError()); return NDBT_FAILED; } rand_lock_mode: switch(lm){ case NdbOperation::LM_Read: case NdbOperation::LM_Exclusive: case NdbOperation::LM_CommittedRead: case NdbOperation::LM_SimpleRead: if(idx && idx->getType() == NdbDictionary::Index::OrderedIndex && pIndexScanOp == 0) { pIndexScanOp = ((NdbIndexScanOperation*)pOp); check = pIndexScanOp->readTuples(lm); } else check = pOp->readTuple(lm); break; default: lm = (NdbOperation::LockMode)((rand() >> 16) & 3); goto rand_lock_mode; } if( check == -1 ) { ERR(pTrans->getNdbError()); return NDBT_FAILED; } // Define primary keys if (equalForRow(pOp, r+recordNo) != 0) return NDBT_FAILED; if(pIndexScanOp) pIndexScanOp->end_of_bound(r); if(r == 0 || pIndexScanOp == 0) { // Define attributes to read for(a = 0; a<tab.getNoOfColumns(); a++){ if((rows[r]->attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(pTrans->getNdbError()); return NDBT_FAILED; } } } pOp = pIndexScanOp; } return NDBT_OK; }
/* 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; } } } }
int UtilTransactions::readRowFromTableAndIndex(Ndb* pNdb, NdbConnection* scanTrans, const NdbDictionary::Index* pIndex, NDBT_ResultRow& row ){ NdbDictionary::Index::Type indexType= pIndex->getType(); int retryAttempt = 0; const int retryMax = 100; int check, a; NdbConnection *pTrans1=NULL; NdbOperation *pOp; int return_code= NDBT_FAILED; // Allocate place to store the result NDBT_ResultRow tabRow(tab); NDBT_ResultRow indexRow(tab); const char * indexName = pIndex->getName(); while (true){ if(retryAttempt) ndbout_c("retryAttempt %d", retryAttempt); if (retryAttempt >= retryMax){ g_info << "ERROR: has retried this operation " << retryAttempt << " times, failing!" << endl; goto close_all; } pTrans1 = pNdb->hupp(scanTrans); //startTransaction(); if (pTrans1 == NULL) { const NdbError err = pNdb->getNdbError(); if (err.status == NdbError::TemporaryError){ ERR(err); NdbSleep_MilliSleep(50); retryAttempt++; continue; } if(err.code == 0){ return_code = NDBT_OK; goto close_all; } ERR(err); goto close_all; } /** * Read the record from TABLE */ pOp = pTrans1->getNdbOperation(tab.getName()); if (pOp == NULL) { ERR(pTrans1->getNdbError()); goto close_all; } check = pOp->readTuple(); if( check == -1 ) { ERR(pTrans1->getNdbError()); goto close_all; } // Define primary keys #if VERBOSE printf("PK: "); #endif for(a = 0; a<tab.getNoOfColumns(); a++){ const NdbDictionary::Column* attr = tab.getColumn(a); if (attr->getPrimaryKey() == true){ if (pOp->equal(attr->getName(), row.attributeStore(a)->aRef()) != 0){ ERR(pTrans1->getNdbError()); goto close_all; } #if VERBOSE printf("%s = %d: ", attr->getName(), row.attributeStore(a)->aRef()); #endif } } #if VERBOSE printf("\n"); #endif // Read all attributes #if VERBOSE printf("Reading %u attributes: ", tab.getNoOfColumns()); #endif for(a = 0; a<tab.getNoOfColumns(); a++){ if((tabRow.attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(pTrans1->getNdbError()); goto close_all; } #if VERBOSE printf("%s ", tab.getColumn(a)->getName()); #endif } #if VERBOSE printf("\n"); #endif /** * Read the record from INDEX_TABLE */ NdbIndexOperation* pIndexOp= NULL; NdbIndexScanOperation *pScanOp= NULL; NdbOperation *pIOp= 0; bool null_found= false; for(a = 0; a<(int)pIndex->getNoOfColumns(); a++){ const NdbDictionary::Column * col = pIndex->getColumn(a); if (row.attributeStore(col->getName())->isNULL()) { null_found= true; break; } } const char * tabName= tab.getName(); if(!null_found) { if (indexType == NdbDictionary::Index::UniqueHashIndex) { pIOp= pIndexOp= pTrans1->getNdbIndexOperation(indexName, tabName); } else { pIOp= pScanOp= pTrans1->getNdbIndexScanOperation(indexName, tabName); } if (pIOp == NULL) { ERR(pTrans1->getNdbError()); goto close_all; } { bool not_ok; if (pIndexOp) { not_ok = pIndexOp->readTuple() == -1; } else { not_ok = pScanOp->readTuples(); } if( not_ok ) { ERR(pTrans1->getNdbError()); goto close_all; } } // Define primary keys for index #if VERBOSE printf("SI: "); #endif for(a = 0; a<(int)pIndex->getNoOfColumns(); a++){ const NdbDictionary::Column * col = pIndex->getColumn(a); int r; if ( !row.attributeStore(col->getName())->isNULL() ) { if(pIOp->equal(col->getName(), row.attributeStore(col->getName())->aRef()) != 0){ ERR(pTrans1->getNdbError()); goto close_all; } } #if VERBOSE printf("%s = %d: ", col->getName(), row.attributeStore(a)->aRef()); #endif } #if VERBOSE printf("\n"); #endif // Read all attributes #if VERBOSE printf("Reading %u attributes: ", tab.getNoOfColumns()); #endif for(a = 0; a<tab.getNoOfColumns(); a++){ void* pCheck; pCheck= indexRow.attributeStore(a)= pIOp->getValue(tab.getColumn(a)->getName()); if(pCheck == NULL) { ERR(pTrans1->getNdbError()); goto close_all; } #if VERBOSE printf("%s ", tab.getColumn(a)->getName()); #endif } } #if VERBOSE printf("\n"); #endif scanTrans->refresh(); check = pTrans1->execute(Commit, AbortOnError); if( check == -1 ) { const NdbError err = pTrans1->getNdbError(); if (err.status == NdbError::TemporaryError){ ERR(err); pNdb->closeTransaction(pTrans1); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ndbout << "Error when comparing records - normal op" << endl; ERR(err); ndbout << "row: " << row.c_str().c_str() << endl; goto close_all; } /** * Compare the two rows */ if(!null_found){ if (pScanOp) { if (pScanOp->nextResult() != 0){ const NdbError err = pTrans1->getNdbError(); ERR(err); ndbout << "Error when comparing records - index op next_result missing" << endl; ndbout << "row: " << row.c_str().c_str() << endl; goto close_all; } } if (!(tabRow.c_str() == indexRow.c_str())){ ndbout << "Error when comapring records" << endl; ndbout << " tabRow: \n" << tabRow.c_str().c_str() << endl; ndbout << " indexRow: \n" << indexRow.c_str().c_str() << endl; goto close_all; } if (pScanOp) { if (pScanOp->nextResult() == 0){ ndbout << "Error when comparing records - index op next_result to many" << endl; ndbout << "row: " << row.c_str().c_str() << endl; goto close_all; } } } return_code= NDBT_OK; goto close_all; } close_all: if (pTrans1) pNdb->closeTransaction(pTrans1); return return_code; }
/** * Transaction 5 - T5 * * Delete session * * Input: * SubscriberNumber * ServerId * ServerBit * DoRollback * Output: * ChangedBy * ChangedTime * Location * BranchExecuted */ void userTransaction_T5(UserHandle * uh, SubscriberNumber inNumber, ServerId inServerId, ServerBit inServerBit, DoRollback inDoRollback, BranchExecuted * outBranchExecuted){ Ndb * pNDB = uh->pNDB; DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); NdbConnection * MyTransaction = 0; NdbOperation * MyOperation = 0; char outChangedBy [sizeof(ChangedBy) +(4-(sizeof(ChangedBy) & 3))]; char outChangedTime [sizeof(ChangedTime)+(4-(sizeof(ChangedTime) & 3))]; Location outLocation; GroupId groupId; ActiveSessions sessions; Permission permission; SubscriberSuffix inSuffix; int check; NdbRecAttr * check2; MyTransaction = pNDB->startTransaction(); if (MyTransaction == NULL) error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), pNDB->getNdbError()); MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); CHECK_NULL(MyOperation, "T5-1: getNdbOperation", MyTransaction); MyOperation->interpretedUpdateTuple(); MyOperation->equal(IND_SUBSCRIBER_NUMBER, inNumber); MyOperation->getValue(IND_SUBSCRIBER_LOCATION, (char *)&outLocation); MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, &outChangedBy[0]); MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, &outChangedTime[0]); MyOperation->getValue(IND_SUBSCRIBER_GROUP, (char *)&groupId); MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, (char *)&sessions); MyOperation->subValue(IND_SUBSCRIBER_SESSIONS, (uint32)inServerBit); MyTransaction->execute( NoCommit ); /* Operation 2 */ MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); CHECK_NULL(MyOperation, "T5-2: getNdbOperation", MyTransaction); MyOperation->readTuple(); MyOperation->equal(IND_GROUP_ID, (char*)&groupId); MyOperation->getValue(IND_GROUP_ALLOW_DELETE, (char *)&permission); check = MyTransaction->execute( NoCommit ); CHECK_MINUS_ONE(check, "T5-2: NoCommit", MyTransaction); if(((permission & inServerBit) == inServerBit) && ((sessions & inServerBit) == inServerBit)){ memcpy(inSuffix, &inNumber[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], SUBSCRIBER_NUMBER_SUFFIX_LENGTH); DEBUG2("deleting(%.*s) - ", SUBSCRIBER_NUMBER_SUFFIX_LENGTH, inSuffix); /* Operation 3 */ MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); CHECK_NULL(MyOperation, "T5-3: getNdbOperation", MyTransaction); MyOperation->deleteTuple(); MyOperation->equal(IND_SESSION_SUBSCRIBER, (char*)inNumber); MyOperation->equal(IND_SESSION_SERVER, (char*)&inServerId); /* Operation 4 */ /* Operation 5 */ MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); CHECK_NULL(MyOperation, "T5-5: getNdbOperation", MyTransaction); MyOperation->interpretedUpdateTuple(); MyOperation->equal(IND_SERVER_ID, (char*)&inServerId); MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, (char*)inSuffix); MyOperation->incValue(IND_SERVER_DELETES, (uint32)1); (* outBranchExecuted) = 1; } else { (* outBranchExecuted) = 0; DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); } if(!inDoRollback && (* outBranchExecuted)){ DEBUG("commit\n"); check = MyTransaction->execute( Commit ); CHECK_MINUS_ONE(check, "T5: Commit", MyTransaction); } else { DEBUG("rollback\n"); check = MyTransaction->execute(Rollback); CHECK_MINUS_ONE(check, "T5:Rollback", MyTransaction); } pNDB->closeTransaction(MyTransaction); }
int HugoOperations::pkReadRecord(Ndb* pNdb, int recordNo, int numRecords, NdbOperation::LockMode lm, NdbOperation::LockMode *lmused){ int a; allocRows(numRecords); indexScans.clear(); int check; NdbOperation* pOp = 0; pIndexScanOp = 0; for(int r=0; r < numRecords; r++){ if(pOp == 0) { pOp = getOperation(pTrans, NdbOperation::ReadRequest); } if (pOp == NULL) { ERR(pTrans->getNdbError()); setNdbError(pTrans->getNdbError()); return NDBT_FAILED; } rand_lock_mode: switch(lm){ case NdbOperation::LM_Read: case NdbOperation::LM_Exclusive: case NdbOperation::LM_CommittedRead: case NdbOperation::LM_SimpleRead: if (lmused) * lmused = lm; if(idx && idx->getType() == NdbDictionary::Index::OrderedIndex) { if (pIndexScanOp == 0) { pIndexScanOp = ((NdbIndexScanOperation*)pOp); bool mrrScan= (numRecords > 1); Uint32 flags= mrrScan? NdbScanOperation::SF_MultiRange : 0; check = pIndexScanOp->readTuples(lm, flags); /* Record NdbIndexScanOperation ptr for later... */ indexScans.push_back(pIndexScanOp); } } else check = pOp->readTuple(lm); break; default: lm = (NdbOperation::LockMode)((rand() >> 16) & 3); goto rand_lock_mode; } if( check == -1 ) { ERR(pTrans->getNdbError()); setNdbError(pTrans->getNdbError()); return NDBT_FAILED; } // Define primary keys if (equalForRow(pOp, r+recordNo) != 0) return NDBT_FAILED; Uint32 partId; /* Do we need to set the partitionId for this operation? */ if (getPartIdForRow(pOp, r+recordNo, partId)) { g_info << "Setting operation partition Id" << endl; pOp->setPartitionId(partId); } if(pIndexScanOp) pIndexScanOp->end_of_bound(r); if(r == 0 || pIndexScanOp == 0) { // Define attributes to read for(a = 0; a<tab.getNoOfColumns(); a++){ if((rows[r]->attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(pTrans->getNdbError()); setNdbError(pTrans->getNdbError()); return NDBT_FAILED; } } } /* Note pIndexScanOp will point to the 'last' index scan op * we used. The full list is in the indexScans vector */ pOp = pIndexScanOp; } return NDBT_OK; }
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); /* Operations 3 + 4 */ if (td->ndbRecordSharedData) { char* rowPtr= (char*) &td->transactionData; const NdbRecord* record= td->ndbRecordSharedData-> sessionTableNdbRecord; Uint32 m=0; unsigned char* mask= (unsigned char*) &m; SET_MASK(mask, IND_SESSION_SUBSCRIBER); SET_MASK(mask, IND_SESSION_SERVER); SET_MASK(mask, IND_SESSION_DATA); const NdbOperation* MyOp= pCON->insertTuple(record, rowPtr, mask); CHECK_NULL((void*)MyOp, "T4-3: insertTuple", td, pCON->getNdbError()); record= td->ndbRecordSharedData-> serverTableNdbRecord; m= 0; NdbOperation::OperationOptions opts; opts.optionsPresent= NdbOperation::OperationOptions::OO_INTERPRETED; opts.interpretedCode= td->ndbRecordSharedData->incrServerInsertsProg; MyOp= pCON->updateTuple(record, rowPtr, record, rowPtr, mask, &opts, sizeof(opts)); CHECK_NULL((void*)MyOp, "T4-3: updateTuple", td, pCON->getNdbError()); } else { 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(IND_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 }
void T3_Callback_2(int result, NdbConnection * pCON, void * threadData) { ThreadData * td = (ThreadData *)threadData; if (result == -1) { CHECK_ALLOWED_ERROR("T3-2: execute", td, pCON->getNdbError()); td->pNDB->closeTransaction(pCON); start_T3(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) == server_bit)) { memcpy(td->transactionData.suffix, &td->transactionData.number[SFX_START], SUBSCRIBER_NUMBER_SUFFIX_LENGTH); DEBUG5("T3(%.*s, %.2d): - Callback 2 - reading(%.*s)", SUBSCRIBER_NUMBER_LENGTH, td->transactionData.number, td->transactionData.server_id, SUBSCRIBER_NUMBER_SUFFIX_LENGTH, td->transactionData.suffix); /* Operations 3 + 4 */ if (td->ndbRecordSharedData) { /* Op 3 */ char* rowPtr= (char*) &td->transactionData; const NdbRecord* record= td->ndbRecordSharedData-> sessionTableNdbRecord; Uint32 m=0; unsigned char* mask= (unsigned char*) &m; SET_MASK(mask, IND_SESSION_DATA); const NdbOperation* MyOp = pCON->readTuple(record, rowPtr, record, rowPtr, NdbOperation::LM_SimpleRead, mask); CHECK_NULL((void*) MyOp, "T3-3: readTuple", td, pCON->getNdbError()); /* Op 4 */ record= td->ndbRecordSharedData-> serverTableNdbRecord; m= 0; /* Attach interpreted program */ NdbOperation::OperationOptions opts; opts.optionsPresent= NdbOperation::OperationOptions::OO_INTERPRETED; opts.interpretedCode= td->ndbRecordSharedData->incrServerReadsProg; MyOp= pCON->updateTuple(record, rowPtr, record, rowPtr, mask, &opts, sizeof(opts)); CHECK_NULL((void*) MyOp, "T3-3: updateTuple", td, pCON->getNdbError()); } else { NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE); CHECK_NULL(MyOp, "T3-3: getNdbOperation", td, pCON->getNdbError()); MyOp->simpleRead(); MyOp->equal(IND_SESSION_SUBSCRIBER, (char*)td->transactionData.number); MyOp->equal(IND_SESSION_SERVER, (char*)&td->transactionData.server_id); MyOp->getValue(IND_SESSION_DATA, (char *)td->transactionData.session_details); MyOp = pCON->getNdbOperation(SERVER_TABLE); CHECK_NULL(MyOp, "T3-4: 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_READS, (uint32)1); } td->transactionData.branchExecuted = 1; } else { DEBUG3("T3(%.*s, %.2d): - Callback 2 - no read", SUBSCRIBER_NUMBER_LENGTH, td->transactionData.number, td->transactionData.server_id); td->transactionData.branchExecuted = 0; } if (stat_async == 1) { pCON->executeAsynchPrepare( Commit , T3_Callback_3, td); } else { int result = pCON->execute( Commit ); T3_Callback_3(result, pCON, (void*)td); return; }//if }
int main(int argc, char** argv) { if (argc != 3) { std::cout << "Arguments are <socket mysqld> <connect_string cluster>.\n"; exit(-1); } char * mysqld_sock = argv[1]; const char *connectstring = argv[2]; ndb_init(); Ndb_cluster_connection *cluster_connection= new Ndb_cluster_connection(connectstring); // Object representing the cluster int r= cluster_connection->connect(5 /* retries */, 3 /* delay between retries */, 1 /* verbose */); if (r > 0) { std::cout << "Cluster connect failed, possibly resolved with more retries.\n"; exit(-1); } else if (r < 0) { std::cout << "Cluster connect failed.\n"; exit(-1); } if (cluster_connection->wait_until_ready(30,0) < 0) { std::cout << "Cluster was not ready within 30 secs." << std::endl; exit(-1); } // connect to mysql server MYSQL mysql; if ( !mysql_init(&mysql) ) { std::cout << "mysql_init failed\n"; exit(-1); } if ( !mysql_real_connect(&mysql, "localhost", "root", "", "", 0, mysqld_sock, 0) ) MYSQLERROR(mysql); /******************************************** * Connect to database via mysql-c * ********************************************/ mysql_query(&mysql, "CREATE DATABASE TEST_DB_1"); if (mysql_query(&mysql, "USE TEST_DB_1") != 0) MYSQLERROR(mysql); create_table(mysql); Ndb* myNdb = new Ndb( cluster_connection, "TEST_DB_1" ); // Object representing the database NdbTransaction* myNdbTransaction[2]; // For transactions NdbOperation* myNdbOperation; // For operations if (myNdb->init(2) == -1) { // Want two parallel insert transactions APIERROR(myNdb->getNdbError()); exit(-1); } /****************************************************** * Insert (we do two insert transactions in parallel) * ******************************************************/ const NdbDictionary::Dictionary* myDict= myNdb->getDictionary(); const NdbDictionary::Table *myTable= myDict->getTable("MYTABLENAME"); if (myTable == NULL) APIERROR(myDict->getNdbError()); for (int i = 0; i < 2; i++) { myNdbTransaction[i] = myNdb->startTransaction(); if (myNdbTransaction[i] == NULL) APIERROR(myNdb->getNdbError()); myNdbOperation = myNdbTransaction[i]->getNdbOperation(myTable); if (myNdbOperation == NULL) APIERROR(myNdbTransaction[i]->getNdbError()); myNdbOperation->insertTuple(); myNdbOperation->equal("ATTR1", 20 + i); myNdbOperation->setValue("ATTR2", 20 + i); // Prepare transaction (the transaction is NOT yet sent to NDB) myNdbTransaction[i]->executeAsynchPrepare(NdbTransaction::Commit, &callback, NULL); } // Send all transactions to NDB myNdb->sendPreparedTransactions(0); // Poll all transactions myNdb->pollNdb(3000, 2); // Close all transactions for (int i = 0; i < 2; i++) myNdb->closeTransaction(myNdbTransaction[i]); delete myNdb; delete cluster_connection; drop_table(mysql); ndb_end(0); return 0; }
int main(int argc, const char** argv) { ndb_init(); int _row = 0; int _hex = 0; int _primaryKey = 0; const char* _tableName = NULL; struct getargs args[] = { { "row", 'r', arg_integer, &_row, "The row number", "row" }, { "primarykey", 'p', arg_integer, &_primaryKey, "The primary key", "primarykey" }, { "hex", 'h', arg_flag, &_hex, "Print hex", "hex" } }; int num_args = sizeof(args) / sizeof(args[0]); int optind = 0, i; if(getarg(args, num_args, argc, argv, &optind) || argv[optind] == NULL) { arg_printusage(args, num_args, argv[0], "table name\n"); return NDBT_WRONGARGS; } // Check if table name is supplied if (argv[optind] != NULL) _tableName = argv[optind]; const NdbDictionary::Table* table = NDBT_Tables::getTable(_tableName); // const NDBT_Attribute* attribute = table->getAttribute(_column); g_info << "Table " << _tableName << endl << "Row: " << _row << ", PrimaryKey: " << _primaryKey << endl; Ndb_cluster_connection con; if(con.connect(12, 5, 1) != 0) { return NDBT_ProgramExit(NDBT_FAILED); } Ndb* ndb = new Ndb(&con, "TEST_DB"); if (ndb->init() == 0 && ndb->waitUntilReady(30) == 0) { NdbConnection* conn = ndb->startTransaction(); if (conn == NULL) { g_info << "ERROR: " << ndb->getNdbError() << endl; delete ndb; return -1; } NdbOperation* op = conn->getNdbOperation(_tableName); if (op == NULL) { g_info << "ERROR: " << conn->getNdbError() << endl; delete ndb; return -1; } op->readTuple(); NdbRecAttr** data = new NdbRecAttr*[table->getNoOfColumns()]; for (i = 0; i < table->getNoOfColumns(); i++) { const NdbDictionary::Column* c = table->getColumn(i); if (c->getPrimaryKey()) { op->equal(c->getName(), _primaryKey); data[i] = op->getValue(c->getName(), NULL); } else { data[i] = op->getValue(c->getName(), NULL); } } if (conn->execute(Commit) == 0) { // Print column names for (i = 0; i < table->getNoOfColumns(); i++) { const NdbDictionary::Column* c = table->getColumn(i); g_info << c->getName() << "[" << c->getType() << "] "; } g_info << endl; if (_hex) { g_info << hex; } for (i = 0; i < table->getNoOfColumns(); i++) { NdbRecAttr* a = data[i]; ndbout << (* a) << " "; } // for g_info << endl; } // if (conn else { g_info << "Failed to commit read transaction... " << conn->getNdbError() << ", commitStatus = " << conn->commitStatus() << endl; } delete[] data; ndb->closeTransaction(conn); } // if (ndb.init else { g_info << "ERROR: Unable to connect to NDB, " << ndb->getNdbError() << endl; } delete ndb; 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 T3_Callback_2(int result, NdbConnection * pCON, void * threadData){ ThreadData * td = (ThreadData *)threadData; if (result == -1) { CHECK_ALLOWED_ERROR("T3-2: execute", td, pCON->getNdbError()); td->pNDB->closeTransaction(pCON); start_T3(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) == server_bit)){ memcpy(td->transactionData.suffix, &td->transactionData.number[SFX_START], SUBSCRIBER_NUMBER_SUFFIX_LENGTH); DEBUG5("T3(%.*s, %.2d): - Callback 2 - reading(%.*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, "T3-3: getNdbOperation", td, pCON->getNdbError()); MyOp->simpleRead(); MyOp->equal(IND_SESSION_SUBSCRIBER, (char*)td->transactionData.number); MyOp->equal(IND_SESSION_SERVER, (char*)&td->transactionData.server_id); MyOp->getValue(IND_SESSION_DATA, (char *)td->transactionData.session_details); /* Operation 4 */ MyOp = pCON->getNdbOperation(SERVER_TABLE); CHECK_NULL(MyOp, "T3-4: 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_READS, (uint32)1); td->transactionData.branchExecuted = 1; } else { DEBUG3("T3(%.*s, %.2d): - Callback 2 - no read", SUBSCRIBER_NUMBER_LENGTH, td->transactionData.number, td->transactionData.server_id); td->transactionData.branchExecuted = 0; } if (stat_async == 1) { pCON->executeAsynchPrepare( Commit , T3_Callback_3, td); } else { int result = pCON->execute( Commit ); T3_Callback_3(result, pCON, (void*)td); return; }//if }
static void run_slave_wait(struct Xxx &xxx, struct XxxR &xxxr) { struct timeval old_end_time = xxxr.start_time, end_time; 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->readTuple(); op->equal(xxx.pk_col, xxxr.pk_val); op->getValue(xxx.col, (char *)&val); if (trans->execute(NdbTransaction::Commit)) goto err; } /* read done, check time of read */ gettimeofday(&end_time, 0); ndb->closeTransaction(trans); //fprintf(stderr, "read %u waiting for %u\n", val, xxxr.val); if (xxxr.val != val) { /* expected value not received yet */ retries = 100; NdbSleep_MilliSleep(retry_sleep); old_end_time = end_time; continue; } 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); } Int64 elapsed_usec1 = ((Int64)end_time.tv_sec - (Int64)xxxr.start_time.tv_sec)*1000*1000 + ((Int64)end_time.tv_usec - (Int64)xxxr.start_time.tv_usec); Int64 elapsed_usec2 = ((Int64)end_time.tv_sec - (Int64)old_end_time.tv_sec)*1000*1000 + ((Int64)end_time.tv_usec - (Int64)old_end_time.tv_usec); xxxr.latency = ((elapsed_usec1 - elapsed_usec2/2)+999)/1000; }
void T5_Callback_2(int result, NdbConnection * pCON, void * threadData){ ThreadData * td = (ThreadData *)threadData; if (result == -1) { CHECK_ALLOWED_ERROR("T5-2: execute", td, pCON->getNdbError()); td->pNDB->closeTransaction(pCON); start_T5(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) == server_bit)){ memcpy(td->transactionData.suffix, &td->transactionData.number[SFX_START], SUBSCRIBER_NUMBER_SUFFIX_LENGTH); DEBUG5("T5(%.*s, %.2d): - Callback 2 - deleting(%.*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, "T5-3: getNdbOperation", td, pCON->getNdbError()); MyOp->deleteTuple(); MyOp->equal(IND_SESSION_SUBSCRIBER, (char*)td->transactionData.number); MyOp->equal(IND_SESSION_SERVER, (char*)&td->transactionData.server_id); /* Operation 4 */ /* Operation 5 */ MyOp = pCON->getNdbOperation(SERVER_TABLE); CHECK_NULL(MyOp, "T5-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_DELETES, (uint32)1); td->transactionData.branchExecuted = 1; } else { td->transactionData.branchExecuted = 0; DEBUG5("T5(%.*s, %.2d): - Callback 2 - no delete - %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 , T5_Callback_3, td); } else { int result = pCON->execute( Commit ); T5_Callback_3(result, pCON, (void*)td); return; }//if } else { if (stat_async == 1) { pCON->executeAsynchPrepare( Rollback , T5_Callback_3, td); } else { int result = pCON->execute( Rollback ); T5_Callback_3(result, pCON, (void*)td); return; }//if } }
int UtilTransactions::verifyOrderedIndex(Ndb* pNdb, const NdbDictionary::Index* pIndex, int parallelism, bool transactional){ int retryAttempt = 0; const int retryMax = 100; int check; NdbScanOperation *pOp; NdbIndexScanOperation * iop = 0; NDBT_ResultRow scanRow(tab); NDBT_ResultRow pkRow(tab); NDBT_ResultRow indexRow(tab); const char * indexName = pIndex->getName(); int res; parallelism = 1; while (true){ if (retryAttempt >= retryMax){ g_info << "ERROR: has retried this operation " << retryAttempt << " times, failing!" << endl; return NDBT_FAILED; } pTrans = pNdb->startTransaction(); if (pTrans == NULL) { const NdbError err = pNdb->getNdbError(); if (err.status == NdbError::TemporaryError){ ERR(err); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); return NDBT_FAILED; } pOp = pTrans->getNdbScanOperation(tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } if( pOp->readTuples(NdbScanOperation::LM_Read, 0, parallelism) ) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } check = pOp->interpret_exit_ok(); if( check == -1 ) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } if(get_values(pOp, scanRow)) { abort(); } check = pTrans->execute(NoCommit, AbortOnError); if( check == -1 ) { const NdbError err = pTrans->getNdbError(); if (err.status == NdbError::TemporaryError){ ERR(err); closeTransaction(pNdb); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); closeTransaction(pNdb); return NDBT_FAILED; } int eof; int rows = 0; while(check == 0 && (eof = pOp->nextResult()) == 0){ rows++; bool null_found= false; for(int a = 0; a<(int)pIndex->getNoOfColumns(); a++){ const NdbDictionary::Column * col = pIndex->getColumn(a); if (scanRow.attributeStore(col->getName())->isNULL()) { null_found= true; break; } } // Do pk lookup NdbOperation * pk = pTrans->getNdbOperation(tab.getName()); if(!pk || pk->readTuple()) goto error; if(equal(&tab, pk, scanRow) || get_values(pk, pkRow)) goto error; if(!null_found) { if(!iop && (iop= pTrans->getNdbIndexScanOperation(indexName, tab.getName()))) { if(iop->readTuples(NdbScanOperation::LM_CommittedRead, parallelism)) goto error; iop->interpret_exit_ok(); if(get_values(iop, indexRow)) goto error; } else if(!iop || iop->reset_bounds()) { goto error; } if(equal(pIndex, iop, scanRow)) goto error; } check = pTrans->execute(NoCommit, AbortOnError); if(check) goto error; if(scanRow.c_str() != pkRow.c_str()){ g_err << "Error when comapring records" << endl; g_err << " scanRow: \n" << scanRow.c_str().c_str() << endl; g_err << " pkRow: \n" << pkRow.c_str().c_str() << endl; closeTransaction(pNdb); return NDBT_FAILED; } if(!null_found) { if((res= iop->nextResult()) != 0){ g_err << "Failed to find row using index: " << res << endl; ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } if(scanRow.c_str() != indexRow.c_str()){ g_err << "Error when comapring records" << endl; g_err << " scanRow: \n" << scanRow.c_str().c_str() << endl; g_err << " indexRow: \n" << indexRow.c_str().c_str() << endl; closeTransaction(pNdb); return NDBT_FAILED; } if(iop->nextResult() == 0){ g_err << "Found extra row!!" << endl; g_err << " indexRow: \n" << indexRow.c_str().c_str() << endl; closeTransaction(pNdb); return NDBT_FAILED; } } } if (eof == -1 || check == -1) { error: const NdbError err = pTrans->getNdbError(); if (err.status == NdbError::TemporaryError){ ERR(err); iop = 0; closeTransaction(pNdb); NdbSleep_MilliSleep(50); retryAttempt++; rows--; continue; } ERR(err); closeTransaction(pNdb); return NDBT_FAILED; } closeTransaction(pNdb); return NDBT_OK; } return NDBT_FAILED; }
int HugoTransactions::pkInterpretedUpdateRecords(Ndb* pNdb, int records, int batch){ int updated = 0; int r = 0; int retryAttempt = 0; int check, a; while (r < records){ if (retryAttempt >= m_retryMax){ g_info << "ERROR: has retried this operation " << retryAttempt << " times, failing!" << endl; return NDBT_FAILED; } pTrans = pNdb->startTransaction(); if (pTrans == NULL) { const NdbError err = pNdb->getNdbError(); if (err.status == NdbError::TemporaryError){ ERR(err); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); return NDBT_FAILED; } NdbOperation* pOp = pTrans->getNdbOperation(tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } check = pOp->readTupleExclusive(); if( check == -1 ) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } // Define primary keys if (equalForRow(pOp, r) != 0) { closeTransaction(pNdb); return NDBT_FAILED; } // Read update value for(a = 0; a<tab.getNoOfColumns(); a++){ if (calc.isUpdateCol(a) == true){ if((row.attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } } } check = pTrans->execute(NoCommit, AbortOnError); if( check == -1 ) { const NdbError err = pTrans->getNdbError(); if (err.status == NdbError::TemporaryError){ ERR(err); closeTransaction(pNdb); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); closeTransaction(pNdb); return NDBT_FAILED; } int updates = calc.getUpdatesValue(&row) + 1; NdbOperation* pUpdOp; pUpdOp = pTrans->getNdbOperation(tab.getName()); if (pUpdOp == NULL) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } check = pUpdOp->interpretedUpdateTuple(); if( check == -1 ) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } // PKs if (equalForRow(pUpdOp, r) != 0) { closeTransaction(pNdb); return NDBT_FAILED; } // Update col for(a = 0; a<tab.getNoOfColumns(); a++){ if ((tab.getColumn(a)->getPrimaryKey() == false) && (calc.isUpdateCol(a) == true)){ // TODO switch for 32/64 bit const NdbDictionary::Column* attr = tab.getColumn(a); Uint32 valToIncWith = 1; check = pUpdOp->incValue(attr->getName(), valToIncWith); if( check == -1 ) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } } } // Remaining attributes for(a = 0; a<tab.getNoOfColumns(); a++){ if ((tab.getColumn(a)->getPrimaryKey() == false) && (calc.isUpdateCol(a) == false)){ if(setValueForAttr(pUpdOp, a, r, updates ) != 0){ ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } } } check = pTrans->execute(Commit, AbortOnError); if( check == -1 ) { const NdbError err = pTrans->getNdbError(); if (err.status == NdbError::TemporaryError){ ERR(err); closeTransaction(pNdb); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); ndbout << "r = " << r << endl; closeTransaction(pNdb); return NDBT_FAILED; } else{ updated++; m_latest_gci = pTrans->getGCI(); } closeTransaction(pNdb); r++; // Read next record } g_info << "|- " << updated << " records updated" << endl; return NDBT_OK; }
int run_read(){ int iter = g_paramters[P_LOOPS].value; NDB_TICKS start1, stop; int sum_time= 0; const Uint32 rows = g_paramters[P_ROWS].value; const Uint32 range = g_paramters[P_RANGE].value; start1 = NdbTick_CurrentMillisecond(); NdbConnection * pTrans = g_ndb->startTransaction(); if(!pTrans){ g_err << "Failed to start transaction" << endl; err(g_ndb->getNdbError()); return -1; } NdbOperation * pOp; NdbScanOperation * pSp; NdbIndexOperation * pUp; NdbIndexScanOperation * pIp; Uint32 start_row = rand() % (rows - range); Uint32 stop_row = start_row + range; /** * 0 - serial pk * 1 - batch pk * 2 - serial uniq * 3 - batch uniq * 4 - index eq * 5 - range scan * 6 - interpreted scan */ int check = 0; void* res = (void*)~0; const Uint32 pk = 0; Uint32 cnt = 0; for(; start_row < stop_row; start_row++){ switch(g_paramters[P_OPER].value){ case 0: pOp = pTrans->getNdbOperation(g_table); check = pOp->readTuple(); check = pOp->equal(pk, start_row); break; case 1: for(; start_row<stop_row; start_row++){ pOp = pTrans->getNdbOperation(g_table); check = pOp->readTuple(); check = pOp->equal(pk, start_row); for(int j = 0; j<g_tab->getNoOfColumns(); j++){ res = pOp->getValue(j); assert(res); } } break; case 2: pOp = pTrans->getNdbIndexOperation(g_unique, g_table); check = pOp->readTuple(); check = pOp->equal(pk, start_row); break; case 3: for(; start_row<stop_row; start_row++){ pOp = pTrans->getNdbIndexOperation(g_unique, g_table); check = pOp->readTuple(); check = pOp->equal(pk, start_row); for(int j = 0; j<g_tab->getNoOfColumns(); j++){ res = pOp->getValue(j); assert(res); } } break; case 4: pOp = pSp = pIp = pTrans->getNdbIndexScanOperation(g_ordered,g_table); pIp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 0); check = pIp->setBound(pk, NdbIndexScanOperation::BoundEQ, &start_row); break; case 5: pOp = pSp = pIp = pTrans->getNdbIndexScanOperation(g_ordered,g_table); pIp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 0); check = pIp->setBound(pk, NdbIndexScanOperation::BoundLE, &start_row); check = pIp->setBound(pk, NdbIndexScanOperation::BoundGT, &stop_row); start_row = stop_row; break; case 6: pOp = pSp = pIp = pTrans->getNdbIndexScanOperation(g_ordered,g_table); pIp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 0, true); check = pIp->setBound(pk, NdbIndexScanOperation::BoundLE, &start_row); check = pIp->setBound(pk, NdbIndexScanOperation::BoundGT, &stop_row); start_row = stop_row; break; case 7: pOp = pSp = pTrans->getNdbScanOperation(g_table); pSp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 0); NdbScanFilter filter(pOp) ; filter.begin(NdbScanFilter::AND); filter.ge(pk, start_row); filter.lt(pk, stop_row); filter.end(); start_row = stop_row; break; } assert(res); if(check != 0){ ndbout << pOp->getNdbError() << endl; ndbout << pTrans->getNdbError() << endl; } assert(check == 0); for(int j = 0; j<g_tab->getNoOfColumns(); j++){ res = pOp->getValue(j); assert(res); } check = pTrans->execute(NoCommit); if(check != 0){ ndbout << pTrans->getNdbError() << endl; } assert(check == 0); if(g_paramters[P_OPER].value >= 4){ while((check = pSp->nextResult(true)) == 0){ cnt++; } if(check == -1){ err(pTrans->getNdbError()); return -1; } assert(check == 1); pSp->close(); } } assert(g_paramters[P_OPER].value < 4 || (cnt == range)); pTrans->close(); stop = NdbTick_CurrentMillisecond(); g_times[g_paramters[P_OPER].value] += (stop - start1); return 0; }
int HugoTransactions::indexReadRecords(Ndb* pNdb, const char * idxName, int records, int batch){ int reads = 0; int r = 0; int retryAttempt = 0; int check, a; NdbOperation *pOp; NdbIndexScanOperation *sOp; const NdbDictionary::Index* pIndex = pNdb->getDictionary()->getIndex(idxName, tab.getName()); const bool ordered = (pIndex->getType()==NdbDictionary::Index::OrderedIndex); if (batch == 0) { g_info << "ERROR: Argument batch == 0 in indexReadRecords(). " << "Not allowed." << endl; return NDBT_FAILED; } if (ordered) { batch = 1; } allocRows(batch); while (r < records){ if (retryAttempt >= m_retryMax){ g_info << "ERROR: has retried this operation " << retryAttempt << " times, failing!" << endl; return NDBT_FAILED; } pTrans = pNdb->startTransaction(); if (pTrans == NULL) { const NdbError err = pNdb->getNdbError(); if (err.status == NdbError::TemporaryError){ ERR(err); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); return NDBT_FAILED; } for(int b=0; (b<batch) && (r+b < records); b++){ if(!ordered){ pOp = pTrans->getNdbIndexOperation(idxName, tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } check = pOp->readTuple(); } else { pOp = sOp = pTrans->getNdbIndexScanOperation(idxName, tab.getName()); if (sOp == NULL) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } check = sOp->readTuples(); } if( check == -1 ) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } // Define primary keys if (equalForRow(pOp, r+b) != 0) { closeTransaction(pNdb); return NDBT_FAILED; } // Define attributes to read for(a = 0; a<tab.getNoOfColumns(); a++){ if((rows[b]->attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } } } check = pTrans->execute(Commit, AbortOnError); check = (check == -1 ? -1 : !ordered ? check : sOp->nextResult(true)); if( check == -1 ) { const NdbError err = pTrans->getNdbError(); if (err.status == NdbError::TemporaryError){ ERR(err); closeTransaction(pNdb); NdbSleep_MilliSleep(50); retryAttempt++; continue; } switch(err.code){ case 626: // Tuple did not exist g_info << r << ": " << err.code << " " << err.message << endl; r++; break; default: ERR(err); closeTransaction(pNdb); return NDBT_FAILED; } } else{ for (int b=0; (b<batch) && (r+b<records); b++){ if (calc.verifyRowValues(rows[b]) != 0){ closeTransaction(pNdb); return NDBT_FAILED; } reads++; r++; } if(ordered && sOp->nextResult(true) == 0){ ndbout << "Error when comparing records " << " - index op next_result to many" << endl; closeTransaction(pNdb); return NDBT_FAILED; } } closeTransaction(pNdb); } deallocRows(); g_info << reads << " records read" << endl; return NDBT_OK; }
/** * Transaction 5 - T5 * * Delete session * * Input: * SubscriberNumber * ServerId * ServerBit * DoRollback * Output: * ChangedBy * ChangedTime * Location * BranchExecuted */ int T5(void * obj, const SubscriberNumber inNumber, const SubscriberSuffix inSuffix, const ServerId inServerId, const ServerBit inServerBit, ChangedBy outChangedBy, ChangedTime outChangedTime, Location * outLocation, DoRollback inDoRollback, BranchExecuted * outBranchExecuted, BenchmarkTime * outTransactionTime) { Ndb * pNDB = (Ndb *) obj; NdbConnection * MyTransaction = 0; NdbOperation * MyOperation = 0; GroupId groupId; ActiveSessions sessions; Permission permission; BenchmarkTime start; get_time(&start); int check; NdbRecAttr * check2; MyTransaction = pNDB->startTransaction(); if (MyTransaction == NULL) error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), 0); MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); CHECK_NULL(MyOperation, "T5-1: getNdbOperation", MyTransaction); check = MyOperation->readTupleExclusive(); CHECK_MINUS_ONE(check, "T5-1: readTuple", MyTransaction); check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, inNumber); CHECK_MINUS_ONE(check, "T5-1: equal subscriber", MyTransaction); check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, (char *)outLocation); CHECK_NULL(check2, "T5-1: getValue location", MyTransaction); check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, outChangedBy); CHECK_NULL(check2, "T5-1: getValue changed_by", MyTransaction); check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, outChangedTime); CHECK_NULL(check2, "T5-1: getValue changed_time", MyTransaction); check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, (char *)&groupId); CHECK_NULL(check2, "T5-1: getValue group", MyTransaction); check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, (char *)&sessions); CHECK_NULL(check2, "T5-1: getValue sessions", MyTransaction); check = MyTransaction->execute( NoCommit ); CHECK_MINUS_ONE(check, "T5-1: NoCommit", MyTransaction); /* Operation 2 */ MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); CHECK_NULL(MyOperation, "T5-2: getNdbOperation", MyTransaction); check = MyOperation->readTuple(); CHECK_MINUS_ONE(check, "T5-2: readTuple", MyTransaction); check = MyOperation->equal(IND_GROUP_ID, (char*)&groupId); CHECK_MINUS_ONE(check, "T5-2: equal group", MyTransaction); check2 = MyOperation->getValue(IND_GROUP_ALLOW_DELETE, (char *)&permission); CHECK_NULL(check2, "T5-2: getValue allow_delete", MyTransaction); check = MyTransaction->execute( NoCommit ); CHECK_MINUS_ONE(check, "T5-2: NoCommit", MyTransaction); DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); if(((permission & inServerBit) == inServerBit) && ((sessions & inServerBit) == inServerBit)) { DEBUG("deleting - "); /* Operation 3 */ MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); CHECK_NULL(MyOperation, "T5-3: getNdbOperation", MyTransaction); check = MyOperation->deleteTuple(); CHECK_MINUS_ONE(check, "T5-3: deleteTuple", MyTransaction); check = MyOperation->equal(IND_SESSION_SUBSCRIBER, (char*)inNumber); CHECK_MINUS_ONE(check, "T5-3: equal number", MyTransaction); check = MyOperation->equal(IND_SESSION_SERVER, (char*)&inServerId); CHECK_MINUS_ONE(check, "T5-3: equal server id", MyTransaction); check = MyTransaction->execute( NoCommit ); CHECK_MINUS_ONE(check, "T5-3: NoCommit", MyTransaction); /* Operation 4 */ MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); CHECK_NULL(MyOperation, "T5-4: getNdbOperation", MyTransaction); check = MyOperation->interpretedUpdateTuple(); CHECK_MINUS_ONE(check, "T5-4: interpretedUpdateTuple", MyTransaction); check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, (char*)inNumber); CHECK_MINUS_ONE(check, "T5-4: equal number", MyTransaction); check = MyOperation->subValue(IND_SUBSCRIBER_SESSIONS, (uint32)inServerBit); CHECK_MINUS_ONE(check, "T5-4: dec value", MyTransaction); check = MyTransaction->execute( NoCommit ); CHECK_MINUS_ONE(check, "T5-4: NoCommit", MyTransaction); /* Operation 5 */ MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); CHECK_NULL(MyOperation, "T5-5: getNdbOperation", MyTransaction); check = MyOperation->interpretedUpdateTuple(); CHECK_MINUS_ONE(check, "T5-5: interpretedUpdateTuple", MyTransaction); check = MyOperation->equal(IND_SERVER_ID, (char*)&inServerId); CHECK_MINUS_ONE(check, "T5-5: equal serverId", MyTransaction); check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, (char*)inSuffix); CHECK_MINUS_ONE(check, "T5-5: equal suffix", MyTransaction); check = MyOperation->incValue(IND_SERVER_DELETES, (uint32)1); CHECK_MINUS_ONE(check, "T5-5: inc value", MyTransaction); check = MyTransaction->execute( NoCommit ); CHECK_MINUS_ONE(check, "T5-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, "T5: Commit", MyTransaction); } else { DEBUG("rollback\n"); check = MyTransaction->execute(Rollback); CHECK_MINUS_ONE(check, "T5:Rollback", MyTransaction); } pNDB->closeTransaction(MyTransaction); get_time(outTransactionTime); time_diff(outTransactionTime, &start); return 0; }
int HugoTransactions::indexUpdateRecords(Ndb* pNdb, const char * idxName, int records, int batch){ int updated = 0; int r = 0; int retryAttempt = 0; int check, a, b; NdbOperation *pOp; NdbScanOperation * sOp; const NdbDictionary::Index* pIndex = pNdb->getDictionary()->getIndex(idxName, tab.getName()); const bool ordered = (pIndex->getType()==NdbDictionary::Index::OrderedIndex); if (ordered){ batch = 1; } allocRows(batch); while (r < records){ if (retryAttempt >= m_retryMax){ g_info << "ERROR: has retried this operation " << retryAttempt << " times, failing!" << endl; return NDBT_FAILED; } pTrans = pNdb->startTransaction(); if (pTrans == NULL) { const NdbError err = pNdb->getNdbError(); if (err.status == NdbError::TemporaryError){ ERR(err); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); return NDBT_FAILED; } for(b = 0; b<batch && (b+r)<records; b++){ if(!ordered){ pOp = pTrans->getNdbIndexOperation(idxName, tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } check = pOp->readTupleExclusive(); if( check == -1 ) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } } else { pOp = sOp = pTrans->getNdbIndexScanOperation(idxName, tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } check = 0; sOp->readTuplesExclusive(); } // Define primary keys if (equalForRow(pOp, r+b) != 0) { closeTransaction(pNdb); return NDBT_FAILED; } // Define attributes to read for(a = 0; a<tab.getNoOfColumns(); a++){ if((rows[b]->attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } } } check = pTrans->execute(NoCommit, AbortOnError); check = (check == -1 ? -1 : !ordered ? check : sOp->nextResult(true)); if( check == -1 ) { const NdbError err = pTrans->getNdbError(); ERR(err); closeTransaction(pNdb); if (err.status == NdbError::TemporaryError){ NdbSleep_MilliSleep(50); retryAttempt++; continue; } return NDBT_FAILED; } if(ordered && check != 0){ g_err << check << " - Row: " << r << " not found!!" << endl; closeTransaction(pNdb); return NDBT_FAILED; } for(b = 0; b<batch && (b+r)<records; b++){ if (calc.verifyRowValues(rows[b]) != 0){ closeTransaction(pNdb); return NDBT_FAILED; } int updates = calc.getUpdatesValue(rows[b]) + 1; NdbOperation* pUpdOp; if(!ordered){ pUpdOp = pTrans->getNdbIndexOperation(idxName, tab.getName()); check = (pUpdOp == 0 ? -1 : pUpdOp->updateTuple()); } else { pUpdOp = sOp->updateCurrentTuple(); } if (pUpdOp == NULL) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } if( check == -1 ) { ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } if(!ordered) { if (equalForRow(pUpdOp, r+b) != 0) { closeTransaction(pNdb); return NDBT_FAILED; } } for(a = 0; a<tab.getNoOfColumns(); a++){ if (tab.getColumn(a)->getPrimaryKey() == false){ if(setValueForAttr(pUpdOp, a, r+b, updates ) != 0){ ERR(pTrans->getNdbError()); closeTransaction(pNdb); return NDBT_FAILED; } } } } check = pTrans->execute(Commit, AbortOnError); if( check == -1 ) { const NdbError err = pTrans->getNdbError(); ERR(err); closeTransaction(pNdb); if (err.status == NdbError::TemporaryError){ NdbSleep_MilliSleep(50); retryAttempt++; continue; } ndbout << "r = " << r << endl; return NDBT_FAILED; } else { updated += batch; m_latest_gci = pTrans->getGCI(); } closeTransaction(pNdb); r+= batch; // Read next record } g_info << "|- " << updated << " records updated" << endl; return NDBT_OK; }
/************************************************************************ * 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; }
/* 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; }
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(); }
inline int ScanInterpretTest::addRowToCheckTrans(Ndb* pNdb, NdbConnection* pCheckTrans){ NdbOperation* pOp = pCheckTrans->getNdbOperation(restab.getName()); if (pOp == NULL) { ERR(pNdb->getNdbError()); return NDBT_FAILED; } if(pOp->readTuple() != 0) { ERR(pNdb->getNdbError()); return NDBT_FAILED; } // Copy pk attribute's to the new operation for (int a = 0; a<restab.getNoOfColumns(); a++){ const NdbDictionary::Column* attr = restab.getColumn(a); if (attr->getPrimaryKey() == true){ 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->equal( attr->getName(), reca->aRef()); break; } case NdbDictionary::Column::Int:{ check = pOp->equal( attr->getName(), reca->int32_value()); } break; case NdbDictionary::Column::Bigint:{ check = pOp->equal( attr->getName(), reca->int64_value()); } break; case NdbDictionary::Column::Unsigned:{ check = pOp->equal( attr->getName(), reca->u_32_value()); } break; case NdbDictionary::Column::Bigunsigned:{ check = pOp->equal( attr->getName(), reca->u_64_value()); } break; default: check = -1; break; } if(check != 0){ ERR(pNdb->getNdbError()); return NDBT_FAILED; } } } return NDBT_OK; }
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 HugoAsynchTransactions::pkUpdateRecordsAsynch(Ndb* pNdb, int records, int batch, int trans, int operations) { g_info << "|- Updating records asynchronous..." << endl; int check = 0; int cTrans = 0; int cReadRecords = 0; int cReadIndex = 0; int cRecords = 0; int cIndex = 0; transactionsCompleted = 0; allocRows(trans*operations); allocTransactions(trans); int a, t, r; for (int i = 0; i < batch; i++) { // For each batch while (cRecords < records*batch) { cTrans = 0; cReadIndex = 0; for (t = 0; t < trans; t++) { // For each transaction transactions[t] = pNdb->startTransaction(); if (transactions[t] == NULL) { ERR(pNdb->getNdbError()); return NDBT_FAILED; } for (int k = 0; k < operations; k++) { // For each operation NdbOperation* pOp = transactions[t]->getNdbOperation(tab.getName()); if (pOp == NULL) { ERR(transactions[t]->getNdbError()); pNdb->closeTransaction(transactions[t]); return NDBT_FAILED; } // Read // Define primary keys check = pOp->readTupleExclusive(); for (a = 0; a < tab.getNoOfColumns(); a++) { if (tab.getColumn(a)->getPrimaryKey() == true) { if (equalForAttr(pOp, a, cReadRecords) != 0){ ERR(transactions[t]->getNdbError()); pNdb->closeTransaction(transactions[t]); return NDBT_FAILED; } } } // Define attributes to read for (a = 0; a < tab.getNoOfColumns(); a++) { if ((rows[cReadIndex]->attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(transactions[t]->getNdbError()); pNdb->closeTransaction(transactions[t]); return NDBT_FAILED; } } cReadIndex++; cReadRecords++; } // For each operation // Let's prepare... transactions[t]->executeAsynchPrepare(NoCommit, &asynchCallback, this); cTrans++; if (cReadRecords >= records) { // No more transactions needed break; } } // For each transaction // Wait for all outstanding transactions pNdb->sendPollNdb(3000, 0, 0); // Verify the data! for (r = 0; r < trans*operations; r++) { if (calc.verifyRowValues(rows[r]) != 0) { g_info << "|- Verify failed..." << endl; // Close all transactions for (int t = 0; t < cTrans; t++) { pNdb->closeTransaction(transactions[t]); } return NDBT_FAILED; } } // Update cTrans = 0; cIndex = 0; for (t = 0; t < trans; t++) { // For each transaction for (int k = 0; k < operations; k++) { // For each operation NdbOperation* pOp = transactions[t]->getNdbOperation(tab.getName()); if (pOp == NULL) { ERR(transactions[t]->getNdbError()); pNdb->closeTransaction(transactions[t]); return NDBT_FAILED; } int updates = calc.getUpdatesValue(rows[cIndex]) + 1; check = pOp->updateTuple(); if (check == -1) { ERR(transactions[t]->getNdbError()); pNdb->closeTransaction(transactions[t]); return NDBT_FAILED; } // Set search condition for the record for (a = 0; a < tab.getNoOfColumns(); a++) { if (tab.getColumn(a)->getPrimaryKey() == true) { if (equalForAttr(pOp, a, cRecords) != 0) { ERR(transactions[t]->getNdbError()); pNdb->closeTransaction(transactions[t]); return NDBT_FAILED; } } } // Update the record for (a = 0; a < tab.getNoOfColumns(); a++) { if (tab.getColumn(a)->getPrimaryKey() == false) { if (setValueForAttr(pOp, a, cRecords, updates) != 0) { ERR(transactions[t]->getNdbError()); pNdb->closeTransaction(transactions[t]); return NDBT_FAILED; } } } cIndex++; cRecords++; } // For each operation // Let's prepare... transactions[t]->executeAsynchPrepare(Commit, &asynchCallback, this); cTrans++; if (cRecords >= records) { // No more transactions needed break; } } // For each transaction // Wait for all outstanding transactions pNdb->sendPollNdb(3000, 0, 0); // Close all transactions for (t = 0; t < cTrans; t++) { pNdb->closeTransaction(transactions[t]); } } // while (cRecords < records*batch) } // For each batch deallocTransactions(); deallocRows(); g_info << "|- " << ((unsigned int)transactionsCompleted * operations)/2 << " updated..." << endl; return NDBT_OK; }