3 ** Copyright (C) 2000-2005 SIA Zabbix
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include "housekeeper.h"
29 extern unsigned char process_type;
31 /******************************************************************************
33 * Function: housekeeping_cleanup *
35 * Purpose: remove deleted items data *
37 * Return value: number of rows deleted *
39 * Author: Alexei Vladishev, Dmitry Borovikov *
41 * Comments: sqlite3 does not use CONFIG_MAX_HOUSEKEEPER_DELETE, deletes all *
43 ******************************************************************************/
44 static int housekeeping_cleanup()
46 const char *__function_name = "housekeeping_cleanup";
47 DB_HOUSEKEEPER housekeeper;
51 zbx_vector_uint64_t housekeeperids;
53 zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
55 zbx_vector_uint64_create(&housekeeperids);
57 /* order by tablename to effectively use DB cache */
59 "select housekeeperid,tablename,field,value"
61 " order by tablename");
63 while (NULL != (row = DBfetch(result)))
65 ZBX_STR2UINT64(housekeeper.housekeeperid, row[0]);
66 housekeeper.tablename = row[1];
67 housekeeper.field = row[2];
68 ZBX_STR2UINT64(housekeeper.value, row[3]);
70 if (0 == CONFIG_MAX_HOUSEKEEPER_DELETE)
74 " where %s=" ZBX_FS_UI64,
75 housekeeper.tablename,
81 #if defined(HAVE_IBM_DB2) || defined(HAVE_ORACLE)
84 " where %s=" ZBX_FS_UI64
86 housekeeper.tablename,
89 CONFIG_MAX_HOUSEKEEPER_DELETE);
90 #elif defined(HAVE_MYSQL)
93 " where %s=" ZBX_FS_UI64 " limit %d",
94 housekeeper.tablename,
97 CONFIG_MAX_HOUSEKEEPER_DELETE);
98 #elif defined(HAVE_POSTGRESQL)
99 extern int ZBX_PG_SVERSION;
101 /* PostgreSQL array constructors are available since version 7.4 */
102 if (70400 > ZBX_PG_SVERSION)
106 " where %s=" ZBX_FS_UI64
107 " and clock in (select clock from %s"
108 " where %s=" ZBX_FS_UI64 " limit %d)",
109 housekeeper.tablename,
112 housekeeper.tablename,
115 CONFIG_MAX_HOUSEKEEPER_DELETE);
121 " where ctid = any(array(select ctid from %s"
122 " where %s=" ZBX_FS_UI64 " limit %d))",
123 housekeeper.tablename,
124 housekeeper.tablename,
127 CONFIG_MAX_HOUSEKEEPER_DELETE);
129 #elif defined(HAVE_SQLITE3)
134 if (0 == d || 0 == CONFIG_MAX_HOUSEKEEPER_DELETE || CONFIG_MAX_HOUSEKEEPER_DELETE > d)
135 zbx_vector_uint64_append(&housekeeperids, housekeeper.housekeeperid);
139 DBfree_result(result);
141 if (0 != housekeeperids.values_num)
144 int sql_alloc = 512, sql_offset = 0;
146 sql = zbx_malloc(sql, sql_alloc);
148 zbx_vector_uint64_sort(&housekeeperids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
150 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 32, "delete from housekeeper where");
151 DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "housekeeperid",
152 housekeeperids.values, housekeeperids.values_num);
154 DBexecute("%s", sql);
159 zbx_vector_uint64_destroy(&housekeeperids);
161 zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d", __function_name, deleted);
166 static int housekeeping_sessions(int now)
168 const char *__function_name = "housekeeping_sessions";
171 zabbix_log(LOG_LEVEL_DEBUG, "In %s() now:%d", __function_name, now);
173 deleted = DBexecute("delete from sessions where lastaccess<%d", now - SEC_PER_YEAR);
175 zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d", __function_name, deleted);
180 static int housekeeping_alerts(int now)
182 const char *__function_name = "housekeeping_alerts";
188 zabbix_log(LOG_LEVEL_DEBUG, "In %s() now:%d", __function_name, now);
190 result = DBselect("select alert_history from config");
192 if (NULL == (row = DBfetch(result)) || SUCCEED == DBis_null(row[0]))
194 zabbix_log(LOG_LEVEL_ERR, "no records in table 'config'");
198 alert_history = atoi(row[0]);
200 deleted = DBexecute("delete from alerts where clock<%d", now - alert_history * SEC_PER_DAY);
202 DBfree_result(result);
204 zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d", __function_name, deleted);
209 static int housekeeping_events(int now)
211 const char *__function_name = "housekeeping_events";
212 int event_history, deleted = 0;
217 zbx_uint64_t eventid;
219 zabbix_log(LOG_LEVEL_DEBUG, "In %s() now:%d", __function_name, now);
221 result = DBselect("select event_history from config");
223 if (NULL == (row1 = DBfetch(result)) || SUCCEED == DBis_null(row1[0]))
225 zabbix_log(LOG_LEVEL_ERR, "no records in table 'config'");
229 event_history = atoi(row1[0]);
231 result2 = DBselect("select eventid from events where clock<%d", now - event_history * SEC_PER_DAY);
233 while (NULL != (row2 = DBfetch(result2)))
235 ZBX_STR2UINT64(eventid, row2[0]);
237 DBexecute("delete from acknowledges where eventid=" ZBX_FS_UI64, eventid);
238 deleted += DBexecute("delete from events where eventid=" ZBX_FS_UI64, eventid);
240 DBfree_result(result2);
242 DBfree_result(result);
244 zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d", __function_name, deleted);
249 /******************************************************************************
251 * Function: delete_history *
253 * Purpose: remove outdated information from historical table *
255 * Parameters: now - current timestamp *
257 * Return value: number of rows deleted *
259 * Author: Alexei Vladishev *
263 ******************************************************************************/
264 static int delete_history(const char *table, zbx_uint64_t itemid, int keep_history, int now)
266 const char *__function_name = "delete_history";
269 int min_clock, deleted;
271 zabbix_log(LOG_LEVEL_DEBUG, "In %s() table:'%s' itemid:" ZBX_FS_UI64 " keep_history:%d now:%d",
272 __function_name, table, itemid, keep_history, now);
274 result = DBselect("select min(clock) from %s where itemid=" ZBX_FS_UI64, table, itemid);
276 if (NULL == (row = DBfetch(result)) || SUCCEED == DBis_null(row[0]))
278 DBfree_result(result);
282 min_clock = atoi(row[0]);
283 min_clock = MIN(now - keep_history * SEC_PER_DAY, min_clock + 4 * CONFIG_HOUSEKEEPING_FREQUENCY * SEC_PER_HOUR);
284 DBfree_result(result);
286 deleted = DBexecute("delete from %s where itemid=" ZBX_FS_UI64 " and clock<%d", table, itemid, min_clock);
288 zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d", __function_name, deleted);
293 /******************************************************************************
295 * Function: housekeeping_history_and_trends *
297 * Purpose: remove outdated information from history and trends *
299 * Parameters: now - current timestamp *
301 * Return value: number of rows deleted *
303 * Author: Alexei Vladishev *
307 ******************************************************************************/
308 static int housekeeping_history_and_trends(int now)
310 const char *__function_name = "housekeeping_history_and_trends";
314 int history, trends, deleted = 0;
316 zabbix_log(LOG_LEVEL_DEBUG, "In %s() now:%d", __function_name, now);
319 "select i.itemid,i.history,i.trends from items i,hosts h"
320 " where i.hostid=h.hostid"
321 " and h.status in (%d,%d)",
322 HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED);
324 while (NULL != (row = DBfetch(result)))
326 ZBX_STR2UINT64(itemid, row[0]);
327 history = atoi(row[1]);
328 trends = atoi(row[2]);
330 deleted += delete_history("history", itemid, history, now);
331 deleted += delete_history("history_uint", itemid, history, now);
332 deleted += delete_history("history_str", itemid, history, now);
333 deleted += delete_history("history_text", itemid, history, now);
334 deleted += delete_history("history_log", itemid, history, now);
335 deleted += delete_history("trends", itemid, trends, now);
336 deleted += delete_history("trends_uint", itemid, trends, now);
338 DBfree_result(result);
340 zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d", __function_name, deleted);
345 void main_housekeeper_loop()
347 int now, d_history_and_trends, d_cleanup, d_events, d_alerts, d_sessions;
351 zabbix_log(LOG_LEVEL_WARNING, "executing housekeeper");
354 zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type));
356 DBconnect(ZBX_DB_CONNECT_NORMAL);
358 zbx_setproctitle("%s [removing old history and trends]", get_process_type_string(process_type));
359 d_history_and_trends = housekeeping_history_and_trends(now);
361 zbx_setproctitle("%s [removing deleted items data]", get_process_type_string(process_type));
362 d_cleanup = housekeeping_cleanup(now);
364 zbx_setproctitle("%s [removing old events]", get_process_type_string(process_type));
365 d_events = housekeeping_events(now);
367 zbx_setproctitle("%s [removing old alerts]", get_process_type_string(process_type));
368 d_alerts = housekeeping_alerts(now);
370 zbx_setproctitle("%s [removing old sessions]", get_process_type_string(process_type));
371 d_sessions = housekeeping_sessions(now);
373 zabbix_log(LOG_LEVEL_WARNING, "housekeeper deleted: %d records from history and trends,"
374 " %d records of deleted items, %d events, %d alerts, %d sessions",
375 d_history_and_trends, d_cleanup, d_events, d_alerts, d_sessions);
379 zbx_sleep_loop(CONFIG_HOUSEKEEPING_FREQUENCY * SEC_PER_HOUR);