From 1019398d55500a5ae0527237c7c149eaaa6ea976 Mon Sep 17 00:00:00 2001 From: Yonas Habteab Date: Wed, 22 May 2024 12:27:54 +0200 Subject: [PATCH] Update object#config_hash after all relations queries --- lib/db_ido/dbobject.cpp | 23 +++++++++++++++++++++++ lib/db_ido/hostdbobject.cpp | 2 -- lib/db_ido/servicedbobject.cpp | 2 -- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/lib/db_ido/dbobject.cpp b/lib/db_ido/dbobject.cpp index 406bf5243..5b5aef4c6 100644 --- a/lib/db_ido/dbobject.cpp +++ b/lib/db_ido/dbobject.cpp @@ -119,6 +119,14 @@ void DbObject::SendConfigUpdateHeavy(const Dictionary::Ptr& configFields) ASSERT(configFields->Contains("config_hash")); + Value configHash = configFields->Get("config_hash"); + // Since all the child tables are relying on the inserted parent ID, we first need to insert/update the + // configuration fields of the current object without the actual config_hash value. Having the config hash + // set only after all relation queries eliminates some rare race conditions where e.g. host group members + // are not written to the database because Icinga 2 / the DBMS was unexpectedly stopped/reloaded shortly + // after the config_hash column was updated. + configFields->Set("config_hash", Empty); + ConfigObject::Ptr object = GetObject(); DbQuery query; @@ -138,7 +146,22 @@ void DbObject::SendConfigUpdateHeavy(const Dictionary::Ptr& configFields) m_LastConfigUpdate = Utility::GetTime(); + // Trigger config heavy udpates of the child classes. OnConfigUpdateHeavy(); + + // Now update the config hash attribute of the current object. + DbQuery configHashQuery; + configHashQuery.Table = GetType()->GetTable() + "s"; + configHashQuery.Type = DbQueryUpdate; + configHashQuery.Category = DbCatConfig; + configHashQuery.Fields = new Dictionary({{"config_hash", configHash}}); + configHashQuery.Object = this; + configHashQuery.ConfigUpdate = true; + configHashQuery.WhereCriteria = new Dictionary({{GetType()->GetIDColumn(), object}}); + OnQuery(configHashQuery); + + // Lastly, update some common configs that do not affect the config_hash column. + OnConfigUpdateLight(); } void DbObject::SendConfigUpdateLight() diff --git a/lib/db_ido/hostdbobject.cpp b/lib/db_ido/hostdbobject.cpp index 60d1a99d1..627b9b74e 100644 --- a/lib/db_ido/hostdbobject.cpp +++ b/lib/db_ido/hostdbobject.cpp @@ -330,8 +330,6 @@ void HostDbObject::OnConfigUpdateHeavy() } DbObject::OnMultipleQueries(queries); - - DoCommonConfigUpdate(); } void HostDbObject::OnConfigUpdateLight() diff --git a/lib/db_ido/servicedbobject.cpp b/lib/db_ido/servicedbobject.cpp index 7f711df5e..6d0701111 100644 --- a/lib/db_ido/servicedbobject.cpp +++ b/lib/db_ido/servicedbobject.cpp @@ -282,8 +282,6 @@ void ServiceDbObject::OnConfigUpdateHeavy() } DbObject::OnMultipleQueries(queries); - - DoCommonConfigUpdate(); } void ServiceDbObject::OnConfigUpdateLight()