diff --git ChangeLog.d/bugfix/ZBX-19715 ChangeLog.d/bugfix/ZBX-19715 new file mode 100644 index 0000000..f01d61c --- /dev/null +++ ChangeLog.d/bugfix/ZBX-19715 @@ -0,0 +1 @@ +........S. [ZBX-19715] fixed high memory usage in trappers and proxy pollers when sending configuration to Zabbix proxy (vso) diff --git include/zbxjson.h include/zbxjson.h index 81fa808..e36e348 100644 --- include/zbxjson.h +++ include/zbxjson.h @@ -256,6 +256,7 @@ const char *zbx_json_strerror(void); void zbx_json_init(struct zbx_json *j, size_t allocate); void zbx_json_initarray(struct zbx_json *j, size_t allocate); void zbx_json_clean(struct zbx_json *j); +void zbx_json_cleanarray(struct zbx_json *j); void zbx_json_free(struct zbx_json *j); void zbx_json_addobject(struct zbx_json *j, const char *name); void zbx_json_addarray(struct zbx_json *j, const char *name); diff --git src/libs/zbxdbhigh/proxy.c src/libs/zbxdbhigh/proxy.c index 4db2d42..b05aee1 100644 --- src/libs/zbxdbhigh/proxy.c +++ src/libs/zbxdbhigh/proxy.c @@ -478,7 +478,7 @@ typedef struct { zbx_uint64_t itemid; zbx_uint64_t master_itemid; - struct zbx_json data; + char *buffer; } zbx_proxy_item_config_t; @@ -498,10 +498,10 @@ static int get_proxyconfig_table_items(zbx_uint64_t proxy_hostid, struct zbx_jso DB_RESULT result; DB_ROW row; zbx_hashset_t proxy_items; - struct zbx_json *jrow; zbx_vector_ptr_t items; zbx_uint64_t itemid; zbx_hashset_iter_t iter; + struct zbx_json json_array; zabbix_log(LOG_LEVEL_DEBUG, "In %s() proxy_hostid:" ZBX_FS_UI64, __func__, proxy_hostid); @@ -566,6 +566,7 @@ static int get_proxyconfig_table_items(zbx_uint64_t proxy_hostid, struct zbx_jso } zbx_hashset_create(&proxy_items, 1000, ZBX_DEFAULT_UINT64_HASH_FUNC, ZBX_DEFAULT_UINT64_COMPARE_FUNC); + zbx_json_initarray(&json_array, 256); while (NULL != (row = DBfetch(result))) { @@ -579,20 +580,26 @@ static int get_proxyconfig_table_items(zbx_uint64_t proxy_hostid, struct zbx_jso ZBX_STR2UINT64(proxy_item_local.itemid, row[0]); ZBX_STR2UINT64(proxy_item_local.master_itemid, row[fld_master]); proxy_item = zbx_hashset_insert(&proxy_items, &proxy_item_local, sizeof(proxy_item_local)); - zbx_json_initarray(&proxy_item->data, 256); - jrow = &proxy_item->data; + + proxyconfig_add_row(&json_array, row, table); + + proxy_item->buffer = zbx_malloc(NULL, json_array.buffer_size + 1); + memcpy(proxy_item->buffer, json_array.buffer, json_array.buffer_size + 1); + + zbx_json_cleanarray(&json_array); } else { ZBX_STR2UINT64(itemid, row[0]); zbx_hashset_insert(itemids, &itemid, sizeof(itemid)); + zbx_json_addarray(j, NULL); - jrow = j; + proxyconfig_add_row(j, row, table); + zbx_json_close(j); } - - proxyconfig_add_row(jrow, row, table); - zbx_json_close(jrow); } + DBfree_result(result); + zbx_json_free(&json_array); /* flush cached dependent items */ @@ -622,9 +629,9 @@ static int get_proxyconfig_table_items(zbx_uint64_t proxy_hostid, struct zbx_jso if (NULL != zbx_hashset_search(itemids, &proxy_item->master_itemid)) { zbx_hashset_insert(itemids, &proxy_item->itemid, sizeof(itemid)); - zbx_json_addraw(j, NULL, proxy_item->data.buffer); + zbx_json_addraw(j, NULL, proxy_item->buffer); } - zbx_json_free(&proxy_item->data); + zbx_free(proxy_item->buffer); zbx_hashset_remove_direct(&proxy_items, proxy_item); } @@ -632,9 +639,6 @@ static int get_proxyconfig_table_items(zbx_uint64_t proxy_hostid, struct zbx_jso } zbx_vector_ptr_destroy(&items); zbx_hashset_destroy(&proxy_items); - - DBfree_result(result); - skip_data: zbx_free(sql); diff --git src/libs/zbxjson/json.c src/libs/zbxjson/json.c index b2415a1..029bbfb 100644 --- src/libs/zbxjson/json.c +++ src/libs/zbxjson/json.c @@ -134,16 +134,24 @@ void zbx_json_initarray(struct zbx_json *j, size_t allocate) zbx_json_addarray(j, NULL); } -void zbx_json_clean(struct zbx_json *j) +static void zbx_json_setempty(struct zbx_json *j) { - assert(j); - j->buffer_offset = 0; j->buffer_size = 0; j->status = ZBX_JSON_EMPTY; j->level = 0; *j->buffer = '\0'; +} + +void zbx_json_cleanarray(struct zbx_json *j) +{ + zbx_json_setempty(j); + zbx_json_addarray(j, NULL); +} +void zbx_json_clean(struct zbx_json *j) +{ + zbx_json_setempty(j); zbx_json_addobject(j, NULL); } diff --git src/zabbix_server/proxypoller/proxypoller.c src/zabbix_server/proxypoller/proxypoller.c index 128136b..d4907ce 100644 --- src/zabbix_server/proxypoller/proxypoller.c +++ src/zabbix_server/proxypoller/proxypoller.c @@ -254,6 +254,8 @@ static int proxy_send_configuration(DC_PROXY *proxy) if (SUCCEED == (ret = send_data_to_proxy(proxy, &s, j.buffer, j.buffer_size))) { + zbx_json_free(&j); /* json buffer can be large, free as fast as possible */ + if (SUCCEED != (ret = zbx_recv_response(&s, 0, &error))) { zabbix_log(LOG_LEVEL_WARNING, "cannot send configuration data to proxy"