diff --git a/catalogue/Catalogue.hpp b/catalogue/Catalogue.hpp index 9a54c7be5347041aeb6fbd23e5e477205264154d..04de8f7e67e82ad1c70a7f108c1d1ed005248b51 100644 --- a/catalogue/Catalogue.hpp +++ b/catalogue/Catalogue.hpp @@ -1024,12 +1024,13 @@ public: const std::string &diskFileId) = 0; /** - * Insert the tape files and ArchiveFiles entries in the recycle-bin and delete - * them from the TAPE_FILE and ARCHIVE_FILE tables + * Insert the ArchiveFile and all its tape files in the FILE_RECYCLE_LOG table. + * There will be one entry on the FILE_RECYCLE_LOG table per deleted tape file + * * @param request the DeleteRequest object that holds information about the file to delete. * @param lc the logContext */ - virtual void moveArchiveFileToRecycleBin(const common::dataStructures::DeleteArchiveRequest &request, + virtual void moveArchiveFileToRecycleLog(const common::dataStructures::DeleteArchiveRequest &request, log::LogContext & lc) = 0; /** diff --git a/catalogue/CatalogueRetryWrapper.hpp b/catalogue/CatalogueRetryWrapper.hpp index 9d1502e9f2cf2b91a81d64f7654ad286a52ea203..3bef9b3b82a6efb5c5aa411f36e05f60faacd7cd 100644 --- a/catalogue/CatalogueRetryWrapper.hpp +++ b/catalogue/CatalogueRetryWrapper.hpp @@ -598,9 +598,9 @@ public: return retryOnLostConnection(m_log, [&]{return m_catalogue->updateDiskFileId(archiveFileId, diskInstance, diskFileId);}, m_maxTriesToConnect); } - void moveArchiveFileToRecycleBin(const common::dataStructures::DeleteArchiveRequest &request, + void moveArchiveFileToRecycleLog(const common::dataStructures::DeleteArchiveRequest &request, log::LogContext & lc) override { - return retryOnLostConnection(m_log,[&]{return m_catalogue->moveArchiveFileToRecycleBin(request,lc);},m_maxTriesToConnect); + return retryOnLostConnection(m_log,[&]{return m_catalogue->moveArchiveFileToRecycleLog(request,lc);},m_maxTriesToConnect); } protected: diff --git a/catalogue/CatalogueTest.cpp b/catalogue/CatalogueTest.cpp index 1f9d9ba56178ac9ec3435b3df0bdc86f1fac8627..221e6c87395d93496c9efa873c2f21cbbb593bc1 100644 --- a/catalogue/CatalogueTest.cpp +++ b/catalogue/CatalogueTest.cpp @@ -9168,6 +9168,8 @@ TEST_P(cta_catalogue_CatalogueTest, prepareToRetrieveFileUsingArchiveFileId_retu file2Written.copyNb = 1; file2Written.tapeDrive = tapeDrive; m_catalogue->filesWrittenToTape(file2WrittenSet); + + ASSERT_TRUE(m_catalogue->getFileRecycleLogItor().hasMore()); const std::string mountPolicyName = "mount_policy"; const uint64_t archivePriority = 1; @@ -15721,13 +15723,14 @@ TEST_P(cta_catalogue_CatalogueTest, moveFilesToRecycleBin) { req.diskFileId = tapeItem->diskFileId; req.diskFilePath = tapeItem->diskFilePath; req.diskInstance = tapeItem->diskInstance; - ASSERT_NO_THROW(m_catalogue->moveArchiveFileToRecycleBin(req,dummyLc)); + req.archiveFile = m_catalogue->getArchiveFileById(tapeItem->archiveFileId); + ASSERT_NO_THROW(m_catalogue->moveArchiveFileToRecycleLog(req,dummyLc)); } ASSERT_FALSE(m_catalogue->getArchiveFilesItor().hasMore()); - std::vector<common::dataStructures::DeletedArchiveFile> deletedArchiveFiles; + std::vector<common::dataStructures::FileRecycleLog> deletedArchiveFiles; { - auto itor = m_catalogue->getDeletedArchiveFilesItor(); + auto itor = m_catalogue->getFileRecycleLogItor(); while(itor.hasMore()){ deletedArchiveFiles.push_back(itor.next()); } @@ -15747,40 +15750,36 @@ TEST_P(cta_catalogue_CatalogueTest, moveFilesToRecycleBin) { std::ostringstream diskFilePath; diskFilePath << "/test/file"<<i; - ASSERT_EQ(i,deletedArchiveFile.archiveFileID); - ASSERT_EQ(diskInstance,deletedArchiveFile.diskInstance); + ASSERT_EQ(i,deletedArchiveFile.archiveFileId); + ASSERT_EQ(diskInstance,deletedArchiveFile.diskInstanceName); ASSERT_EQ(diskFileId.str(),deletedArchiveFile.diskFileId); ASSERT_EQ(diskFilePath.str(),deletedArchiveFile.diskFilePath); - ASSERT_EQ(PUBLIC_DISK_USER,deletedArchiveFile.diskFileInfo.owner_uid); - ASSERT_EQ(PUBLIC_DISK_GROUP,deletedArchiveFile.diskFileInfo.gid); - ASSERT_EQ(archiveFileSize,deletedArchiveFile.fileSize); + ASSERT_EQ(PUBLIC_DISK_USER,deletedArchiveFile.diskFileUid); + ASSERT_EQ(PUBLIC_DISK_GROUP,deletedArchiveFile.diskFileGid); + ASSERT_EQ(archiveFileSize,deletedArchiveFile.sizeInBytes); ASSERT_EQ(cta::checksum::ChecksumBlob(checksum::ADLER32, "1357"),deletedArchiveFile.checksumBlob); - ASSERT_EQ(m_storageClassSingleCopy.name, deletedArchiveFile.storageClass); + ASSERT_EQ(m_storageClassSingleCopy.name, deletedArchiveFile.storageClassName); ASSERT_EQ(diskFileId.str(),deletedArchiveFile.diskFileIdWhenDeleted); - auto tapeFile = deletedArchiveFile.tapeFiles.at(1); - ASSERT_EQ(tape1.vid, tapeFile.vid); - ASSERT_EQ(i,tapeFile.fSeq); - ASSERT_EQ(i * 100,tapeFile.blockId); - ASSERT_EQ(1, tapeFile.copyNb); - ASSERT_EQ(archiveFileSize,tapeFile.fileSize); + ASSERT_EQ(tape1.vid, deletedArchiveFile.vid); + ASSERT_EQ(i,deletedArchiveFile.fSeq); + ASSERT_EQ(i * 100,deletedArchiveFile.blockId); + ASSERT_EQ(1, deletedArchiveFile.copyNb); + ASSERT_EQ(archiveFileSize,deletedArchiveFile.logicalSizeInBytes); } //Let's try the deletion of the files from the recycle-bin. for(uint64_t i = 1; i <= nbArchiveFiles; i++) { - m_catalogue->deleteFileFromRecycleBin(i,dummyLc); + m_catalogue->deleteFilesFromRecycleLog(tape1.vid,dummyLc); } { - auto itor = m_catalogue->getDeletedArchiveFilesItor(); + auto itor = m_catalogue->getFileRecycleLogItor(); ASSERT_FALSE(itor.hasMore()); } - //Delete an archive file from the recycle-bin should be idempotent - ASSERT_NO_THROW(m_catalogue->deleteFileFromRecycleBin(12532,dummyLc)); - } -TEST_P(cta_catalogue_CatalogueTest, reclaimTapeRemovesFilesFromRecycleBin) { +TEST_P(cta_catalogue_CatalogueTest, reclaimTapeRemovesFilesFromRecycleLog) { using namespace cta; const bool logicalLibraryIsDisabled= false; @@ -15851,27 +15850,27 @@ TEST_P(cta_catalogue_CatalogueTest, reclaimTapeRemovesFilesFromRecycleBin) { req.diskFileId = tapeItem->diskFileId; req.diskFilePath = tapeItem->diskFilePath; req.diskInstance = tapeItem->diskInstance; - ASSERT_NO_THROW(m_catalogue->moveArchiveFileToRecycleBin(req,dummyLc)); + req.archiveFile = m_catalogue->getArchiveFileById(tapeItem->archiveFileId); + ASSERT_NO_THROW(m_catalogue->moveArchiveFileToRecycleLog(req,dummyLc)); } ASSERT_FALSE(m_catalogue->getArchiveFilesItor().hasMore()); - - std::vector<common::dataStructures::DeletedArchiveFile> deletedArchiveFiles; + std::vector<common::dataStructures::FileRecycleLog> deletedArchiveFiles; { - auto itor = m_catalogue->getDeletedArchiveFilesItor(); + auto itor = m_catalogue->getFileRecycleLogItor(); while(itor.hasMore()){ deletedArchiveFiles.push_back(itor.next()); } } - //And test that these files are there. - //Run the unit test for all the databases + //And test that these files are in the recycle log ASSERT_EQ(nbArchiveFiles,deletedArchiveFiles.size()); + ASSERT_TRUE(m_catalogue->getFileRecycleLogItor().hasMore()); //Reclaim the tape m_catalogue->setTapeFull(m_admin, tape1.vid, true); m_catalogue->reclaimTape(m_admin, tape1.vid, dummyLc); { - auto itor = m_catalogue->getDeletedArchiveFilesItor(); + auto itor = m_catalogue->getFileRecycleLogItor(); ASSERT_FALSE(itor.hasMore()); } } diff --git a/catalogue/DummyCatalogue.hpp b/catalogue/DummyCatalogue.hpp index ee988e747bb80a92dfa1776c781ed642768c592a..8d650dd01217c0a52c247686ff00d1b73c71ee4c 100644 --- a/catalogue/DummyCatalogue.hpp +++ b/catalogue/DummyCatalogue.hpp @@ -164,7 +164,7 @@ public: void tapeMountedForRetrieve(const std::string& vid, const std::string& drive) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } bool tapePoolExists(const std::string& tapePoolName) const { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } void updateDiskFileId(uint64_t archiveFileId, const std::string &diskInstance, const std::string &diskFileId) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } - void moveArchiveFileToRecycleBin(const common::dataStructures::DeleteArchiveRequest &request, + void moveArchiveFileToRecycleLog(const common::dataStructures::DeleteArchiveRequest &request, log::LogContext & lc) override {throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented");} // Special functions for unit tests. void addEnabledTape(const std::string & vid) { diff --git a/catalogue/InsertFileRecycleLog.hpp b/catalogue/InsertFileRecycleLog.hpp index f7cc50d4fcaba08423bbf357f5b975d4d2ebaf15..51d3f5bc87696118087ba5ee70231694b18d46ee 100644 --- a/catalogue/InsertFileRecycleLog.hpp +++ b/catalogue/InsertFileRecycleLog.hpp @@ -28,19 +28,23 @@ namespace cta { namespace catalogue { class InsertFileRecycleLog { public: std::string vid; - uint64_t fseq; + uint64_t fSeq; uint64_t blockId; uint64_t logicalSizeInBytes; uint8_t copyNb; time_t tapeFileCreationTime; uint64_t archiveFileId; - std::string diskFilePath; + cta::optional<std::string> diskFilePath; std::string reasonLog; time_t recycleLogTime; static std::string getRepackReasonLog(){ return "REPACK"; } + + static std::string getDeletionReasonLog(const std::string & deleterName, const std::string & diskInstanceName){ + return "File deleted by " + deleterName + "from the " + diskInstanceName + "instance"; + } }; }} diff --git a/catalogue/MysqlCatalogue.cpp b/catalogue/MysqlCatalogue.cpp index 00721767bdb92b2eb405754bd5b9898a59c63221..c5bc490ed498ef84cbb79a1b1b6960b94d9fa1c4 100644 --- a/catalogue/MysqlCatalogue.cpp +++ b/catalogue/MysqlCatalogue.cpp @@ -729,14 +729,14 @@ void MysqlCatalogue::DO_NOT_USE_deleteArchiveFile_DO_NOT_USE(const std::string & //------------------------------------------------------------------------------ // copyArchiveFileToRecycleBinAndDelete //------------------------------------------------------------------------------ -void MysqlCatalogue::copyArchiveFileToRecycleBinAndDelete(rdbms::Conn & conn, const common::dataStructures::DeleteArchiveRequest &request, log::LogContext & lc){ +void MysqlCatalogue::copyArchiveFileToFileRecyleLogAndDelete(rdbms::Conn & conn, const common::dataStructures::DeleteArchiveRequest &request, log::LogContext & lc){ try { utils::Timer t; log::TimingList tl; //We currently do an INSERT INTO and a DELETE FROM //in a single transaction conn.executeNonQuery("START TRANSACTION"); - copyArchiveFileToRecycleBin(conn,request); + copyArchiveFileToFileRecycleLog(conn,request); tl.insertAndReset("insertToRecycleBinTime",t); setTapeDirty(conn,request.archiveFileID); tl.insertAndReset("setTapeDirtyTime",t); diff --git a/catalogue/MysqlCatalogue.hpp b/catalogue/MysqlCatalogue.hpp index 15fc098b23cbfd62eea0155f04946184f4fc3c16..955b4272051b53b0d7500f0810f0cff032bb3cd9 100644 --- a/catalogue/MysqlCatalogue.hpp +++ b/catalogue/MysqlCatalogue.hpp @@ -194,13 +194,13 @@ protected: log::LogContext &lc) override; /** - * Copy the archiveFile and the associated tape files from the ARCHIVE_FILE and TAPE_FILE tables to the recycle-bin tables + * Copy the archiveFile and the associated tape files from the ARCHIVE_FILE and TAPE_FILE tables to the FILE_RECYCLE_LOG table * and deletes the ARCHIVE_FILE and TAPE_FILE entries. * @param conn the database connection - * @param request the request that contains the necessary informations to identify the archiveFile to copy to the recycle-bin + * @param request the request that contains the necessary informations to identify the archiveFile to copy to the FILE_RECYCLE_LOG table * @param lc the log context */ - void copyArchiveFileToRecycleBinAndDelete(rdbms::Conn & conn,const common::dataStructures::DeleteArchiveRequest &request, log::LogContext & lc) override; + void copyArchiveFileToFileRecyleLogAndDelete(rdbms::Conn & conn,const common::dataStructures::DeleteArchiveRequest &request, log::LogContext & lc) override; /** * Delete the TapeFiles and the ArchiveFile from the recycle-bin in one transaction diff --git a/catalogue/OracleCatalogue.cpp b/catalogue/OracleCatalogue.cpp index c852a188da850a15a6ec985d56482c424a41a980..4acede6852c097d23eaca5a008ba539e0cb44957 100644 --- a/catalogue/OracleCatalogue.cpp +++ b/catalogue/OracleCatalogue.cpp @@ -593,7 +593,7 @@ void OracleCatalogue::filesWrittenToTape(const std::set<TapeItemWrittenPointer> auto stmt = conn.createStmt(sql); stmt.bindString(":VID",recycledFile.vid); - stmt.bindUint64(":FSEQ",recycledFile.fseq); + stmt.bindUint64(":FSEQ",recycledFile.fSeq); stmt.executeNonQuery(); } @@ -788,7 +788,7 @@ std::list<cta::catalogue::InsertFileRecycleLog> OracleCatalogue::insertOldCopies while(rset.next()){ cta::catalogue::InsertFileRecycleLog fileRecycleLog; fileRecycleLog.vid = rset.columnString("VID"); - fileRecycleLog.fseq = rset.columnUint64("FSEQ"); + fileRecycleLog.fSeq = rset.columnUint64("FSEQ"); fileRecycleLog.blockId = rset.columnUint64("BLOCK_ID"); fileRecycleLog.logicalSizeInBytes = rset.columnUint64("LOGICAL_SIZE_IN_BYTES"); fileRecycleLog.copyNb = rset.columnUint8("COPY_NB"); @@ -801,70 +801,7 @@ std::list<cta::catalogue::InsertFileRecycleLog> OracleCatalogue::insertOldCopies } { for(auto & fileRecycleLog: fileRecycleLogsToInsert){ - const char *const sql = - "INSERT INTO FILE_RECYCLE_LOG(" - "FILE_RECYCLE_LOG_ID," - "VID," - "FSEQ," - "BLOCK_ID," - "LOGICAL_SIZE_IN_BYTES," - "COPY_NB," - "TAPE_FILE_CREATION_TIME," - "ARCHIVE_FILE_ID," - "DISK_INSTANCE_NAME," - "DISK_FILE_ID," - "DISK_FILE_ID_WHEN_DELETED," - "DISK_FILE_UID," - "DISK_FILE_GID," - "SIZE_IN_BYTES," - "CHECKSUM_BLOB," - "CHECKSUM_ADLER32," - "STORAGE_CLASS_ID," - "ARCHIVE_FILE_CREATION_TIME," - "RECONCILIATION_TIME," - "COLLOCATION_HINT," - "REASON_LOG," - "RECYCLE_LOG_TIME" - ") SELECT " - "FILE_RECYCLE_LOG_ID_SEQ.NEXTVAL," - ":VID," - ":FSEQ," - ":BLOCK_ID," - ":LOGICAL_SIZE_IN_BYTES," - ":COPY_NB," - ":TAPE_FILE_CREATION_TIME," - ":ARCHIVE_FILE_ID," - "ARCHIVE_FILE.DISK_INSTANCE_NAME AS DISK_INSTANCE_NAME," - "ARCHIVE_FILE.DISK_FILE_ID AS DISK_FILE_ID," - "ARCHIVE_FILE.DISK_FILE_ID AS DISK_FILE_ID_2," - "ARCHIVE_FILE.DISK_FILE_UID AS DISK_FILE_UID," - "ARCHIVE_FILE.DISK_FILE_GID AS DISK_FILE_GID," - "ARCHIVE_FILE.SIZE_IN_BYTES AS SIZE_IN_BYTES," - "ARCHIVE_FILE.CHECKSUM_BLOB AS CHECKSUM_BLOB," - "ARCHIVE_FILE.CHECKSUM_ADLER32 AS CHECKSUM_ADLER32," - "ARCHIVE_FILE.STORAGE_CLASS_ID AS STORAGE_CLASS_ID," - "ARCHIVE_FILE.CREATION_TIME AS ARCHIVE_FILE_CREATION_TIME," - "ARCHIVE_FILE.RECONCILIATION_TIME AS RECONCILIATION_TIME," - "ARCHIVE_FILE.COLLOCATION_HINT AS COLLOCATION_HINT," - ":REASON_LOG," - ":RECYCLE_LOG_TIME " - "FROM " - "DUAL," - "ARCHIVE_FILE " - "WHERE " - "ARCHIVE_FILE.ARCHIVE_FILE_ID = :ARCHIVE_FILE_ID_2"; - auto stmt = conn.createStmt(sql); - stmt.bindString(":VID",fileRecycleLog.vid); - stmt.bindUint64(":FSEQ",fileRecycleLog.fseq); - stmt.bindUint64(":BLOCK_ID",fileRecycleLog.blockId); - stmt.bindUint64(":LOGICAL_SIZE_IN_BYTES",fileRecycleLog.logicalSizeInBytes); - stmt.bindUint8(":COPY_NB",fileRecycleLog.copyNb); - stmt.bindUint64(":TAPE_FILE_CREATION_TIME",fileRecycleLog.tapeFileCreationTime); - stmt.bindUint64(":ARCHIVE_FILE_ID",fileRecycleLog.archiveFileId); - stmt.bindString(":REASON_LOG",fileRecycleLog.reasonLog); - stmt.bindUint64(":RECYCLE_LOG_TIME",fileRecycleLog.recycleLogTime); - stmt.bindUint64(":ARCHIVE_FILE_ID_2",fileRecycleLog.archiveFileId); - stmt.executeNonQuery(); + insertFileInFileRecycleLog(conn,fileRecycleLog); } } return fileRecycleLogsToInsert; @@ -1123,14 +1060,14 @@ void OracleCatalogue::DO_NOT_USE_deleteArchiveFile_DO_NOT_USE(const std::string //------------------------------------------------------------------------------ // copyArchiveFileToRecycleBinAndDelete //------------------------------------------------------------------------------ -void OracleCatalogue::copyArchiveFileToRecycleBinAndDelete(rdbms::Conn & conn, const common::dataStructures::DeleteArchiveRequest &request, log::LogContext & lc){ +void OracleCatalogue::copyArchiveFileToFileRecyleLogAndDelete(rdbms::Conn & conn, const common::dataStructures::DeleteArchiveRequest &request, log::LogContext & lc){ try { utils::Timer t; log::TimingList tl; //We currently do an INSERT INTO, update and two DELETE FROM //in a single transaction conn.setAutocommitMode(rdbms::AutocommitMode::AUTOCOMMIT_OFF); - copyArchiveFileToRecycleBin(conn,request); + copyArchiveFileToFileRecycleLog(conn,request); tl.insertAndReset("insertToRecycleBinTime",t); setTapeDirty(conn,request.archiveFileID); tl.insertAndReset("setTapeDirtyTime",t); diff --git a/catalogue/OracleCatalogue.hpp b/catalogue/OracleCatalogue.hpp index f51bd9a10f5dd0bedf242c46cd6f2b5aac974536..74f311dac11f9f72dcc73aa2c2cc5505efe4c9e0 100644 --- a/catalogue/OracleCatalogue.hpp +++ b/catalogue/OracleCatalogue.hpp @@ -237,13 +237,13 @@ private: std::list<cta::catalogue::InsertFileRecycleLog> insertOldCopiesOfFilesIfAnyOnFileRecycleLog(rdbms::Conn & conn); /** - * Copy the archiveFile and the associated tape files from the ARCHIVE_FILE and TAPE_FILE tables to the recycle-bin tables + * Copy the archiveFile and the associated tape files from the ARCHIVE_FILE and TAPE_FILE tables to the FILE_RECYCLE_LOG table * and deletes the ARCHIVE_FILE and TAPE_FILE entries. * @param conn the database connection - * @param request the request that contains the necessary informations to identify the archiveFile to copy to the recycle-bin + * @param request the request that contains the necessary informations to identify the archiveFile to copy to the FILE_RECYCLE_LOG table * @param lc the log context */ - void copyArchiveFileToRecycleBinAndDelete(rdbms::Conn & conn, const common::dataStructures::DeleteArchiveRequest &request, log::LogContext & lc) override; + void copyArchiveFileToFileRecyleLogAndDelete(rdbms::Conn & conn, const common::dataStructures::DeleteArchiveRequest &request, log::LogContext & lc) override; /** * Delete the TapeFiles and the ArchiveFile from the recycle-bin in one transaction diff --git a/catalogue/PostgresCatalogue.cpp b/catalogue/PostgresCatalogue.cpp index 1dfb9d9df51e8f27b4b0e6de34864dd9ff294114..00c66d5a7a237f599acd481bf4af17781206a7c1 100644 --- a/catalogue/PostgresCatalogue.cpp +++ b/catalogue/PostgresCatalogue.cpp @@ -533,7 +533,7 @@ void PostgresCatalogue::filesWrittenToTape(const std::set<TapeItemWrittenPointer "DELETE FROM TAPE_FILE WHERE TAPE_FILE.VID = :VID AND TAPE_FILE.FSEQ = :FSEQ"; auto deleteTapeFileStmt = conn.createStmt(deleteTapeFileSql); deleteTapeFileStmt.bindString(":VID",recycledFile.vid); - deleteTapeFileStmt.bindUint64(":FSEQ",recycledFile.fseq); + deleteTapeFileStmt.bindUint64(":FSEQ",recycledFile.fSeq); deleteTapeFileStmt.executeNonQuery(); } @@ -697,7 +697,7 @@ std::list<cta::catalogue::InsertFileRecycleLog> PostgresCatalogue::insertOldCopi while(rset.next()){ cta::catalogue::InsertFileRecycleLog fileRecycleLog; fileRecycleLog.vid = rset.columnString("VID"); - fileRecycleLog.fseq = rset.columnUint64("FSEQ"); + fileRecycleLog.fSeq = rset.columnUint64("FSEQ"); fileRecycleLog.blockId = rset.columnUint64("BLOCK_ID"); fileRecycleLog.logicalSizeInBytes = rset.columnUint64("LOGICAL_SIZE_IN_BYTES"); fileRecycleLog.copyNb = rset.columnUint8("COPY_NB"); @@ -710,72 +710,10 @@ std::list<cta::catalogue::InsertFileRecycleLog> PostgresCatalogue::insertOldCopi } { for(auto & fileRecycleLog: fileRecycleLogsToInsert){ - const char *const sql = - "INSERT INTO FILE_RECYCLE_LOG(" - "FILE_RECYCLE_LOG_ID," - "VID," - "FSEQ," - "BLOCK_ID," - "LOGICAL_SIZE_IN_BYTES," - "COPY_NB," - "TAPE_FILE_CREATION_TIME," - "ARCHIVE_FILE_ID," - "DISK_INSTANCE_NAME," - "DISK_FILE_ID," - "DISK_FILE_ID_WHEN_DELETED," - "DISK_FILE_UID," - "DISK_FILE_GID," - "SIZE_IN_BYTES," - "CHECKSUM_BLOB," - "CHECKSUM_ADLER32," - "STORAGE_CLASS_ID," - "ARCHIVE_FILE_CREATION_TIME," - "RECONCILIATION_TIME," - "COLLOCATION_HINT," - "REASON_LOG," - "RECYCLE_LOG_TIME" - ") SELECT " - "nextval('FILE_RECYCLE_LOG_ID_SEQ')," - ":VID," - ":FSEQ," - ":BLOCK_ID," - ":LOGICAL_SIZE_IN_BYTES," - ":COPY_NB," - ":TAPE_FILE_CREATION_TIME," - ":ARCHIVE_FILE_ID," - "ARCHIVE_FILE.DISK_INSTANCE_NAME," - "ARCHIVE_FILE.DISK_FILE_ID," - "ARCHIVE_FILE.DISK_FILE_ID," - "ARCHIVE_FILE.DISK_FILE_UID," - "ARCHIVE_FILE.DISK_FILE_GID," - "ARCHIVE_FILE.SIZE_IN_BYTES," - "ARCHIVE_FILE.CHECKSUM_BLOB," - "ARCHIVE_FILE.CHECKSUM_ADLER32," - "ARCHIVE_FILE.STORAGE_CLASS_ID," - "ARCHIVE_FILE.CREATION_TIME," - "ARCHIVE_FILE.RECONCILIATION_TIME," - "ARCHIVE_FILE.COLLOCATION_HINT," - ":REASON_LOG," - ":RECYCLE_LOG_TIME " - "FROM " - "ARCHIVE_FILE " - "WHERE " - "ARCHIVE_FILE.ARCHIVE_FILE_ID = :ARCHIVE_FILE_ID_2"; - auto stmt = conn.createStmt(sql); - stmt.bindString(":VID",fileRecycleLog.vid); - stmt.bindUint64(":FSEQ",fileRecycleLog.fseq); - stmt.bindUint64(":BLOCK_ID",fileRecycleLog.blockId); - stmt.bindUint64(":LOGICAL_SIZE_IN_BYTES",fileRecycleLog.logicalSizeInBytes); - stmt.bindUint8(":COPY_NB",fileRecycleLog.copyNb); - stmt.bindUint64(":TAPE_FILE_CREATION_TIME",fileRecycleLog.tapeFileCreationTime); - stmt.bindUint64(":ARCHIVE_FILE_ID",fileRecycleLog.archiveFileId); - stmt.bindString(":REASON_LOG",fileRecycleLog.reasonLog); - stmt.bindUint64(":RECYCLE_LOG_TIME",fileRecycleLog.recycleLogTime); - stmt.bindUint64(":ARCHIVE_FILE_ID_2",fileRecycleLog.archiveFileId); - stmt.executeNonQuery(); + insertFileInFileRecycleLog(conn,fileRecycleLog); } + return fileRecycleLogsToInsert; } - return fileRecycleLogsToInsert; } catch(exception::Exception &ex) { ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str()); throw; @@ -1080,14 +1018,14 @@ void PostgresCatalogue::beginCreateTemporarySetDeferred(rdbms::Conn &conn) const //------------------------------------------------------------------------------ // copyArchiveFileToRecycleBinAndDelete //------------------------------------------------------------------------------ -void PostgresCatalogue::copyArchiveFileToRecycleBinAndDelete(rdbms::Conn & conn, const common::dataStructures::DeleteArchiveRequest &request, log::LogContext & lc) { +void PostgresCatalogue::copyArchiveFileToFileRecyleLogAndDelete(rdbms::Conn & conn, const common::dataStructures::DeleteArchiveRequest &request, log::LogContext & lc) { try { utils::Timer t; log::TimingList tl; //We currently do an INSERT INTO and a DELETE FROM //in a single transaction conn.executeNonQuery("BEGIN"); - copyArchiveFileToRecycleBin(conn,request); + copyArchiveFileToFileRecycleLog(conn,request); tl.insertAndReset("insertToRecycleBinTime",t); setTapeDirty(conn,request.archiveFileID); tl.insertAndReset("setTapeDirtyTime",t); diff --git a/catalogue/PostgresCatalogue.hpp b/catalogue/PostgresCatalogue.hpp index 5a216a5dcad31e1d6b18a94f85713f82e84526fd..93e284b35f0b4f0df4619550e03ff431bab2efff 100644 --- a/catalogue/PostgresCatalogue.hpp +++ b/catalogue/PostgresCatalogue.hpp @@ -271,13 +271,13 @@ private: void insertTapeFileBatchIntoTempTable(rdbms::Conn &conn, const std::set<TapeFileWritten> &events) const; /** - * Copy the archiveFile and the associated tape files from the ARCHIVE_FILE and TAPE_FILE tables to the recycle-bin tables + * Copy the archiveFile and the associated tape files from the ARCHIVE_FILE and TAPE_FILE tables to the FILE_RECYCLE_LOG table * and deletes the ARCHIVE_FILE and TAPE_FILE entries. * @param conn the database connection - * @param request the request that contains the necessary informations to identify the archiveFile to copy to the recycle-bin + * @param request the request that contains the necessary informations to identify the archiveFile to copy to the FILE_RECYCLE_LOG table * @param lc the log context */ - void copyArchiveFileToRecycleBinAndDelete(rdbms::Conn & conn, const common::dataStructures::DeleteArchiveRequest &request, log::LogContext & lc) override; + void copyArchiveFileToFileRecyleLogAndDelete(rdbms::Conn & conn, const common::dataStructures::DeleteArchiveRequest &request, log::LogContext & lc) override; /** * Delete the TapeFiles and the ArchiveFile from the recycle-bin in one transaction diff --git a/catalogue/RdbmsCatalogue.cpp b/catalogue/RdbmsCatalogue.cpp index d7edf975fb1f92766abb42679d3605db8d881930..8861bdeddbb3cc76c5761d3287a14d7881f51676 100644 --- a/catalogue/RdbmsCatalogue.cpp +++ b/catalogue/RdbmsCatalogue.cpp @@ -3910,28 +3910,6 @@ std::map<std::string, std::string> &vidToLogicalLibrary) const { } } -//------------------------------------------------------------------------------ -//getNbNonSupersededFilesOnTape -//------------------------------------------------------------------------------ -uint64_t RdbmsCatalogue::getNbNonSupersededFilesOnTape(rdbms::Conn& conn, const std::string& vid) const { - try { - const char *const sql = - "SELECT COUNT(*) AS NB_NON_SUPERSEDED_FILES FROM TAPE_FILE " - "WHERE VID = :VID " - "AND SUPERSEDED_BY_VID IS NULL " - "AND SUPERSEDED_BY_FSEQ IS NULL"; - auto stmt = conn.createStmt(sql); - stmt.bindString(":VID", vid); - auto rset = stmt.executeQuery(); - rset.next(); - return rset.columnUint64("NB_NON_SUPERSEDED_FILES"); - } catch(exception::Exception &ex) { - ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str()); - throw; - } -} - - //------------------------------------------------------------------------------ // getNbFilesOnTape //------------------------------------------------------------------------------ @@ -4078,13 +4056,11 @@ void RdbmsCatalogue::reclaimTape(const common::dataStructures::SecurityIdentity } } //The tape exists and is full, we can try to reclaim it - if(getNbNonSupersededFilesOnTape(conn,vid) == 0){ - tl.insertAndReset("getNbNonSupersededFilesOnTapeTime",t); - //There is no non-superseded files on the tape, we can reclaim it : delete the files and reset the counters - deleteTapeFiles(conn,vid); - tl.insertAndReset("deleteTapeFilesTime",t); - deleteFilesFromRecycleBin(conn,vid,lc); - tl.insertAndReset("deleteFileFromRecycleBinTime",t); + if(this->getNbFilesOnTape(conn,vid) == 0){ + tl.insertAndReset("getNbFilesOnTape",t); + //There is no files on the tape, we can reclaim it : delete the files and reset the counters + deleteFilesFromRecycleLog(conn,vid,lc); + tl.insertAndReset("deleteFileFromRecycleLogTime",t); resetTapeCounters(conn,admin,vid); tl.insertAndReset("resetTapeCountersTime",t); log::ScopedParamContainer spc(lc); @@ -7734,7 +7710,7 @@ void RdbmsCatalogue::insertTapeFile( "FSEQ=:FSEQ"; auto stmt = conn.createStmt(sql); stmt.bindString(":VID",fileRecycleLog.vid); - stmt.bindUint64(":FSEQ",fileRecycleLog.fseq); + stmt.bindUint64(":FSEQ",fileRecycleLog.fSeq); stmt.executeNonQuery(); } } @@ -8476,20 +8452,15 @@ void RdbmsCatalogue::updateDiskFileId(const uint64_t archiveFileId, const std::s //------------------------------------------------------------------------------ // moveArchiveFileToRecycleBin //------------------------------------------------------------------------------ -void RdbmsCatalogue::moveArchiveFileToRecycleBin(const common::dataStructures::DeleteArchiveRequest &request, +void RdbmsCatalogue::moveArchiveFileToRecycleLog(const common::dataStructures::DeleteArchiveRequest &request, log::LogContext & lc) { - cta::common::dataStructures::ArchiveFile archiveFile; - utils::Timer t, totalTime; - log::TimingList tl; - try{ - archiveFile = getArchiveFileById(request.archiveFileID); - tl.insertAndReset("getArchiveFileByIdTime",t); - } catch (cta::exception::Exception &ex){ - log::ScopedParamContainer spc(lc); - spc.add("fileId", request.archiveFileID); - lc.log(log::WARNING, "Ignoring request to delete archive file because it does not exist in the catalogue"); + if(!request.archiveFile){ + //The archive file does not exist in the catalogue, nothing to do with it return; } + cta::common::dataStructures::ArchiveFile archiveFile = request.archiveFile.value(); + utils::Timer t, totalTime; + log::TimingList tl; try { checkDeleteRequestConsistency(request,archiveFile); tl.insertAndReset("checkDeleteRequestConsistency",t); @@ -8518,10 +8489,10 @@ void RdbmsCatalogue::moveArchiveFileToRecycleBin(const common::dataStructures::D << " fileSize: " << it->fileSize; spc.add("TAPE FILE", tapeCopyLogStream.str()); } - lc.log(log::WARNING, "Failed to move archive file to recycle-bin."); + lc.log(log::WARNING, "Failed to move archive file to the file-recycle-log."); exception::UserError ue; - ue.getMessage() << "Failed to move archive file with ID " << request.archiveFileID << " to the recycle-bin. errorMessage=" << ex.getMessageValue(); + ue.getMessage() << "Failed to move archive file with ID " << request.archiveFileID << " to the file-recycle-log. errorMessage=" << ex.getMessageValue(); throw ue; } @@ -8529,8 +8500,8 @@ void RdbmsCatalogue::moveArchiveFileToRecycleBin(const common::dataStructures::D //All checks are good, we can move the file to the recycle-bin auto conn = m_connPool.getConn(); rdbms::AutoRollback autoRollback(conn); - copyArchiveFileToRecycleBinAndDelete(conn,request,lc); - tl.insertAndReset("copyArchiveFileToRecycleBinAndDeleteTime",t); + copyArchiveFileToFileRecyleLogAndDelete(conn,request,lc); + tl.insertAndReset("copyArchiveFileToFileRecyleLogAndDeleteTime",t); tl.insertAndReset("totalTime",totalTime); log::ScopedParamContainer spc(lc); spc.add("fileId", std::to_string(request.archiveFileID)) @@ -8555,7 +8526,7 @@ void RdbmsCatalogue::moveArchiveFileToRecycleBin(const common::dataStructures::D spc.add("TAPE FILE", tapeCopyLogStream.str()); } tl.addToLog(spc); - lc.log(log::INFO, "In RdbmsCatalogue::moveArchiveFileToRecycleBin(): ArchiveFile moved to the recycle-bin."); + lc.log(log::INFO, "In RdbmsCatalogue::moveArchiveFileToRecycleLog(): ArchiveFile moved to the file-recycle-log."); } catch(exception::UserError &) { throw; } catch(exception::Exception &ex) { @@ -8565,110 +8536,110 @@ void RdbmsCatalogue::moveArchiveFileToRecycleBin(const common::dataStructures::D } //------------------------------------------------------------------------------ -// insertArchiveFileToRecycleBin +// copyArchiveFileToFileRecycleLog //------------------------------------------------------------------------------ -void RdbmsCatalogue::copyArchiveFileToRecycleBin(rdbms::Conn & conn, const common::dataStructures::DeleteArchiveRequest & request) { - +void RdbmsCatalogue::copyArchiveFileToFileRecycleLog(rdbms::Conn & conn, const common::dataStructures::DeleteArchiveRequest & request) { try{ - const char *const afRecycleBinInsertSql = - "INSERT INTO ARCHIVE_FILE_RECYCLE_BIN " - "(" - "ARCHIVE_FILE_ID," - "DISK_INSTANCE_NAME," - "DISK_FILE_ID," - "DISK_FILE_ID_WHEN_DELETED," - "DISK_FILE_UID," - "DISK_FILE_GID," - "SIZE_IN_BYTES," - "CHECKSUM_BLOB," - "CHECKSUM_ADLER32," - "STORAGE_CLASS_ID," - "CREATION_TIME," - "RECONCILIATION_TIME," - "COLLOCATION_HINT," - "DISK_FILE_PATH," - "DELETION_TIME" - ") SELECT " - "ARCHIVE_FILE.ARCHIVE_FILE_ID," - "ARCHIVE_FILE.DISK_INSTANCE_NAME," - "ARCHIVE_FILE.DISK_FILE_ID," - ":DISK_FILE_ID_WHEN_DELETED," - "ARCHIVE_FILE.DISK_FILE_UID," - "ARCHIVE_FILE.DISK_FILE_GID," - "ARCHIVE_FILE.SIZE_IN_BYTES," - "ARCHIVE_FILE.CHECKSUM_BLOB," - "ARCHIVE_FILE.CHECKSUM_ADLER32," - "ARCHIVE_FILE.STORAGE_CLASS_ID," - "ARCHIVE_FILE.CREATION_TIME," - "ARCHIVE_FILE.RECONCILIATION_TIME," - "ARCHIVE_FILE.COLLOCATION_HINT," - ":DISK_FILE_PATH," - ":DELETION_TIME " - "FROM " - "ARCHIVE_FILE " - "JOIN " - "STORAGE_CLASS ON ARCHIVE_FILE.STORAGE_CLASS_ID = STORAGE_CLASS.STORAGE_CLASS_ID " - "WHERE " - "ARCHIVE_FILE.ARCHIVE_FILE_ID = :ARCHIVE_FILE_ID"; - - //const auto getConnTime = t.secs(utils::Timer::resetCounter); - auto insertArchiveFileStmt = conn.createStmt(afRecycleBinInsertSql); - insertArchiveFileStmt.bindUint64(":ARCHIVE_FILE_ID",request.archiveFileID); - insertArchiveFileStmt.bindString(":DISK_FILE_PATH",request.diskFilePath); - insertArchiveFileStmt.bindString(":DISK_FILE_ID_WHEN_DELETED",request.diskFileId); - const time_t now = time(nullptr); - insertArchiveFileStmt.bindUint64(":DELETION_TIME",now); + if(!request.archiveFile){ + throw cta::exception::Exception("No archiveFile object has been set in the DeleteArchiveRequest object."); + } + const common::dataStructures::ArchiveFile & archiveFile = request.archiveFile.value(); - insertArchiveFileStmt.executeNonQuery(); + for(auto &tapeFile: archiveFile.tapeFiles){ + //Create one file recycle log entry per tape file + InsertFileRecycleLog fileRecycleLog; + fileRecycleLog.vid = tapeFile.vid; + fileRecycleLog.fSeq = tapeFile.fSeq; + fileRecycleLog.blockId = tapeFile.blockId; + fileRecycleLog.logicalSizeInBytes = tapeFile.fileSize; + fileRecycleLog.copyNb = tapeFile.copyNb; + fileRecycleLog.tapeFileCreationTime = tapeFile.creationTime; + fileRecycleLog.archiveFileId = archiveFile.archiveFileID; + fileRecycleLog.diskFilePath = request.diskFilePath; + fileRecycleLog.reasonLog = InsertFileRecycleLog::getDeletionReasonLog(request.requester.name,request.diskInstance); + fileRecycleLog.recycleLogTime = time(nullptr); + insertFileInFileRecycleLog(conn,fileRecycleLog); + } - const char *const tfRecycleBinInsertSql = - "INSERT INTO TAPE_FILE_RECYCLE_BIN" - "(" + } catch(exception::Exception &ex) { + ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str()); + throw; + } +} + +//------------------------------------------------------------------------------ +// insertFileInFileRecycleLog +//------------------------------------------------------------------------------ +void RdbmsCatalogue::insertFileInFileRecycleLog(rdbms::Conn& conn, const InsertFileRecycleLog& fileRecycleLog){ + try{ + uint64_t fileRecycleLogId = getNextFileRecyleLogId(conn); + const char *const sql = + "INSERT INTO FILE_RECYCLE_LOG(" + "FILE_RECYCLE_LOG_ID," "VID," "FSEQ," "BLOCK_ID," "LOGICAL_SIZE_IN_BYTES," "COPY_NB," - "CREATION_TIME," + "TAPE_FILE_CREATION_TIME," "ARCHIVE_FILE_ID," - "SUPERSEDED_BY_VID," - "SUPERSEDED_BY_FSEQ," - "WRITE_START_WRAP," - "WRITE_START_LPOS," - "WRITE_END_WRAP," - "WRITE_END_LPOS," - "READ_START_WRAP," - "READ_START_LPOS," - "READ_END_WRAP," - "READ_END_LPOS" + "DISK_INSTANCE_NAME," + "DISK_FILE_ID," + "DISK_FILE_ID_WHEN_DELETED," + "DISK_FILE_UID," + "DISK_FILE_GID," + "SIZE_IN_BYTES," + "CHECKSUM_BLOB," + "CHECKSUM_ADLER32," + "STORAGE_CLASS_ID," + "ARCHIVE_FILE_CREATION_TIME," + "RECONCILIATION_TIME," + "COLLOCATION_HINT," + "DISK_FILE_PATH," + "REASON_LOG," + "RECYCLE_LOG_TIME" ") SELECT " - "TAPE_FILE.VID," - "TAPE_FILE.FSEQ," - "TAPE_FILE.BLOCK_ID," - "TAPE_FILE.LOGICAL_SIZE_IN_BYTES," - "TAPE_FILE.COPY_NB," - "TAPE_FILE.CREATION_TIME," - "TAPE_FILE.ARCHIVE_FILE_ID," - "TAPE_FILE.SUPERSEDED_BY_VID," - "TAPE_FILE.SUPERSEDED_BY_FSEQ," - "TAPE_FILE.WRITE_START_WRAP," - "TAPE_FILE.WRITE_START_LPOS," - "TAPE_FILE.WRITE_END_WRAP," - "TAPE_FILE.WRITE_END_LPOS," - "TAPE_FILE.READ_START_WRAP," - "TAPE_FILE.READ_START_LPOS," - "TAPE_FILE.READ_END_WRAP," - "TAPE_FILE.READ_END_LPOS " + ":FILE_RECYCLE_LOG_ID," + ":VID," + ":FSEQ," + ":BLOCK_ID," + ":LOGICAL_SIZE_IN_BYTES," + ":COPY_NB," + ":TAPE_FILE_CREATION_TIME," + ":ARCHIVE_FILE_ID," + "ARCHIVE_FILE.DISK_INSTANCE_NAME AS DISK_INSTANCE_NAME," + "ARCHIVE_FILE.DISK_FILE_ID AS DISK_FILE_ID," + "ARCHIVE_FILE.DISK_FILE_ID AS DISK_FILE_ID_2," + "ARCHIVE_FILE.DISK_FILE_UID AS DISK_FILE_UID," + "ARCHIVE_FILE.DISK_FILE_GID AS DISK_FILE_GID," + "ARCHIVE_FILE.SIZE_IN_BYTES AS SIZE_IN_BYTES," + "ARCHIVE_FILE.CHECKSUM_BLOB AS CHECKSUM_BLOB," + "ARCHIVE_FILE.CHECKSUM_ADLER32 AS CHECKSUM_ADLER32," + "ARCHIVE_FILE.STORAGE_CLASS_ID AS STORAGE_CLASS_ID," + "ARCHIVE_FILE.CREATION_TIME AS ARCHIVE_FILE_CREATION_TIME," + "ARCHIVE_FILE.RECONCILIATION_TIME AS RECONCILIATION_TIME," + "ARCHIVE_FILE.COLLOCATION_HINT AS COLLOCATION_HINT," + ":DISK_FILE_PATH," + ":REASON_LOG," + ":RECYCLE_LOG_TIME " "FROM " - "TAPE_FILE " - "WHERE TAPE_FILE.ARCHIVE_FILE_ID = :ARCHIVE_FILE_ID"; - - auto insertTapeFileStmt = conn.createStmt(tfRecycleBinInsertSql); - insertTapeFileStmt.bindUint64(":ARCHIVE_FILE_ID",request.archiveFileID); - - insertTapeFileStmt.executeNonQuery(); - } catch(exception::UserError &) { - throw; + "ARCHIVE_FILE " + "WHERE " + "ARCHIVE_FILE.ARCHIVE_FILE_ID = :ARCHIVE_FILE_ID_2"; + auto stmt = conn.createStmt(sql); + stmt.bindUint64(":FILE_RECYCLE_LOG_ID",fileRecycleLogId); + stmt.bindString(":VID",fileRecycleLog.vid); + stmt.bindUint64(":FSEQ",fileRecycleLog.fSeq); + stmt.bindUint64(":BLOCK_ID",fileRecycleLog.blockId); + stmt.bindUint64(":LOGICAL_SIZE_IN_BYTES",fileRecycleLog.logicalSizeInBytes); + stmt.bindUint8(":COPY_NB",fileRecycleLog.copyNb); + stmt.bindUint64(":TAPE_FILE_CREATION_TIME",fileRecycleLog.tapeFileCreationTime); + stmt.bindString(":DISK_FILE_PATH",fileRecycleLog.diskFilePath); + stmt.bindUint64(":ARCHIVE_FILE_ID",fileRecycleLog.archiveFileId); + stmt.bindString(":REASON_LOG",fileRecycleLog.reasonLog); + stmt.bindUint64(":RECYCLE_LOG_TIME",fileRecycleLog.recycleLogTime); + stmt.bindUint64(":ARCHIVE_FILE_ID_2",fileRecycleLog.archiveFileId); + stmt.executeNonQuery(); } catch(exception::Exception &ex) { ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str()); throw; @@ -8805,7 +8776,7 @@ std::list<InsertFileRecycleLog> RdbmsCatalogue::insertOldCopiesOfFilesIfAnyOnFil while(rset.next()){ cta::catalogue::InsertFileRecycleLog fileRecycleLog; fileRecycleLog.vid = rset.columnString("VID"); - fileRecycleLog.fseq = rset.columnUint64("FSEQ"); + fileRecycleLog.fSeq = rset.columnUint64("FSEQ"); fileRecycleLog.blockId = rset.columnUint64("BLOCK_ID"); fileRecycleLog.logicalSizeInBytes = rset.columnUint64("LOGICAL_SIZE_IN_BYTES"); fileRecycleLog.copyNb = rset.columnUint8("COPY_NB"); @@ -8818,71 +8789,7 @@ std::list<InsertFileRecycleLog> RdbmsCatalogue::insertOldCopiesOfFilesIfAnyOnFil } { for(auto & fileRecycleLog: fileRecycleLogsToInsert){ - uint64_t fileRecycleLogId = getNextFileRecyleLogId(conn); - const char *const sql = - "INSERT INTO FILE_RECYCLE_LOG(" - "FILE_RECYCLE_LOG_ID," - "VID," - "FSEQ," - "BLOCK_ID," - "LOGICAL_SIZE_IN_BYTES," - "COPY_NB," - "TAPE_FILE_CREATION_TIME," - "ARCHIVE_FILE_ID," - "DISK_INSTANCE_NAME," - "DISK_FILE_ID," - "DISK_FILE_ID_WHEN_DELETED," - "DISK_FILE_UID," - "DISK_FILE_GID," - "SIZE_IN_BYTES," - "CHECKSUM_BLOB," - "CHECKSUM_ADLER32," - "STORAGE_CLASS_ID," - "ARCHIVE_FILE_CREATION_TIME," - "RECONCILIATION_TIME," - "COLLOCATION_HINT," - "REASON_LOG," - "RECYCLE_LOG_TIME" - ") SELECT " - ":FILE_RECYCLE_LOG_ID," - ":VID," - ":FSEQ," - ":BLOCK_ID," - ":LOGICAL_SIZE_IN_BYTES," - ":COPY_NB," - ":TAPE_FILE_CREATION_TIME," - ":ARCHIVE_FILE_ID," - "ARCHIVE_FILE.DISK_INSTANCE_NAME AS DISK_INSTANCE_NAME," - "ARCHIVE_FILE.DISK_FILE_ID AS DISK_FILE_ID," - "ARCHIVE_FILE.DISK_FILE_ID AS DISK_FILE_ID_2," - "ARCHIVE_FILE.DISK_FILE_UID AS DISK_FILE_UID," - "ARCHIVE_FILE.DISK_FILE_GID AS DISK_FILE_GID," - "ARCHIVE_FILE.SIZE_IN_BYTES AS SIZE_IN_BYTES," - "ARCHIVE_FILE.CHECKSUM_BLOB AS CHECKSUM_BLOB," - "ARCHIVE_FILE.CHECKSUM_ADLER32 AS CHECKSUM_ADLER32," - "ARCHIVE_FILE.STORAGE_CLASS_ID AS STORAGE_CLASS_ID," - "ARCHIVE_FILE.CREATION_TIME AS ARCHIVE_FILE_CREATION_TIME," - "ARCHIVE_FILE.RECONCILIATION_TIME AS RECONCILIATION_TIME," - "ARCHIVE_FILE.COLLOCATION_HINT AS COLLOCATION_HINT," - ":REASON_LOG," - ":RECYCLE_LOG_TIME " - "FROM " - "ARCHIVE_FILE " - "WHERE " - "ARCHIVE_FILE.ARCHIVE_FILE_ID = :ARCHIVE_FILE_ID_2"; - auto stmt = conn.createStmt(sql); - stmt.bindUint64(":FILE_RECYCLE_LOG_ID",fileRecycleLogId); - stmt.bindString(":VID",fileRecycleLog.vid); - stmt.bindUint64(":FSEQ",fileRecycleLog.fseq); - stmt.bindUint64(":BLOCK_ID",fileRecycleLog.blockId); - stmt.bindUint64(":LOGICAL_SIZE_IN_BYTES",fileRecycleLog.logicalSizeInBytes); - stmt.bindUint8(":COPY_NB",fileRecycleLog.copyNb); - stmt.bindUint64(":TAPE_FILE_CREATION_TIME",fileRecycleLog.tapeFileCreationTime); - stmt.bindUint64(":ARCHIVE_FILE_ID",fileRecycleLog.archiveFileId); - stmt.bindString(":REASON_LOG",fileRecycleLog.reasonLog); - stmt.bindUint64(":RECYCLE_LOG_TIME",fileRecycleLog.recycleLogTime); - stmt.bindUint64(":ARCHIVE_FILE_ID_2",fileRecycleLog.archiveFileId); - stmt.executeNonQuery(); + insertFileInFileRecycleLog(conn,fileRecycleLog); } } } catch(exception::Exception &ex) { @@ -8928,6 +8835,19 @@ void RdbmsCatalogue::deleteFilesFromRecycleBin(rdbms::Conn & conn, const std::st // deleteFilesFromRecycleLog //------------------------------------------------------------------------------ void RdbmsCatalogue::deleteFilesFromRecycleLog(const std::string& vid, log::LogContext& lc) { + try { + auto conn = m_connPool.getConn(); + deleteFilesFromRecycleLog(conn,vid,lc); + } catch(exception::Exception &ex) { + ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str()); + throw; + } +} + +//------------------------------------------------------------------------------ +// deleteFilesFromRecycleLog +//------------------------------------------------------------------------------ +void RdbmsCatalogue::deleteFilesFromRecycleLog(rdbms::Conn & conn, const std::string& vid, log::LogContext& lc) { try { const char *const deleteFilesFromRecycleLogSql = "DELETE FROM " @@ -8937,7 +8857,6 @@ void RdbmsCatalogue::deleteFilesFromRecycleLog(const std::string& vid, log::LogC cta::utils::Timer t; log::TimingList tl; - auto conn = m_connPool.getConn(); auto selectFileStmt = conn.createStmt(deleteFilesFromRecycleLogSql); selectFileStmt.bindString(":VID",vid); selectFileStmt.executeNonQuery(); diff --git a/catalogue/RdbmsCatalogue.hpp b/catalogue/RdbmsCatalogue.hpp index 828e2991af269eade2c0c81bbce11cda557bc49a..6368174aa2fb57b9b2ebe2f338c4a4cfa9dfd26f 100644 --- a/catalogue/RdbmsCatalogue.hpp +++ b/catalogue/RdbmsCatalogue.hpp @@ -537,14 +537,6 @@ public: */ void checkTapeForLabel(const std::string &vid) override; - /** - * Returns the number of non superseded files contained in the tape identified by its vid - * @param conn the database connection - * @param vid the vid in which we will count non superseded files - * @return the number of non superseded files on the vid - */ - uint64_t getNbNonSupersededFilesOnTape(rdbms::Conn &conn, const std::string &vid) const; - /** * Returns the number of any files contained in the tape identified by its vid * @param vid the vid in which we will count non superseded files @@ -1854,29 +1846,37 @@ protected: const std::string &diskFileId) override; /** - * Insert the tape files and ArchiveFiles entries in the recycle-bin and delete - * them from the TAPE_FILE and ARCHIVE_FILE tables + * Insert the ArchiveFile and all its tape files in the FILE_RECYCLE_LOG table. + * There will be one entry on the FILE_RECYCLE_LOG table per deleted tape file + * * @param request the DeleteRequest object that holds information about the file to delete. * @param lc the logContext */ - void moveArchiveFileToRecycleBin(const common::dataStructures::DeleteArchiveRequest &request, + void moveArchiveFileToRecycleLog(const common::dataStructures::DeleteArchiveRequest &request, log::LogContext & lc) override; /** - * Copy the archiveFile and the associated tape files from the ARCHIVE_FILE and TAPE_FILE tables to the recycle-bin tables + * Copy the archiveFile and the associated tape files from the ARCHIVE_FILE and TAPE_FILE tables to the FILE_RECYCLE_LOG table * and deletes the ARCHIVE_FILE and TAPE_FILE entries. * @param conn the database connection - * @param request the request that contains the necessary informations to identify the archiveFile to copy to the recycle-bin + * @param request the request that contains the necessary informations to identify the archiveFile to copy to the FILE_RECYCLE_LOG table * @param lc the log context */ - virtual void copyArchiveFileToRecycleBinAndDelete(rdbms::Conn & conn,const common::dataStructures::DeleteArchiveRequest &request, log::LogContext & lc) = 0; + virtual void copyArchiveFileToFileRecyleLogAndDelete(rdbms::Conn & conn,const common::dataStructures::DeleteArchiveRequest &request, log::LogContext & lc) = 0; /** * Copies the ARCHIVE_FILE and TAPE_FILE entries to the recycle-bin tables * @param conn the database connection * @param request the request that contains the necessary informations to identify the archiveFile to copy to the recycle-bin */ - void copyArchiveFileToRecycleBin(rdbms::Conn & conn, const common::dataStructures::DeleteArchiveRequest & request); + void copyArchiveFileToFileRecycleLog(rdbms::Conn & conn, const common::dataStructures::DeleteArchiveRequest & request); + + /** + * Insert the file in the FILE_RECYCLE_LOG table + * @param conn the database connection + * @param fileRecycleLog the file to insert into the FILE_RECYCLE_LOG table + */ + void insertFileToRecycleLog(rdbms::Conn & conn, const InsertFileRecycleLog & fileRecycleLog); /** * Deletes the ArchiveFile from the ARCHIVE_FILE table @@ -1926,6 +1926,19 @@ protected: */ void deleteFilesFromRecycleLog(const std::string & vid, log::LogContext & lc); + /** + * Deletes all the log entries corresponding to the vid passed in parameter. + * + * Please note that this method is idempotent. If there are no recycle log + * entries associated to the vid passed in parameter, the method will return + * without any error. + * + *@param conn, the database connection + * @param vid, the vid of the files to be deleted + * @param lc, the logContext + */ + void deleteFilesFromRecycleLog(rdbms::Conn & conn, const std::string & vid, log::LogContext & lc); + /** * Delete the TapeFiles and the ArchiveFile from the recycle-bin in one transaction * @param conn the database connection @@ -1959,6 +1972,13 @@ protected: */ std::list<cta::catalogue::InsertFileRecycleLog> insertOldCopiesOfFilesIfAnyOnFileRecycleLog(rdbms::Conn & conn,const common::dataStructures::TapeFile &tapeFile, const uint64_t archiveFileId); + /** + * Insert the file passed in parameter in the FILE_RECYCLE_LOG table + * @param conn the database connection + * @param fileRecycleLog the file to insert on the FILE_RECYCLE_LOG table + */ + void insertFileInFileRecycleLog(rdbms::Conn & conn, const InsertFileRecycleLog & fileRecycleLog); + /** * Generates the SELECT statement required to search for tapes using 100 tape * VIDs. Each tape VID is represented in the SQL by a bind parameter with the diff --git a/catalogue/SqliteCatalogue.cpp b/catalogue/SqliteCatalogue.cpp index eee30e6fa0c132ed77917d1dc3130b28a85177b6..365232ffa818406895193cb97ca591b55a79a441 100644 --- a/catalogue/SqliteCatalogue.cpp +++ b/catalogue/SqliteCatalogue.cpp @@ -592,14 +592,14 @@ void SqliteCatalogue::fileWrittenToTape(rdbms::Conn &conn, const TapeFileWritten //------------------------------------------------------------------------------ // copyArchiveFileToRecycleBinAndDelete //------------------------------------------------------------------------------ -void SqliteCatalogue::copyArchiveFileToRecycleBinAndDelete(rdbms::Conn & conn, const common::dataStructures::DeleteArchiveRequest &request, log::LogContext & lc) { +void SqliteCatalogue::copyArchiveFileToFileRecyleLogAndDelete(rdbms::Conn & conn, const common::dataStructures::DeleteArchiveRequest &request, log::LogContext & lc) { try { utils::Timer t; log::TimingList tl; //We currently do an INSERT INTO and a DELETE FROM //in a single transaction conn.executeNonQuery("BEGIN TRANSACTION"); - copyArchiveFileToRecycleBin(conn,request); + copyArchiveFileToFileRecycleLog(conn,request); tl.insertAndReset("insertToRecycleBinTime",t); setTapeDirty(conn,request.archiveFileID); tl.insertAndReset("setTapeDirtyTime",t); diff --git a/catalogue/SqliteCatalogue.hpp b/catalogue/SqliteCatalogue.hpp index 85ed56ed78c4d1b2bb85937de344c377355f8225..473bc542c8d3bb57ed2e6e998216b18797162a3a 100644 --- a/catalogue/SqliteCatalogue.hpp +++ b/catalogue/SqliteCatalogue.hpp @@ -202,13 +202,13 @@ protected: void filesWrittenToTape(const std::set<TapeItemWrittenPointer> &events) override; /** - * Copy the archiveFile and the associated tape files from the ARCHIVE_FILE and TAPE_FILE tables to the recycle-bin tables + * Copy the archiveFile and the associated tape files from the ARCHIVE_FILE and TAPE_FILE tables to the FILE_RECYCLE_LOG table * and deletes the ARCHIVE_FILE and TAPE_FILE entries. * @param conn the database connection - * @param request the request that contains the necessary informations to identify the archiveFile to copy to the recycle-bin + * @param request the request that contains the necessary informations to identify the archiveFile to copy to the FILE_RECYCLE_LOG table * @param lc the log context */ - void copyArchiveFileToRecycleBinAndDelete(rdbms::Conn & conn, const common::dataStructures::DeleteArchiveRequest &request, log::LogContext & lc) override; + void copyArchiveFileToFileRecyleLogAndDelete(rdbms::Conn & conn, const common::dataStructures::DeleteArchiveRequest &request, log::LogContext & lc) override; /** * Delete the TapeFiles and the ArchiveFile from the recycle-bin in one transaction diff --git a/common/dataStructures/DeleteArchiveRequest.hpp b/common/dataStructures/DeleteArchiveRequest.hpp index ec7c75bab2fd3de81384d66b897cabfb0c3e2941..7735227f52ca34563c96eaa49fa9e20d8b1f3a65 100644 --- a/common/dataStructures/DeleteArchiveRequest.hpp +++ b/common/dataStructures/DeleteArchiveRequest.hpp @@ -25,6 +25,7 @@ #include "common/optional.hpp" #include "common/dataStructures/RequesterIdentity.hpp" +#include "ArchiveFile.hpp" namespace cta { namespace common { @@ -49,6 +50,8 @@ struct DeleteArchiveRequest { std::string diskFileId; std::string diskInstance; time_t recycleTime; + //In the case the ArchiveFile does not exist yet, it will not be set + cta::optional<ArchiveFile> archiveFile; }; // struct DeleteArchiveRequest diff --git a/scheduler/Scheduler.cpp b/scheduler/Scheduler.cpp index 9493863153dbb96f1dba56630c5b73c996f5224e..a1ea61bc09ff193cd3ccda7aeaae9bfe7a72a166 100644 --- a/scheduler/Scheduler.cpp +++ b/scheduler/Scheduler.cpp @@ -272,7 +272,7 @@ void Scheduler::deleteArchive(const std::string &instanceName, const common::dat m_db.cancelArchive(request,lc); } tl.insertAndReset("schedulerDbTime",t); - m_catalogue.moveArchiveFileToRecycleBin(request,lc); + m_catalogue.moveArchiveFileToRecycleLog(request,lc); tl.insertAndReset("catalogueTime",t); log::ScopedParamContainer spc(lc); tl.addToLog(spc); diff --git a/xroot_plugins/XrdSsiCtaRequestMessage.cpp b/xroot_plugins/XrdSsiCtaRequestMessage.cpp index 758076dbfdd9b8d5117ebc99d2737f07ad01ed10..60bba26ed7bb6c0c9c031064a6017cbba9c3c04e 100644 --- a/xroot_plugins/XrdSsiCtaRequestMessage.cpp +++ b/xroot_plugins/XrdSsiCtaRequestMessage.cpp @@ -709,14 +709,23 @@ void RequestMessage::processDELETE(const cta::eos::Notification ¬ification, c // Delete the file from the catalogue or from the objectstore if archive request is created cta::utils::Timer t; + cta::log::TimingList tl; + try { + request.archiveFile = m_catalogue.getArchiveFileById(request.archiveFileID); + tl.insertAndReset("catalogueGetArchiveFileByIdTime",t); + } catch (cta::exception::Exception &ex){ + log::ScopedParamContainer spc(m_lc); + spc.add("fileId", request.archiveFileID); + m_lc.log(log::WARNING, "Ignoring request to delete archive file because it does not exist in the catalogue"); + } m_scheduler.deleteArchive(m_cliIdentity.username, request, m_lc); - + tl.insertAndReset("schedulerTime",t); // Create a log entry cta::log::ScopedParamContainer params(m_lc); params.add("fileId", request.archiveFileID) .add("address", (request.address ? request.address.value() : "null")) - .add("filePath",request.diskFilePath) - .add("schedulerTime", t.secs()); + .add("filePath",request.diskFilePath); + tl.addToLog(params); m_lc.log(cta::log::INFO, "In RequestMessage::processDELETE(): archive file deleted."); // Set response type