Implement support for incremental IDO updates

fixes #12435
This commit is contained in:
Gunnar Beutner 2016-08-14 22:24:51 +02:00
parent ebaf239d3b
commit 2e8d3d3934
22 changed files with 635 additions and 221 deletions

View File

@ -204,6 +204,12 @@ Array::Ptr Array::Reverse(void) const
return result;
}
void Array::Sort(void)
{
ObjectLock olock(this);
std::sort(m_Data.begin(), m_Data.end());
}
String Array::ToString(void) const
{
std::ostringstream msgbuf;

View File

@ -131,6 +131,8 @@ public:
Array::Ptr Reverse(void) const;
void Sort(void);
virtual String ToString(void) const override;
virtual Value GetFieldByName(const String& field, bool sandboxed, const DebugInfo& debugInfo) const override;

View File

@ -285,6 +285,42 @@ void DbConnection::CleanUpExecuteQuery(const String&, const String&, double)
/* Default handler does nothing. */
}
void DbConnection::SetConfigHash(const DbObject::Ptr& dbobj, const String& hash)
{
SetConfigHash(dbobj->GetType(), GetObjectID(dbobj), hash);
}
void DbConnection::SetConfigHash(const DbType::Ptr& type, const DbReference& objid, const String& hash)
{
if (!objid.IsValid())
return;
if (!hash.IsEmpty())
m_ConfigHashes[std::make_pair(type, objid)] = hash;
else
m_ConfigHashes.erase(std::make_pair(type, objid));
}
String DbConnection::GetConfigHash(const DbObject::Ptr& dbobj) const
{
return GetConfigHash(dbobj->GetType(), GetObjectID(dbobj));
}
String DbConnection::GetConfigHash(const DbType::Ptr& type, const DbReference& objid) const
{
if (!objid.IsValid())
return String();
std::map<std::pair<DbType::Ptr, DbReference>, String>::const_iterator it;
it = m_ConfigHashes.find(std::make_pair(type, objid));
if (it == m_ConfigHashes.end())
return String();
return it->second;
}
void DbConnection::SetObjectID(const DbObject::Ptr& dbobj, const DbReference& dbref)
{
if (dbref.IsValid())
@ -363,6 +399,7 @@ void DbConnection::ClearIDCache(void)
m_ActiveObjects.clear();
m_ConfigUpdates.clear();
m_StatusUpdates.clear();
m_ConfigHashes.clear();
}
void DbConnection::SetConfigUpdate(const DbObject::Ptr& dbobj, bool hasupdate)
@ -406,8 +443,18 @@ void DbConnection::UpdateObject(const ConfigObject::Ptr& object)
if (!dbActive)
ActivateObject(dbobj);
dbobj->SendConfigUpdate();
dbobj->SendStatusUpdate();
Dictionary::Ptr configFields = dbobj->GetConfigFields();
String configHash = dbobj->CalculateConfigHash(configFields);
configFields->Set("config_hash", configHash);
String cachedHash = GetConfigHash(dbobj);
if (cachedHash != configHash) {
dbobj->SendConfigUpdateHeavy(configFields);
dbobj->SendStatusUpdate();
} else {
dbobj->SendConfigUpdateLight();
}
} else if (!active) {
/* Deactivate the deleted object no matter
* which state it had in the database.
@ -429,43 +476,6 @@ void DbConnection::UpdateAllObjects(void)
void DbConnection::PrepareDatabase(void)
{
/*
* only clear tables on reconnect which
* cannot be updated by their existing ids
* for details check https://dev.icinga.org/issues/5565
*/
//ClearConfigTable("commands");
//ClearConfigTable("comments");
ClearConfigTable("contact_addresses");
ClearConfigTable("contact_notificationcommands");
//ClearConfigTable("contactgroup_members");
//ClearConfigTable("contactgroups");
//ClearConfigTable("contacts");
//ClearConfigTable("contactstatus");
//ClearConfigTable("customvariables");
//ClearConfigTable("customvariablestatus");
//ClearConfigTable("endpoints");
//ClearConfigTable("endpointstatus");
ClearConfigTable("host_contactgroups");
ClearConfigTable("host_contacts");
ClearConfigTable("host_parenthosts");
ClearConfigTable("hostdependencies");
//ClearConfigTable("hostgroup_members");
//ClearConfigTable("hostgroups");
//ClearConfigTable("hosts");
//ClearConfigTable("hoststatus");
//ClearConfigTable("scheduleddowntime");
ClearConfigTable("service_contactgroups");
ClearConfigTable("service_contacts");
ClearConfigTable("servicedependencies");
//ClearConfigTable("servicegroup_members");
//ClearConfigTable("servicegroups");
//ClearConfigTable("services");
//ClearConfigTable("servicestatus");
ClearConfigTable("timeperiod_timeranges");
//ClearConfigTable("timeperiods");
BOOST_FOREACH(const DbType::Ptr& type, DbType::GetAllTypes()) {
FillIDCache(type);
}

View File

@ -49,6 +49,11 @@ public:
static void InitializeDbTimer(void);
void SetConfigHash(const DbObject::Ptr& dbobj, const String& hash);
void SetConfigHash(const DbType::Ptr& type, const DbReference& objid, const String& hash);
String GetConfigHash(const DbObject::Ptr& dbobj) const;
String GetConfigHash(const DbType::Ptr& type, const DbReference& objid) const;
void SetObjectID(const DbObject::Ptr& dbobj, const DbReference& dbref);
DbReference GetObjectID(const DbObject::Ptr& dbobj) const;
@ -106,6 +111,7 @@ protected:
private:
bool m_IDCacheValid;
std::map<std::pair<DbType::Ptr, DbReference>, String> m_ConfigHashes;
std::map<DbObject::Ptr, DbReference> m_ObjectIDs;
std::map<std::pair<DbType::Ptr, DbReference>, DbReference> m_InsertIDs;
std::set<DbObject::Ptr> m_ActiveObjects;
@ -115,8 +121,6 @@ private:
void CleanUpHandler(void);
virtual void ClearConfigTable(const String& table) = 0;
static Timer::Ptr m_ProgramStatusTimer;
static boost::once_flag m_OnceFlag;

View File

@ -30,6 +30,8 @@
#include "base/configobject.hpp"
#include "base/configtype.hpp"
#include "base/json.hpp"
#include "base/serializer.hpp"
#include "base/json.hpp"
#include "base/convert.hpp"
#include "base/objectlock.hpp"
#include "base/utility.hpp"
@ -83,35 +85,82 @@ DbType::Ptr DbObject::GetType(void) const
return m_Type;
}
void DbObject::SendConfigUpdate(void)
String DbObject::CalculateConfigHash(const Dictionary::Ptr& configFields) const
{
Dictionary::Ptr configFieldsDup = configFields->ShallowClone();
{
ObjectLock olock(configFieldsDup);
BOOST_FOREACH(const Dictionary::Pair& kv, configFieldsDup) {
if (kv.second.IsObjectType<ConfigObject>()) {
ConfigObject::Ptr obj = kv.second;
configFieldsDup->Set(kv.first, obj->GetName());
}
}
}
Array::Ptr data = new Array();
data->Add(configFieldsDup);
CustomVarObject::Ptr custom_var_object = dynamic_pointer_cast<CustomVarObject>(GetObject());
if (custom_var_object)
data->Add(custom_var_object->GetVars());
return HashValue(data);
}
String DbObject::HashValue(const Value& value)
{
Value temp;
Type::Ptr type = value.GetReflectionType();
if (ConfigObject::TypeInstance->IsAssignableFrom(type))
temp = Serialize(value, FAConfig);
else
temp = value;
return SHA256(JsonEncode(temp));
}
void DbObject::SendConfigUpdateHeavy(const Dictionary::Ptr& configFields)
{
/* update custom var config and status */
SendVarsConfigUpdate();
SendVarsConfigUpdateHeavy();
SendVarsStatusUpdate();
/* config attributes */
Dictionary::Ptr fields = GetConfigFields();
if (!fields)
if (!configFields)
return;
ASSERT(configFields->Contains("config_hash"));
ConfigObject::Ptr object = GetObject();
DbQuery query;
query.Table = GetType()->GetTable() + "s";
query.Type = DbQueryInsert | DbQueryUpdate;
query.Category = DbCatConfig;
query.Fields = fields;
query.Fields->Set(GetType()->GetIDColumn(), GetObject());
query.Fields = configFields;
query.Fields->Set(GetType()->GetIDColumn(), object);
query.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
query.Fields->Set("config_type", 1);
query.WhereCriteria = new Dictionary();
query.WhereCriteria->Set(GetType()->GetIDColumn(), GetObject());
query.WhereCriteria->Set(GetType()->GetIDColumn(), object);
query.Object = this;
query.ConfigUpdate = true;
OnQuery(query);
m_LastConfigUpdate = Utility::GetTime();
OnConfigUpdate();
OnConfigUpdateHeavy();
}
void DbObject::SendConfigUpdateLight(void)
{
OnConfigUpdateLight();
}
void DbObject::SendStatusUpdate(void)
@ -152,7 +201,7 @@ void DbObject::SendStatusUpdate(void)
OnStatusUpdate();
}
void DbObject::SendVarsConfigUpdate(void)
void DbObject::SendVarsConfigUpdateHeavy(void)
{
ConfigObject::Ptr obj = GetObject();
@ -161,10 +210,29 @@ void DbObject::SendVarsConfigUpdate(void)
if (!custom_var_object)
return;
std::vector<DbQuery> queries;
DbQuery query1;
query1.Table = "customvariables";
query1.Type = DbQueryDelete;
query1.Category = DbCatConfig;
query1.WhereCriteria = new Dictionary();
query1.WhereCriteria->Set("object_id", obj);
queries.push_back(query1);
DbQuery query2;
query2.Table = "customvariablestatus";
query2.Type = DbQueryDelete;
query2.Category = DbCatConfig;
query2.WhereCriteria = new Dictionary();
query2.WhereCriteria->Set("object_id", obj);
queries.push_back(query2);
Dictionary::Ptr vars = CompatUtility::GetCustomAttributeConfig(custom_var_object);
if (vars) {
std::vector<DbQuery> queries;
ObjectLock olock (vars);
BOOST_FOREACH(const Dictionary::Pair& kv, vars) {
@ -185,26 +253,25 @@ void DbObject::SendVarsConfigUpdate(void)
fields->Set("varvalue", value);
fields->Set("is_json", is_json);
fields->Set("config_type", 1);
fields->Set("session_token", 0); /* DbConnection class fills in real ID */
fields->Set("object_id", obj);
fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
DbQuery query;
query.Table = "customvariables";
query.Type = DbQueryInsert | DbQueryUpdate;
query.Category = DbCatConfig;
query.Fields = fields;
DbQuery query3;
query3.Table = "customvariables";
query3.Type = DbQueryInsert;
query3.Category = DbCatConfig;
query3.Fields = fields;
query.WhereCriteria = new Dictionary();
query.WhereCriteria->Set("object_id", obj);
query.WhereCriteria->Set("varname", kv.first);
query.Object = this;
query3.WhereCriteria = new Dictionary();
query3.WhereCriteria->Set("object_id", obj);
query3.WhereCriteria->Set("varname", kv.first);
query3.Object = this;
queries.push_back(query);
queries.push_back(query3);
}
OnMultipleQueries(queries);
}
OnMultipleQueries(queries);
}
void DbObject::SendVarsStatusUpdate(void)
@ -240,7 +307,6 @@ void DbObject::SendVarsStatusUpdate(void)
fields->Set("varvalue", value);
fields->Set("is_json", is_json);
fields->Set("status_update_time", DbValue::FromTimestamp(Utility::GetTime()));
fields->Set("session_token", 0); /* DbConnection class fills in real ID */
fields->Set("object_id", obj);
fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
@ -272,7 +338,12 @@ double DbObject::GetLastStatusUpdate(void) const
return m_LastStatusUpdate;
}
void DbObject::OnConfigUpdate(void)
void DbObject::OnConfigUpdateHeavy(void)
{
/* Default handler does nothing. */
}
void DbObject::OnConfigUpdateLight(void)
{
/* Default handler does nothing. */
}
@ -350,7 +421,11 @@ void DbObject::VersionChangedHandler(const ConfigObject::Ptr& object)
DbObject::Ptr dbobj = DbObject::GetOrCreateByObject(object);
if (dbobj) {
dbobj->SendConfigUpdate();
Dictionary::Ptr configFields = dbobj->GetConfigFields();
String configHash = dbobj->CalculateConfigHash(configFields);
configFields->Set("config_hash", configHash);
dbobj->SendConfigUpdateHeavy(configFields);
dbobj->SendStatusUpdate();
}
}

View File

@ -81,20 +81,26 @@ public:
static boost::signals2::signal<void (const DbQuery&)> OnQuery;
static boost::signals2::signal<void (const std::vector<DbQuery>&)> OnMultipleQueries;
void SendConfigUpdate(void);
void SendConfigUpdateHeavy(const Dictionary::Ptr& configFields);
void SendConfigUpdateLight(void);
void SendStatusUpdate(void);
void SendVarsConfigUpdate(void);
void SendVarsConfigUpdateHeavy(void);
void SendVarsStatusUpdate(void);
double GetLastConfigUpdate(void) const;
double GetLastStatusUpdate(void) const;
virtual String CalculateConfigHash(const Dictionary::Ptr& configFields) const;
protected:
DbObject(const intrusive_ptr<DbType>& type, const String& name1, const String& name2);
virtual void OnConfigUpdate(void);
virtual void OnConfigUpdateHeavy(void);
virtual void OnConfigUpdateLight(void);
virtual void OnStatusUpdate(void);
static String HashValue(const Value& value);
private:
String m_Name1;
String m_Name2;

View File

@ -177,36 +177,59 @@ Dictionary::Ptr HostDbObject::GetStatusFields(void) const
return fields;
}
void HostDbObject::OnConfigUpdate(void)
void HostDbObject::OnConfigUpdateHeavy(void)
{
Host::Ptr host = static_pointer_cast<Host>(GetObject());
/* groups */
Array::Ptr groups = host->GetGroups();
std::vector<DbQuery> queries;
DbQuery query1;
query1.Table = DbType::GetByName("HostGroup")->GetTable() + "_members";
query1.Type = DbQueryDelete;
query1.Category = DbCatConfig;
query1.WhereCriteria = new Dictionary();
query1.WhereCriteria->Set("host_object_id", host);
queries.push_back(query1);
if (groups) {
ObjectLock olock(groups);
BOOST_FOREACH(const String& groupName, groups) {
HostGroup::Ptr group = HostGroup::GetByName(groupName);
DbQuery query1;
query1.Table = DbType::GetByName("HostGroup")->GetTable() + "_members";
query1.Type = DbQueryInsert | DbQueryUpdate;
query1.Category = DbCatConfig;
query1.Fields = new Dictionary();
query1.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
query1.Fields->Set("hostgroup_id", DbValue::FromObjectInsertID(group));
query1.Fields->Set("host_object_id", host);
query1.Fields->Set("session_token", 0); /* DbConnection class fills in real ID */
query1.WhereCriteria = new Dictionary();
query1.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
query1.WhereCriteria->Set("hostgroup_id", DbValue::FromObjectInsertID(group));
query1.WhereCriteria->Set("host_object_id", host);
DbQuery query2;
query2.Table = DbType::GetByName("HostGroup")->GetTable() + "_members";
query2.Type = DbQueryInsert;
query2.Category = DbCatConfig;
query2.Fields = new Dictionary();
query2.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
query2.Fields->Set("hostgroup_id", DbValue::FromObjectInsertID(group));
query2.Fields->Set("host_object_id", host);
query2.WhereCriteria = new Dictionary();
query2.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
query2.WhereCriteria->Set("hostgroup_id", DbValue::FromObjectInsertID(group));
query2.WhereCriteria->Set("host_object_id", host);
DbObject::OnQuery(query1);
queries.push_back(query2);
}
}
DbObject::OnMultipleQueries(queries);
queries.clear();
DbQuery query2;
query2.Table = GetType()->GetTable() + "_parenthosts";
query2.Type = DbQueryDelete;
query2.Category = DbCatConfig;
query2.WhereCriteria = new Dictionary();
query2.WhereCriteria->Set(GetType()->GetTable() + "_id", DbValue::FromObjectInsertID(GetObject()));
queries.push_back(query2);
/* parents */
BOOST_FOREACH(const Checkable::Ptr& checkable, host->GetParents()) {
Host::Ptr parent = dynamic_pointer_cast<Host>(checkable);
@ -228,13 +251,27 @@ void HostDbObject::OnConfigUpdate(void)
query1.Type = DbQueryInsert;
query1.Category = DbCatConfig;
query1.Fields = fields1;
OnQuery(query1);
queries.push_back(query1);
}
DbObject::OnMultipleQueries(queries);
/* host dependencies */
Log(LogDebug, "HostDbObject")
<< "host dependencies for '" << host->GetName() << "'";
queries.clear();
DbQuery query3;
query3.Table = GetType()->GetTable() + "dependencies";
query3.Type = DbQueryDelete;
query3.Category = DbCatConfig;
query3.WhereCriteria = new Dictionary();
query3.WhereCriteria->Set("dependent_host_object_id", host);
queries.push_back(query3);
BOOST_FOREACH(const Dependency::Ptr& dep, host->GetDependencies()) {
Checkable::Ptr parent = dep->GetParent();
@ -263,12 +300,26 @@ void HostDbObject::OnConfigUpdate(void)
query2.Type = DbQueryInsert;
query2.Category = DbCatConfig;
query2.Fields = fields2;
OnQuery(query2);
queries.push_back(query2);
}
DbObject::OnMultipleQueries(queries);
Log(LogDebug, "HostDbObject")
<< "host contacts: " << host->GetName();
queries.clear();
DbQuery query4;
query4.Table = GetType()->GetTable() + "_contacts";
query4.Type = DbQueryDelete;
query4.Category = DbCatConfig;
query4.WhereCriteria = new Dictionary();
query4.WhereCriteria->Set("host_id", DbValue::FromObjectInsertID(host));
queries.push_back(query4);
BOOST_FOREACH(const User::Ptr& user, CompatUtility::GetCheckableNotificationUsers(host)) {
Log(LogDebug, "HostDbObject")
<< "host contacts: " << user->GetName();
@ -283,12 +334,26 @@ void HostDbObject::OnConfigUpdate(void)
query_contact.Type = DbQueryInsert;
query_contact.Category = DbCatConfig;
query_contact.Fields = fields_contact;
OnQuery(query_contact);
queries.push_back(query_contact);
}
DbObject::OnMultipleQueries(queries);
Log(LogDebug, "HostDbObject")
<< "host contactgroups: " << host->GetName();
queries.clear();
DbQuery query5;
query5.Table = GetType()->GetTable() + "_contactgroups";
query5.Type = DbQueryDelete;
query5.Category = DbCatConfig;
query5.WhereCriteria = new Dictionary();
query5.WhereCriteria->Set("host_id", DbValue::FromObjectInsertID(host));
queries.push_back(query5);
BOOST_FOREACH(const UserGroup::Ptr& usergroup, CompatUtility::GetCheckableNotificationUserGroups(host)) {
Log(LogDebug, "HostDbObject")
<< "host contactgroups: " << usergroup->GetName();
@ -303,14 +368,93 @@ void HostDbObject::OnConfigUpdate(void)
query_contact.Type = DbQueryInsert;
query_contact.Category = DbCatConfig;
query_contact.Fields = fields_contact;
OnQuery(query_contact);
queries.push_back(query_contact);
}
DbObject::OnMultipleQueries(queries);
DoCommonConfigUpdate();
}
void HostDbObject::OnConfigUpdateLight(void)
{
DoCommonConfigUpdate();
}
void HostDbObject::DoCommonConfigUpdate(void)
{
Host::Ptr host = static_pointer_cast<Host>(GetObject());
/* update comments and downtimes on config change */
DbEvents::AddComments(host);
DbEvents::AddDowntimes(host);
}
void HostDbObject::OnStatusUpdate(void)
String HostDbObject::CalculateConfigHash(const Dictionary::Ptr& configFields) const
{
String hashData = DbObject::CalculateConfigHash(configFields);
Host::Ptr host = static_pointer_cast<Host>(GetObject());
Array::Ptr parents = new Array();
/* parents */
BOOST_FOREACH(const Checkable::Ptr& checkable, host->GetParents()) {
Host::Ptr parent = dynamic_pointer_cast<Host>(checkable);
if (!parent)
continue;
parents->Add(parent->GetName());
}
parents->Sort();
hashData += DbObject::HashValue(parents);
Array::Ptr dependencies = new Array();
/* dependencies */
BOOST_FOREACH(const Dependency::Ptr& dep, host->GetDependencies()) {
Checkable::Ptr parent = dep->GetParent();
if (!parent)
continue;
int state_filter = dep->GetStateFilter();
Array::Ptr depInfo = new Array();
depInfo->Add(parent->GetName());
depInfo->Add(dep->GetStateFilter());
depInfo->Add(dep->GetPeriodRaw());
dependencies->Add(depInfo);
}
dependencies->Sort();
hashData += DbObject::HashValue(dependencies);
Array::Ptr users = new Array();
BOOST_FOREACH(const User::Ptr& user, CompatUtility::GetCheckableNotificationUsers(host)) {
users->Add(user->GetName());
}
users->Sort();
hashData += DbObject::HashValue(users);
Array::Ptr userGroups = new Array();
BOOST_FOREACH(const UserGroup::Ptr& usergroup, CompatUtility::GetCheckableNotificationUserGroups(host)) {
userGroups->Add(usergroup->GetName());
}
userGroups->Sort();
hashData += DbObject::HashValue(userGroups);
return SHA256(hashData);
}

View File

@ -41,9 +41,13 @@ public:
virtual Dictionary::Ptr GetConfigFields(void) const override;
virtual Dictionary::Ptr GetStatusFields(void) const override;
virtual void OnConfigUpdateHeavy(void) override;
virtual void OnConfigUpdateLight(void) override;
virtual String CalculateConfigHash(const Dictionary::Ptr& configFields) const;
private:
virtual void OnConfigUpdate(void) override;
virtual void OnStatusUpdate(void) override;
void DoCommonConfigUpdate(void);
};
}

View File

@ -171,40 +171,63 @@ Dictionary::Ptr ServiceDbObject::GetStatusFields(void) const
return fields;
}
void ServiceDbObject::OnConfigUpdate(void)
void ServiceDbObject::OnConfigUpdateHeavy(void)
{
Service::Ptr service = static_pointer_cast<Service>(GetObject());
/* groups */
Array::Ptr groups = service->GetGroups();
std::vector<DbQuery> queries;
DbQuery query1;
query1.Table = DbType::GetByName("ServiceGroup")->GetTable() + "_members";
query1.Type = DbQueryDelete;
query1.Category = DbCatConfig;
query1.WhereCriteria = new Dictionary();
query1.WhereCriteria->Set("service_object_id", service);
queries.push_back(query1);
if (groups) {
ObjectLock olock(groups);
BOOST_FOREACH(const String& groupName, groups) {
ServiceGroup::Ptr group = ServiceGroup::GetByName(groupName);
DbQuery query1;
query1.Table = DbType::GetByName("ServiceGroup")->GetTable() + "_members";
query1.Type = DbQueryInsert | DbQueryUpdate;
query1.Category = DbCatConfig;
query1.Fields = new Dictionary();
query1.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
query1.Fields->Set("servicegroup_id", DbValue::FromObjectInsertID(group));
query1.Fields->Set("service_object_id", service);
query1.Fields->Set("session_token", 0); /* DbConnection class fills in real ID */
query1.WhereCriteria = new Dictionary();
query1.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
query1.WhereCriteria->Set("servicegroup_id", DbValue::FromObjectInsertID(group));
query1.WhereCriteria->Set("service_object_id", service);
DbQuery query2;
query2.Table = DbType::GetByName("ServiceGroup")->GetTable() + "_members";
query2.Type = DbQueryInsert;
query2.Category = DbCatConfig;
query2.Fields = new Dictionary();
query2.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
query2.Fields->Set("servicegroup_id", DbValue::FromObjectInsertID(group));
query2.Fields->Set("service_object_id", service);
query2.WhereCriteria = new Dictionary();
query2.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
query2.WhereCriteria->Set("servicegroup_id", DbValue::FromObjectInsertID(group));
query2.WhereCriteria->Set("service_object_id", service);
DbObject::OnQuery(query1);
queries.push_back(query2);
}
}
DbObject::OnMultipleQueries(queries);
/* service dependencies */
Log(LogDebug, "ServiceDbObject")
<< "service dependencies for '" << service->GetName() << "'";
queries.clear();
DbQuery query2;
query2.Table = GetType()->GetTable() + "dependencies";
query2.Type = DbQueryDelete;
query2.Category = DbCatConfig;
query2.WhereCriteria = new Dictionary();
query2.WhereCriteria->Set("dependent_service_object_id", service);
queries.push_back(query2);
BOOST_FOREACH(const Dependency::Ptr& dep, service->GetDependencies()) {
Checkable::Ptr parent = dep->GetParent();
@ -236,13 +259,27 @@ void ServiceDbObject::OnConfigUpdate(void)
query1.Type = DbQueryInsert;
query1.Category = DbCatConfig;
query1.Fields = fields1;
OnQuery(query1);
queries.push_back(query1);
}
DbObject::OnMultipleQueries(queries);
/* service contacts, contactgroups */
Log(LogDebug, "ServiceDbObject")
<< "service contacts: " << service->GetName();
queries.clear();
DbQuery query3;
query3.Table = GetType()->GetTable() + "_contacts";
query3.Type = DbQueryDelete;
query3.Category = DbCatConfig;
query3.WhereCriteria = new Dictionary();
query3.WhereCriteria->Set("service_id", DbValue::FromObjectInsertID(service));
queries.push_back(query3);
BOOST_FOREACH(const User::Ptr& user, CompatUtility::GetCheckableNotificationUsers(service)) {
Log(LogDebug, "ServiceDbObject")
<< "service contacts: " << user->GetName();
@ -257,12 +294,26 @@ void ServiceDbObject::OnConfigUpdate(void)
query_contact.Type = DbQueryInsert;
query_contact.Category = DbCatConfig;
query_contact.Fields = fields_contact;
OnQuery(query_contact);
queries.push_back(query_contact);
}
DbObject::OnMultipleQueries(queries);
Log(LogDebug, "ServiceDbObject")
<< "service contactgroups: " << service->GetName();
queries.clear();
DbQuery query4;
query4.Table = GetType()->GetTable() + "_contactgroups";
query4.Type = DbQueryDelete;
query4.Category = DbCatConfig;
query4.WhereCriteria = new Dictionary();
query4.WhereCriteria->Set("service_id", DbValue::FromObjectInsertID(service));
queries.push_back(query4);
BOOST_FOREACH(const UserGroup::Ptr& usergroup, CompatUtility::GetCheckableNotificationUserGroups(service)) {
Log(LogDebug, "ServiceDbObject")
<< "service contactgroups: " << usergroup->GetName();
@ -277,14 +328,77 @@ void ServiceDbObject::OnConfigUpdate(void)
query_contact.Type = DbQueryInsert;
query_contact.Category = DbCatConfig;
query_contact.Fields = fields_contact;
OnQuery(query_contact);
queries.push_back(query_contact);
}
DbObject::OnMultipleQueries(queries);
DoCommonConfigUpdate();
}
void ServiceDbObject::OnConfigUpdateLight(void)
{
DoCommonConfigUpdate();
}
void ServiceDbObject::DoCommonConfigUpdate(void)
{
Service::Ptr service = static_pointer_cast<Service>(GetObject());
/* update comments and downtimes on config change */
DbEvents::AddComments(service);
DbEvents::AddDowntimes(service);
}
void ServiceDbObject::OnStatusUpdate(void)
String ServiceDbObject::CalculateConfigHash(const Dictionary::Ptr& configFields) const
{
String hashData = DbObject::CalculateConfigHash(configFields);
Service::Ptr service = static_pointer_cast<Service>(GetObject());
Array::Ptr dependencies = new Array();
/* dependencies */
BOOST_FOREACH(const Dependency::Ptr& dep, service->GetDependencies()) {
Checkable::Ptr parent = dep->GetParent();
if (!parent)
continue;
int state_filter = dep->GetStateFilter();
Array::Ptr depInfo = new Array();
depInfo->Add(parent->GetName());
depInfo->Add(dep->GetStateFilter());
depInfo->Add(dep->GetPeriodRaw());
dependencies->Add(depInfo);
}
dependencies->Sort();
hashData += DbObject::HashValue(dependencies);
Array::Ptr users = new Array();
BOOST_FOREACH(const User::Ptr& user, CompatUtility::GetCheckableNotificationUsers(service)) {
users->Add(user->GetName());
}
users->Sort();
hashData += DbObject::HashValue(users);
Array::Ptr userGroups = new Array();
BOOST_FOREACH(const UserGroup::Ptr& usergroup, CompatUtility::GetCheckableNotificationUserGroups(service)) {
userGroups->Add(usergroup->GetName());
}
userGroups->Sort();
hashData += DbObject::HashValue(userGroups);
return SHA256(hashData);
}

View File

@ -44,9 +44,13 @@ public:
virtual Dictionary::Ptr GetConfigFields(void) const override;
virtual Dictionary::Ptr GetStatusFields(void) const override;
protected:
virtual void OnConfigUpdate(void) override;
virtual void OnStatusUpdate(void) override;
virtual void OnConfigUpdateHeavy(void) override;
virtual void OnConfigUpdateLight(void) override;
virtual String CalculateConfigHash(const Dictionary::Ptr& configFields) const;
private:
void DoCommonConfigUpdate(void);
};
}

View File

@ -50,7 +50,7 @@ Dictionary::Ptr TimePeriodDbObject::GetStatusFields(void) const
return Empty;
}
void TimePeriodDbObject::OnConfigUpdate(void)
void TimePeriodDbObject::OnConfigUpdateHeavy(void)
{
TimePeriod::Ptr tp = static_pointer_cast<TimePeriod>(GetObject());

View File

@ -38,9 +38,11 @@ public:
TimePeriodDbObject(const DbType::Ptr& type, const String& name1, const String& name2);
protected:
virtual Dictionary::Ptr GetConfigFields(void) const override;
virtual Dictionary::Ptr GetStatusFields(void) const override;
virtual void OnConfigUpdate(void) override;
virtual void OnConfigUpdateHeavy(void) override;
};
}

View File

@ -80,45 +80,65 @@ Dictionary::Ptr UserDbObject::GetStatusFields(void) const
return fields;
}
void UserDbObject::OnConfigUpdate(void)
void UserDbObject::OnConfigUpdateHeavy(void)
{
Dictionary::Ptr fields = new Dictionary();
User::Ptr user = static_pointer_cast<User>(GetObject());
/* groups */
Array::Ptr groups = user->GetGroups();
std::vector<DbQuery> queries;
DbQuery query1;
query1.Table = DbType::GetByName("UserGroup")->GetTable() + "_members";
query1.Type = DbQueryDelete;
query1.Category = DbCatConfig;
query1.WhereCriteria = new Dictionary();
query1.WhereCriteria->Set("contact_object_id", user);
queries.push_back(query1);
if (groups) {
ObjectLock olock(groups);
BOOST_FOREACH(const String& groupName, groups) {
UserGroup::Ptr group = UserGroup::GetByName(groupName);
DbQuery query1;
query1.Table = DbType::GetByName("UserGroup")->GetTable() + "_members";
query1.Type = DbQueryInsert | DbQueryUpdate;
query1.Category = DbCatConfig;
query1.Fields = new Dictionary();
query1.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
query1.Fields->Set("contactgroup_id", DbValue::FromObjectInsertID(group));
query1.Fields->Set("contact_object_id", user);
query1.Fields->Set("session_token", 0); /* DbConnection class fills in real ID */
query1.WhereCriteria = new Dictionary();
query1.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
query1.WhereCriteria->Set("contactgroup_id", DbValue::FromObjectInsertID(group));
query1.WhereCriteria->Set("contact_object_id", user);
DbQuery query2;
query2.Table = DbType::GetByName("UserGroup")->GetTable() + "_members";
query2.Type = DbQueryInsert | DbQueryUpdate;
query2.Category = DbCatConfig;
query2.Fields = new Dictionary();
query2.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
query2.Fields->Set("contactgroup_id", DbValue::FromObjectInsertID(group));
query2.Fields->Set("contact_object_id", user);
query2.WhereCriteria = new Dictionary();
query2.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
query2.WhereCriteria->Set("contactgroup_id", DbValue::FromObjectInsertID(group));
query2.WhereCriteria->Set("contact_object_id", user);
OnQuery(query1);
queries.push_back(query2);
}
}
/* contact addresses */
Log(LogDebug, "UserDbObject")
<< "contact addresses for '" << user->GetName() << "'";
DbObject::OnMultipleQueries(queries);
queries.clear();
DbQuery query2;
query2.Table = "contact_addresses";
query2.Type = DbQueryDelete;
query2.Category = DbCatConfig;
query2.WhereCriteria = new Dictionary();
query2.WhereCriteria->Set("contact_id", DbValue::FromObjectInsertID(user));
queries.push_back(query2);
Dictionary::Ptr vars = user->GetVars();
if (vars) { /* This is sparta. */
for (int i = 1; i <= 6; i++) {
Dictionary::Ptr fields = new Dictionary();
String key = "address" + Convert::ToString(i);
if (!vars->Contains(key))
@ -136,7 +156,10 @@ void UserDbObject::OnConfigUpdate(void)
query.Table = "contact_addresses";
query.Category = DbCatConfig;
query.Fields = fields;
OnQuery(query);
queries.push_back(query);
}
}
DbObject::OnMultipleQueries(queries);
}

View File

@ -38,10 +38,11 @@ public:
UserDbObject(const DbType::Ptr& type, const String& name1, const String& name2);
protected:
virtual Dictionary::Ptr GetConfigFields(void) const override;
virtual Dictionary::Ptr GetStatusFields(void) const override;
virtual void OnConfigUpdate(void) override;
virtual void OnConfigUpdateHeavy(void) override;
};
}

View File

@ -436,12 +436,7 @@ void IdoMysqlConnection::FinishConnect(double startTime)
void IdoMysqlConnection::ClearTablesBySession(void)
{
/* delete all customvariables and group members without current session token */
ClearTableBySession("customvariables");
ClearTableBySession("customvariablestatus");
ClearTableBySession("hostgroup_members");
ClearTableBySession("servicegroup_members");
ClearTableBySession("contactgroup_members");
/* delete all comments and downtimes without current session token */
ClearTableBySession("comments");
ClearTableBySession("scheduleddowntime");
}
@ -453,11 +448,6 @@ void IdoMysqlConnection::ClearTableBySession(const String& table)
Convert::ToString(GetSessionToken()));
}
void IdoMysqlConnection::ClearConfigTable(const String& table)
{
Query("DELETE FROM " + GetTablePrefix() + table + " WHERE instance_id = " + Convert::ToString(static_cast<long>(m_InstanceID)));
}
void IdoMysqlConnection::AsyncQuery(const String& query, const boost::function<void (const IdoMysqlResult&)>& callback)
{
AssertOnWorkQueue();
@ -1058,13 +1048,15 @@ void IdoMysqlConnection::InternalCleanUpExecuteQuery(const String& table, const
void IdoMysqlConnection::FillIDCache(const DbType::Ptr& type)
{
String query = "SELECT " + type->GetIDColumn() + " AS object_id, " + type->GetTable() + "_id FROM " + GetTablePrefix() + type->GetTable() + "s";
String query = "SELECT " + type->GetIDColumn() + " AS object_id, " + type->GetTable() + "_id, config_hash FROM " + GetTablePrefix() + type->GetTable() + "s";
IdoMysqlResult result = Query(query);
Dictionary::Ptr row;
while ((row = FetchRow(result))) {
SetInsertID(type, DbReference(row->Get("object_id")), DbReference(row->Get(type->GetTable() + "_id")));
DbReference dbref(row->Get("object_id"));
SetInsertID(type, dbref, DbReference(row->Get(type->GetTable() + "_id")));
SetConfigHash(type, dbref, row->Get("config_hash"));
}
}

View File

@ -114,7 +114,6 @@ private:
void InternalCleanUpExecuteQuery(const String& table, const String& time_key, double time_value);
void InternalNewTransaction(void);
virtual void ClearConfigTable(const String& table) override;
void ClearTableBySession(const String& table);
void ClearTablesBySession(void);

View File

@ -54,6 +54,7 @@ CREATE TABLE IF NOT EXISTS icinga_commands (
config_type smallint default 0,
object_id bigint unsigned default 0,
command_line TEXT character set latin1 default '',
config_hash varchar(64) DEFAULT NULL,
PRIMARY KEY (command_id),
UNIQUE KEY instance_id (instance_id,object_id,config_type)
) ENGINE=InnoDB COMMENT='Command definitions';
@ -182,6 +183,7 @@ CREATE TABLE IF NOT EXISTS icinga_contactgroups (
config_type smallint default 0,
contactgroup_object_id bigint unsigned default 0,
alias varchar(255) character set latin1 default '',
config_hash varchar(64) DEFAULT NULL,
PRIMARY KEY (contactgroup_id),
UNIQUE KEY instance_id (instance_id,config_type,contactgroup_object_id)
) ENGINE=InnoDB COMMENT='Contactgroup definitions';
@ -197,7 +199,6 @@ CREATE TABLE IF NOT EXISTS icinga_contactgroup_members (
instance_id bigint unsigned default 0,
contactgroup_id bigint unsigned default 0,
contact_object_id bigint unsigned default 0,
session_token int default NULL,
PRIMARY KEY (contactgroup_member_id)
) ENGINE=InnoDB COMMENT='Contactgroup members';
@ -270,6 +271,7 @@ CREATE TABLE IF NOT EXISTS icinga_contacts (
notify_host_unreachable smallint default 0,
notify_host_flapping smallint default 0,
notify_host_downtime smallint default 0,
config_hash varchar(64) DEFAULT NULL,
PRIMARY KEY (contact_id),
UNIQUE KEY instance_id (instance_id,config_type,contact_object_id)
) ENGINE=InnoDB COMMENT='Contact definitions';
@ -344,7 +346,6 @@ CREATE TABLE IF NOT EXISTS icinga_customvariables (
varname varchar(255) character set latin1 collate latin1_general_cs default NULL,
varvalue TEXT character set latin1 default '',
is_json smallint default 0,
session_token int default NULL,
PRIMARY KEY (customvariable_id),
UNIQUE KEY object_id_2 (object_id,config_type,varname),
KEY varname (varname)
@ -365,7 +366,6 @@ CREATE TABLE IF NOT EXISTS icinga_customvariablestatus (
varname varchar(255) character set latin1 collate latin1_general_cs default NULL,
varvalue TEXT character set latin1 default '',
is_json smallint default 0,
session_token int default NULL,
PRIMARY KEY (customvariablestatus_id),
UNIQUE KEY object_id_2 (object_id,varname),
KEY varname (varname)
@ -612,6 +612,7 @@ CREATE TABLE IF NOT EXISTS icinga_hostgroups (
notes TEXT character set latin1 default NULL,
notes_url TEXT character set latin1 default NULL,
action_url TEXT character set latin1 default NULL,
config_hash varchar(64) DEFAULT NULL,
PRIMARY KEY (hostgroup_id),
UNIQUE KEY instance_id (instance_id,hostgroup_object_id)
) ENGINE=InnoDB COMMENT='Hostgroup definitions';
@ -627,7 +628,6 @@ CREATE TABLE IF NOT EXISTS icinga_hostgroup_members (
instance_id bigint unsigned default 0,
hostgroup_id bigint unsigned default 0,
host_object_id bigint unsigned default 0,
session_token int default NULL,
PRIMARY KEY (hostgroup_member_id)
) ENGINE=InnoDB COMMENT='Hostgroup members';
@ -697,6 +697,7 @@ CREATE TABLE IF NOT EXISTS icinga_hosts (
x_3d double default '0',
y_3d double default '0',
z_3d double default '0',
config_hash varchar(64) DEFAULT NULL,
PRIMARY KEY (host_id),
UNIQUE KEY instance_id (instance_id,config_type,host_object_id),
KEY host_object_id (host_object_id)
@ -1108,6 +1109,7 @@ CREATE TABLE IF NOT EXISTS icinga_servicegroups (
notes TEXT character set latin1 default NULL,
notes_url TEXT character set latin1 default NULL,
action_url TEXT character set latin1 default NULL,
config_hash varchar(64) DEFAULT NULL,
PRIMARY KEY (servicegroup_id),
UNIQUE KEY instance_id (instance_id,config_type,servicegroup_object_id)
) ENGINE=InnoDB COMMENT='Servicegroup definitions';
@ -1123,7 +1125,6 @@ CREATE TABLE IF NOT EXISTS icinga_servicegroup_members (
instance_id bigint unsigned default 0,
servicegroup_id bigint unsigned default 0,
service_object_id bigint unsigned default 0,
session_token int default NULL,
PRIMARY KEY (servicegroup_member_id)
) ENGINE=InnoDB COMMENT='Servicegroup members';
@ -1186,6 +1187,7 @@ CREATE TABLE IF NOT EXISTS icinga_services (
action_url TEXT character set latin1 default '',
icon_image TEXT character set latin1 default '',
icon_image_alt TEXT character set latin1 default '',
config_hash varchar(64) DEFAULT NULL,
PRIMARY KEY (service_id),
UNIQUE KEY instance_id (instance_id,config_type,service_object_id),
KEY service_object_id (service_object_id)
@ -1342,6 +1344,7 @@ CREATE TABLE IF NOT EXISTS icinga_timeperiods (
config_type smallint default 0,
timeperiod_object_id bigint unsigned default 0,
alias varchar(255) character set latin1 default '',
config_hash varchar(64) DEFAULT NULL,
PRIMARY KEY (timeperiod_id),
UNIQUE KEY instance_id (instance_id,config_type,timeperiod_object_id)
) ENGINE=InnoDB COMMENT='Timeperiod definitions';
@ -1379,6 +1382,7 @@ CREATE TABLE IF NOT EXISTS icinga_endpoints (
config_type smallint(6) DEFAULT '0',
identity varchar(255) DEFAULT NULL,
node varchar(255) DEFAULT NULL,
config_hash varchar(64) DEFAULT NULL,
PRIMARY KEY (endpoint_id)
) ENGINE=InnoDB COMMENT='Endpoint configuration';
@ -1411,6 +1415,7 @@ CREATE TABLE IF NOT EXISTS icinga_zones (
config_type smallint(6) DEFAULT '0',
parent_zone_object_id bigint(20) unsigned DEFAULT '0',
is_global smallint(6),
config_hash varchar(64) DEFAULT NULL,
PRIMARY KEY (zone_id)
) ENGINE=InnoDB COMMENT='Zone configuration';
@ -1664,19 +1669,22 @@ CREATE INDEX idx_zones_parent_object_id on icinga_zones(parent_zone_object_id);
CREATE INDEX idx_zonestatus_parent_object_id on icinga_zonestatus(parent_zone_object_id);
-- #12210
CREATE INDEX idx_hg_session_del ON icinga_hostgroup_members (instance_id, session_token);
CREATE INDEX idx_sg_session_del ON icinga_servicegroup_members (instance_id, session_token);
CREATE INDEX idx_cg_session_del ON icinga_contactgroup_members (instance_id, session_token);
CREATE INDEX idx_cv_session_del ON icinga_customvariables (instance_id, session_token);
CREATE INDEX idx_cvs_session_del ON icinga_customvariablestatus (instance_id, session_token);
CREATE INDEX idx_comments_session_del ON icinga_comments (instance_id, session_token);
CREATE INDEX idx_downtimes_session_del ON icinga_scheduleddowntime (instance_id, session_token);
-- #12107
CREATE INDEX idx_statehistory_cleanup on icinga_statehistory(instance_id, state_time);
-- #12435
CREATE INDEX idx_customvariables_object_id on icinga_customvariables(object_id);
CREATE INDEX idx_contactgroup_members_object_id on icinga_contactgroup_members(contact_object_id);
CREATE INDEX idx_hostgroup_members_object_id on icinga_hostgroup_members(host_object_id);
CREATE INDEX idx_servicegroup_members_object_id on icinga_servicegroup_members(service_object_id);
CREATE INDEX idx_servicedependencies_dependent_service_object_id on icinga_servicedependencies(dependent_service_object_id);
CREATE INDEX idx_hostdependencies_dependent_host_object_id on icinga_hostdependencies(dependent_host_object_id);
CREATE INDEX idx_service_contacts_service_id on icinga_service_contacts(service_id);
CREATE INDEX idx_host_contacts_host_id on icinga_host_contacts(host_id);
-- -----------------------------------------
-- set dbversion
-- -----------------------------------------

View File

@ -60,24 +60,6 @@ CREATE INDEX idx_zonestatus_parent_object_id on icinga_zonestatus(parent_zone_ob
-- -----------------------------------------
CREATE INDEX idx_statehistory_cleanup on icinga_statehistory(instance_id, state_time);
-- -----------------------------------------
-- #12210
-- -----------------------------------------
ALTER TABLE icinga_hostgroup_members ADD COLUMN session_token int default NULL;
ALTER TABLE icinga_servicegroup_members ADD COLUMN session_token int default NULL;
ALTER TABLE icinga_contactgroup_members ADD COLUMN session_token int default NULL;
CREATE INDEX idx_hg_session_del ON icinga_hostgroup_members (instance_id, session_token);
CREATE INDEX idx_sg_session_del ON icinga_servicegroup_members (instance_id, session_token);
CREATE INDEX idx_cg_session_del ON icinga_contactgroup_members (instance_id, session_token);
DROP INDEX cv_session_del_idx ON icinga_customvariables;
DROP INDEX cvs_session_del_idx ON icinga_customvariablestatus;
CREATE INDEX idx_cv_session_del ON icinga_customvariables (instance_id, session_token);
CREATE INDEX idx_cvs_session_del ON icinga_customvariablestatus (instance_id, session_token);
-- -----------------------------------------
-- #12258
-- -----------------------------------------
@ -87,6 +69,32 @@ ALTER TABLE icinga_scheduleddowntime ADD COLUMN session_token INTEGER default NU
CREATE INDEX idx_comments_session_del ON icinga_comments (instance_id, session_token);
CREATE INDEX idx_downtimes_session_del ON icinga_scheduleddowntime (instance_id, session_token);
-- -----------------------------------------
-- #12435
-- -----------------------------------------
ALTER TABLE icinga_commands ADD config_hash VARCHAR(64) DEFAULT NULL;
ALTER TABLE icinga_contactgroups ADD config_hash VARCHAR(64) DEFAULT NULL;
ALTER TABLE icinga_contacts ADD config_hash VARCHAR(64) DEFAULT NULL;
ALTER TABLE icinga_hostgroups ADD config_hash VARCHAR(64) DEFAULT NULL;
ALTER TABLE icinga_hosts ADD config_hash VARCHAR(64) DEFAULT NULL;
ALTER TABLE icinga_servicegroups ADD config_hash VARCHAR(64) DEFAULT NULL;
ALTER TABLE icinga_services ADD config_hash VARCHAR(64) DEFAULT NULL;
ALTER TABLE icinga_timeperiods ADD config_hash VARCHAR(64) DEFAULT NULL;
ALTER TABLE icinga_endpoints ADD config_hash VARCHAR(64) DEFAULT NULL;
ALTER TABLE icinga_zones ADD config_hash VARCHAR(64) DEFAULT NULL;
ALTER TABLE icinga_customvariables DROP session_token;
ALTER TABLE icinga_customvariablestatus DROP session_token;
CREATE INDEX idx_customvariables_object_id on icinga_customvariables(object_id);
CREATE INDEX idx_contactgroup_members_object_id on icinga_contactgroup_members(contact_object_id);
CREATE INDEX idx_hostgroup_members_object_id on icinga_hostgroup_members(host_object_id);
CREATE INDEX idx_servicegroup_members_object_id on icinga_servicegroup_members(service_object_id);
CREATE INDEX idx_servicedependencies_dependent_service_object_id on icinga_servicedependencies(dependent_service_object_id);
CREATE INDEX idx_hostdependencies_dependent_host_object_id on icinga_hostdependencies(dependent_host_object_id);
CREATE INDEX idx_service_contacts_service_id on icinga_service_contacts(service_id);
CREATE INDEX idx_host_contacts_host_id on icinga_host_contacts(host_id);
-- -----------------------------------------
-- set dbversion
-- -----------------------------------------

View File

@ -407,12 +407,7 @@ void IdoPgsqlConnection::FinishConnect(double startTime)
void IdoPgsqlConnection::ClearTablesBySession(void)
{
/* delete all customvariables and group members without current session token */
ClearTableBySession("customvariables");
ClearTableBySession("customvariablestatus");
ClearTableBySession("hostgroup_members");
ClearTableBySession("servicegroup_members");
ClearTableBySession("contactgroup_members");
/* delete all comments and downtimes without current session token */
ClearTableBySession("comments");
ClearTableBySession("scheduleddowntime");
}
@ -424,11 +419,6 @@ void IdoPgsqlConnection::ClearTableBySession(const String& table)
Convert::ToString(GetSessionToken()));
}
void IdoPgsqlConnection::ClearConfigTable(const String& table)
{
Query("DELETE FROM " + GetTablePrefix() + table + " WHERE instance_id = " + Convert::ToString(static_cast<long>(m_InstanceID)));
}
IdoPgsqlResult IdoPgsqlConnection::Query(const String& query)
{
AssertOnWorkQueue();
@ -919,7 +909,7 @@ void IdoPgsqlConnection::InternalCleanUpExecuteQuery(const String& table, const
void IdoPgsqlConnection::FillIDCache(const DbType::Ptr& type)
{
String query = "SELECT " + type->GetIDColumn() + " AS object_id, " + type->GetTable() + "_id FROM " + GetTablePrefix() + type->GetTable() + "s";
String query = "SELECT " + type->GetIDColumn() + " AS object_id, " + type->GetTable() + "_id, config_hash FROM " + GetTablePrefix() + type->GetTable() + "s";
IdoPgsqlResult result = Query(query);
Dictionary::Ptr row;
@ -927,7 +917,9 @@ void IdoPgsqlConnection::FillIDCache(const DbType::Ptr& type)
int index = 0;
while ((row = FetchRow(result, index))) {
index++;
SetInsertID(type, DbReference(row->Get("object_id")), DbReference(row->Get(type->GetTable() + "_id")));
DbReference dbref(row->Get("object_id"));
SetInsertID(type, dbref, DbReference(row->Get(type->GetTable() + "_id")));
SetConfigHash(type, dbref, row->Get("config_hash"));
}
}

View File

@ -99,7 +99,6 @@ private:
void InternalExecuteMultipleQueries(const std::vector<DbQuery>& queries);
void InternalCleanUpExecuteQuery(const String& table, const String& time_key, double time_value);
virtual void ClearConfigTable(const String& table) override;
void ClearTableBySession(const String& table);
void ClearTablesBySession(void);

View File

@ -80,6 +80,7 @@ CREATE TABLE icinga_commands (
config_type INTEGER default 0,
object_id bigint default 0,
command_line TEXT default '',
config_hash varchar(64) DEFAULT NULL,
CONSTRAINT PK_command_id PRIMARY KEY (command_id) ,
CONSTRAINT UQ_commands UNIQUE (instance_id,object_id,config_type)
) ;
@ -208,6 +209,7 @@ CREATE TABLE icinga_contactgroups (
config_type INTEGER default 0,
contactgroup_object_id bigint default 0,
alias TEXT default '',
config_hash varchar(64) DEFAULT NULL,
CONSTRAINT PK_contactgroup_id PRIMARY KEY (contactgroup_id) ,
CONSTRAINT UQ_contactgroups UNIQUE (instance_id,config_type,contactgroup_object_id)
);
@ -296,6 +298,7 @@ CREATE TABLE icinga_contacts (
notify_host_unreachable INTEGER default 0,
notify_host_flapping INTEGER default 0,
notify_host_downtime INTEGER default 0,
config_hash varchar(64) DEFAULT NULL,
CONSTRAINT PK_contact_id PRIMARY KEY (contact_id) ,
CONSTRAINT UQ_contacts UNIQUE (instance_id,config_type,contact_object_id)
) ;
@ -639,6 +642,7 @@ CREATE TABLE icinga_hostgroups (
notes TEXT default NULL,
notes_url TEXT default NULL,
action_url TEXT default NULL,
config_hash varchar(64) DEFAULT NULL,
CONSTRAINT PK_hostgroup_id PRIMARY KEY (hostgroup_id) ,
CONSTRAINT UQ_hostgroups UNIQUE (instance_id,hostgroup_object_id)
) ;
@ -724,6 +728,7 @@ CREATE TABLE icinga_hosts (
x_3d double precision default 0,
y_3d double precision default 0,
z_3d double precision default 0,
config_hash varchar(64) DEFAULT NULL,
CONSTRAINT PK_host_id PRIMARY KEY (host_id) ,
CONSTRAINT UQ_hosts UNIQUE (instance_id,config_type,host_object_id)
) ;
@ -1135,6 +1140,7 @@ CREATE TABLE icinga_servicegroups (
notes TEXT default NULL,
notes_url TEXT default NULL,
action_url TEXT default NULL,
config_hash varchar(64) DEFAULT NULL,
CONSTRAINT PK_servicegroup_id PRIMARY KEY (servicegroup_id) ,
CONSTRAINT UQ_servicegroups UNIQUE (instance_id,config_type,servicegroup_object_id)
) ;
@ -1213,6 +1219,7 @@ CREATE TABLE icinga_services (
action_url TEXT default '',
icon_image TEXT default '',
icon_image_alt TEXT default '',
config_hash varchar(64) DEFAULT NULL,
CONSTRAINT PK_service_id PRIMARY KEY (service_id) ,
CONSTRAINT UQ_services UNIQUE (instance_id,config_type,service_object_id)
) ;
@ -1368,6 +1375,7 @@ CREATE TABLE icinga_timeperiods (
config_type INTEGER default 0,
timeperiod_object_id bigint default 0,
alias TEXT default '',
config_hash varchar(64) DEFAULT NULL,
CONSTRAINT PK_timeperiod_id PRIMARY KEY (timeperiod_id) ,
CONSTRAINT UQ_timeperiods UNIQUE (instance_id,config_type,timeperiod_object_id)
) ;
@ -1405,6 +1413,7 @@ CREATE TABLE icinga_endpoints (
config_type integer default 0,
identity text DEFAULT NULL,
node text DEFAULT NULL,
config_hash varchar(64) DEFAULT NULL,
CONSTRAINT PK_endpoint_id PRIMARY KEY (endpoint_id) ,
CONSTRAINT UQ_endpoints UNIQUE (instance_id,config_type,endpoint_object_id)
) ;
@ -1439,6 +1448,7 @@ CREATE TABLE icinga_zones (
parent_zone_object_id bigint default 0,
config_type integer default 0,
is_global integer default 0,
config_hash varchar(64) DEFAULT NULL,
CONSTRAINT PK_zone_id PRIMARY KEY (zone_id) ,
CONSTRAINT UQ_zones UNIQUE (instance_id,config_type,zone_object_id)
) ;
@ -1693,19 +1703,22 @@ CREATE INDEX idx_zones_parent_object_id on icinga_zones(parent_zone_object_id);
CREATE INDEX idx_zonestatus_parent_object_id on icinga_zonestatus(parent_zone_object_id);
-- #12210
CREATE INDEX idx_hg_session_del ON icinga_hostgroup_members (instance_id, session_token);
CREATE INDEX idx_sg_session_del ON icinga_servicegroup_members (instance_id, session_token);
CREATE INDEX idx_cg_session_del ON icinga_contactgroup_members (instance_id, session_token);
CREATE INDEX idx_comments_session_del ON icinga_comments (instance_id, session_token);
CREATE INDEX idx_downtimes_session_del ON icinga_scheduleddowntime (instance_id, session_token);
CREATE INDEX idx_cv_session_del ON icinga_customvariables (instance_id, session_token);
CREATE INDEX idx_cvs_session_del ON icinga_customvariablestatus (instance_id, session_token);
-- #12107
CREATE INDEX idx_statehistory_cleanup on icinga_statehistory(instance_id, state_time);
-- #12435
CREATE INDEX idx_customvariables_object_id on icinga_customvariables(object_id);
CREATE INDEX idx_contactgroup_members_object_id on icinga_contactgroup_members(contact_object_id);
CREATE INDEX idx_hostgroup_members_object_id on icinga_hostgroup_members(host_object_id);
CREATE INDEX idx_servicegroup_members_object_id on icinga_servicegroup_members(service_object_id);
CREATE INDEX idx_servicedependencies_dependent_service_object_id on icinga_servicedependencies(dependent_service_object_id);
CREATE INDEX idx_hostdependencies_dependent_host_object_id on icinga_hostdependencies(dependent_host_object_id);
CREATE INDEX idx_service_contacts_service_id on icinga_service_contacts(service_id);
CREATE INDEX idx_host_contacts_host_id on icinga_host_contacts(host_id);
-- -----------------------------------------
-- set dbversion
-- -----------------------------------------

View File

@ -38,24 +38,6 @@ CREATE INDEX idx_zonestatus_object_id on icinga_zonestatus(zone_object_id);
CREATE INDEX idx_zones_parent_object_id on icinga_zones(parent_zone_object_id);
CREATE INDEX idx_zonestatus_parent_object_id on icinga_zonestatus(parent_zone_object_id);
-- -----------------------------------------
-- #12210
-- -----------------------------------------
ALTER TABLE icinga_hostgroup_members ADD COLUMN session_token INTEGER default NULL;
ALTER TABLE icinga_servicegroup_members ADD COLUMN session_token INTEGER default NULL;
ALTER TABLE icinga_contactgroup_members ADD COLUMN session_token INTEGER default NULL;
CREATE INDEX idx_hg_session_del ON icinga_hostgroup_members (instance_id, session_token);
CREATE INDEX idx_sg_session_del ON icinga_servicegroup_members (instance_id, session_token);
CREATE INDEX idx_cg_session_del ON icinga_contactgroup_members (instance_id, session_token);
DROP INDEX cv_session_del_idx;
DROP INDEX cvs_session_del_idx;
CREATE INDEX idx_cv_session_del ON icinga_customvariables (instance_id, session_token);
CREATE INDEX idx_cvs_session_del ON icinga_customvariablestatus (instance_id, session_token);
-- -----------------------------------------
-- #12258
-- -----------------------------------------
@ -70,6 +52,32 @@ CREATE INDEX idx_downtimes_session_del ON icinga_scheduleddowntime (instance_id,
-- -----------------------------------------
CREATE INDEX idx_statehistory_cleanup on icinga_statehistory(instance_id, state_time);
-- -----------------------------------------
-- #12435
-- -----------------------------------------
ALTER TABLE icinga_commands ADD config_hash VARCHAR(64) DEFAULT NULL;
ALTER TABLE icinga_contactgroups ADD config_hash VARCHAR(64) DEFAULT NULL;
ALTER TABLE icinga_contacts ADD config_hash VARCHAR(64) DEFAULT NULL;
ALTER TABLE icinga_hostgroups ADD config_hash VARCHAR(64) DEFAULT NULL;
ALTER TABLE icinga_hosts ADD config_hash VARCHAR(64) DEFAULT NULL;
ALTER TABLE icinga_servicegroups ADD config_hash VARCHAR(64) DEFAULT NULL;
ALTER TABLE icinga_services ADD config_hash VARCHAR(64) DEFAULT NULL;
ALTER TABLE icinga_timeperiods ADD config_hash VARCHAR(64) DEFAULT NULL;
ALTER TABLE icinga_endpoints ADD config_hash VARCHAR(64) DEFAULT NULL;
ALTER TABLE icinga_zones ADD config_hash VARCHAR(64) DEFAULT NULL;
ALTER TABLE icinga_customvariables DROP session_token;
ALTER TABLE icinga_customvariablestatus DROP session_token;
CREATE INDEX idx_customvariables_object_id on icinga_customvariables(object_id);
CREATE INDEX idx_contactgroup_members_object_id on icinga_contactgroup_members(contact_object_id);
CREATE INDEX idx_hostgroup_members_object_id on icinga_hostgroup_members(host_object_id);
CREATE INDEX idx_servicegroup_members_object_id on icinga_servicegroup_members(service_object_id);
CREATE INDEX idx_servicedependencies_dependent_service_object_id on icinga_servicedependencies(dependent_service_object_id);
CREATE INDEX idx_hostdependencies_dependent_host_object_id on icinga_hostdependencies(dependent_host_object_id);
CREATE INDEX idx_service_contacts_service_id on icinga_service_contacts(service_id);
CREATE INDEX idx_host_contacts_host_id on icinga_host_contacts(host_id);
-- -----------------------------------------
-- set dbversion
-- -----------------------------------------