diff --git a/castor/db/ora/OraStagerSvc.cpp b/castor/db/ora/OraStagerSvc.cpp index c40e48bc2b729d382d4443ee7cc3b19999f4a12e..b7fea6cc6da8503c64369e36d38e87061bb7778f 100644 --- a/castor/db/ora/OraStagerSvc.cpp +++ b/castor/db/ora/OraStagerSvc.cpp @@ -193,10 +193,6 @@ const std::string castor::db::ora::OraStagerSvc::s_getConfigOptionStatementStrin const std::string castor::db::ora::OraStagerSvc::s_dumpDBLogsString = "BEGIN dumpDBLogs(:1); END;"; -const std::string castor::db::ora::OraStagerSvc::s_truncateDBLogsString = - "DELETE FROM DLFLogs"; -// here a TRUNCATE statement won't work because we locked the table - //------------------------------------------------------------------------------ // OraStagerSvc //------------------------------------------------------------------------------ @@ -224,8 +220,7 @@ castor::db::ora::OraStagerSvc::OraStagerSvc(const std::string name) : m_enterPriorityStatement(0), m_deletePriorityStatement(0), m_getConfigOptionStatement(0), - m_dumpDBLogsStatement(0), - m_truncateDBLogsStatement(0) { + m_dumpDBLogsStatement(0) { } //------------------------------------------------------------------------------ @@ -280,7 +275,6 @@ void castor::db::ora::OraStagerSvc::reset() throw() { if (m_deletePriorityStatement) deleteStatement(m_deletePriorityStatement); if (m_getConfigOptionStatement) deleteStatement(m_getConfigOptionStatement); if (m_dumpDBLogsStatement) deleteStatement(m_dumpDBLogsStatement); - if (m_truncateDBLogsStatement) deleteStatement(m_truncateDBLogsStatement); } catch (castor::exception::Exception& ignored) {}; // Now reset all pointers to 0 @@ -307,7 +301,6 @@ void castor::db::ora::OraStagerSvc::reset() throw() { m_deletePriorityStatement = 0; m_getConfigOptionStatement = 0; m_dumpDBLogsStatement = 0; - m_truncateDBLogsStatement = 0; } //------------------------------------------------------------------------------ @@ -1338,10 +1331,9 @@ void castor::db::ora::OraStagerSvc::dumpDBLogs() if (0 == m_dumpDBLogsStatement) { m_dumpDBLogsStatement = createStatement(s_dumpDBLogsString); m_dumpDBLogsStatement->registerOutParam(1, oracle::occi::OCCICURSOR); - m_truncateDBLogsStatement = createStatement(s_truncateDBLogsString); - m_truncateDBLogsStatement->setAutoCommit(true); } - // execute the statement + // execute the statement. This deletes the selected rows from the DB + // and return them without commiting unsigned int nb = m_dumpDBLogsStatement->executeUpdate(); if (nb == 0) { rollback(); @@ -1379,10 +1371,8 @@ void castor::db::ora::OraStagerSvc::dumpDBLogs() status = rs->next(); } m_dumpDBLogsStatement->closeResultSet(rs); - // Now truncate the log table and commit. Note that we're sure - // no one else could have picked up data from this table - // as the previous statement took a table lock. - m_truncateDBLogsStatement->executeUpdate(); + // Now commit, and thus drop effectively the logs from the DB + commit(); } catch (oracle::occi::SQLException e) { handleException(e); castor::exception::Internal ex; diff --git a/castor/db/ora/OraStagerSvc.hpp b/castor/db/ora/OraStagerSvc.hpp index 8830a156b47cf4f741c5933890592706654c6872..f7a1d24be638d07527db4aac5669e1501771a9fe 100644 --- a/castor/db/ora/OraStagerSvc.hpp +++ b/castor/db/ora/OraStagerSvc.hpp @@ -513,11 +513,9 @@ namespace castor { /// SQL statement for dumpDBLogs function static const std::string s_dumpDBLogsString; - static const std::string s_truncateDBLogsString; /// SQL statement object for dumpDBLogs function oracle::occi::Statement *m_dumpDBLogsStatement; - oracle::occi::Statement *m_truncateDBLogsStatement; }; // end of class OraStagerSvc diff --git a/castor/db/oracleCommon.schema.sql b/castor/db/oracleCommon.schema.sql index b6e953ccef6c39278a634cc5585b24bd7a5147e6..4f9c67188be1a3c53b92bb7721814f954b3eaebc 100644 --- a/castor/db/oracleCommon.schema.sql +++ b/castor/db/oracleCommon.schema.sql @@ -497,6 +497,10 @@ ALTER TABLE SvcClass ADD CONSTRAINT UN_SvcClass_Name UNIQUE (name); CREATE OR REPLACE TYPE "numList" IS TABLE OF INTEGER; / +/* Custom type to handle float arrays */ +CREATE OR REPLACE TYPE floatList IS TABLE OF NUMBER; +/ + /* Custom type to handle strings returned by pipelined functions */ CREATE OR REPLACE TYPE strListTable AS TABLE OF VARCHAR2(2048); / @@ -576,7 +580,7 @@ CREATE GLOBAL TEMPORARY TABLE ProcessRepackAbortHelperSR (srId NUMBER) ON COMMIT /* Global temporary table to handle bulk update of diskCopies in processBulkAbortForRepack */ CREATE GLOBAL TEMPORARY TABLE ProcessRepackAbortHelperDCmigr (cfId NUMBER) ON COMMIT DELETE ROWS; -/* Table to log the DB activity */ +/* Tables to log the DB activity */ CREATE TABLE DLFLogs (timeinfo NUMBER, uuid VARCHAR2(2048), @@ -586,7 +590,17 @@ CREATE TABLE DLFLogs nsHost VARCHAR2(2048), source VARCHAR2(2048), params VARCHAR2(2048)); - +CREATE GLOBAL TEMPORARY TABLE DLFLogsHelper + (timeinfo NUMBER, + uuid VARCHAR2(2048), + priority INTEGER, + msg VARCHAR2(2048), + fileId NUMBER, + nsHost VARCHAR2(2048), + source VARCHAR2(2048), + params VARCHAR2(2048)) +ON COMMIT DELETE ROWS; + /* Temporary table to handle removing of priviledges */ CREATE GLOBAL TEMPORARY TABLE RemovePrivilegeTmpTable (svcClass VARCHAR2(2048), diff --git a/castor/db/oracleStager.sql b/castor/db/oracleStager.sql index 706192cb0acab7448f811c4fe0d8baa576296bde..8e2449ef5988e9f6fe6e6d8a0a8b26d417954642 100644 --- a/castor/db/oracleStager.sql +++ b/castor/db/oracleStager.sql @@ -137,7 +137,6 @@ END; * coming back but already exist on another one */ CREATE OR REPLACE PROCEDURE checkFSBackInProd(fsId NUMBER) AS - srIds "numList"; BEGIN -- Flag the filesystem for processing in a bulk operation later. -- We need to do this because some operations are database intensive @@ -3304,12 +3303,26 @@ END; /* PL/SQL method used by the stager to collect the logging made in the DB */ CREATE OR REPLACE PROCEDURE dumpDBLogs(logEntries OUT castor.LogEntry_Cur) AS - unused NUMBER; + timeinfos floatList; + uuids strListTable; + priorities "numList"; + msgs strListTable; + fileIds "numList"; + nsHosts strListTable; + sources strListTable; + paramss strListTable; BEGIN - -- if we got here, we have something in the log table, let's lock it and dump it - LOCK TABLE DLFLogs IN EXCLUSIVE MODE; + -- get whatever we can from the table + DELETE FROM DLFLogs + RETURNING timeinfo, uuid, priority, msg, fileId, nsHost, source, params + BULK COLLECT INTO timeinfos, uuids, priorities, msgs, fileIds, nsHosts, sources, paramss; + -- insert into tmp table so that we can open a cursor on it + FORALL i IN timeinfos.FIRST .. timeinfos.LAST + INSERT INTO DLFLogsHelper + VALUES (timeinfos(i), uuids(i), priorities(i), msgs(i), fileIds(i), nsHosts(i), sources(i), paramss(i)); + -- return list of entries by opening a cursor on temp table OPEN logEntries FOR - SELECT timeinfo, uuid, priority, msg, fileId, nsHost, source, params FROM DLFLogs; + SELECT timeinfo, uuid, priority, msg, fileId, nsHost, source, params FROM DLFLogsHelper; END; / diff --git a/upgrades/stager_2.1.12-4_to_2.1.13-0.sql b/upgrades/stager_2.1.12-4_to_2.1.13-0.sql index f1e565591f71584838f82e32b9cd8ee1aadc9c32..743a6831d348f7dbf1b92e71fd53d01cc36e4ddf 100644 --- a/upgrades/stager_2.1.12-4_to_2.1.13-0.sql +++ b/upgrades/stager_2.1.12-4_to_2.1.13-0.sql @@ -97,6 +97,16 @@ CREATE TABLE DLFLogs nsHost VARCHAR2(2048), source VARCHAR2(2048), params VARCHAR2(2048)); +CREATE GLOBAL TEMPORARY TABLE DLFLogsHelper + (timeinfo NUMBER, + uuid VARCHAR2(2048), + priority INTEGER, + msg VARCHAR2(2048), + fileId NUMBER, + nsHost VARCHAR2(2048), + source VARCHAR2(2048), + params VARCHAR2(2048)) +ON COMMIT DELETE ROWS; DROP PROCEDURE dumpCleanupLogs; DROP TABLE TapeGatewayRequest;