]> granicus.if.org Git - icinga2/commitdiff
Avoid duplicate entries in the icinga_objects table for commands
authorGunnar Beutner <gunnar.beutner@netways.de>
Fri, 15 Jul 2016 07:40:39 +0000 (09:40 +0200)
committerGunnar Beutner <gunnar.beutner@netways.de>
Fri, 15 Jul 2016 07:40:39 +0000 (09:40 +0200)
refs #12147

lib/db_ido/commanddbobject.cpp
lib/db_ido/dbconnection.cpp
lib/db_ido/dbconnection.hpp
lib/db_ido/dbtype.cpp
lib/db_ido_mysql/idomysqlconnection.cpp
lib/db_ido_pgsql/idopgsqlconnection.cpp

index 6f12a65005a36030824839f92c9992f6ddddaa78..6620c83321b4cf0247a76d14652870dbb0cfe50c 100644 (file)
@@ -28,9 +28,7 @@
 
 using namespace icinga;
 
-REGISTER_DBTYPE(CheckCommand, "command", DbObjectTypeCommand, "object_id", CommandDbObject);
-REGISTER_DBTYPE(EventCommand, "command", DbObjectTypeCommand, "object_id", CommandDbObject);
-REGISTER_DBTYPE(NotificationCommand, "command", DbObjectTypeCommand, "object_id", CommandDbObject);
+REGISTER_DBTYPE(Command, "command", DbObjectTypeCommand, "object_id", CommandDbObject);
 
 CommandDbObject::CommandDbObject(const DbType::Ptr& type, const String& name1, const String& name2)
        : DbObject(type, name1, name2)
index 1e54bfcd63b82990a4b488b80415b292fe5813ca..186e78c7c90bdc74b27f61123b83d7c4dfc5eae8 100644 (file)
@@ -39,7 +39,7 @@ Timer::Ptr DbConnection::m_ProgramStatusTimer;
 boost::once_flag DbConnection::m_OnceFlag = BOOST_ONCE_INIT;
 
 DbConnection::DbConnection(void)
-       : m_QueryStats(15 * 60), m_PendingQueries(0), m_PendingQueriesTimestamp(0)
+       : m_QueryStats(15 * 60), m_PendingQueries(0), m_PendingQueriesTimestamp(0), m_IDCacheValid(false)
 { }
 
 void DbConnection::OnConfigLoaded(void)
@@ -352,6 +352,8 @@ bool DbConnection::GetObjectActive(const DbObject::Ptr& dbobj) const
 
 void DbConnection::ClearIDCache(void)
 {
+       SetIDCacheValid(false);
+
        m_ObjectIDs.clear();
        m_InsertIDs.clear();
        m_ActiveObjects.clear();
@@ -484,3 +486,13 @@ int DbConnection::GetQueryCount(RingBuffer::SizeType span) const
        boost::mutex::scoped_lock lock(m_StatsMutex);
        return m_QueryStats.GetValues(span);
 }
+
+bool DbConnection::IsIDCacheValid(void) const
+{
+       return m_IDCacheValid;
+}
+
+void DbConnection::SetIDCacheValid(bool valid)
+{
+       m_IDCacheValid = valid;
+}
index 2f100eeda47b46a6cec44094ce431326692924b0..ca05a4760bba95bf336c7a65b2f9658bb651b6ec 100644 (file)
@@ -95,9 +95,13 @@ protected:
 
        void IncreaseQueryCount(void);
 
+       bool IsIDCacheValid(void) const;
+       void SetIDCacheValid(bool valid);
+
        static void UpdateProgramStatus(void);
 
 private:
+       bool m_IDCacheValid;
        std::map<DbObject::Ptr, DbReference> m_ObjectIDs;
        std::map<std::pair<DbType::Ptr, DbReference>, DbReference> m_InsertIDs;
        std::set<DbObject::Ptr> m_ActiveObjects;
index 44c33fb3e7a1ca30fd882a01c1068e4ef96672b4..ea25ec56c6ce8466e68b5a6a8ff7f1ef1761561e 100644 (file)
@@ -58,8 +58,15 @@ void DbType::RegisterType(const DbType::Ptr& type)
 
 DbType::Ptr DbType::GetByName(const String& name)
 {
+       String typeName;
+
+       if (name == "CheckCommand" || name == "NotificationCommand" || name == "EventCommand")
+               typeName = "Command";
+       else
+               typeName = name;
+
        boost::mutex::scoped_lock lock(GetStaticMutex());
-       DbType::TypeMap::const_iterator it = GetTypes().find(name);
+       DbType::TypeMap::const_iterator it = GetTypes().find(typeName);
 
        if (it == GetTypes().end())
                return DbType::Ptr();
@@ -96,7 +103,22 @@ DbObject::Ptr DbType::GetOrCreateObjectByName(const String& name1, const String&
        if (!name2.IsEmpty())
                objName += "!" + name2;
 
-       dbobj->SetObject(ConfigObject::GetObject(m_Name, objName));
+       String objType = m_Name;
+
+       if (m_TypeID == DbObjectTypeCommand) {
+               if (objName.SubStr(0, 6) == "check_") {
+                       objType = "CheckCommand";
+                       objName = objName.SubStr(6);
+               } else if (objName.SubStr(0, 13) == "notification_") {
+                       objType = "NotificationCommand";
+                       objName = objName.SubStr(13);
+               } else if (objName.SubStr(0, 6) == "event_") {
+                       objType = "EventCommand";
+                       objName = objName.SubStr(6);
+               }
+       }
+
+       dbobj->SetObject(ConfigObject::GetObject(objType, objName));
 
        return dbobj;
 }
index d0026826bd13bacca3efd99ffefcc7aae86cc5d9..6e66075e9cd051d94236f43258fc648e1da0edfd 100644 (file)
@@ -398,6 +398,8 @@ void IdoMysqlConnection::Reconnect(void)
                        activeDbObjs.push_back(dbobj);
        }
 
+       SetIDCacheValid(true);
+
        BOOST_FOREACH(const DbObject::Ptr& dbobj, activeDbObjs) {
                if (dbobj->GetObject() == NULL) {
                        Log(LogNotice, "IdoMysqlConnection")
@@ -750,6 +752,9 @@ bool IdoMysqlConnection::FieldToEscapedString(const String& key, const Value& va
                        return true;
                }
 
+               if (!IsIDCacheValid())
+                       return false;
+
                DbReference dbrefcol;
 
                if (DbValue::IsObjectInsertID(value)) {
@@ -817,6 +822,9 @@ void IdoMysqlConnection::ExecuteMultipleQueries(const std::vector<DbQuery>& quer
 
 bool IdoMysqlConnection::CanExecuteQuery(const DbQuery& query)
 {
+       if (query.Object && !IsIDCacheValid())
+               return false;
+
        if (query.WhereCriteria) {
                ObjectLock olock(query.WhereCriteria);
                Value value;
@@ -877,6 +885,11 @@ void IdoMysqlConnection::InternalExecuteQuery(const DbQuery& query, DbQueryType
                return;
        }
 
+       if (!CanExecuteQuery(query)) {
+               m_QueryQueue.Enqueue(boost::bind(&IdoMysqlConnection::InternalExecuteQuery, this, query, typeOverride), query.Priority);
+               return;
+       }
+
        if (GetCategoryFilter() != DbCatEverything && (query.Category & GetCategoryFilter()) == 0)
                return;
 
index 94976c23a9cab921cb868be4d7272451c88838c2..c9e1ab0fc964115662a161d186e919722fd519dd 100644 (file)
@@ -371,6 +371,8 @@ void IdoPgsqlConnection::Reconnect(void)
                        activeDbObjs.push_back(dbobj);
        }
 
+       SetIDCacheValid(true);
+
        BOOST_FOREACH(const DbObject::Ptr& dbobj, activeDbObjs) {
                if (dbobj->GetObject() == NULL) {
                        Log(LogNotice, "IdoPgsqlConnection")
@@ -607,6 +609,9 @@ bool IdoPgsqlConnection::FieldToEscapedString(const String& key, const Value& va
                        return true;
                }
 
+               if (!IsIDCacheValid())
+                       return false;
+
                DbReference dbrefcol;
 
                if (DbValue::IsObjectInsertID(value)) {
@@ -674,6 +679,9 @@ void IdoPgsqlConnection::ExecuteMultipleQueries(const std::vector<DbQuery>& quer
 
 bool IdoPgsqlConnection::CanExecuteQuery(const DbQuery& query)
 {
+       if (query.Object && !IsIDCacheValid())
+               return false;
+
        if (query.WhereCriteria) {
                ObjectLock olock(query.WhereCriteria);
                Value value;
@@ -734,6 +742,11 @@ void IdoPgsqlConnection::InternalExecuteQuery(const DbQuery& query, DbQueryType
                return;
        }
 
+       if (!CanExecuteQuery(query)) {
+               m_QueryQueue.Enqueue(boost::bind(&IdoPgsqlConnection::InternalExecuteQuery, this, query, typeOverride), query.Priority);
+               return;
+       }
+
        if (GetCategoryFilter() != DbCatEverything && (query.Category & GetCategoryFilter()) == 0)
                return;