mirror of
https://github.com/MariaDB/server.git
synced 2025-05-27 01:57:48 +03:00
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)
This commit is contained in:
parent
9f9d7e0ae2
commit
b66f3574ea
@ -1933,15 +1933,16 @@ static struct Ev_t {
|
|||||||
enum_DEL = NdbDictionary::Event::_TE_DELETE,
|
enum_DEL = NdbDictionary::Event::_TE_DELETE,
|
||||||
enum_UPD = NdbDictionary::Event::_TE_UPDATE,
|
enum_UPD = NdbDictionary::Event::_TE_UPDATE,
|
||||||
enum_NUL = NdbDictionary::Event::_TE_NUL,
|
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;
|
int t1, t2, t3;
|
||||||
} ev_t[] = {
|
} 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_DEL, Ev_t::enum_NUL }, //ok
|
||||||
{ Ev_t::enum_INS, Ev_t::enum_UPD, Ev_t::enum_INS }, //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_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_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_INS, Ev_t::enum_ERR },
|
||||||
{ Ev_t::enum_UPD, Ev_t::enum_DEL, Ev_t::enum_DEL }, //ok
|
{ 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);
|
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
|
// save old data
|
||||||
EventBufData olddata = *data;
|
EventBufData olddata = *data;
|
||||||
data->memory = 0;
|
data->memory = 0;
|
||||||
|
@ -25,7 +25,8 @@
|
|||||||
|
|
||||||
#define GETNDB(ps) ((NDBT_NdbApiStep*)ps)->getNdb()
|
#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];
|
char eventName[1024];
|
||||||
sprintf(eventName,"%s_EVENT",tab.getName());
|
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++){
|
for(int a = 0; a < tab.getNoOfColumns(); a++){
|
||||||
myEvent.addEventColumn(a);
|
myEvent.addEventColumn(a);
|
||||||
}
|
}
|
||||||
|
myEvent.mergeEvents(merge_events);
|
||||||
|
|
||||||
int res = myDict->createEvent(myEvent); // Add event to database
|
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)
|
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_FAILED;
|
||||||
}
|
}
|
||||||
return NDBT_OK;
|
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;
|
g_err << "Event operation creation failed on %s" << buf << endl;
|
||||||
DBUG_RETURN(NDBT_FAILED);
|
DBUG_RETURN(NDBT_FAILED);
|
||||||
}
|
}
|
||||||
|
bool merge_events = ctx->getProperty("MergeEvents");
|
||||||
|
pOp->mergeEvents(merge_events);
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
int n_columns= table->getNoOfColumns();
|
int n_columns= table->getNoOfColumns();
|
||||||
@ -616,6 +621,11 @@ int runEventApplier(NDBT_Context* ctx, NDBT_Step* step)
|
|||||||
while ((pOp= ndb->nextEvent()) != 0)
|
while ((pOp= ndb->nextEvent()) != 0)
|
||||||
{
|
{
|
||||||
assert(pOp == pCreate);
|
assert(pOp == pCreate);
|
||||||
|
|
||||||
|
if (pOp->getEventType() >=
|
||||||
|
NdbDictionary::Event::TE_FIRST_NON_DATA_EVENT)
|
||||||
|
continue;
|
||||||
|
|
||||||
int noRetries= 0;
|
int noRetries= 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@ -640,7 +650,7 @@ int runEventApplier(NDBT_Context* ctx, NDBT_Step* step)
|
|||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (pOp->getEventType()) {
|
switch (pOp->getEventType()) {
|
||||||
case NdbDictionary::Event::TE_INSERT:
|
case NdbDictionary::Event::TE_INSERT:
|
||||||
if (op->writeTuple())
|
if (op->writeTuple())
|
||||||
@ -1607,6 +1617,33 @@ TESTCASE("EventOperationApplier_NR",
|
|||||||
FINALIZER(runVerify);
|
FINALIZER(runVerify);
|
||||||
FINALIZER(runDropShadowTable);
|
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",
|
TESTCASE("Multi",
|
||||||
"Verify that we can work with all tables in parallell"
|
"Verify that we can work with all tables in parallell"
|
||||||
"NOTE! HugoOperations::startTransaction, pTrans != NULL errors, "
|
"NOTE! HugoOperations::startTransaction, pTrans != NULL errors, "
|
||||||
|
@ -213,6 +213,11 @@ max-time: 2500
|
|||||||
cmd: test_event
|
cmd: test_event
|
||||||
args: -n EventOperationApplier_NR -l 2
|
args: -n EventOperationApplier_NR -l 2
|
||||||
|
|
||||||
|
#
|
||||||
|
max-time: 2500
|
||||||
|
cmd: test_event
|
||||||
|
args: -n MergeEventOperationApplier_NR -l 2
|
||||||
|
|
||||||
#
|
#
|
||||||
max-time: 2500
|
max-time: 2500
|
||||||
cmd: test_event
|
cmd: test_event
|
||||||
|
Loading…
x
Reference in New Issue
Block a user