mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 02:51:44 +01:00
ndb - bug#18352
Use variable waitfor_response_timeout (depending on TransactionDeadLockTimeout) When getting 4012, set NeedAbort and ReleaseOnClose ndb/src/ndbapi/NdbConnection.cpp: Use variable for WAITFOR_RESPONSE_TIMEOUT ndb/src/ndbapi/Ndbif.cpp: Use variable timeout for waitfor, when receiving 4012, set NeedAbort and ReleaseOnClose ndb/src/ndbapi/TransporterFacade.cpp: Init wait_for_response_timoue as max TRANSACTION_DEADLOCK_TIMEOUT ndb/src/ndbapi/TransporterFacade.hpp: Init wait_for_response_timoue as max TRANSACTION_DEADLOCK_TIMEOUT ndb/test/ndbapi/testTimeout.cpp: Add testcase for 4012 ndb/test/run-test/daily-basic-tests.txt: Add testcase for 4012
This commit is contained in:
parent
37230a2a88
commit
51a093f187
6 changed files with 129 additions and 7 deletions
|
@ -450,12 +450,12 @@ NdbConnection::executeNoBlobs(ExecType aTypeOfExec,
|
|||
//------------------------------------------------------------------------
|
||||
Ndb* tNdb = theNdb;
|
||||
|
||||
Uint32 timeout = TransporterFacade::instance()->m_waitfor_timeout;
|
||||
m_waitForReply = false;
|
||||
executeAsynchPrepare(aTypeOfExec, NULL, NULL, abortOption);
|
||||
if (m_waitForReply){
|
||||
while (1) {
|
||||
int noOfComp = tNdb->sendPollNdb((3 * WAITFOR_RESPONSE_TIMEOUT),
|
||||
1, forceSend);
|
||||
int noOfComp = tNdb->sendPollNdb(3 * timeout, 1, forceSend);
|
||||
if (noOfComp == 0) {
|
||||
/**
|
||||
* This timeout situation can occur if NDB crashes.
|
||||
|
|
|
@ -954,23 +954,25 @@ Ndb::pollCompleted(NdbConnection** aCopyArray)
|
|||
void
|
||||
Ndb::check_send_timeout()
|
||||
{
|
||||
Uint32 timeout = TransporterFacade::instance()->m_waitfor_timeout;
|
||||
NDB_TICKS current_time = NdbTick_CurrentMillisecond();
|
||||
if (current_time - the_last_check_time > 1000) {
|
||||
the_last_check_time = current_time;
|
||||
Uint32 no_of_sent = theNoOfSentTransactions;
|
||||
for (Uint32 i = 0; i < no_of_sent; i++) {
|
||||
NdbConnection* a_con = theSentTransactionsArray[i];
|
||||
if ((current_time - a_con->theStartTransTime) >
|
||||
WAITFOR_RESPONSE_TIMEOUT) {
|
||||
if ((current_time - a_con->theStartTransTime) > timeout)
|
||||
{
|
||||
#ifdef VM_TRACE
|
||||
a_con->printState();
|
||||
Uint32 t1 = a_con->theTransactionId;
|
||||
Uint32 t2 = a_con->theTransactionId >> 32;
|
||||
ndbout_c("[%.8x %.8x]", t1, t2);
|
||||
abort();
|
||||
ndbout_c("4012 [%.8x %.8x]", t1, t2);
|
||||
//abort();
|
||||
#endif
|
||||
a_con->theReleaseOnClose = true;
|
||||
a_con->setOperationErrorCodeAbort(4012);
|
||||
a_con->theCommitStatus = NdbConnection::Aborted;
|
||||
a_con->theCommitStatus = NdbConnection::NeedAbort;
|
||||
a_con->theCompletionStatus = NdbConnection::CompletedFailure;
|
||||
a_con->handleExecuteCompletion();
|
||||
remove_sent_list(i);
|
||||
|
|
|
@ -567,6 +567,20 @@ TransporterFacade::init(Uint32 nodeId, const ndb_mgm_configuration* props)
|
|||
}
|
||||
#endif
|
||||
|
||||
Uint32 timeout = 120000;
|
||||
iter.first();
|
||||
for (iter.first(); iter.valid(); iter.next())
|
||||
{
|
||||
Uint32 tmp1 = 0, tmp2 = 0;
|
||||
iter.get(CFG_DB_TRANSACTION_CHECK_INTERVAL, &tmp1);
|
||||
iter.get(CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT, &tmp2);
|
||||
tmp1 += tmp2;
|
||||
if (tmp1 > timeout)
|
||||
timeout = tmp1;
|
||||
}
|
||||
m_waitfor_timeout = timeout;
|
||||
ndbout_c("Using waitfor: %d", timeout);
|
||||
|
||||
if (!theTransporterRegistry->start_service(m_socket_server)){
|
||||
ndbout_c("Unable to start theTransporterRegistry->start_service");
|
||||
DBUG_RETURN(false);
|
||||
|
|
|
@ -172,6 +172,7 @@ private:
|
|||
*/
|
||||
public:
|
||||
STATIC_CONST( MAX_NO_THREADS = 4711 );
|
||||
Uint32 m_waitfor_timeout; // in milli seconds...
|
||||
private:
|
||||
|
||||
struct ThreadData {
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#define TIMEOUT (Uint32)3000
|
||||
Uint32 g_org_timeout = 3000;
|
||||
Uint32 g_org_deadlock = 3000;
|
||||
|
||||
int
|
||||
setTransactionTimeout(NDBT_Context* ctx, NDBT_Step* step){
|
||||
|
@ -59,6 +60,60 @@ resetTransactionTimeout(NDBT_Context* ctx, NDBT_Step* step){
|
|||
return NDBT_OK;
|
||||
}
|
||||
|
||||
int
|
||||
setDeadlockTimeout(NDBT_Context* ctx, NDBT_Step* step){
|
||||
NdbRestarter restarter;
|
||||
int timeout = ctx->getProperty("TransactionDeadlockTimeout", TIMEOUT);
|
||||
|
||||
NdbConfig conf(GETNDB(step)->getNodeId()+1);
|
||||
unsigned int nodeId = conf.getMasterNodeId();
|
||||
if (!conf.getProperty(nodeId,
|
||||
NODE_TYPE_DB,
|
||||
CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT,
|
||||
&g_org_deadlock))
|
||||
return NDBT_FAILED;
|
||||
|
||||
g_err << "Setting timeout: " << timeout << endl;
|
||||
int val[] = { DumpStateOrd::TcSetTransactionTimeout, timeout };
|
||||
if(restarter.dumpStateAllNodes(val, 2) != 0){
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
return NDBT_OK;
|
||||
}
|
||||
|
||||
int
|
||||
getDeadlockTimeout(NDBT_Context* ctx, NDBT_Step* step){
|
||||
NdbRestarter restarter;
|
||||
|
||||
Uint32 val = 0;
|
||||
NdbConfig conf(GETNDB(step)->getNodeId()+1);
|
||||
unsigned int nodeId = conf.getMasterNodeId();
|
||||
if (!conf.getProperty(nodeId,
|
||||
NODE_TYPE_DB,
|
||||
CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT,
|
||||
&val))
|
||||
return NDBT_FAILED;
|
||||
|
||||
if (val < 120000)
|
||||
val = 120000;
|
||||
ctx->setProperty("TransactionDeadlockTimeout", 4*val);
|
||||
|
||||
return NDBT_OK;
|
||||
}
|
||||
|
||||
int
|
||||
resetDeadlockTimeout(NDBT_Context* ctx, NDBT_Step* step){
|
||||
NdbRestarter restarter;
|
||||
|
||||
int val[] = { DumpStateOrd::TcSetTransactionTimeout, g_org_deadlock };
|
||||
if(restarter.dumpStateAllNodes(val, 2) != 0){
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
return NDBT_OK;
|
||||
}
|
||||
|
||||
|
||||
int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){
|
||||
|
||||
|
@ -374,6 +429,43 @@ int runBuddyTransNoTimeout(NDBT_Context* ctx, NDBT_Step* step){
|
|||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
runError4012(NDBT_Context* ctx, NDBT_Step* step){
|
||||
int result = NDBT_OK;
|
||||
int loops = ctx->getNumLoops();
|
||||
int stepNo = step->getStepNo();
|
||||
|
||||
int timeout = ctx->getProperty("TransactionDeadlockTimeout", TIMEOUT);
|
||||
|
||||
HugoOperations hugoOps(*ctx->getTab());
|
||||
Ndb* pNdb = GETNDB(step);
|
||||
|
||||
do{
|
||||
// Commit transaction
|
||||
CHECK(hugoOps.startTransaction(pNdb) == 0);
|
||||
CHECK(hugoOps.pkUpdateRecord(pNdb, 0) == 0);
|
||||
int ret = hugoOps.execute_NoCommit(pNdb);
|
||||
if (ret == 0)
|
||||
{
|
||||
int sleep = timeout;
|
||||
ndbout << "Sleeping for " << sleep << " milliseconds" << endl;
|
||||
NdbSleep_MilliSleep(sleep);
|
||||
|
||||
// Expect that transaction has NOT timed-out
|
||||
CHECK(hugoOps.execute_Commit(pNdb) == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK(ret == 4012);
|
||||
}
|
||||
} while(false);
|
||||
|
||||
hugoOps.closeTransaction(pNdb);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
NDBT_TESTSUITE(testTimeout);
|
||||
TESTCASE("DontTimeoutTransaction",
|
||||
"Test that the transaction does not timeout "\
|
||||
|
@ -465,6 +557,15 @@ TESTCASE("BuddyTransNoTimeout5",
|
|||
FINALIZER(resetTransactionTimeout);
|
||||
FINALIZER(runClearTable);
|
||||
}
|
||||
TESTCASE("Error4012", ""){
|
||||
TC_PROPERTY("TransactionDeadlockTimeout", 120000);
|
||||
INITIALIZER(runLoadTable);
|
||||
INITIALIZER(getDeadlockTimeout);
|
||||
INITIALIZER(setDeadlockTimeout);
|
||||
STEPS(runError4012, 2);
|
||||
FINALIZER(runClearTable);
|
||||
}
|
||||
|
||||
NDBT_TESTSUITE_END(testTimeout);
|
||||
|
||||
int main(int argc, const char** argv){
|
||||
|
|
|
@ -236,6 +236,10 @@ max-time: 500
|
|||
cmd: testTimeout
|
||||
args: -n TimeoutRandTransaction T1
|
||||
|
||||
max-time: 600
|
||||
cmd: testTimeout
|
||||
args: -n Error4012 T1
|
||||
|
||||
# SCAN TESTS
|
||||
#
|
||||
max-time: 500
|
||||
|
|
Loading…
Add table
Reference in a new issue