Avoid duplicate entries in the icinga_objects table for commands

refs #12147
This commit is contained in:
Gunnar Beutner 2016-07-15 09:40:39 +02:00
parent 3f852f118b
commit 959e2501aa
6 changed files with 68 additions and 6 deletions

View 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)

View 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;
}

View 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;

View 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;
}

View 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;

View 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;