mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-04-26 11:48:52 +03:00
856 lines
26 KiB
C++
856 lines
26 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. */
|
||
|
||
#include "we_confirmhdfsdbfile.h"
|
||
|
||
#include <cerrno>
|
||
#include <cstring>
|
||
#include <iostream>
|
||
#include <sstream>
|
||
#include <vector>
|
||
|
||
#include <boost/scoped_array.hpp>
|
||
#include <boost/scoped_ptr.hpp>
|
||
|
||
#include "we_define.h"
|
||
#include "we_config.h"
|
||
#include "we_fileop.h"
|
||
#include "we_rbmetawriter.h"
|
||
#include "IDBPolicy.h"
|
||
#include "IDBDataFile.h"
|
||
|
||
namespace
|
||
{
|
||
const int BUF_SIZE = 1024; // size of buffer used to read meta data records
|
||
}
|
||
|
||
namespace WriteEngine
|
||
{
|
||
|
||
//------------------------------------------------------------------------------
|
||
// Constructor
|
||
// This class should typically only be used on an HDFS system, so we could
|
||
// hardcode this to pass HDFS to getFsi(); but it comes in handy for testing,
|
||
// to be able to execute this class on a non-HDFS stack as well. So I rely
|
||
// on useHdfs() to tell me which FileSystem reference to get.
|
||
//------------------------------------------------------------------------------
|
||
ConfirmHdfsDbFile::ConfirmHdfsDbFile() :
|
||
fFs(idbdatafile::IDBPolicy::useHdfs() ?
|
||
idbdatafile::IDBFileSystem::getFs(idbdatafile::IDBDataFile::HDFS) :
|
||
idbdatafile::IDBPolicy::useCloud() ?
|
||
idbdatafile::IDBFileSystem::getFs(idbdatafile::IDBDataFile::CLOUD) :
|
||
idbdatafile::IDBFileSystem::getFs(idbdatafile::IDBDataFile::BUFFERED))
|
||
{
|
||
}
|
||
|
||
//------------------------------------------------------------------------------
|
||
// Destructor
|
||
//------------------------------------------------------------------------------
|
||
ConfirmHdfsDbFile::~ConfirmHdfsDbFile()
|
||
{
|
||
}
|
||
|
||
//------------------------------------------------------------------------------
|
||
// Backup a cdf file and replace it with the updated tmp file.
|
||
//------------------------------------------------------------------------------
|
||
int ConfirmHdfsDbFile::confirmDbFileChange(
|
||
const std::string& backUpFileType,
|
||
const std::string& filename,
|
||
std::string& errMsg) const
|
||
{
|
||
// return value
|
||
int rc = NO_ERROR;
|
||
|
||
// This rlc file should be renamed if success, just skip it
|
||
if (backUpFileType.compare("rlc") == 0)
|
||
{
|
||
return rc;
|
||
}
|
||
|
||
if (backUpFileType.compare("tmp") != 0 )
|
||
{
|
||
std::ostringstream oss;
|
||
oss << backUpFileType << " is a bad type to confirm DbFile change: " <<
|
||
filename;
|
||
errMsg = oss.str();
|
||
rc = ERR_HDFS_BACKUP;
|
||
|
||
return rc;
|
||
}
|
||
|
||
// add safety checks, just in case
|
||
std::string tmp(filename + ".tmp");
|
||
|
||
if (!fFs.exists(tmp.c_str())) // file already swapped
|
||
return rc;
|
||
|
||
if (fFs.size(tmp.c_str()) <= 0)
|
||
{
|
||
std::ostringstream oss;
|
||
oss << "tmp file " << tmp << " has bad size" << fFs.size(tmp.c_str());
|
||
errMsg = oss.str();
|
||
rc = ERR_COMP_RENAME_FILE;
|
||
|
||
return rc;
|
||
}
|
||
|
||
// remove the old orig if exists
|
||
std::string orig(filename + ".orig");
|
||
errno = 0;
|
||
|
||
if ((fFs.exists(orig.c_str())) &&
|
||
(fFs.remove(orig.c_str())) != 0)
|
||
{
|
||
int errNum = errno;
|
||
std::ostringstream oss;
|
||
oss << "remove old " << orig << " failed: " << strerror(errNum);
|
||
errMsg = oss.str();
|
||
rc = ERR_COMP_REMOVE_FILE;
|
||
|
||
return rc;
|
||
}
|
||
|
||
// backup the original
|
||
errno = 0;
|
||
|
||
if (fFs.rename(filename.c_str(), orig.c_str()) != 0)
|
||
{
|
||
int errNum = errno;
|
||
std::ostringstream oss;
|
||
oss << "rename " << filename << " to " << orig << " failed: " <<
|
||
strerror(errNum);
|
||
errMsg = oss.str();
|
||
rc = ERR_COMP_RENAME_FILE;
|
||
|
||
return rc;
|
||
}
|
||
|
||
// rename the new file
|
||
errno = 0;
|
||
|
||
if (fFs.rename(tmp.c_str(), filename.c_str()) != 0)
|
||
{
|
||
int errNum = errno;
|
||
std::ostringstream oss;
|
||
oss << "rename " << tmp << " to " << filename << " failed: " <<
|
||
strerror(errNum);
|
||
errMsg = oss.str();
|
||
rc = ERR_COMP_RENAME_FILE;
|
||
|
||
return rc;
|
||
}
|
||
|
||
return rc;
|
||
}
|
||
|
||
//------------------------------------------------------------------------------
|
||
// Finalize the changes to a db file.
|
||
// If success flag is true, then remove the orig
|
||
// otherwise, move the orig back to cdf
|
||
//------------------------------------------------------------------------------
|
||
int ConfirmHdfsDbFile::endDbFileChange(
|
||
const std::string& backUpFileType,
|
||
const std::string& filename,
|
||
bool success,
|
||
std::string& errMsg) const
|
||
{
|
||
// return value
|
||
int rc = NO_ERROR;
|
||
|
||
// This rlc file should be renamed if success, it is useless if failed.
|
||
if (backUpFileType.compare("rlc") == 0)
|
||
{
|
||
std::string rlc(filename + ".rlc");
|
||
|
||
if (fFs.exists(rlc.c_str()))
|
||
fFs.remove(rlc.c_str()); // TBD-okay to ignore failed removal?
|
||
|
||
return rc;
|
||
}
|
||
|
||
if (backUpFileType.compare("tmp") != 0)
|
||
{
|
||
std::ostringstream oss;
|
||
oss << backUpFileType << " is a bad type to finalize DbFile change: " <<
|
||
filename;
|
||
errMsg = oss.str();
|
||
rc = ERR_HDFS_BACKUP;
|
||
|
||
return rc;
|
||
}
|
||
|
||
std::string orig(filename + ".orig");
|
||
|
||
if (success)
|
||
{
|
||
// remove the orig file
|
||
errno = 0;
|
||
|
||
if ((fFs.exists(orig.c_str())) &&
|
||
(fFs.remove(orig.c_str())) != 0)
|
||
{
|
||
int errNum = errno;
|
||
std::ostringstream oss;
|
||
oss << "remove " << orig << " failed: " << strerror(errNum);
|
||
errMsg = oss.str();
|
||
rc = ERR_COMP_REMOVE_FILE;
|
||
|
||
return rc;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// restore the orig file
|
||
if (fFs.exists(orig.c_str()))
|
||
{
|
||
errno = 0;
|
||
|
||
// Try to remove file only if it exists
|
||
if ((fFs.exists(filename.c_str())) &&
|
||
(fFs.remove(filename.c_str()) != 0))
|
||
{
|
||
int errNum = errno;
|
||
std::ostringstream oss;
|
||
oss << "failed restore; remove " << filename << " failed: " <<
|
||
strerror(errNum);
|
||
errMsg = oss.str();
|
||
rc = ERR_COMP_REMOVE_FILE;
|
||
|
||
return rc;
|
||
}
|
||
|
||
errno = 0;
|
||
|
||
if (fFs.rename(orig.c_str(), filename.c_str()) != 0)
|
||
{
|
||
int errNum = errno;
|
||
std::ostringstream oss;
|
||
oss << "failed restore; rename " << orig << " failed: " <<
|
||
strerror(errNum);
|
||
errMsg = oss.str();
|
||
rc = ERR_COMP_RENAME_FILE;
|
||
|
||
return rc;
|
||
}
|
||
}
|
||
|
||
// remove the tmp file
|
||
std::string tmp(filename + ".tmp");
|
||
errno = 0;
|
||
|
||
if ((fFs.exists(tmp.c_str())) &&
|
||
(fFs.remove(tmp.c_str())) != 0)
|
||
{
|
||
int errNum = errno;
|
||
std::ostringstream oss;
|
||
oss << "failed restore; remove " << tmp << " failed: " <<
|
||
strerror(errNum);
|
||
errMsg = oss.str();
|
||
rc = ERR_COMP_REMOVE_FILE;
|
||
|
||
return rc;
|
||
}
|
||
|
||
// remove the chunk shifting helper
|
||
std::string rlc(filename + ".rlc");
|
||
errno = 0;
|
||
|
||
if ((fFs.exists(rlc.c_str())) &&
|
||
(fFs.remove(rlc.c_str())) != 0)
|
||
{
|
||
int errNum = errno;
|
||
std::ostringstream oss;
|
||
oss << "failed restore; remove " << rlc << " failed: " <<
|
||
strerror(errNum);
|
||
errMsg = oss.str();
|
||
rc = ERR_COMP_REMOVE_FILE;
|
||
|
||
return rc;
|
||
}
|
||
}
|
||
|
||
return rc;
|
||
}
|
||
|
||
//------------------------------------------------------------------------------
|
||
// Confirm the changes to the hwm DB files listed in the bulk rollback meta
|
||
// data file corresponding to the specified table OID.
|
||
//------------------------------------------------------------------------------
|
||
int ConfirmHdfsDbFile::confirmDbFileListFromMetaFile(
|
||
OID tableOID,
|
||
std::string& errMsg)
|
||
{
|
||
int rc = NO_ERROR;
|
||
|
||
try
|
||
{
|
||
std::vector<uint16_t> dbRoots;
|
||
Config::getRootIdList( dbRoots );
|
||
|
||
for (unsigned m = 0; m < dbRoots.size(); m++)
|
||
{
|
||
std::istringstream metaDataStream;
|
||
openMetaDataFile ( tableOID,
|
||
dbRoots[m], metaDataStream );
|
||
|
||
confirmDbFiles( metaDataStream );
|
||
}
|
||
}
|
||
catch (WeException& ex)
|
||
{
|
||
std::ostringstream oss;
|
||
oss << "Error confirming changes to table " << tableOID <<
|
||
"; " << ex.what();
|
||
errMsg = oss.str();
|
||
rc = ex.errorCode();
|
||
}
|
||
catch (std::exception& ex)
|
||
{
|
||
std::ostringstream oss;
|
||
oss << "Error confirming changes to table " << tableOID <<
|
||
"; " << ex.what();
|
||
errMsg = oss.str();
|
||
rc = ERR_UNKNOWN;
|
||
}
|
||
|
||
return rc;
|
||
}
|
||
|
||
//------------------------------------------------------------------------------
|
||
// Confirm the changes to the hwm DB files listed in the bulk rollback meta
|
||
// data file stream stored in metaDataStream.
|
||
//------------------------------------------------------------------------------
|
||
void ConfirmHdfsDbFile::confirmDbFiles(std::istringstream& metaDataStream) const
|
||
{
|
||
char inBuf[ BUF_SIZE ];
|
||
|
||
// Loop through the records in the meta-data file
|
||
while (metaDataStream.getline( inBuf, BUF_SIZE ))
|
||
{
|
||
// Restore Files for current DBRoot
|
||
if (RBMetaWriter::verifyColumn1Rec(inBuf))
|
||
{
|
||
confirmColumnDbFile(inBuf);
|
||
}
|
||
else if (RBMetaWriter::verifyDStore1Rec(inBuf))
|
||
{
|
||
confirmDctnryStoreDbFile(inBuf);
|
||
}
|
||
}
|
||
}
|
||
|
||
//------------------------------------------------------------------------------
|
||
// Confirm the changes to the hwm column DB file described in the bulk
|
||
// rollback meta data file record stored in inBuf.
|
||
//------------------------------------------------------------------------------
|
||
void ConfirmHdfsDbFile::confirmColumnDbFile(const char* inBuf) const
|
||
{
|
||
char recType[100];
|
||
OID columnOID;
|
||
uint32_t dbRootHwm;
|
||
uint32_t partNumHwm;
|
||
uint32_t segNumHwm;
|
||
HWM lastLocalHwm;
|
||
int colTypeInt;
|
||
char colTypeName[100];
|
||
uint32_t colWidth;
|
||
int compressionType = 0; // optional parameter
|
||
|
||
// Read meta-data record
|
||
int numFields = sscanf(inBuf, "%s %u %u %u %u %u %d %s %u %d",
|
||
recType, &columnOID,
|
||
&dbRootHwm, &partNumHwm, &segNumHwm, &lastLocalHwm,
|
||
&colTypeInt, colTypeName, &colWidth, &compressionType );
|
||
|
||
if (numFields < 9) // compressionType is optional
|
||
{
|
||
std::ostringstream oss;
|
||
oss << "Invalid COLUM1 record in meta-data file " <<
|
||
fMetaFileName << "; record-<" << inBuf << ">";
|
||
|
||
throw WeException( oss.str(), ERR_INVALID_PARAM );
|
||
}
|
||
|
||
// Construct the DB file name
|
||
char dbFileName[FILE_NAME_SIZE];
|
||
FileOp dbFile(false);
|
||
int rc = dbFile.getFileName( columnOID,
|
||
dbFileName,
|
||
dbRootHwm,
|
||
partNumHwm,
|
||
segNumHwm );
|
||
|
||
if (rc != NO_ERROR)
|
||
{
|
||
WErrorCodes ec;
|
||
std::ostringstream oss;
|
||
oss << "Error constructing column filename to confirm changes" <<
|
||
"; columnOID-" << columnOID <<
|
||
"; dbRoot-" << dbRootHwm <<
|
||
"; partNum-" << partNumHwm <<
|
||
"; segNum-" << segNumHwm <<
|
||
"; " << ec.errorString(rc);
|
||
|
||
throw WeException( oss.str(), rc );
|
||
}
|
||
|
||
// Confirm the changes to the DB file name
|
||
std::string errMsg;
|
||
rc = confirmDbFileChange( std::string("tmp"),
|
||
dbFileName,
|
||
errMsg );
|
||
|
||
if (rc != NO_ERROR)
|
||
{
|
||
throw WeException( errMsg, rc );
|
||
}
|
||
}
|
||
|
||
//------------------------------------------------------------------------------
|
||
// Confirm the changes to the hwm dctnry store DB file described in the bulk
|
||
// rollback meta data file record stored in inBuf.
|
||
//------------------------------------------------------------------------------
|
||
void ConfirmHdfsDbFile::confirmDctnryStoreDbFile(const char* inBuf) const
|
||
{
|
||
char recType[100];
|
||
OID dColumnOID;
|
||
OID dStoreOID;
|
||
uint32_t dbRootHwm;
|
||
uint32_t partNumHwm;
|
||
uint32_t segNumHwm;
|
||
HWM localHwm;
|
||
int compressionType = 0; // optional parameter
|
||
|
||
// Read meta-data record
|
||
int numFields = sscanf(inBuf, "%s %u %u %u %u %u %u %d",
|
||
recType, &dColumnOID, &dStoreOID,
|
||
&dbRootHwm, &partNumHwm, &segNumHwm, &localHwm, &compressionType );
|
||
|
||
if (numFields < 7) // compressionType optional
|
||
{
|
||
std::ostringstream oss;
|
||
oss << "Invalid DSTOR1 record in meta-data file " <<
|
||
fMetaFileName << "; record-<" << inBuf << ">";
|
||
|
||
throw WeException( oss.str(), ERR_INVALID_PARAM );
|
||
}
|
||
|
||
// Construct the DB file name
|
||
char dbFileName[FILE_NAME_SIZE];
|
||
FileOp dbFile(false);
|
||
int rc = dbFile.getFileName( dStoreOID,
|
||
dbFileName,
|
||
dbRootHwm,
|
||
partNumHwm,
|
||
segNumHwm );
|
||
|
||
if (rc != NO_ERROR)
|
||
{
|
||
WErrorCodes ec;
|
||
std::ostringstream oss;
|
||
oss << "Error constructing dictionary store filename to confirm changes" <<
|
||
"; columnOID-" << dStoreOID <<
|
||
"; dbRoot-" << dbRootHwm <<
|
||
"; partNum-" << partNumHwm <<
|
||
"; segNum-" << segNumHwm <<
|
||
"; " << ec.errorString(rc);
|
||
|
||
throw WeException( oss.str(), rc );
|
||
}
|
||
|
||
// Confirm the changes to the DB file name
|
||
std::string errMsg;
|
||
rc = confirmDbFileChange( std::string("tmp"),
|
||
dbFileName,
|
||
errMsg );
|
||
|
||
if (rc != NO_ERROR)
|
||
{
|
||
throw WeException( errMsg, rc );
|
||
}
|
||
}
|
||
|
||
//------------------------------------------------------------------------------
|
||
// End the changes to the hwm DB files listed in the bulk rollback meta
|
||
// data file corresponding to the specified table OID. Delete temp files.
|
||
//------------------------------------------------------------------------------
|
||
int ConfirmHdfsDbFile::endDbFileListFromMetaFile(
|
||
OID tableOID,
|
||
bool success,
|
||
std::string& errMsg)
|
||
{
|
||
int rc = NO_ERROR;
|
||
errMsg.clear();
|
||
|
||
std::vector<uint16_t> dbRoots;
|
||
Config::getRootIdList( dbRoots );
|
||
|
||
for (unsigned m = 0; m < dbRoots.size(); m++)
|
||
{
|
||
std::istringstream metaDataStream;
|
||
|
||
try
|
||
{
|
||
std::istringstream metaDataStream;
|
||
openMetaDataFile ( tableOID,
|
||
dbRoots[m], metaDataStream );
|
||
|
||
endDbFiles( metaDataStream, success );
|
||
}
|
||
// We catch any errors, but not deleting a temp file is not fatal,
|
||
// so we capture the error msg and keep going if a problem occurs.
|
||
// We return a concatenated list of error msgs if multiple errors
|
||
// take place.
|
||
catch (WeException& ex)
|
||
{
|
||
if (errMsg.size() == 0)
|
||
{
|
||
std::ostringstream oss;
|
||
oss << "Error deleting temp files for table " << tableOID <<
|
||
"; " << ex.what();
|
||
errMsg = oss.str();
|
||
rc = ex.errorCode();
|
||
}
|
||
else
|
||
{
|
||
errMsg += "; ";
|
||
errMsg += ex.what();
|
||
}
|
||
}
|
||
catch (std::exception& ex)
|
||
{
|
||
if (errMsg.size() == 0)
|
||
{
|
||
std::ostringstream oss;
|
||
oss << "Error deleting temp files for table " << tableOID <<
|
||
"; " << ex.what();
|
||
errMsg = oss.str();
|
||
rc = ERR_UNKNOWN;
|
||
}
|
||
else
|
||
{
|
||
errMsg += "; ";
|
||
errMsg += ex.what();
|
||
}
|
||
}
|
||
}
|
||
|
||
return rc;
|
||
}
|
||
|
||
//------------------------------------------------------------------------------
|
||
// End the changes to the hwm DB files listed in the bulk rollback meta
|
||
// data file stream stored in metaDataStream. Delete temp files.
|
||
//------------------------------------------------------------------------------
|
||
void ConfirmHdfsDbFile::endDbFiles(
|
||
std::istringstream& metaDataStream,
|
||
bool success) const
|
||
{
|
||
char inBuf[ BUF_SIZE ];
|
||
std::string errMsg;
|
||
int rc = NO_ERROR;
|
||
|
||
// Loop through the records in the meta-data file
|
||
while (metaDataStream.getline( inBuf, BUF_SIZE ))
|
||
{
|
||
try
|
||
{
|
||
// Delete Temp Files for current DBRoot
|
||
if (RBMetaWriter::verifyColumn1Rec(inBuf))
|
||
{
|
||
endColumnDbFile(inBuf, success);
|
||
}
|
||
else if (RBMetaWriter::verifyDStore1Rec(inBuf))
|
||
{
|
||
endDctnryStoreDbFile(inBuf, success);
|
||
}
|
||
}
|
||
// We catch any errors, but not deleting a temp file is not fatal,
|
||
// so we capture the error msg and keep going if a problem occurs.
|
||
// We return a concatenated list of error msgs if multiple errors
|
||
// take place.
|
||
catch (WeException& ex)
|
||
{
|
||
if (errMsg.size() == 0)
|
||
{
|
||
rc = ex.errorCode();
|
||
}
|
||
else
|
||
{
|
||
errMsg += "; ";
|
||
}
|
||
|
||
errMsg += ex.what();
|
||
}
|
||
catch (std::exception& ex)
|
||
{
|
||
if (errMsg.size() == 0)
|
||
{
|
||
rc = ERR_UNKNOWN;
|
||
}
|
||
else
|
||
{
|
||
errMsg += "; ";
|
||
}
|
||
|
||
errMsg += ex.what();
|
||
}
|
||
}
|
||
|
||
// Throw exception with cumulative list of any error msgs
|
||
if (errMsg.size() > 0)
|
||
{
|
||
throw WeException( errMsg, rc );
|
||
}
|
||
}
|
||
|
||
//------------------------------------------------------------------------------
|
||
// End the changes to the hwm column DB file described in the bulk
|
||
// rollback meta data file record stored in inBuf. Delete the temp file.
|
||
//------------------------------------------------------------------------------
|
||
void ConfirmHdfsDbFile::endColumnDbFile(
|
||
const char* inBuf,
|
||
bool success) const
|
||
{
|
||
char recType[100];
|
||
OID columnOID;
|
||
uint32_t dbRootHwm;
|
||
uint32_t partNumHwm;
|
||
uint32_t segNumHwm;
|
||
HWM lastLocalHwm;
|
||
int colTypeInt;
|
||
char colTypeName[100];
|
||
uint32_t colWidth;
|
||
int compressionType = 0; // optional parameter
|
||
|
||
// Read meta-data record
|
||
int numFields = sscanf(inBuf, "%s %u %u %u %u %u %d %s %u %d",
|
||
recType, &columnOID,
|
||
&dbRootHwm, &partNumHwm, &segNumHwm, &lastLocalHwm,
|
||
&colTypeInt, colTypeName, &colWidth, &compressionType );
|
||
|
||
if (numFields < 9) // compressionType is optional
|
||
{
|
||
std::ostringstream oss;
|
||
oss << "Invalid COLUM1 record in meta-data file " <<
|
||
fMetaFileName << "; record-<" << inBuf << ">";
|
||
|
||
throw WeException( oss.str(), ERR_INVALID_PARAM );
|
||
}
|
||
|
||
// Construct the DB file name
|
||
char dbFileName[FILE_NAME_SIZE];
|
||
FileOp dbFile(false);
|
||
int rc = dbFile.getFileName( columnOID,
|
||
dbFileName,
|
||
dbRootHwm,
|
||
partNumHwm,
|
||
segNumHwm );
|
||
|
||
if (rc != NO_ERROR)
|
||
{
|
||
WErrorCodes ec;
|
||
std::ostringstream oss;
|
||
oss << "Error constructing column filename to end changes" <<
|
||
"; columnOID-" << columnOID <<
|
||
"; dbRoot-" << dbRootHwm <<
|
||
"; partNum-" << partNumHwm <<
|
||
"; segNum-" << segNumHwm <<
|
||
"; " << ec.errorString(rc);
|
||
|
||
throw WeException( oss.str(), rc );
|
||
}
|
||
|
||
// Confirm the changes to the DB file name
|
||
std::string errMsg;
|
||
rc = endDbFileChange( std::string("tmp"),
|
||
dbFileName,
|
||
success,
|
||
errMsg );
|
||
|
||
if (rc != NO_ERROR)
|
||
{
|
||
throw WeException( errMsg, rc );
|
||
}
|
||
}
|
||
|
||
//------------------------------------------------------------------------------
|
||
// End the changes to the hwm dctnry store DB file described in the bulk
|
||
// rollback meta data file record stored in inBuf. Delete the temp file.
|
||
//------------------------------------------------------------------------------
|
||
void ConfirmHdfsDbFile::endDctnryStoreDbFile(
|
||
const char* inBuf,
|
||
bool success) const
|
||
{
|
||
char recType[100];
|
||
OID dColumnOID;
|
||
OID dStoreOID;
|
||
uint32_t dbRootHwm;
|
||
uint32_t partNumHwm;
|
||
uint32_t segNumHwm;
|
||
HWM localHwm;
|
||
int compressionType = 0; // optional parameter
|
||
|
||
// Read meta-data record
|
||
int numFields = sscanf(inBuf, "%s %u %u %u %u %u %u %d",
|
||
recType, &dColumnOID, &dStoreOID,
|
||
&dbRootHwm, &partNumHwm, &segNumHwm, &localHwm, &compressionType );
|
||
|
||
if (numFields < 7) // compressionType optional
|
||
{
|
||
std::ostringstream oss;
|
||
oss << "Invalid DSTOR1 record in meta-data file " <<
|
||
fMetaFileName << "; record-<" << inBuf << ">";
|
||
|
||
throw WeException( oss.str(), ERR_INVALID_PARAM );
|
||
}
|
||
|
||
// Construct the DB file name
|
||
char dbFileName[FILE_NAME_SIZE];
|
||
FileOp dbFile(false);
|
||
int rc = dbFile.getFileName( dStoreOID,
|
||
dbFileName,
|
||
dbRootHwm,
|
||
partNumHwm,
|
||
segNumHwm );
|
||
|
||
if (rc != NO_ERROR)
|
||
{
|
||
WErrorCodes ec;
|
||
std::ostringstream oss;
|
||
oss << "Error constructing dictionary store filename to end changes" <<
|
||
"; columnOID-" << dStoreOID <<
|
||
"; dbRoot-" << dbRootHwm <<
|
||
"; partNum-" << partNumHwm <<
|
||
"; segNum-" << segNumHwm <<
|
||
"; " << ec.errorString(rc);
|
||
|
||
throw WeException( oss.str(), rc );
|
||
}
|
||
|
||
// Confirm the changes to the DB file name
|
||
std::string errMsg;
|
||
rc = endDbFileChange( std::string("tmp"),
|
||
dbFileName,
|
||
success,
|
||
errMsg );
|
||
|
||
if (rc != NO_ERROR)
|
||
{
|
||
throw WeException( errMsg, rc );
|
||
}
|
||
}
|
||
|
||
//------------------------------------------------------------------------------
|
||
// Open and read the bulk rollback metadata file for the specified table OID
|
||
// and DBRoot. The contents of the metadata file is returned in the meta-
|
||
// DataStream argument.
|
||
//------------------------------------------------------------------------------
|
||
void ConfirmHdfsDbFile::openMetaDataFile(OID tableOID,
|
||
uint16_t dbRoot,
|
||
std::istringstream& metaDataStream)
|
||
{
|
||
std::string bulkRollbackPath( Config::getDBRootByNum( dbRoot ) );
|
||
|
||
// Construct file name and check for it's existence
|
||
std::ostringstream ossFileName;
|
||
ossFileName << '/' << DBROOT_BULK_ROLLBACK_SUBDIR << '/' << tableOID;
|
||
fMetaFileName = bulkRollbackPath;
|
||
fMetaFileName += ossFileName.str();
|
||
|
||
// Return if the meta-data file does not exist.
|
||
if ( !fFs.exists( fMetaFileName.c_str() ) )
|
||
{
|
||
std::ostringstream oss;
|
||
oss << "Bulk rollback meta-data file " <<
|
||
fMetaFileName << " does not exist.";
|
||
|
||
throw WeException( oss.str(), ERR_FILE_NOT_EXIST );
|
||
}
|
||
|
||
// Open the file
|
||
boost::scoped_ptr<IDBDataFile> metaFile;
|
||
errno = 0;
|
||
metaFile.reset(idbdatafile::IDBDataFile::open(
|
||
idbdatafile::IDBPolicy::getType(fMetaFileName.c_str(),
|
||
idbdatafile::IDBPolicy::WRITEENG),
|
||
fMetaFileName.c_str(), "rb", 0) );
|
||
|
||
if ( !metaFile )
|
||
{
|
||
int errRc = errno;
|
||
std::ostringstream oss;
|
||
oss << "Error opening bulk rollback meta-data file " <<
|
||
fMetaFileName << "; err-" <<
|
||
errRc << "; " << strerror( errRc );
|
||
|
||
throw WeException( oss.str(), ERR_FILE_OPEN );
|
||
}
|
||
|
||
// First record in the file must be a Version record.
|
||
char inBuf[ BUF_SIZE ];
|
||
ssize_t metaFileSize = fFs.size( fMetaFileName.c_str() );
|
||
boost::scoped_array<char> buf( new char[ metaFileSize ] );
|
||
// retry 10 times for partial reads, just in case
|
||
ssize_t readSofar = 0; // bytes read so far
|
||
ssize_t bytes = 0; // bytes read by one pread
|
||
char* p = buf.get();
|
||
|
||
for (int i = 0; i < 10 && readSofar < metaFileSize; i++)
|
||
{
|
||
errno = 0;
|
||
bytes = metaFile->pread( p + readSofar,
|
||
readSofar,
|
||
metaFileSize - readSofar);
|
||
|
||
if (bytes < 0)
|
||
break;
|
||
|
||
readSofar += bytes;
|
||
}
|
||
|
||
if ( readSofar != metaFileSize )
|
||
{
|
||
int errRc = errno;
|
||
std::ostringstream oss;
|
||
oss << "Error reading bulk rollback meta-data file "
|
||
<< fMetaFileName << "; read/expect:" << readSofar << "/"
|
||
<< metaFileSize
|
||
<< "; err-" << errRc << "; " << strerror( errRc );
|
||
|
||
throw WeException( oss.str(), ERR_FILE_READ );
|
||
}
|
||
|
||
// put the data in a string stream
|
||
metaDataStream.str( std::string( p, metaFileSize ) );
|
||
buf.reset();
|
||
|
||
// read data
|
||
metaDataStream.getline( inBuf, BUF_SIZE );
|
||
|
||
if (!RBMetaWriter::verifyVersion4(inBuf))
|
||
{
|
||
std::ostringstream oss;
|
||
oss << "Invalid version record in meta-data file " << fMetaFileName
|
||
<< "; record-<" << inBuf << ">";
|
||
|
||
throw WeException( oss.str(), ERR_INVALID_PARAM );
|
||
}
|
||
}
|
||
|
||
} // end of namespace
|