]> granicus.if.org Git - icinga2/commitdiff
DB IDO: Remove deleted custom variables
authorMichael Friedrich <michael.friedrich@netways.de>
Mon, 26 Oct 2015 12:14:41 +0000 (13:14 +0100)
committerMichael Friedrich <michael.friedrich@netways.de>
Thu, 29 Oct 2015 15:00:06 +0000 (16:00 +0100)
We cannot clear the custom variable tables on startup and then re-insert
all known custom vars. Instead we "fixed" it by leaving them
in the database only updating their value if changed. We certainly
forgot about deleted custom vars at that point.

Since the older fix must stay in place, we'll use a session
token stored in the backend to check whether the custom
variable has been updated/inserted in the current session, or not.
If the session token does not match, the custom vars are deleted
at the end of the config dump. Ugly but fairly the only performant
solution as CVs don't have an object_id.

fixes #10436

lib/db_ido/dbobject.cpp
lib/db_ido_mysql/idomysqlconnection.cpp
lib/db_ido_mysql/idomysqlconnection.hpp
lib/db_ido_mysql/schema/mysql.sql
lib/db_ido_mysql/schema/upgrade/2.4.0.sql
lib/db_ido_pgsql/idopgsqlconnection.cpp
lib/db_ido_pgsql/idopgsqlconnection.hpp
lib/db_ido_pgsql/schema/pgsql.sql
lib/db_ido_pgsql/schema/upgrade/2.4.0.sql

index 6a6f11201faac53dbc3170cc7d99e9da878207ee..f201cf60c835be5ab5e484683c77b7d265ecaac2 100644 (file)
@@ -186,6 +186,7 @@ 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 */
 
@@ -240,6 +241,7 @@ 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 */
 
index 237cf6f2ead0534f0c122da4e6c38d5729c90d2b..731e1e48ba68b3c8e6024fd60f7fa9e0c47bda8b 100644 (file)
@@ -160,6 +160,8 @@ void IdoMysqlConnection::Reconnect(void)
 
        CONTEXT("Reconnecting to MySQL IDO database '" + GetName() + "'");
 
+       m_SessionToken = Utility::NewUniqueID();
+
        SetShouldConnect(true);
 
        std::vector<DbObject::Ptr> active_dbobjs;
@@ -369,6 +371,18 @@ void IdoMysqlConnection::Reconnect(void)
                        DeactivateObject(dbobj);
                }
        }
+
+       /* delete all customvariables without current session token */
+       ClearCustomVarTable("customvariables");
+       ClearCustomVarTable("customvariablestatus");
+
+       Query("COMMIT");
+       Query("BEGIN");
+}
+
+void IdoMysqlConnection::ClearCustomVarTable(const String& table)
+{
+       Query("DELETE FROM " + GetTablePrefix() + table + " WHERE session_token <> '" + Escape(m_SessionToken) + "'");
 }
 
 void IdoMysqlConnection::ClearConfigTable(const String& table)
@@ -665,6 +679,10 @@ bool IdoMysqlConnection::FieldToEscapedString(const String& key, const Value& va
                *result = static_cast<long>(m_InstanceID);
                return true;
        }
+       if (key == "session_token") {
+               *result = "'" + Escape(m_SessionToken) + "'";
+               return true;
+       }
        if (key == "notification_id") {
                *result = static_cast<long>(GetNotificationInsertID(value));
                return true;
index dd414186c5a70d62c0477883404525398f510e99..bab16a7a84f4765d2cd05724fc5f3f539525b779 100644 (file)
@@ -69,6 +69,7 @@ protected:
 
 private:
        DbReference m_InstanceID;
+       String m_SessionToken;
 
        WorkQueue m_QueryQueue;
 
@@ -109,6 +110,7 @@ private:
        void InternalNewTransaction(void);
 
        virtual void ClearConfigTable(const String& table) override;
+       void ClearCustomVarTable(const String& table);
 
        void ExceptionHandler(boost::exception_ptr exp);
 };
index 9eed8537381b401497575921029d2fdb2cc91081..90db69994c078b4a306d50153792547227a885d9 100644 (file)
@@ -340,6 +340,7 @@ 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 varchar(512) character set latin1 default NULL,
   PRIMARY KEY  (customvariable_id),
   UNIQUE KEY object_id_2 (object_id,config_type,varname),
   KEY varname (varname)
@@ -360,6 +361,7 @@ 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 varchar(512) character set latin1 default NULL,
   PRIMARY KEY  (customvariablestatus_id),
   UNIQUE KEY object_id_2 (object_id,varname),
   KEY varname (varname)
index a5b686b31827eaff73d12e0250c8b2aa29be8b05..36f1447f99618709530c35d0c6fbfe202bc56ea6 100644 (file)
@@ -48,6 +48,13 @@ ALTER TABLE icinga_hosts MODIFY freshness_threshold int;
 ALTER TABLE icinga_servicestatus ADD COLUMN original_attributes TEXT character set latin1  default NULL;
 ALTER TABLE icinga_hoststatus ADD COLUMN original_attributes TEXT character set latin1  default NULL;
 
+-- -----------------------------------------
+-- #10436 deleted custom vars
+-- -----------------------------------------
+
+ALTER TABLE icinga_customvariables ADD COLUMN session_token varchar(512) character set latin1 default NULL;
+ALTER TABLE icinga_customvariablestatus ADD COLUMN session_token varchar(512) character set latin1 default NULL;
+
 -- -----------------------------------------
 -- update dbversion
 -- -----------------------------------------
index 8c7a104871910979e9bbefc84eeb21c1f9b4b290..cef8ef555b59cdbcfe945918535dcedaea3c5109 100644 (file)
@@ -160,12 +160,13 @@ void IdoPgsqlConnection::Reconnect(void)
 
        CONTEXT("Reconnecting to PostgreSQL IDO database '" + GetName() + "'");
 
+       m_SessionToken = Utility::NewUniqueID();
+
        SetShouldConnect(true);
 
        std::vector<DbObject::Ptr> active_dbobjs;
 
        {
-
                bool reconnect = false;
 
                if (GetConnected()) {
@@ -365,6 +366,18 @@ void IdoPgsqlConnection::Reconnect(void)
                        DeactivateObject(dbobj);
                }
        }
+
+       /* delete all customvariables without current session token */
+       ClearCustomVarTable("customvariables");
+       ClearCustomVarTable("customvariablestatus");
+
+       Query("COMMIT");
+       Query("BEGIN");
+}
+
+void IdoPgsqlConnection::ClearCustomVarTable(const String& table)
+{
+       Query("DELETE FROM " + GetTablePrefix() + table + " WHERE session_token <> '" + Escape(m_SessionToken) + "'");
 }
 
 void IdoPgsqlConnection::ClearConfigTable(const String& table)
index f0998b18f04dfaf902bdd6ab70690311c391ac78..d3cedff01f903a50c38a1a6ceaa2f338701b7df1 100644 (file)
@@ -61,6 +61,7 @@ protected:
 
 private:
        DbReference m_InstanceID;
+       String m_SessionToken;
 
        WorkQueue m_QueryQueue;
 
@@ -93,6 +94,7 @@ private:
        void InternalCleanUpExecuteQuery(const String& table, const String& time_key, double time_value);
 
        virtual void ClearConfigTable(const String& table) override;
+       void ClearCustomVarTable(const String& table);
 
        void ExceptionHandler(boost::exception_ptr exp);
 };
index 78340e495acbad591c3f1cb0347f89ca8bb409d8..1c2dce81b4bf827f049dd283d3ed6f641a98574d 100644 (file)
@@ -366,6 +366,7 @@ CREATE TABLE  icinga_customvariables (
   varname TEXT  default '',
   varvalue TEXT  default '',
   is_json INTEGER  default 0,
+  session_token TEXT default NULL,
   CONSTRAINT PK_customvariable_id PRIMARY KEY (customvariable_id) ,
   CONSTRAINT UQ_customvariables UNIQUE (object_id,config_type,varname)
 ) ;
@@ -386,6 +387,7 @@ CREATE TABLE  icinga_customvariablestatus (
   varname TEXT  default '',
   varvalue TEXT  default '',
   is_json INTEGER  default 0,
+  session_token TEXT default NULL,
   CONSTRAINT PK_customvariablestatus_id PRIMARY KEY (customvariablestatus_id) ,
   CONSTRAINT UQ_customvariablestatus UNIQUE (object_id,varname)
 ) ;
index 633351325a06dfe1ebff24880f8cb712e2652f79..d9075394753e31cebc10375067752ace491f1276 100644 (file)
@@ -157,6 +157,12 @@ CREATE TABLE  icinga_zonestatus (
 ALTER TABLE icinga_servicestatus ADD COLUMN  original_attributes TEXT default NULL;
 ALTER TABLE icinga_hoststatus ADD COLUMN  original_attributes TEXT default NULL;
 
+-- -----------------------------------------
+-- #10436 deleted custom vars
+-- -----------------------------------------
+ALTER TABLE icinga_customvariables ADD COLUMN session_token TEXT default NULL;
+ALTER TABLE icinga_customvariablestatus ADD COLUMN session_token TEXT default NULL;
+
 -- -----------------------------------------
 -- update dbversion
 -- -----------------------------------------