You've already forked mariadb-columnstore-engine
							
							
				mirror of
				https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
				synced 2025-11-03 17:13:17 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			761 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			761 lines
		
	
	
		
			22 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);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
}  // namespace WriteEngine
 |