diff options
-rw-r--r-- | include/zbxdb.h | 12 | ||||
-rw-r--r-- | include/zbxserver.h | 3 | ||||
-rw-r--r-- | src/libs/zbxdb/db.c | 10 | ||||
-rw-r--r-- | src/libs/zbxdbhigh/db.c | 41 | ||||
-rw-r--r-- | src/zabbix_server/housekeeper/housekeeper.c | 103 | ||||
-rw-r--r-- | src/zabbix_server/server.c | 24 |
6 files changed, 183 insertions, 10 deletions
diff --git a/include/zbxdb.h b/include/zbxdb.h index 13c7df0270e..dc607e1cc31 100644 --- a/include/zbxdb.h +++ b/include/zbxdb.h @@ -102,6 +102,11 @@ zbx_err_codes_t zbx_db_last_errcode(void); int zbx_tsdb_get_version(void); char *zbx_tsdb_get_license(void); #define ZBX_DB_TSDB_V1 (20000 > zbx_tsdb_get_version()) +int zbx_tsdb_table_has_compressed_chunks(const char *table_names); +#define ZBX_TSDB1_HISTORY_TABLES "'history_uint'::regclass,'history_log'::regclass,'history_str'::regclass,'history_text'::regclass,'history'::regclass" +#define ZBX_TSDB2_HISTORY_TABLES "'history_uint','history_log','history_str','history_text','history'" +#define ZBX_TSDB1_TRENDS_TABLES "'trends'::regclass,'trends_uint'::regclass" +#define ZBX_TSDB2_TRENDS_TABLES "'trends','trends_uint'" #endif #ifdef HAVE_ORACLE @@ -281,8 +286,15 @@ struct zbx_db_version_info_t char *ext_lic; zbx_db_ext_err_code_t ext_err_code; + + int history_compressed_chunks; + int trends_compressed_chunks; }; +#if defined(HAVE_POSTGRESQL) +void zbx_tsdb_update_dbversion_info(struct zbx_db_version_info_t *db_version_info); +#endif + void zbx_dbms_version_info_extract(struct zbx_db_version_info_t *version_info); #ifdef HAVE_POSTGRESQL void zbx_tsdb_info_extract(struct zbx_db_version_info_t *version_info); diff --git a/include/zbxserver.h b/include/zbxserver.h index a58b54d17da..df1451e55d5 100644 --- a/include/zbxserver.h +++ b/include/zbxserver.h @@ -22,6 +22,8 @@ #include "dbcache.h" #include "zbxvariant.h" +#include "zbxeval.h" +#include "zbxdb.h" #define MACRO_TYPE_MESSAGE_NORMAL 0x00000001 #define MACRO_TYPE_MESSAGE_RECOVERY 0x00000002 @@ -142,5 +144,4 @@ int xml_xpath_check(const char *xpath, char *error, size_t errlen); int zbx_substitute_expression_lld_macros(char **data, zbx_uint64_t rules, const struct zbx_json_parse *jp_row, const zbx_vector_ptr_t *lld_macro_paths, char **error); - #endif diff --git a/src/libs/zbxdb/db.c b/src/libs/zbxdb/db.c index 9dea3c999b5..91949607c4d 100644 --- a/src/libs/zbxdb/db.c +++ b/src/libs/zbxdb/db.c @@ -103,7 +103,7 @@ static ub4 OCI_DBserver_status(void); #elif defined(HAVE_POSTGRESQL) static PGconn *conn = NULL; static unsigned int ZBX_PG_BYTEAOID = 0; -static int ZBX_TSDB_VERSION = -1; +int ZBX_TSDB_VERSION = -1; static zbx_uint32_t ZBX_PG_SVERSION = ZBX_DBVERSION_UNDEFINED; char ZBX_PG_ESCAPE_BACKSLASH = 1; static int ZBX_TIMESCALE_COMPRESSION_AVAILABLE = OFF; @@ -2545,6 +2545,14 @@ void zbx_db_version_json_create(struct zbx_json *json, struct zbx_db_version_inf } zbx_json_addint64(json, "flag", info->flag); + +#if defined(HAVE_POSTGRESQL) + if (ZBX_TSDB_VERSION > 0) + { + zbx_json_addint64(json, "history_compressed_chunks", info->history_compressed_chunks); + zbx_json_addint64(json, "trends_compressed_chunks", info->trends_compressed_chunks); + } +#endif zbx_json_close(json); if (NULL != info->extension) diff --git a/src/libs/zbxdbhigh/db.c b/src/libs/zbxdbhigh/db.c index b2501e5c1a6..2f4bb43bdef 100644 --- a/src/libs/zbxdbhigh/db.c +++ b/src/libs/zbxdbhigh/db.c @@ -52,6 +52,47 @@ void DBclose(void) zbx_db_close(); } +#if defined(HAVE_POSTGRESQL) +int zbx_tsdb_table_has_compressed_chunks(const char *table_names) +{ + DB_RESULT result; + int ret; + + if (1 == ZBX_DB_TSDB_V1) { + result = DBselect("select null from timescaledb_information.compressed_chunk_stats where hypertable_name in (%s) and " + "compression_status='Compressed'", table_names); + } + else + { + result = DBselect("select null from timescaledb_information.chunks where hypertable_name in (%s) and " + "is_compressed='t'", table_names); + } + + if (NULL != DBfetch(result)) + ret = SUCCEED; + else + ret = FAIL; + + DBfree_result(result); + + return ret; +} + +void zbx_tsdb_update_dbversion_info(struct zbx_db_version_info_t *db_version_info) +{ + const char *history_tables, *trends_tables; + + history_tables = (1 == ZBX_DB_TSDB_V1 ? ZBX_TSDB1_HISTORY_TABLES : ZBX_TSDB2_HISTORY_TABLES); + trends_tables = (1 == ZBX_DB_TSDB_V1 ? ZBX_TSDB1_TRENDS_TABLES : ZBX_TSDB2_TRENDS_TABLES); + + db_version_info->history_compressed_chunks = (SUCCEED == + zbx_tsdb_table_has_compressed_chunks(history_tables)) ? 1 : 0; + + db_version_info->trends_compressed_chunks = (SUCCEED == + zbx_tsdb_table_has_compressed_chunks(trends_tables)) ? 1 : 0; +} +#endif + int zbx_db_validate_config_features(void) { int err = 0; diff --git a/src/zabbix_server/housekeeper/housekeeper.c b/src/zabbix_server/housekeeper/housekeeper.c index f76be50ae06..d801a9a84e2 100644 --- a/src/zabbix_server/housekeeper/housekeeper.c +++ b/src/zabbix_server/housekeeper/housekeeper.c @@ -31,6 +31,11 @@ extern ZBX_THREAD_LOCAL unsigned char process_type; extern unsigned char program_type; extern ZBX_THREAD_LOCAL int server_num, process_num; +extern struct zbx_db_version_info_t db_version_info; + +#if defined(HAVE_POSTGRESQL) +extern int ZBX_TSDB_VERSION; +#endif static int hk_period; @@ -563,6 +568,21 @@ out: #endif } +static void hk_update_dbversion_status(void) +{ + struct zbx_json db_version_json; + + zbx_json_initarray(&db_version_json, ZBX_JSON_STAT_BUF_LEN); + + zbx_tsdb_update_dbversion_info(&db_version_info); + + + zbx_db_version_json_create(&db_version_json, &db_version_info); + zbx_db_flush_version_requirements(db_version_json.buffer); + + zbx_json_free(&db_version_json); +} + /****************************************************************************** * * * Purpose: performs housekeeping for history and trends tables * @@ -570,22 +590,32 @@ out: * Parameters: now - [IN] the current timestamp * * * ******************************************************************************/ + static int housekeeping_history_and_trends(int now) { - int deleted = 0, i, rc; - zbx_hk_history_rule_t *rule; - + int deleted = 0, i, rc; + zbx_hk_history_rule_t *rule; +#if defined(HAVE_POSTGRESQL) + int ignore_history = 0, ignore_trends = 0; +#endif zabbix_log(LOG_LEVEL_DEBUG, "In %s() now:%d", __func__, now); /* prepare delete queues for all history housekeeping rules */ hk_history_delete_queue_prepare_all(hk_history_rules, now); +#if defined(HAVE_POSTGRESQL) + if (ZBX_TSDB_VERSION > 0) + { + hk_update_dbversion_status(); + } +#endif + /* Loop through the history rules. Each rule is a history table (such as history_log, trends_uint, etc) */ /* we need to clear records from */ for (rule = hk_history_rules; NULL != rule->table; rule++) { if (ZBX_HK_MODE_DISABLED == *rule->poption_mode) - continue; + goto skip; /* If partitioning enabled for history and/or trends then drop partitions with expired history. */ /* ZBX_HK_MODE_PARTITION is set during configuration sync based on the following: */ @@ -594,8 +624,42 @@ static int housekeeping_history_and_trends(int now) if (ZBX_HK_MODE_PARTITION == *rule->poption_mode) { hk_drop_partition_for_rule(rule, now); - continue; + goto skip; + } + +#if defined(HAVE_POSTGRESQL) + if (ZBX_TSDB_VERSION > 0) + { + if (0 == strcmp(rule->history, "history")) + { + if (1 == ignore_history) + goto skip; + + if (1 == db_version_info.history_compressed_chunks) + { + zabbix_log(LOG_LEVEL_WARNING, "Unable to perform housekeeping for history " + "tables due to having compressed chunks and disabled item history period override."); + + ignore_history = 1; + goto skip; + } + } + else if (0 == strcmp(rule->history, "trends")) + { + if (1 == ignore_trends) + goto skip; + + if (1 == db_version_info.trends_compressed_chunks) + { + zabbix_log(LOG_LEVEL_WARNING, "Unable to perform housekeeping for trends " + "tables due to having compressed chunks and disabled item trends period override."); + + ignore_trends = 1; + goto skip; + } + } } +#endif /* process delete queue for the housekeeping rule */ @@ -611,6 +675,7 @@ static int housekeeping_history_and_trends(int now) deleted += rc; } +skip: /* clear history rule delete queue so it's ready for the next housekeeping cycle */ hk_history_delete_queue_clear(rule); } @@ -1109,6 +1174,25 @@ static int get_housekeeping_period(double time_slept) return (int)time_slept; } +#if defined(HAVE_POSTGRESQL) +static void hk_tsdb_check_config() +{ + if (cfg.hk.history_global == ZBX_HK_OPTION_DISABLED && cfg.hk.history_mode == ZBX_HK_OPTION_ENABLED && + 1 == db_version_info.history_compressed_chunks) + { + zabbix_log(LOG_LEVEL_WARNING, "Incorrect configuration. Override item history period is disabled, but " + "historical data is compressed. Housekeeper may skip deleting this data."); + } + + if (cfg.hk.trends_global == ZBX_HK_OPTION_DISABLED && cfg.hk.trends_mode == ZBX_HK_OPTION_ENABLED && + 1 == db_version_info.trends_compressed_chunks) + { + zabbix_log(LOG_LEVEL_WARNING, "Incorrect configuration. Override item trends period is disabled, but " + "trends data is compressed. Housekeeper may skip deleting this data."); + } +} +#endif + ZBX_THREAD_ENTRY(housekeeper_thread, args) { int now, d_history_and_trends, d_cleanup, d_events, d_problems, d_sessions, d_services, @@ -1144,6 +1228,15 @@ ZBX_THREAD_ENTRY(housekeeper_thread, args) zbx_rtc_subscribe(&rtc, process_type, process_num); +#if defined(HAVE_POSTGRESQL) + + if (ZBX_TSDB_VERSION > 0) + { + zbx_config_get(&cfg, ZBX_CONFIG_FLAGS_HOUSEKEEPER); + hk_tsdb_check_config(); + } +#endif + while (ZBX_IS_RUNNING()) { zbx_uint32_t rtc_cmd; diff --git a/src/zabbix_server/server.c b/src/zabbix_server/server.c index c422d34e2df..538d72b70bd 100644 --- a/src/zabbix_server/server.c +++ b/src/zabbix_server/server.c @@ -174,6 +174,7 @@ static int ha_status = ZBX_NODE_STATUS_UNKNOWN; static int ha_failover_delay = ZBX_HA_DEFAULT_FAILOVER_DELAY; zbx_cuid_t ha_sessionid; + unsigned char program_type = ZBX_PROGRAM_TYPE_SERVER; ZBX_THREAD_LOCAL unsigned char process_type = ZBX_PROCESS_TYPE_UNKNOWN; ZBX_THREAD_LOCAL int process_num = 0; @@ -347,6 +348,14 @@ char *CONFIG_WEBSERVICE_URL = NULL; int CONFIG_SERVICEMAN_SYNC_FREQUENCY = 60; +#if defined(HAVE_POSTGRESQL) +extern int ZBX_TSDB_VERSION; +#endif + +struct zbx_db_version_info_t db_version_info; + +static volatile sig_atomic_t zbx_rtc_command; + int get_process_info_by_thread(int local_server_num, unsigned char *local_process_type, int *local_process_num); int get_process_info_by_thread(int local_server_num, unsigned char *local_process_type, int *local_process_num) @@ -1090,9 +1099,8 @@ int main(int argc, char **argv) static void zbx_check_db(void) { - struct zbx_db_version_info_t db_version_info; - struct zbx_json db_version_json; - int result = SUCCEED; + struct zbx_json db_version_json; + int result = SUCCEED; memset(&db_version_info, 0, sizeof(db_version_info)); result = zbx_db_check_version_info(&db_version_info, CONFIG_ALLOW_UNSUPPORTED_DB_VERSIONS); @@ -1127,6 +1135,11 @@ static void zbx_check_db(void) zabbix_log(LOG_LEVEL_WARNING, "database could be upgraded to use primary keys in history tables"); } +#if defined(HAVE_POSTGRESQL) + if (ZBX_TSDB_VERSION > 0) + zbx_tsdb_update_dbversion_info(&db_version_info); +#endif + zbx_db_version_json_create(&db_version_json, &db_version_info); if (SUCCEED == result) @@ -1137,6 +1150,7 @@ static void zbx_check_db(void) } DBclose(); + zbx_free(db_version_info.friendly_current_version); zbx_free(db_version_info.extension); zbx_free(db_version_info.ext_friendly_current_version); @@ -1144,6 +1158,7 @@ static void zbx_check_db(void) if(SUCCEED != result) { + zbx_free(db_version_info.friendly_current_version); exit(EXIT_FAILURE); } } @@ -1495,6 +1510,7 @@ static void server_teardown(zbx_rtc_t *rtc, zbx_socket_t *listen_sock) } } + int MAIN_ZABBIX_ENTRY(int flags) { char *error = NULL; @@ -1913,5 +1929,7 @@ void zbx_on_exit(int ret) setproctitle_free_env(); #endif + zbx_free(db_version_info.friendly_current_version); + exit(EXIT_SUCCESS); } |