summaryrefslogtreecommitdiff
path: root/ndb
diff options
context:
space:
mode:
authorunknown <pekka@mysql.com>2006-05-02 14:33:55 +0200
committerunknown <pekka@mysql.com>2006-05-02 14:33:55 +0200
commite93b203d08dd7f64b140485993ac85791343e115 (patch)
treedf2c1b2c7520bcb59e8e099c028639d568c20a77 /ndb
parent7400f10a887232653ac0d26d214e3d4256d6463d (diff)
downloadmariadb-git-e93b203d08dd7f64b140485993ac85791343e115.tar.gz
ndb - bug#19201 (4.1), see comment in NdbBlob.cpp
ndb/test/ndbapi/testBlobs.cpp: option -fac (fetch across commit) ndb/tools/delete_all.cpp: option --transactional (default remains truncate) mysql-test/r/ndb_blob.result: bug#19201 mysql-test/t/ndb_blob.test: bug#19201 ndb/include/kernel/signaldata/TcKeyReq.hpp: bug#19201 ndb/include/ndbapi/NdbBlob.hpp: bug#19201 ndb/src/ndbapi/NdbBlob.cpp: bug#19201
Diffstat (limited to 'ndb')
-rw-r--r--ndb/include/kernel/signaldata/TcKeyReq.hpp1
-rw-r--r--ndb/include/ndbapi/NdbBlob.hpp1
-rw-r--r--ndb/src/ndbapi/NdbBlob.cpp24
-rw-r--r--ndb/test/ndbapi/testBlobs.cpp23
-rw-r--r--ndb/tools/delete_all.cpp31
5 files changed, 48 insertions, 32 deletions
diff --git a/ndb/include/kernel/signaldata/TcKeyReq.hpp b/ndb/include/kernel/signaldata/TcKeyReq.hpp
index 9e42f2a70d5..820425b97e2 100644
--- a/ndb/include/kernel/signaldata/TcKeyReq.hpp
+++ b/ndb/include/kernel/signaldata/TcKeyReq.hpp
@@ -39,6 +39,7 @@ class TcKeyReq {
friend class NdbOperation;
friend class NdbIndexOperation;
friend class NdbScanOperation;
+ friend class NdbBlob;
friend class DbUtil;
/**
diff --git a/ndb/include/ndbapi/NdbBlob.hpp b/ndb/include/ndbapi/NdbBlob.hpp
index a04f4f72bc9..f2c215ba14d 100644
--- a/ndb/include/ndbapi/NdbBlob.hpp
+++ b/ndb/include/ndbapi/NdbBlob.hpp
@@ -275,6 +275,7 @@ private:
bool isWriteOp();
bool isDeleteOp();
bool isScanOp();
+ bool isTakeOverOp();
// computations
Uint32 getPartNumber(Uint64 pos);
Uint32 getPartCount();
diff --git a/ndb/src/ndbapi/NdbBlob.cpp b/ndb/src/ndbapi/NdbBlob.cpp
index 416e983ec14..e595b4b6472 100644
--- a/ndb/src/ndbapi/NdbBlob.cpp
+++ b/ndb/src/ndbapi/NdbBlob.cpp
@@ -23,6 +23,7 @@
#include <NdbBlob.hpp>
#include "NdbBlobImpl.hpp"
#include <NdbScanOperation.hpp>
+#include <signaldata/TcKeyReq.hpp>
#ifdef NDB_BLOB_DEBUG
#define DBG(x) \
@@ -290,6 +291,13 @@ NdbBlob::isScanOp()
theNdbOp->theOperationType == NdbOperation::OpenRangeScanRequest;
}
+inline bool
+NdbBlob::isTakeOverOp()
+{
+ return
+ TcKeyReq::getTakeOverScanFlag(theNdbOp->theScanInfo);
+}
+
// computations (inline)
inline Uint32
@@ -1218,8 +1226,22 @@ NdbBlob::preExecute(ExecType anExecType, bool& batch)
if (isUpdateOp() || isWriteOp() || isDeleteOp()) {
// add operation before this one to read head+inline
NdbOperation* tOp = theNdbCon->getNdbOperation(theTable, theNdbOp);
+ /*
+ * If main op is from take over scan lock, the added read is done
+ * as committed read:
+ *
+ * In normal transactional case, the row is locked by us and
+ * committed read returns same as normal read.
+ *
+ * In current TRUNCATE TABLE, the deleting trans is committed in
+ * batches and then restarted with new trans id. A normal read
+ * would hang on the scan delete lock and then fail.
+ */
+ NdbOperation::LockMode lockMode =
+ ! isTakeOverOp() ?
+ NdbOperation::LM_Read : NdbOperation::LM_CommittedRead;
if (tOp == NULL ||
- tOp->readTuple() == -1 ||
+ tOp->readTuple(lockMode) == -1 ||
setTableKeyValue(tOp) == -1 ||
getHeadInlineValue(tOp) == -1) {
setErrorCode(tOp);
diff --git a/ndb/test/ndbapi/testBlobs.cpp b/ndb/test/ndbapi/testBlobs.cpp
index 4c82f718788..05a462c12c6 100644
--- a/ndb/test/ndbapi/testBlobs.cpp
+++ b/ndb/test/ndbapi/testBlobs.cpp
@@ -45,6 +45,7 @@ struct Opt {
bool m_dbg;
bool m_dbgall;
const char* m_dbug;
+ bool m_fac;
bool m_full;
unsigned m_loop;
unsigned m_parts;
@@ -73,6 +74,7 @@ struct Opt {
m_dbg(false),
m_dbgall(false),
m_dbug(0),
+ m_fac(false),
m_full(false),
m_loop(1),
m_parts(10),
@@ -111,6 +113,7 @@ printusage()
<< " -dbg print debug" << endl
<< " -dbgall print also NDB API debug (if compiled in)" << endl
<< " -dbug opt dbug options" << endl
+ << " -fac fetch across commit in scan delete [" << d.m_fac << "]" << endl
<< " -full read/write only full blob values" << endl
<< " -loop N loop N times 0=forever [" << d.m_loop << "]" << endl
<< " -parts N max parts in blob value [" << d.m_parts << "]" << endl
@@ -1260,23 +1263,11 @@ deleteScan(bool idx)
CHK((ret = rs->nextResult(false)) == 0 || ret == 1 || ret == 2);
if (++n == g_opt.m_batch || ret == 2) {
DBG("execute batch: n=" << n << " ret=" << ret);
- switch (0) {
- case 0: // works normally
+ if (! g_opt.m_fac) {
CHK(g_con->execute(NoCommit) == 0);
- CHK(true || g_con->restart() == 0);
- break;
- case 1: // nonsense - g_con is invalid for 2nd batch
- CHK(g_con->execute(Commit) == 0);
- CHK(true || g_con->restart() == 0);
- break;
- case 2: // DBTC sendSignalErrorRefuseLab
- CHK(g_con->execute(NoCommit) == 0);
- CHK(g_con->restart() == 0);
- break;
- case 3: // 266 time-out
+ } else {
CHK(g_con->execute(Commit) == 0);
CHK(g_con->restart() == 0);
- break;
}
n = 0;
}
@@ -1824,6 +1815,10 @@ NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535)
continue;
}
}
+ if (strcmp(arg, "-fac") == 0) {
+ g_opt.m_fac = true;
+ continue;
+ }
if (strcmp(arg, "-full") == 0) {
g_opt.m_full = true;
continue;
diff --git a/ndb/tools/delete_all.cpp b/ndb/tools/delete_all.cpp
index d4a07fdf505..c1ab77cb39f 100644
--- a/ndb/tools/delete_all.cpp
+++ b/ndb/tools/delete_all.cpp
@@ -23,17 +23,21 @@
#include <NDBT.hpp>
static int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab,
- bool commit_across_open_cursor, int parallelism=240);
+ bool fetch_across_commit, int parallelism=240);
NDB_STD_OPTS_VARS;
static const char* _dbname = "TEST_DB";
+static my_bool _transactional = false;
static struct my_option my_long_options[] =
{
NDB_STD_OPTS("ndb_desc"),
{ "database", 'd', "Name of database table is in",
(gptr*) &_dbname, (gptr*) &_dbname, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ { "transactional", 't', "Single transaction (may run out of operations)",
+ (gptr*) &_transactional, (gptr*) &_transactional, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
static void usage()
@@ -82,18 +86,11 @@ int main(int argc, char** argv){
ndbout << " Table " << argv[i] << " does not exist!" << endl;
return NDBT_ProgramExit(NDBT_WRONGARGS);
}
- // Check if we have any blobs
- bool commit_across_open_cursor = true;
- for (int j = 0; j < pTab->getNoOfColumns(); j++) {
- NdbDictionary::Column::Type t = pTab->getColumn(j)->getType();
- if (t == NdbDictionary::Column::Blob ||
- t == NdbDictionary::Column::Text) {
- commit_across_open_cursor = false;
- break;
- }
- }
- ndbout << "Deleting all from " << argv[i] << "...";
- if(clear_table(&MyNdb, pTab, commit_across_open_cursor) == NDBT_FAILED){
+ ndbout << "Deleting all from " << argv[i];
+ if (! _transactional)
+ ndbout << " (non-transactional)";
+ ndbout << " ...";
+ if(clear_table(&MyNdb, pTab, ! _transactional) == NDBT_FAILED){
res = NDBT_FAILED;
ndbout << "FAILED" << endl;
}
@@ -103,7 +100,7 @@ int main(int argc, char** argv){
int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab,
- bool commit_across_open_cursor, int parallelism)
+ bool fetch_across_commit, int parallelism)
{
// Scan all records exclusive and delete
// them one by one
@@ -134,7 +131,7 @@ int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab,
}
goto failed;
}
-
+
pOp = pTrans->getNdbScanOperation(pTab->getName());
if (pOp == NULL) {
goto failed;
@@ -165,7 +162,7 @@ int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab,
} while((check = rs->nextResult(false)) == 0);
if(check != -1){
- if (commit_across_open_cursor) {
+ if (fetch_across_commit) {
check = pTrans->execute(Commit);
pTrans->restart(); // new tx id
} else {
@@ -196,7 +193,7 @@ int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab,
}
goto failed;
}
- if (! commit_across_open_cursor && pTrans->execute(Commit) != 0) {
+ if (! fetch_across_commit && pTrans->execute(Commit) != 0) {
err = pTrans->getNdbError();
goto failed;
}