1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-07-30 19:23:07 +03:00

MCOL-4328 MCS avoids chown() calls for files that are on S3

MCS now chowns created directories hierarchy not only files and
immediate parent directories

Minor changes to cpimport's help printout

cpimport's -f option is now mandatory with mode 2
This commit is contained in:
Roman Nozdrin
2020-10-08 13:21:22 +00:00
parent d85fc579ba
commit 6f120d2637
9 changed files with 97 additions and 84 deletions

View File

@ -134,6 +134,19 @@ public:
return true; return true;
} }
/**
* chown() changes the owner of the object on the FS
* Returns 0 on success. -1 on error.
*/
virtual int chown(const char* objectName,
const uid_t p_uid,
const gid_t p_pid,
int& funcErrno) const
{
return 0;
}
protected: protected:
IDBFileSystem( Types type ); IDBFileSystem( Types type );

View File

@ -306,4 +306,16 @@ int PosixFileSystem::copyFile(const char* srcPath, const char* destPath) const
return ret; return ret;
} }
int PosixFileSystem::chown(const char* objectName,
const uid_t p_uid,
const gid_t p_gid,
int& funcErrno) const
{
int ret = 0;
errno = 0;
if ((ret = ::chown(objectName, p_uid, p_gid)))
funcErrno = errno;
return ret;
}
} }

View File

@ -27,17 +27,21 @@ class PosixFileSystem : public IDBFileSystem
{ {
public: public:
PosixFileSystem(); PosixFileSystem();
/* virtual */ ~PosixFileSystem(); ~PosixFileSystem();
/* virtual */ int mkdir(const char* pathname); int mkdir(const char* pathname) override;
/* virtual */ off64_t size(const char* path) const; off64_t size(const char* path) const override;
/* virtual */ off64_t compressedSize(const char* path) const; off64_t compressedSize(const char* path) const override;
/* virtual */ int remove(const char* pathname); int remove(const char* pathname) override;
/* virtual */ int rename(const char* oldpath, const char* newpath); int rename(const char* oldpath, const char* newpath) override;
/* virtual */ bool exists(const char* pathname) const; bool exists(const char* pathname) const override;
/* virtual */ int listDirectory(const char* pathname, std::list<std::string>& contents) const; int listDirectory(const char* pathname, std::list<std::string>& contents) const override;
/* virtual */ bool isDir(const char* pathname) const; bool isDir(const char* pathname) const override;
/* virtual */ int copyFile(const char* srcPath, const char* destPath) const; int copyFile(const char* srcPath, const char* destPath) const override;
int chown(const char* objectName,
const uid_t p_uid,
const gid_t p_pid,
int& funcErrno) const override;
}; };
} }

View File

@ -219,8 +219,7 @@ int Dctnry::createDctnry( const OID& dctnryOID, int colWidth,
{ {
// We presume the path will contain / // We presume the path will contain /
std::string filePath(fileName); std::string filePath(fileName);
std::ostringstream ossChown; if (chownDataPath(filePath))
if (chownDataFileDir(ossChown, filePath))
{ {
return ERR_FILE_CHOWN; return ERR_FILE_CHOWN;
} }

View File

@ -791,8 +791,7 @@ int FileOp::extendFile(
{ {
// We presume the path will contain / // We presume the path will contain /
std::string filePath(fileName); std::string filePath(fileName);
std::ostringstream ossChown; if (chownDataPath(filePath))
if (chownDataFileDir(ossChown, filePath))
return ERR_FILE_CHOWN; return ERR_FILE_CHOWN;
} }
@ -2365,57 +2364,27 @@ int FileOp::oid2FileName( FID fid,
return ERR_FILE_NOT_EXIST; return ERR_FILE_NOT_EXIST;
} }
/*
char dirName[FILE_NAME_SIZE];
sprintf( dirName, "%s/%s", Config::getDBRootByNum(dbRoot).c_str(),
dbDir[0] );
if( !isDir( dirName ) )
RETURN_ON_ERROR( createDir( dirName ));
sprintf( dirName, "%s/%s", dirName, dbDir[1] );
if( !isDir( dirName ) )
RETURN_ON_ERROR( createDir( dirName ));
sprintf( dirName, "%s/%s", dirName, dbDir[2] );
if( !isDir( dirName ) )
RETURN_ON_ERROR( createDir( dirName ));
sprintf( dirName, "%s/%s", dirName, dbDir[3] );
if( !isDir( dirName ) )
RETURN_ON_ERROR( createDir( dirName ));
sprintf( dirName, "%s/%s", dirName, dbDir[4] );
if( !isDir( dirName ) )
RETURN_ON_ERROR( createDir( dirName ));
*/
std::stringstream aDirName; std::stringstream aDirName;
for (size_t i = 0; i < MaxDirLevels; i++)
{
if (i == 0)
{
aDirName << Config::getDBRootByNum(dbRoot).c_str()
<< "/" << dbDir[i];
}
else
{
aDirName << "/" << dbDir[i];
}
if (!isDir(aDirName.str().c_str()))
RETURN_ON_ERROR( createDir(aDirName.str().c_str()) );
aDirName << Config::getDBRootByNum(dbRoot).c_str() << "/" << dbDir[0]; {
std::ostringstream ossChown;
if (!isDir((aDirName.str()).c_str())) if (chownDataPath(aDirName.str()))
RETURN_ON_ERROR( createDir((aDirName.str()).c_str()) ); return ERR_FILE_CHOWN;
}
aDirName << "/" << dbDir[1]; }
if (!isDir(aDirName.str().c_str()))
RETURN_ON_ERROR( createDir(aDirName.str().c_str()) );
aDirName << "/" << dbDir[2];
if (!isDir(aDirName.str().c_str()))
RETURN_ON_ERROR( createDir(aDirName.str().c_str()) );
aDirName << "/" << dbDir[3];
if (!isDir(aDirName.str().c_str()))
RETURN_ON_ERROR( createDir(aDirName.str().c_str()) );
aDirName << "/" << dbDir[4];
if (!isDir(aDirName.str().c_str()))
RETURN_ON_ERROR( createDir(aDirName.str().c_str()) );
return NO_ERROR; return NO_ERROR;
} }
@ -2932,11 +2901,13 @@ void FileOp::setFixFlag(bool isFix)
m_isFix = isFix; m_isFix = isFix;
} }
bool FileOp::chownDataFileDir(std::ostringstream& error, // Small note. We call chownFileDir in couple places to chown of the
const std::string& fileName) // target file and call in oid2Filename() chowns directories created
bool FileOp::chownDataPath(const std::string& fileName) const
{ {
std::string dirName = fileName.substr(0, fileName.find_last_of('/')); std::ostringstream error;
if (chownFileDir(error, fileName, dirName)) idbdatafile::IDBFileSystem& fs = IDBPolicy::getFs(fileName);
if (chownPath(error, fileName, fs))
{ {
logging::Message::Args args; logging::Message::Args args;
logging::Message message(1); logging::Message message(1);

View File

@ -58,6 +58,8 @@
namespace WriteEngine namespace WriteEngine
{ {
constexpr size_t MaxDirLevels = 5;
/** Class FileOp */ /** Class FileOp */
class FileOp : public BlockOp, public WeUIDGID class FileOp : public BlockOp, public WeUIDGID
{ {
@ -503,8 +505,7 @@ public:
bool bOptExtension=false ); bool bOptExtension=false );
// Calls a chown and logs an error message // Calls a chown and logs an error message
bool chownDataFileDir(std::ostringstream& error, bool chownDataPath(const std::string& fileName) const;
const std::string& fileName);
protected: protected:
EXPORT virtual int updateColumnExtent(IDBDataFile* pFile, int nBlocks); EXPORT virtual int updateColumnExtent(IDBDataFile* pFile, int nBlocks);

View File

@ -454,8 +454,12 @@ std::string RBMetaWriter::openMetaFile ( uint16_t dbRoot )
{ {
std::ostringstream ossChown; std::ostringstream ossChown;
if (chownFileDir(ossChown, tmpMetaFileName, bulkRollbackPath)) idbdatafile::IDBFileSystem& fs = IDBPolicy::getFs(tmpMetaFileName.c_str());
if (chownPath(ossChown, tmpMetaFileName, fs)
|| chownPath(ossChown, bulkRollbackPath, fs))
{
throw WeException(ossChown.str(), ERR_FILE_CHOWN); throw WeException(ossChown.str(), ERR_FILE_CHOWN);
}
} }
fMetaDataStream << fMetaDataStream <<
@ -1336,8 +1340,12 @@ int RBMetaWriter::writeHWMChunk(
{ {
std::ostringstream ossChown; std::ostringstream ossChown;
if (chownFileDir(ossChown, fileName, dirPath)) idbdatafile::IDBFileSystem& fs = IDBPolicy::getFs(fileName.c_str());
if (chownPath(ossChown, fileName, fs)
|| chownPath(ossChown, dirPath, fs))
{
throw WeException(ossChown.str(), ERR_FILE_CHOWN); throw WeException(ossChown.str(), ERR_FILE_CHOWN);
}
} }
return NO_ERROR; return NO_ERROR;

View File

@ -32,6 +32,8 @@
#include <sys/types.h> #include <sys/types.h>
#include <pwd.h> #include <pwd.h>
#include <sstream> #include <sstream>
#include "IDBFileSystem.h"
/** Namespace WriteEngine */ /** Namespace WriteEngine */
namespace WriteEngine namespace WriteEngine
@ -67,8 +69,9 @@ public:
virtual ~WeUIDGID() {}; virtual ~WeUIDGID() {};
virtual void setUIDGID(const uid_t uid, const gid_t gid); virtual void setUIDGID(const uid_t uid, const gid_t gid);
void setUIDGID(const WeUIDGID* id); void setUIDGID(const WeUIDGID* id);
bool chownFileDir(std::ostringstream& error, bool chownPath(std::ostringstream& error,
const std::string& fileName, const std::string& dirName) const; const std::string& fileName,
const idbdatafile::IDBFileSystem& fs) const;
; ;
private: private:
@ -87,18 +90,18 @@ inline void WeUIDGID::setUIDGID(const WeUIDGID* id)
*this = *id; *this = *id;
} }
inline bool WeUIDGID::chownFileDir(std::ostringstream& error, inline bool WeUIDGID::chownPath(std::ostringstream& error,
const std::string& fileName, const std::string& dirName) const const std::string& fileName,
const idbdatafile::IDBFileSystem& fs) const
{ {
if (uid != UID_NONE) if (uid != UID_NONE)
{ {
errno = 0; int funcErrno = 0;
if (chown(fileName.c_str(), uid, gid) == -1 || if (fs.chown(fileName.c_str(), uid, gid, funcErrno) == -1)
chown(dirName.c_str(), uid, gid) == -1)
{ {
error << "Error calling chown() with uid " << uid error << "Error calling chown() with uid " << uid
<< " and gid " << gid << " with the file " << " and gid " << gid << " with the file "
<< fileName << " with errno " << errno; << fileName << " with errno " << funcErrno;
return true; return true;
} }
} }

View File

@ -505,7 +505,7 @@ void WECmdArgs::usage()
cout << "\t\t [-r readers] [-j JobID] [-e maxErrs] [-B libBufSize] [-w parsers]\n"; cout << "\t\t [-r readers] [-j JobID] [-e maxErrs] [-B libBufSize] [-w parsers]\n";
cout << "\t\t [-s c] [-E enclosedChar] [-C escapeChar] [-n NullOption]\n"; cout << "\t\t [-s c] [-E enclosedChar] [-C escapeChar] [-n NullOption]\n";
cout << "\t\t [-q batchQty] [-p jobPath] [-P list of PMs] [-S] [-i] [-v verbose]\n"; cout << "\t\t [-q batchQty] [-p jobPath] [-P list of PMs] [-S] [-i] [-v verbose]\n";
cout << "\t\t [-I binaryOpt] [-T timeZone] [-U username]\n"; cout << "\t\t [-I binaryOpt] [-T timeZone]\n";
cout << "Traditional usage without positional parameters (XML job file required):\n"; cout << "Traditional usage without positional parameters (XML job file required):\n";
@ -514,7 +514,7 @@ void WECmdArgs::usage()
cout << "\t\t [-b readBufs] [-p path] [-c readBufSize] [-e maxErrs] [-B libBufSize]\n"; cout << "\t\t [-b readBufs] [-p path] [-c readBufSize] [-e maxErrs] [-B libBufSize]\n";
cout << "\t\t [-n NullOption] [-E encloseChar] [-C escapeChar] [-i] [-v verbose]\n"; cout << "\t\t [-n NullOption] [-E encloseChar] [-C escapeChar] [-i] [-v verbose]\n";
cout << "\t\t [-d debugLevel] [-q batchQty] [-l loadFile] [-P list of PMs] [-S]\n"; cout << "\t\t [-d debugLevel] [-q batchQty] [-l loadFile] [-P list of PMs] [-S]\n";
cout << "\t\t [-I binaryOpt] [-T timeZone] [-U username]\n"; cout << "\t\t [-I binaryOpt] [-T timeZone]\n";
cout << "\n\nPositional parameters:\n"; cout << "\n\nPositional parameters:\n";
cout << "\tdbName Name of the database to load\n"; cout << "\tdbName Name of the database to load\n";
@ -566,8 +566,7 @@ void WECmdArgs::usage()
<< "\t-K\tS3 Authentication Secret (for S3 imports)\n" << "\t-K\tS3 Authentication Secret (for S3 imports)\n"
<< "\t-t\tS3 Bucket (for S3 imports)\n" << "\t-t\tS3 Bucket (for S3 imports)\n"
<< "\t-H\tS3 Hostname (for S3 imports, Amazon's S3 default)\n" << "\t-H\tS3 Hostname (for S3 imports, Amazon's S3 default)\n"
<< "\t-g\tS3 Region (for S3 imports)\n" << "\t-g\tS3 Region (for S3 imports)\n";
<< "\t-U\tusername of the data files owner. Default is mysql\n";
cout << "\nExample1: Traditional usage\n" cout << "\nExample1: Traditional usage\n"
<< "\tcpimport -j 1234"; << "\tcpimport -j 1234";
@ -580,7 +579,7 @@ void WECmdArgs::usage()
cout << "\nExample4: Import a nation table to only PM1 and PM2 in Mode 1\n" cout << "\nExample4: Import a nation table to only PM1 and PM2 in Mode 1\n"
<< "\tcpimport -m 1 -P 1,2 tpch nation nation.tbl"; << "\tcpimport -m 1 -P 1,2 tpch nation nation.tbl";
cout << "\nExample5: Import nation.tbl from PMs to nation table in Mode 2\n" cout << "\nExample5: Import nation.tbl from PMs to nation table in Mode 2\n"
<< "\tcpimport -m 2 tpch nation -l nation.tbl"; << "\tcpimport -m 2 tpch nation -f /var/lib/columnstore/data/bulk/data/import/ -l nation.tbl";
cout << "\nExample6: Import nation.tbl in mode 3\n" cout << "\nExample6: Import nation.tbl in mode 3\n"
<< "\tcpimport -m 3 tpch nation nation.tbl\n\n"; << "\tcpimport -m 3 tpch nation nation.tbl\n\n";
@ -959,6 +958,9 @@ void WECmdArgs::parseCmdLineArgs(int argc, char** argv)
checkForBulkLogDir(bulkRootPath); checkForBulkLogDir(bulkRootPath);
if (2 == fArgMode && fPmFilePath.empty())
throw runtime_error("-f option is mandatory with mode 2.");
if (aJobType) if (aJobType)
{ {
if (0 == fArgMode) throw runtime_error("Incompatible mode and option types"); if (0 == fArgMode) throw runtime_error("Incompatible mode and option types");