[icinga-checkins] icinga.org: icinga2/master: Avoid duplicate entries in the icinga_objects table for commands

git at icinga.org git at icinga.org
Fri Jul 15 09:42:35 CEST 2016


Module: icinga2
Branch: master
Commit: 959e2501aaffe630245726d8cdcce3c2699e2b4f
URL:    https://git.icinga.org/?p=icinga2.git;a=commit;h=959e2501aaffe630245726d8cdcce3c2699e2b4f

Author: Gunnar Beutner <gunnar.beutner at netways.de>
Date:   Fri Jul 15 09:40:39 2016 +0200

Avoid duplicate entries in the icinga_objects table for commands

refs #12147

---

 lib/db_ido/commanddbobject.cpp          |    4 +---
 lib/db_ido/dbconnection.cpp             |   14 +++++++++++++-
 lib/db_ido/dbconnection.hpp             |    4 ++++
 lib/db_ido/dbtype.cpp                   |   26 ++++++++++++++++++++++++--
 lib/db_ido_mysql/idomysqlconnection.cpp |   13 +++++++++++++
 lib/db_ido_pgsql/idopgsqlconnection.cpp |   13 +++++++++++++
 6 files changed, 68 insertions(+), 6 deletions(-)

diff --git a/lib/db_ido/commanddbobject.cpp b/lib/db_ido/commanddbobject.cpp
index 6f12a65..6620c83 100644
--- a/lib/db_ido/commanddbobject.cpp
+++ b/lib/db_ido/commanddbobject.cpp
@@ -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)
diff --git a/lib/db_ido/dbconnection.cpp b/lib/db_ido/dbconnection.cpp
index 1e54bfc..186e78c 100644
--- a/lib/db_ido/dbconnection.cpp
+++ b/lib/db_ido/dbconnection.cpp
@@ -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;
+}
diff --git a/lib/db_ido/dbconnection.hpp b/lib/db_ido/dbconnection.hpp
index 2f100ee..ca05a47 100644
--- a/lib/db_ido/dbconnection.hpp
+++ b/lib/db_ido/dbconnection.hpp
@@ -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;
diff --git a/lib/db_ido/dbtype.cpp b/lib/db_ido/dbtype.cpp
index 44c33fb..ea25ec5 100644
--- a/lib/db_ido/dbtype.cpp
+++ b/lib/db_ido/dbtype.cpp
@@ -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;
 }
diff --git a/lib/db_ido_mysql/idomysqlconnection.cpp b/lib/db_ido_mysql/idomysqlconnection.cpp
index d002682..6e66075 100644
--- a/lib/db_ido_mysql/idomysqlconnection.cpp
+++ b/lib/db_ido_mysql/idomysqlconnection.cpp
@@ -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;
 
diff --git a/lib/db_ido_pgsql/idopgsqlconnection.cpp b/lib/db_ido_pgsql/idopgsqlconnection.cpp
index 94976c2..c9e1ab0 100644
--- a/lib/db_ido_pgsql/idopgsqlconnection.cpp
+++ b/lib/db_ido_pgsql/idopgsqlconnection.cpp
@@ -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;
 



More information about the icinga-checkins mailing list