DB IDO: Remove deleted custom variables

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
This commit is contained in:
Michael Friedrich 2015-10-26 13:14:41 +01:00
parent e3efe208bb
commit cf5735e3df
9 changed files with 55 additions and 1 deletions

View 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 */

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

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

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

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

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

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

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

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