You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-08-10 01:22:48 +03:00
Progress keep and test commit Progress keep and test commit Progress keep and test commit Again, trying to pinpoint problematic part of a change Revert "Again, trying to pinpoint problematic part of a change" This reverts commit 71874e7c0d7e4eeed0c201b12d306b583c07b9e2. Revert "Progress keep and test commit" This reverts commit 63c7bc67ae55bdb81433ca58bbd239d6171a1031. Revert "Progress keep and test commit" This reverts commit 121c09febd78dacd37158caeab9ac70f65b493df. Small steps - I walk minefield here Propagating changes - now CPInfo in convertValArray Progress keep commit Restoring old functionality Progress keep commit Small steps to avoid/better locate old problem with the write engine. Progress keeping commit Thread the CPInfo up to convertValArray call in writeColumnRec About to test changes - I should get no regression and no updates in ranges either. Testing out why I get a regression Investigating source of regression Debugging prints Fix compile error Debugging print - debug regression I clearly see calls to writeColumnRec and prints there added to discern between these. Fix warning error Possible culprit Add forgotten default parameter for convertValArray New logic to test Max/min gets updated during value conversion To test results of updates Debug logs Debug logs An attempt to provide proper sequence index Debug logs An attempt to provide proper sequence index - now magic for resetting Debug logs Debug logs Debug logs Trying to perform correct updates Trying to perform correct updates - seqNum woes fight COMMIT after INSERT performs 'mark extent as invalid' operation - investigating To test: cut setting of CPInfo upon commit from DML processor It may be superfluous as write engine does that too Debug logs Debug logs Better interface for CPMaxMin Old interface forgot to set isBinaryColumn field Possible fix for the problems I forgot to reassign the value in cpinfoList Debug logs Computation of 'binary' column property logs indicated that it was not set in getExtentCPMaxMin, and it was impossible to compute there so I had to move that into writeengine. To test: code to allow cross-extent insertion To test: removed another assertion for probable cause of errors Debug logs Dropped excessive logs Better reset code Again, trying to fix ordering Fixing order of rowids for LBID computation Debug logs Remove update of second LBID in split insert I have to validate incorrect behaviour for this test Restoring the case where everything almost worked Tracking changes in newly created extents Progress keeping commit Fixing build errors with recent server An ability to get old values from blocks we update Progress keeping commit Adding analysis of old values to write engine code. It is needed for updates and deletes. Progress keeping commit Moving max/min range update from convertValArray into separate function with simpler logic. To test and debug - logic is there Fix build errors Update logic to debug There is a suspicious write engine method updateColumnRecs which receives a vector of column types but does not iterate over them (otherwise it will be identical to updateColumnRec in logic). Other than that, the updateColumnRec looks like the center of all updates - deleteRow calls it, for example, dml processor also calls it. Debug logs for insert bookkeeping regression Set up operation type in externally-callable interface Internal operations depend on the operation type and consistency is what matters there. Debug logs Fix for extent range update failure during update operation Fix build error Debug logs Fix for update on deletion I am not completely sure in it - to debug. Debug log writeColumnRec cannot set m_opType to UPDATE unconditionally It is called from deleteRow Better diagnostics Debug logs Fixed search condition Debug logs Debugging invalid LBID appearance Debug logs - fixed condition Fix problems with std::vector reallocation during growth Fix growing std::vector data dangling access error Still fixing indexing errors Make in-range update to work Correct sequence numbers Debug logs Debug logs Remove range drop from DML part of write engine A hack to test the culprit of range non-keeping Tests - no results for now MTR-style comments Empty test results To be filled with actual results. Special database and result selects for all tests Pleasing MTR with better folder name Pleasing MTR - testing test result comparison Pleasing MTR by disabling warnings All test results Cleaning up result files Reset ranges before update Remove comments from results - point of failure in MTR Remove empty line from result - another MTR failure point Probably fix for deletes Possible fix for remaining failed delete test Fix a bug in writeRows It should not affect delete-with-range test case, yet it is a bug. Debug logs Debug logs Tests reorganization and description Support for unsigned integer for new tests Fix type omission Fix test failure due to warnings on clean installation Support for bigint to test Fix for failed signed bigint test Set proper unsignedness flag Removed that assignment during refactoring. Tests for types with column width 1 and 2 Support for types in new tests Remove trailing empty lines from results Tests had failed because of extra empty lines. Remove debug logs Update README with info about new tests Move tests for easier testing Add task tag to tests Fix invalid unsaigned range check Fix for signed types Fix regressions - progress keeping commit Do not set invalid ranges into valid state A possible fix for mcs81_self_join test MCOL 2044 test database cleanup Missing expected results Delete extraneous assignment to m_opType nullptr instead of NULL Refactor extended CPInfo with TypeHandler Better handling of ranges - safer types, less copy-paste Fix logic error related to typo Fix logic error related to typo Trying to figure out why invalid ranges aren't displayed as NULL..NULL Debug logs Debug logs Debug logs Debug logs for worker node Debug logs for worker node in extent map Debugging virtual table fill operation Debugging virtual table fill operation Fix for invalid range computation Remove debug logs Change handling of invalid ranges They are also set, but to invalid state. Complete change Fix typo Remove unused code "Fix" for tests - -1..0 instead of NULL..NULL for invalid unsigned ranges Not a good change, yet I cannot do better for now. MTR output requires tabs instead of spaces Debug logs Debug logs Debug logs - fix build Debug logs and logic error fix Fix for clearly incorrect firstLBID in CPInfo being set - to test Fix for system catalog operations suppot Better interface to fix build errors Delete tests we cannot satisfy due to extent rescan due to WHERE Tests for wide decimals Testing support for wide decimals Fix for wide decimals tests Fix for delete within range Memory leak fix and, possible, double free fix Dispatch on CalpontSystemCatalog::ColDataType is more robust Add support for forgotten MEDINT type Add forgottent BIGINT empty() instead of size() > 0 Better layout Remove confusing comment Sensible names for special values of seqNum field Tests for wide decimal support Addressing concerns of drrtuy Remove test we cannot satisfy Final touches for PR Remove unused result file
916 lines
24 KiB
C++
916 lines
24 KiB
C++
/* Copyright (C) 2014 InfiniDB, Inc.
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; version 2 of
|
|
the License.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
MA 02110-1301, USA. */
|
|
|
|
/***********************************************************************
|
|
* $Id: dmlpackageprocessor.cpp 9673 2013-07-09 15:59:49Z chao $
|
|
*
|
|
*
|
|
***********************************************************************/
|
|
#include "dmlpackageprocessor.h"
|
|
|
|
#include <math.h>
|
|
using namespace std;
|
|
|
|
#include <boost/algorithm/string/case_conv.hpp>
|
|
using namespace boost::algorithm;
|
|
#include <boost/tokenizer.hpp>
|
|
#include <boost/shared_ptr.hpp>
|
|
|
|
#include "we_messages.h"
|
|
using namespace WriteEngine;
|
|
using namespace dmlpackage;
|
|
#include "calpontselectexecutionplan.h"
|
|
#include "simplecolumn.h"
|
|
#include "constantcolumn.h"
|
|
#include "simplefilter.h"
|
|
#include "constantfilter.h"
|
|
#include "columnresult.h"
|
|
using namespace execplan;
|
|
using namespace logging;
|
|
#include "configcpp.h"
|
|
using namespace config;
|
|
#include "joblistfactory.h"
|
|
#include "joblist.h"
|
|
#include "distributedenginecomm.h"
|
|
using namespace joblist;
|
|
#include "bytestream.h"
|
|
#include "messagequeue.h"
|
|
using namespace messageqcpp;
|
|
#include "tablelockdata.h"
|
|
#include "exceptclasses.h"
|
|
|
|
namespace
|
|
{
|
|
using namespace execplan;
|
|
|
|
const SOP opeq(new Operator("="));
|
|
const SOP opne(new Operator("<>"));
|
|
const SOP opor(new Operator("or"));
|
|
const SOP opand(new Operator("and"));
|
|
}
|
|
|
|
namespace dmlpackageprocessor
|
|
{
|
|
|
|
DMLPackageProcessor::~DMLPackageProcessor()
|
|
{
|
|
//cout << "In DMLPackageProcessor destructor " << this << endl;
|
|
if (fWEClient)
|
|
delete fWEClient;
|
|
|
|
if (fExeMgr)
|
|
delete fExeMgr;
|
|
}
|
|
|
|
//@bug 397
|
|
void DMLPackageProcessor::cleanString(string& s)
|
|
{
|
|
string::size_type pos = s.find_first_not_of(" ");
|
|
|
|
//stripe off space and ' or '' at beginning and end
|
|
if ( pos < s.length() )
|
|
{
|
|
s = s.substr( pos, s.length() - pos );
|
|
|
|
if ( (pos = s.find_last_of(" ")) < s.length())
|
|
{
|
|
s = s.substr(0, pos );
|
|
}
|
|
}
|
|
|
|
if ( s[0] == '\'')
|
|
{
|
|
s = s.substr(1, s.length() - 2);
|
|
|
|
if ( s[0] == '\'')
|
|
s = s.substr(1, s.length() - 2);
|
|
}
|
|
}
|
|
#if 0
|
|
boost::any DMLPackageProcessor::tokenizeData( execplan::CalpontSystemCatalog::SCN txnID,
|
|
execplan::CalpontSystemCatalog::ColType colType,
|
|
const std::string& data, DMLResult& result, bool isNULL )
|
|
{
|
|
SUMMARY_INFO("DMLPackageProcessor::tokenizeData");
|
|
|
|
bool retval = true;
|
|
boost::any value;
|
|
|
|
if (isNULL)
|
|
{
|
|
WriteEngine::Token nullToken;
|
|
value = nullToken;
|
|
}
|
|
else
|
|
{
|
|
if ( data.length() > (unsigned int)colType.colWidth )
|
|
{
|
|
retval = false;
|
|
// build the logging message
|
|
logging::Message::Args args;
|
|
logging::Message message(6);
|
|
args.add("Insert value is too large for colum ");
|
|
message.format( args );
|
|
|
|
result.result = INSERT_ERROR;
|
|
result.message = message;
|
|
}
|
|
else
|
|
{
|
|
//Tokenize the data value
|
|
WriteEngine::DctnryStruct dictStruct;
|
|
dictStruct.dctnryOid = colType.ddn.dictOID;
|
|
//cout << "Dictionary OIDs: " << colType.ddn.treeOID << " " << colType.ddn.listOID << endl;
|
|
WriteEngine::DctnryTuple dictTuple;
|
|
dictTuple.sigValue = data.c_str();
|
|
dictTuple.sigSize = data.length();
|
|
int error = NO_ERROR;
|
|
|
|
if ( NO_ERROR != (error = fWriteEngine.tokenize( txnID, dictStruct, dictTuple)) )
|
|
{
|
|
retval = false;
|
|
//cout << "Error code from WE: " << error << endl;
|
|
// build the logging message
|
|
logging::Message::Args args;
|
|
logging::Message message(1);
|
|
args.add("Tokenization failed on: ");
|
|
args.add(data);
|
|
args.add("error number: ");
|
|
args.add( error );
|
|
message.format( args );
|
|
|
|
result.result = TOKEN_ERROR;
|
|
result.message = message;
|
|
}
|
|
|
|
WriteEngine::Token aToken = dictTuple.token;
|
|
value = aToken;
|
|
}
|
|
}
|
|
|
|
return value;
|
|
}
|
|
#endif
|
|
void DMLPackageProcessor::getColumnsForTable(uint32_t sessionID, std::string schema,
|
|
std::string table, dmlpackage::ColumnList& colList)
|
|
{
|
|
|
|
CalpontSystemCatalog::TableName tableName;
|
|
tableName.schema = schema;
|
|
tableName.table = table;
|
|
|
|
boost::shared_ptr<CalpontSystemCatalog> systemCatalogPtr = CalpontSystemCatalog::makeCalpontSystemCatalog( sessionID );
|
|
CalpontSystemCatalog::RIDList ridList = systemCatalogPtr->columnRIDs(tableName, true);
|
|
|
|
CalpontSystemCatalog::RIDList::const_iterator rid_iterator = ridList.begin();
|
|
|
|
while (rid_iterator != ridList.end())
|
|
{
|
|
CalpontSystemCatalog::ROPair roPair = *rid_iterator;
|
|
DMLColumn* columnPtr = new DMLColumn();
|
|
CalpontSystemCatalog::TableColName tblColName = systemCatalogPtr->colName( roPair.objnum );
|
|
columnPtr->set_Name(tblColName.column);
|
|
|
|
colList.push_back(columnPtr);
|
|
|
|
++rid_iterator;
|
|
}
|
|
|
|
}
|
|
|
|
char* DMLPackageProcessor::strlower(char* in)
|
|
{
|
|
char* p = in;
|
|
|
|
if (p)
|
|
{
|
|
while (*p)
|
|
{
|
|
*p = tolower(*p);
|
|
p++;
|
|
}
|
|
}
|
|
|
|
return in;
|
|
}
|
|
|
|
void DMLPackageProcessor::convertRidToColumn(uint64_t& rid, unsigned& dbRoot, unsigned& partition,
|
|
unsigned& segment, unsigned filesPerColumnPartition, unsigned extentsPerSegmentFile, unsigned extentRows,
|
|
unsigned startDBRoot, unsigned dbrootCnt, const unsigned startPartitionNum)
|
|
{
|
|
partition = rid / (filesPerColumnPartition * extentsPerSegmentFile * extentRows);
|
|
|
|
segment = (((rid % ( filesPerColumnPartition * extentsPerSegmentFile * extentRows)) /
|
|
extentRows)) % filesPerColumnPartition;
|
|
|
|
dbRoot = ((startDBRoot - 1 + segment) % dbrootCnt) + 1;
|
|
|
|
//Calculate the relative rid for this segment file
|
|
uint64_t relRidInPartition = rid - ((uint64_t)partition * (uint64_t)filesPerColumnPartition *
|
|
(uint64_t)extentsPerSegmentFile * (uint64_t)extentRows);
|
|
idbassert(relRidInPartition <= (uint64_t)filesPerColumnPartition * (uint64_t)extentsPerSegmentFile *
|
|
(uint64_t)extentRows);
|
|
uint32_t numExtentsInThisPart = relRidInPartition / extentRows;
|
|
unsigned numExtentsInThisSegPart = numExtentsInThisPart / filesPerColumnPartition;
|
|
uint64_t relRidInThisExtent = relRidInPartition - numExtentsInThisPart * extentRows;
|
|
rid = relRidInThisExtent + numExtentsInThisSegPart * extentRows;
|
|
}
|
|
|
|
|
|
string DMLPackageProcessor::projectTableErrCodeToMsg(uint32_t ec)
|
|
{
|
|
if (ec < 1000) // pre IDB error code
|
|
{
|
|
ErrorCodes ecObj;
|
|
string errMsg("Statement failed.");
|
|
errMsg += ecObj.errorString(ec).substr(150); // substr removes ErrorCodes::fPreamble
|
|
return errMsg;
|
|
}
|
|
|
|
// IDB error
|
|
return IDBErrorInfo::instance()->errorMsg(ec);
|
|
}
|
|
|
|
bool DMLPackageProcessor::validateVarbinaryVal( std::string& inStr)
|
|
{
|
|
bool invalid = false;
|
|
|
|
for (unsigned i = 0; i < inStr.length(); i++)
|
|
{
|
|
if (!isxdigit(inStr[i]))
|
|
{
|
|
invalid = true;
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
return invalid;
|
|
}
|
|
|
|
int DMLPackageProcessor::commitTransaction(uint64_t uniqueId, BRM::TxnID txnID)
|
|
{
|
|
int rc = fDbrm->vbCommit(txnID.id);
|
|
return rc;
|
|
}
|
|
|
|
int DMLPackageProcessor::rollBackTransaction(uint64_t uniqueId, BRM::TxnID txnID, uint32_t sessionID,
|
|
std::string& errorMsg)
|
|
{
|
|
std::vector<BRM::LBID_t> lbidList;
|
|
std::vector<BRM::LBIDRange> lbidRangeList;
|
|
BRM::LBIDRange range;
|
|
int rc = 0;
|
|
//Check BRM status before processing.
|
|
rc = fDbrm->isReadWrite();
|
|
|
|
if (rc != 0 )
|
|
{
|
|
std::string brmMsg;
|
|
errorMsg = "Can't read DBRM isReadWrite [ ";
|
|
BRM::errString(rc, brmMsg);
|
|
errorMsg += brmMsg;
|
|
errorMsg += "]";
|
|
return rc;
|
|
}
|
|
|
|
ByteStream bytestream;
|
|
fWEClient->addQueue(uniqueId);
|
|
//cout << "adding to queue with id " << uniqueId << endl;
|
|
bytestream << (ByteStream::byte) WE_SVR_ROLLBACK_BLOCKS;
|
|
bytestream << uniqueId;
|
|
bytestream << sessionID;
|
|
bytestream << (uint32_t)txnID.id;
|
|
uint32_t msgRecived = 0;
|
|
|
|
try
|
|
{
|
|
fWEClient->write_to_all(bytestream);
|
|
boost::shared_ptr<messageqcpp::ByteStream> bsIn;
|
|
bsIn.reset(new ByteStream());
|
|
ByteStream::byte tmp8;
|
|
|
|
while (1)
|
|
{
|
|
if (msgRecived == fWEClient->getPmCount())
|
|
break;
|
|
|
|
fWEClient->read(uniqueId, bsIn);
|
|
|
|
if ( bsIn->length() == 0 ) //read error
|
|
{
|
|
rc = NETWORK_ERROR;
|
|
errorMsg = "Network error reading WEClient";
|
|
fWEClient->removeQueue(uniqueId);
|
|
//cout << "erroring out remove queue id " << uniqueId << endl;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
*bsIn >> tmp8;
|
|
rc = tmp8;
|
|
|
|
if (rc != 0)
|
|
{
|
|
char szrc[20];
|
|
*bsIn >> errorMsg;
|
|
errorMsg += " (WriteEngine returns error ";
|
|
sprintf(szrc, "%d", rc);
|
|
errorMsg += szrc;
|
|
errorMsg += ")";
|
|
fWEClient->removeQueue(uniqueId);
|
|
cout << "erroring out remove queue id " << uniqueId << endl;
|
|
break;
|
|
}
|
|
else
|
|
msgRecived++;
|
|
}
|
|
}
|
|
}
|
|
catch (std::exception& e)
|
|
{
|
|
rc = NETWORK_ERROR;
|
|
errorMsg = "Network error occured when rolling back blocks";
|
|
errorMsg += e.what();
|
|
fWEClient->removeQueue(uniqueId);
|
|
cout << "erroring out remove queue id " << uniqueId << endl;
|
|
//delete fWEClient;
|
|
return rc;
|
|
}
|
|
catch ( ... )
|
|
{
|
|
rc = NETWORK_ERROR;
|
|
errorMsg = "Unknown exception caught while rolling back transaction.";
|
|
fWEClient->removeQueue(uniqueId);
|
|
cout << "erroring out remove queue id " << uniqueId << endl;
|
|
//delete fWEClient;
|
|
return rc;
|
|
}
|
|
|
|
if (rc != 0)
|
|
{
|
|
//delete fWEClient;
|
|
return rc;
|
|
}
|
|
|
|
fWEClient->removeQueue(uniqueId);
|
|
//delete fWEClient;
|
|
// cout << "success. remove queue id " << uniqueId << endl;
|
|
rc = fDbrm->getUncommittedLBIDs(txnID.id, lbidList);
|
|
|
|
if (rc != 0 )
|
|
{
|
|
std::string brmMsg;
|
|
errorMsg = "DBRM getUncommittedLBIDs [ ";
|
|
BRM::errString(rc, brmMsg);
|
|
errorMsg += brmMsg;
|
|
errorMsg += "]";
|
|
return rc;
|
|
}
|
|
|
|
for (size_t i = 0; i < lbidList.size(); i++)
|
|
{
|
|
range.start = lbidList[i];
|
|
range.size = 1;
|
|
lbidRangeList.push_back(range);
|
|
}
|
|
|
|
rc = fDbrm->vbRollback(txnID.id, lbidRangeList);
|
|
|
|
if (rc != 0 )
|
|
{
|
|
std::string brmMsg;
|
|
errorMsg = "DBRM vbRollback [ ";
|
|
BRM::errString(rc, brmMsg);
|
|
errorMsg += brmMsg;
|
|
errorMsg += "]";
|
|
return rc;
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
int DMLPackageProcessor::commitBatchAutoOnTransaction(uint64_t uniqueId, BRM::TxnID txnID, const uint32_t tableOid, std::string& errorMsg)
|
|
{
|
|
//collect hwm info from all pms and set them here. remove table metadata if all successful
|
|
ByteStream bytestream;
|
|
fWEClient->addQueue(uniqueId);
|
|
bytestream << (ByteStream::byte)WE_SVR_COMMIT_BATCH_AUTO_ON;
|
|
bytestream << uniqueId;
|
|
bytestream << (uint32_t) txnID.id;
|
|
bytestream << tableOid;
|
|
bytestream << fSessionID;
|
|
|
|
uint32_t msgRecived = 0;
|
|
fWEClient->write_to_all(bytestream);
|
|
boost::shared_ptr<messageqcpp::ByteStream> bsIn;
|
|
bsIn.reset(new ByteStream());
|
|
int rc = 0;
|
|
ByteStream::byte tmp8;
|
|
typedef std::vector<BRM::BulkSetHWMArg> BulkSetHWMArgs;
|
|
std::vector<BulkSetHWMArgs> hwmArgsAllPms;
|
|
|
|
while (1)
|
|
{
|
|
if (msgRecived == fWEClient->getPmCount())
|
|
break;
|
|
|
|
fWEClient->read(uniqueId, bsIn);
|
|
|
|
if ( bsIn->length() == 0 ) //read error
|
|
{
|
|
rc = NETWORK_ERROR;
|
|
fWEClient->removeQueue(uniqueId);
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
*bsIn >> tmp8;
|
|
rc = tmp8;
|
|
|
|
if (rc != 0)
|
|
{
|
|
*bsIn >> errorMsg;
|
|
fWEClient->removeQueue(uniqueId);
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
//get hwm info
|
|
*bsIn >> errorMsg;
|
|
BulkSetHWMArgs setHWMArgs;
|
|
//cout << "received from WES bytestream length = " << bsIn->length() << endl;
|
|
deserializeInlineVector(*(bsIn.get()), setHWMArgs);
|
|
//cout << "get hwm info from WES size " << setHWMArgs.size() << endl;
|
|
hwmArgsAllPms.push_back(setHWMArgs);
|
|
msgRecived++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (rc != 0)
|
|
return rc;
|
|
|
|
//set hwm
|
|
std::vector<BRM::BulkSetHWMArg> allHwm;
|
|
BulkSetHWMArgs::const_iterator itor;
|
|
|
|
//cout << "total hwmArgsAllPms size " << hwmArgsAllPms.size() << endl;
|
|
for (unsigned i = 0; i < fWEClient->getPmCount(); i++)
|
|
{
|
|
itor = hwmArgsAllPms[i].begin();
|
|
|
|
while (itor != hwmArgsAllPms[i].end())
|
|
{
|
|
allHwm.push_back(*itor);
|
|
//cout << "received hwm info: " << itor->oid << ":" << itor->hwm << endl;
|
|
itor++;
|
|
}
|
|
}
|
|
|
|
//set CP data before hwm.
|
|
|
|
//cout << "setting hwm allHwm size " << allHwm.size() << endl;
|
|
BRM::CPInfoList_t cpInfos;
|
|
|
|
std::vector<BRM::CPInfoMerge> mergeCPDataArgs;
|
|
rc = fDbrm->bulkSetHWMAndCP(allHwm, cpInfos, mergeCPDataArgs, txnID.id);
|
|
fDbrm->takeSnapshot();
|
|
//Set tablelock to rollforward remove meta files
|
|
|
|
if (rc != 0)
|
|
return rc;
|
|
|
|
bool stateChanged = true;
|
|
TablelockData* tablelockData = TablelockData::makeTablelockData(fSessionID);
|
|
uint64_t tablelockId = tablelockData->getTablelockId(tableOid);
|
|
|
|
try
|
|
{
|
|
stateChanged = fDbrm->changeState(tablelockId, BRM::CLEANUP);
|
|
}
|
|
catch (std::exception&)
|
|
{
|
|
errorMsg = IDBErrorInfo::instance()->errorMsg(ERR_HARD_FAILURE);
|
|
stateChanged = false;
|
|
}
|
|
|
|
if (!stateChanged)
|
|
return rc;
|
|
|
|
bytestream.restart();
|
|
//@Bug 4517 Remove meta data failure doesn't stop tablelock releasing.
|
|
bytestream << (ByteStream::byte)WE_SVR_BATCH_AUTOON_REMOVE_META;
|
|
bytestream << uniqueId;
|
|
bytestream << tableOid;
|
|
msgRecived = 0;
|
|
fWEClient->write_to_all(bytestream);
|
|
|
|
while (1)
|
|
{
|
|
if (msgRecived == fWEClient->getPmCount())
|
|
break;
|
|
|
|
fWEClient->read(uniqueId, bsIn);
|
|
|
|
if ( bsIn->length() == 0 ) //read error
|
|
{
|
|
fWEClient->removeQueue(uniqueId);
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
*bsIn >> tmp8;
|
|
msgRecived++;
|
|
}
|
|
}
|
|
|
|
return rc;
|
|
|
|
|
|
}
|
|
|
|
int DMLPackageProcessor::rollBackBatchAutoOnTransaction(uint64_t uniqueId, BRM::TxnID txnID, uint32_t sessionID,
|
|
const uint32_t tableOid, std::string& errorMsg)
|
|
{
|
|
//Bulkrollback, rollback blocks, vbrollback, change state, remove meta file
|
|
//cout << "In rollBackBatchAutoOnTransaction" << endl;
|
|
std::vector<BRM::TableLockInfo> tableLocks;
|
|
tableLocks = fDbrm->getAllTableLocks();
|
|
//cout << " Got all tablelocks" << endl;
|
|
unsigned idx = 0;
|
|
string ownerName ("DMLProc batchinsert");
|
|
uint64_t tableLockId = 0;
|
|
int rc = 0;
|
|
|
|
for (; idx < tableLocks.size(); idx++)
|
|
{
|
|
if ((tableLocks[idx].ownerName == ownerName) && (tableLocks[idx].tableOID == tableOid))
|
|
{
|
|
tableLockId = tableLocks[idx].id;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((tableLockId == 0) || (tableOid == 0))
|
|
{
|
|
// table is not locked by DMLProc. Could happen if we failed to get lock
|
|
// while inserting. Not an error during rollback, but we don't
|
|
// want to do anything.
|
|
return rc;
|
|
}
|
|
|
|
//cout << "sending to WES" << endl;
|
|
ByteStream bytestream;
|
|
fWEClient->addQueue(uniqueId);
|
|
//cout << "adding queue id " << uniqueId << endl;
|
|
bytestream << (ByteStream::byte) WE_SVR_ROLLBACK_BATCH_AUTO_ON;
|
|
bytestream << uniqueId;
|
|
bytestream << sessionID;
|
|
bytestream << tableLockId;
|
|
bytestream << tableOid;
|
|
uint32_t msgRecived = 0;
|
|
fWEClient->write_to_all(bytestream);
|
|
boost::shared_ptr<messageqcpp::ByteStream> bsIn;
|
|
bsIn.reset(new ByteStream());
|
|
ByteStream::byte tmp8;
|
|
|
|
//cout << "waiting for reply from WES" << endl;
|
|
while (1)
|
|
{
|
|
if (msgRecived == fWEClient->getPmCount())
|
|
break;
|
|
|
|
fWEClient->read(uniqueId, bsIn);
|
|
|
|
if ( bsIn->length() == 0 ) //read error
|
|
{
|
|
rc = NETWORK_ERROR;
|
|
fWEClient->removeQueue(uniqueId);
|
|
//cout << "erroring out remove queue id " << uniqueId << endl;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
*bsIn >> tmp8;
|
|
rc = tmp8;
|
|
|
|
if (rc != 0)
|
|
{
|
|
*bsIn >> errorMsg;
|
|
fWEClient->removeQueue(uniqueId);
|
|
//cout << "erroring out remove queue id " << uniqueId << endl;
|
|
break;
|
|
}
|
|
else
|
|
msgRecived++;
|
|
}
|
|
}
|
|
|
|
if (rc == 0) //change table lock state
|
|
{
|
|
bool stateChanged = true;
|
|
|
|
//cout << "changing tablelock state" << endl;
|
|
try
|
|
{
|
|
stateChanged = fDbrm->changeState(tableLockId, BRM::CLEANUP);
|
|
}
|
|
catch (std::exception&)
|
|
{
|
|
errorMsg = IDBErrorInfo::instance()->errorMsg(ERR_HARD_FAILURE);
|
|
stateChanged = false;
|
|
}
|
|
|
|
if (!stateChanged)
|
|
{
|
|
rc = 1;
|
|
}
|
|
}
|
|
|
|
if ( rc != 0 )
|
|
return rc;
|
|
|
|
bytestream.restart();
|
|
bytestream << (ByteStream::byte)WE_SVR_BATCH_AUTOON_REMOVE_META;
|
|
bytestream << uniqueId;
|
|
bytestream << tableOid;
|
|
msgRecived = 0;
|
|
fWEClient->write_to_all(bytestream);
|
|
|
|
while (1)
|
|
{
|
|
if (msgRecived == fWEClient->getPmCount())
|
|
break;
|
|
|
|
fWEClient->read(uniqueId, bsIn);
|
|
|
|
if ( bsIn->length() == 0 ) //read error
|
|
{
|
|
fWEClient->removeQueue(uniqueId);
|
|
//cout << "erroring out remove queue id " << uniqueId << endl;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
*bsIn >> tmp8;
|
|
msgRecived++;
|
|
}
|
|
}
|
|
|
|
fWEClient->removeQueue(uniqueId);
|
|
return rc;
|
|
}
|
|
|
|
int DMLPackageProcessor::commitBatchAutoOffTransaction(uint64_t uniqueId, BRM::TxnID txnID, const uint32_t tableOid, std::string& errorMsg)
|
|
{
|
|
std::vector<BRM::TableLockInfo> tableLocks;
|
|
tableLocks = fDbrm->getAllTableLocks();
|
|
//cout << " Got all tablelocks" << endl;
|
|
unsigned idx = 0;
|
|
string ownerName ("DMLProc batchinsert");
|
|
uint64_t tableLockId = 0;
|
|
int rc = 0;
|
|
boost::shared_ptr<messageqcpp::ByteStream> bsIn;
|
|
bsIn.reset(new ByteStream());
|
|
ByteStream::byte tmp8;
|
|
|
|
for (; idx < tableLocks.size(); idx++)
|
|
{
|
|
if ((tableLocks[idx].ownerName == ownerName) && (tableLocks[idx].tableOID == tableOid))
|
|
{
|
|
tableLockId = tableLocks[idx].id;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((tableLockId == 0) || (tableOid == 0))
|
|
{
|
|
// table is not locked by DMLProc. Could happen if we failed to get lock
|
|
// while inserting. Not an error during rollback, but we don't
|
|
// want to do anything.
|
|
return rc;
|
|
}
|
|
|
|
bool stateChanged = true;
|
|
|
|
//cout << "changing tablelock state" << endl;
|
|
try
|
|
{
|
|
stateChanged = fDbrm->changeState(tableLockId, BRM::CLEANUP);
|
|
}
|
|
catch (std::exception&)
|
|
{
|
|
errorMsg = IDBErrorInfo::instance()->errorMsg(ERR_HARD_FAILURE);
|
|
stateChanged = false;
|
|
}
|
|
|
|
if (!stateChanged)
|
|
{
|
|
rc = 1;
|
|
}
|
|
|
|
if ( rc != 0 )
|
|
return rc;
|
|
|
|
ByteStream bytestream;
|
|
fWEClient->addQueue(uniqueId);
|
|
bytestream << (ByteStream::byte)WE_SVR_BATCH_AUTOON_REMOVE_META;
|
|
bytestream << uniqueId;
|
|
bytestream << tableOid;
|
|
uint32_t msgRecived = 0;
|
|
fWEClient->write_to_all(bytestream);
|
|
|
|
while (1)
|
|
{
|
|
if (msgRecived == fWEClient->getPmCount())
|
|
break;
|
|
|
|
fWEClient->read(uniqueId, bsIn);
|
|
|
|
if ( bsIn->length() == 0 ) //read error
|
|
{
|
|
fWEClient->removeQueue(uniqueId);
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
*bsIn >> tmp8;
|
|
msgRecived++;
|
|
}
|
|
}
|
|
|
|
fWEClient->removeQueue(uniqueId);
|
|
return rc;
|
|
}
|
|
|
|
int DMLPackageProcessor::rollBackBatchAutoOffTransaction(uint64_t uniqueId, BRM::TxnID txnID, uint32_t sessionID,
|
|
const uint32_t tableOid, std::string& errorMsg)
|
|
{
|
|
ByteStream bytestream;
|
|
fWEClient->addQueue(uniqueId);
|
|
bytestream << (ByteStream::byte) WE_SVR_ROLLBACK_BATCH_AUTO_OFF;
|
|
bytestream << uniqueId;
|
|
bytestream << sessionID;
|
|
bytestream << (uint32_t)txnID.id;
|
|
bytestream << tableOid;
|
|
uint32_t msgRecived = 0;
|
|
fWEClient->write_to_all(bytestream);
|
|
boost::shared_ptr<messageqcpp::ByteStream> bsIn;
|
|
bsIn.reset(new ByteStream());
|
|
int rc = 0;
|
|
ByteStream::byte tmp8;
|
|
|
|
while (1)
|
|
{
|
|
if (msgRecived == fWEClient->getPmCount())
|
|
break;
|
|
|
|
fWEClient->read(uniqueId, bsIn);
|
|
|
|
if ( bsIn->length() == 0 ) //read error
|
|
{
|
|
rc = NETWORK_ERROR;
|
|
fWEClient->removeQueue(uniqueId);
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
*bsIn >> tmp8;
|
|
rc = tmp8;
|
|
|
|
if (rc != 0)
|
|
{
|
|
*bsIn >> errorMsg;
|
|
fWEClient->removeQueue(uniqueId);
|
|
break;
|
|
}
|
|
else
|
|
msgRecived++;
|
|
}
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
int DMLPackageProcessor::flushDataFiles (int rcIn, std::map<FID, FID>& columnOids, uint64_t uniqueId, BRM::TxnID txnID, uint32_t tableOid)
|
|
{
|
|
//cout <<"in flushDataFiles" << endl;
|
|
ByteStream bytestream;
|
|
bytestream << (ByteStream::byte) WE_SVR_FLUSH_FILES;
|
|
bytestream << uniqueId;
|
|
bytestream << (uint32_t) rcIn;
|
|
bytestream << (uint32_t)txnID.id;
|
|
bytestream << tableOid;
|
|
uint32_t msgRecived = 0;
|
|
fWEClient->write_to_all(bytestream);
|
|
boost::shared_ptr<messageqcpp::ByteStream> bsIn;
|
|
bsIn.reset(new ByteStream());
|
|
int rc = 0;
|
|
ByteStream::byte tmp8;
|
|
std::string errorMsg;
|
|
|
|
try
|
|
{
|
|
while (1)
|
|
{
|
|
if (msgRecived == fWEClient->getPmCount())
|
|
break;
|
|
|
|
fWEClient->read(uniqueId, bsIn);
|
|
|
|
if ( bsIn->length() == 0 ) //read error
|
|
{
|
|
rc = NETWORK_ERROR;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
*bsIn >> tmp8;
|
|
rc = tmp8;
|
|
|
|
if (rc != 0)
|
|
{
|
|
*bsIn >> errorMsg;
|
|
break;
|
|
}
|
|
else
|
|
msgRecived++;
|
|
}
|
|
}
|
|
}
|
|
catch (std::exception&)
|
|
{
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
int DMLPackageProcessor::endTransaction (uint64_t uniqueId, BRM::TxnID txnID, bool success)
|
|
{
|
|
//cout <<"in flushDataFiles" << endl;
|
|
ByteStream bytestream;
|
|
bytestream << (ByteStream::byte) WE_END_TRANSACTION;
|
|
bytestream << uniqueId;
|
|
bytestream << (uint32_t)txnID.id;
|
|
bytestream << (ByteStream::byte)success;
|
|
uint32_t msgRecived = 0;
|
|
fWEClient->write_to_all(bytestream);
|
|
boost::shared_ptr<messageqcpp::ByteStream> bsIn;
|
|
bsIn.reset(new ByteStream());
|
|
int rc = 0;
|
|
ByteStream::byte tmp8;
|
|
std::string errorMsg;
|
|
|
|
try
|
|
{
|
|
while (1)
|
|
{
|
|
if (msgRecived == fWEClient->getPmCount())
|
|
break;
|
|
|
|
fWEClient->read(uniqueId, bsIn);
|
|
|
|
if ( bsIn->length() == 0 ) //read error
|
|
{
|
|
rc = NETWORK_ERROR;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
*bsIn >> tmp8;
|
|
rc = tmp8;
|
|
|
|
if (rc != 0)
|
|
{
|
|
*bsIn >> errorMsg;
|
|
break;
|
|
}
|
|
else
|
|
msgRecived++;
|
|
}
|
|
}
|
|
}
|
|
catch (std::exception&)
|
|
{
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
}
|
|
// vim:ts=4 sw=4:
|