Commit c0f28669 authored by unknown's avatar unknown
Browse files

ndb - bug#27169

  Fix bug in SUMA::resend_bucket which could cause mysqld to crash


storage/ndb/src/kernel/blocks/suma/Suma.cpp:
  Remove *len* part from sz,
    or an extra word will be sent (sometimes) which will cause event-api barf
storage/ndb/test/ndbapi/test_event.cpp:
  test prg for bug#27169
storage/ndb/test/run-test/daily-basic-tests.txt:
  test prg for bug#27169
parent 442595da
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -4998,7 +4998,10 @@ Suma::resend_bucket(Signal* signal, Uint32 buck, Uint32 min_gci,
      continue;
    }

    if(sz == 1)
    ndbrequire(sz);
    sz --; // remove *len* part of sz
    
    if(sz == 0)
    {
      SubGcpCompleteRep * rep = (SubGcpCompleteRep*)signal->getDataPtrSend();
      rep->gci = last_gci;
+150 −0
Original line number Diff line number Diff line
@@ -836,6 +836,67 @@ int runEventApplier(NDBT_Context* ctx, NDBT_Step* step)
  DBUG_RETURN(result);
}

int runEventListenerUntilStopped(NDBT_Context* ctx, NDBT_Step* step)
{
  
  int result = NDBT_OK;
  const NdbDictionary::Table * table= ctx->getTab();
  HugoTransactions hugoTrans(* table);

  char buf[1024];
  sprintf(buf, "%s_EVENT", table->getName());
  NdbEventOperation *pOp, *pCreate = 0;
  pCreate = pOp = GETNDB(step)->createEventOperation(buf);
  if ( pOp == NULL ) {
    g_err << "Event operation creation failed on %s" << buf << endl;
    return NDBT_FAILED;
  }
  
  int i;
  int n_columns= table->getNoOfColumns();
  NdbRecAttr* recAttr[1024];
  NdbRecAttr* recAttrPre[1024];
  for (i = 0; i < n_columns; i++) {
    recAttr[i]    = pOp->getValue(table->getColumn(i)->getName());
    recAttrPre[i] = pOp->getPreValue(table->getColumn(i)->getName());
  }

  if (pOp->execute()) 
  { // This starts changes to "start flowing"
    g_err << "execute operation execution failed: \n";
    g_err << pOp->getNdbError().code << " "
	  << pOp->getNdbError().message << endl;
    result = NDBT_FAILED;
    goto end;
  }
  
  Ndb* ndb= GETNDB(step);
  while(!ctx->isTestStopped())
  {
    Uint64 curr_gci = 0;
    while(!ctx->isTestStopped())
    {
      ndb->pollEvents(100, &curr_gci);
      while ((pOp= ndb->nextEvent()) != 0)
      {
	assert(pOp == pCreate);
      } 
    }
  }
  
end:
  if(pCreate)
  {
    if (GETNDB(step)->dropEventOperation(pCreate)) {
      g_err << "dropEventOperation execution failed "
	    << GETNDB(step)->getNdbError().code << " "
	    << GETNDB(step)->getNdbError().message << endl;
      result = NDBT_FAILED;
    }
  }
  return result;
}

int runRestarter(NDBT_Context* ctx, NDBT_Step* step){
  int result = NDBT_OK;
  int loops = ctx->getNumLoops();
@@ -877,6 +938,51 @@ int runRestarter(NDBT_Context* ctx, NDBT_Step* step){
  return result;
}

int runRestarterLoop(NDBT_Context* ctx, NDBT_Step* step)
{
  int result = NDBT_OK;
  int loops = ctx->getNumLoops();
  NdbRestarter restarter;
  int i = 0;
  int lastId = 0;

  if (restarter.getNumDbNodes() < 2){
    ctx->stopTest();
    return NDBT_OK;
  }

  if(restarter.waitClusterStarted(60) != 0){
    g_err << "Cluster failed to start" << endl;
    return NDBT_FAILED;
  }
  
  while(result != NDBT_FAILED 
	&& !ctx->isTestStopped() 
	&& i < loops)
  {
    int id = lastId % restarter.getNumDbNodes();
    int nodeId = restarter.getDbNodeId(id);
    ndbout << "Restart node " << nodeId << endl; 
    if(restarter.restartOneDbNode(nodeId, false, false, true) != 0){
      g_err << "Failed to restartNextDbNode" << endl;
      result = NDBT_FAILED;
      break;
    }    
    
    if(restarter.waitClusterStarted(60) != 0){
      g_err << "Cluster failed to start" << endl;
      result = NDBT_FAILED;
      break;
    }
    
    lastId++;
    i++;
  }

  ctx->stopTest();
  return result;
}

Vector<const NdbDictionary::Table*> pTabs;
Vector<const NdbDictionary::Table*> pShadowTabs;

@@ -1616,6 +1722,42 @@ runSubscribeUnsubscribe(NDBT_Context* ctx, NDBT_Step* step)
  return NDBT_OK;
}

int 
runScanUpdateUntilStopped(NDBT_Context* ctx, NDBT_Step* step){
  int records = ctx->getNumRecords();
  int parallelism = ctx->getProperty("Parallelism", (Uint32)0);
  int abort = ctx->getProperty("AbortProb", (Uint32)0);
  HugoTransactions hugoTrans(*ctx->getTab());
  while (ctx->isTestStopped() == false) 
  {
    if (hugoTrans.scanUpdateRecords(GETNDB(step), records, abort, 
				    parallelism) == NDBT_FAILED){
      return NDBT_FAILED;
    }
  }
  return NDBT_OK;
}

int 
runInsertDeleteUntilStopped(NDBT_Context* ctx, NDBT_Step* step)
{
  int result = NDBT_OK;
  int records = ctx->getNumRecords();
  HugoTransactions hugoTrans(*ctx->getTab());
  UtilTransactions utilTrans(*ctx->getTab());
  while (ctx->isTestStopped() == false) 
  {
    if (hugoTrans.loadTable(GETNDB(step), records, 1) != 0){
      return NDBT_FAILED;
    }
    if (utilTrans.clearTable(GETNDB(step),  records) != 0){
      return NDBT_FAILED;
    }
  }
  
  return NDBT_OK;
}

NDBT_TESTSUITE(test_event);
TESTCASE("BasicEventOperation", 
	 "Verify that we can listen to Events"
@@ -1737,6 +1879,14 @@ TESTCASE("SubscribeUnsubscribe",
  STEPS(runSubscribeUnsubscribe, 16);
  FINALIZER(runDropEvent);
}
TESTCASE("Bug27169", ""){
  INITIALIZER(runCreateEvent);
  STEP(runEventListenerUntilStopped);
  STEP(runInsertDeleteUntilStopped);
  STEP(runScanUpdateUntilStopped);
  STEP(runRestarterLoop);
  FINALIZER(runDropEvent);
}
NDBT_TESTSUITE_END(test_event);

int main(int argc, const char** argv){
+4 −0
Original line number Diff line number Diff line
@@ -788,6 +788,10 @@ max-time: 1000
cmd: testNodeRestart
args: -n Bug25468 T1

max-time: 1000
cmd: test_event
args: -l 10 -n Bug27169 T1

# OLD FLEX
max-time: 500
cmd: flexBench