Commit f395e89e authored by unknown's avatar unknown

ndb - bug#19872 fix (sufficient for replication)


storage/ndb/test/ndbapi/test_event.cpp:
  test applier under merge events
  also fix run in 5.1 (check for data event)
storage/ndb/test/run-test/daily-devel-tests.txt:
  add: test_event -n MergeEventOperationApplier_NR
storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp:
  allow idempotency INSoINS or DELoDEL
  does NOT check data section 2 (before data)
parent 4db0d644
......@@ -1933,15 +1933,16 @@ static struct Ev_t {
enum_DEL = NdbDictionary::Event::_TE_DELETE,
enum_UPD = NdbDictionary::Event::_TE_UPDATE,
enum_NUL = NdbDictionary::Event::_TE_NUL,
enum_ERR = 255
enum_IDM = 254, // idempotent op possibly allowed on NF
enum_ERR = 255 // always impossible
};
int t1, t2, t3;
} ev_t[] = {
{ Ev_t::enum_INS, Ev_t::enum_INS, Ev_t::enum_ERR },
{ Ev_t::enum_INS, Ev_t::enum_INS, Ev_t::enum_IDM },
{ Ev_t::enum_INS, Ev_t::enum_DEL, Ev_t::enum_NUL }, //ok
{ Ev_t::enum_INS, Ev_t::enum_UPD, Ev_t::enum_INS }, //ok
{ Ev_t::enum_DEL, Ev_t::enum_INS, Ev_t::enum_UPD }, //ok
{ Ev_t::enum_DEL, Ev_t::enum_DEL, Ev_t::enum_ERR },
{ Ev_t::enum_DEL, Ev_t::enum_DEL, Ev_t::enum_IDM },
{ Ev_t::enum_DEL, Ev_t::enum_UPD, Ev_t::enum_ERR },
{ Ev_t::enum_UPD, Ev_t::enum_INS, Ev_t::enum_ERR },
{ Ev_t::enum_UPD, Ev_t::enum_DEL, Ev_t::enum_DEL }, //ok
......@@ -2010,6 +2011,34 @@ NdbEventBuffer::merge_data(const SubTableData * const sdata,
}
assert(tp != 0 && tp->t3 != Ev_t::enum_ERR);
if (tp->t3 == Ev_t::enum_IDM) {
LinearSectionPtr (&ptr1)[3] = data->ptr;
/*
* TODO
* - can get data in INS ptr2[2] which is supposed to be empty
* - can get extra data in DEL ptr2[2]
* - why does DBUG_PRINT not work in this file ???
*
* replication + bug#19872 can ignore this since merge is on
* only for tables with explicit PK and before data is not used
*/
const int maxsec = 1; // ignore section 2
int i;
for (i = 0; i <= maxsec; i++) {
if (ptr1[i].sz != ptr2[i].sz ||
memcmp(ptr1[i].p, ptr2[i].p, ptr1[i].sz << 2) != 0) {
DBUG_PRINT("info", ("idempotent op %d*%d data differs in sec %d",
tp->t1, tp->t2, i));
assert(false);
DBUG_RETURN_EVENT(-1);
}
}
DBUG_PRINT("info", ("idempotent op %d*%d data ok", tp->t1, tp->t2));
DBUG_RETURN_EVENT(0);
}
// save old data
EventBufData olddata = *data;
data->memory = 0;
......
......@@ -25,7 +25,8 @@
#define GETNDB(ps) ((NDBT_NdbApiStep*)ps)->getNdb()
static int createEvent(Ndb *pNdb, const NdbDictionary::Table &tab)
static int createEvent(Ndb *pNdb, const NdbDictionary::Table &tab,
bool merge_events = false)
{
char eventName[1024];
sprintf(eventName,"%s_EVENT",tab.getName());
......@@ -45,6 +46,7 @@ static int createEvent(Ndb *pNdb, const NdbDictionary::Table &tab)
for(int a = 0; a < tab.getNoOfColumns(); a++){
myEvent.addEventColumn(a);
}
myEvent.mergeEvents(merge_events);
int res = myDict->createEvent(myEvent); // Add event to database
......@@ -137,7 +139,8 @@ NdbEventOperation *createEventOperation(Ndb *ndb,
static int runCreateEvent(NDBT_Context* ctx, NDBT_Step* step)
{
if (createEvent(GETNDB(step),* ctx->getTab()) != 0){
bool merge_events = ctx->getProperty("MergeEvents");
if (createEvent(GETNDB(step),* ctx->getTab(), merge_events) != 0){
return NDBT_FAILED;
}
return NDBT_OK;
......@@ -584,6 +587,8 @@ int runEventApplier(NDBT_Context* ctx, NDBT_Step* step)
g_err << "Event operation creation failed on %s" << buf << endl;
DBUG_RETURN(NDBT_FAILED);
}
bool merge_events = ctx->getProperty("MergeEvents");
pOp->mergeEvents(merge_events);
int i;
int n_columns= table->getNoOfColumns();
......@@ -616,6 +621,11 @@ int runEventApplier(NDBT_Context* ctx, NDBT_Step* step)
while ((pOp= ndb->nextEvent()) != 0)
{
assert(pOp == pCreate);
if (pOp->getEventType() >=
NdbDictionary::Event::TE_FIRST_NON_DATA_EVENT)
continue;
int noRetries= 0;
do
{
......@@ -1607,6 +1617,33 @@ TESTCASE("EventOperationApplier_NR",
FINALIZER(runVerify);
FINALIZER(runDropShadowTable);
}
TESTCASE("MergeEventOperationApplier",
"Verify that if we apply the data we get from merged event "
"operation is the same as the original table"
"NOTE! No errors are allowed!" ){
TC_PROPERTY("MergeEvents", 1);
INITIALIZER(runCreateEvent);
INITIALIZER(runCreateShadowTable);
STEP(runEventApplier);
STEP(runEventMixedLoad);
FINALIZER(runDropEvent);
FINALIZER(runVerify);
FINALIZER(runDropShadowTable);
}
TESTCASE("MergeEventOperationApplier_NR",
"Verify that if we apply the data we get from merged event "
"operation is the same as the original table"
"NOTE! No errors are allowed!" ){
TC_PROPERTY("MergeEvents", 1);
INITIALIZER(runCreateEvent);
INITIALIZER(runCreateShadowTable);
STEP(runEventApplier);
STEP(runEventMixedLoad);
STEP(runRestarter);
FINALIZER(runDropEvent);
FINALIZER(runVerify);
FINALIZER(runDropShadowTable);
}
TESTCASE("Multi",
"Verify that we can work with all tables in parallell"
"NOTE! HugoOperations::startTransaction, pTrans != NULL errors, "
......
......@@ -213,6 +213,11 @@ max-time: 2500
cmd: test_event
args: -n EventOperationApplier_NR -l 2
#
max-time: 2500
cmd: test_event
args: -n MergeEventOperationApplier_NR -l 2
#
max-time: 2500
cmd: test_event
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment